Place Autocomplete Data API

Avrupa Ekonomik Alanı (AEA) geliştiricileri

Yer Otomatik Tamamlama Verileri API'si, otomatik tamamlama widget'ı ile mümkün olandan daha hassas bir kontrol derecesiyle özelleştirilmiş otomatik tamamlama deneyimleri oluşturmak için yer tahminlerini programatik olarak almanıza olanak tanır. Bu kılavuzda, kullanıcı sorgularına dayalı otomatik tamamlama istekleri göndermek için Yer Adı Otomatik Tamamlama Verileri API'sini nasıl kullanacağınızı öğreneceksiniz.

Aşağıdaki örnekte basitleştirilmiş bir otomatik tamamlama entegrasyonu gösterilmektedir. Arama sorgunuzu (ör. "pizza" veya "poke") girin, ardından istediğiniz sonucu seçmek için tıklayın.

Otomatik tamamlama istekleri

Otomatik tamamlama isteği, sorgu giriş dizesini alır ve yer tahminlerinin listesini döndürür. Otomatik tamamlama isteğinde bulunmak için fetchAutocompleteSuggestions() işlevini çağırın ve gerekli özelliklere sahip bir istek iletin. input özelliği, aranacak dizeyi içerir. Normal bir uygulamada bu değer, kullanıcı sorgu yazarken güncellenir. İstek, faturalandırma amacıyla kullanılan bir sessionToken içermelidir.

Aşağıdaki snippet'te, istek gövdesi oluşturma ve oturum jetonu ekleme, ardından fetchAutocompleteSuggestions() çağrısı yaparak PlacePrediction listesini alma işlemi gösterilmektedir.

// Add an initial request body.
let request = {
  input: "Tadi",
  locationRestriction: {
    west: -122.44,
    north: 37.8,
    east: -122.39,
    south: 37.78,
  },
  origin: { lat: 37.7893, lng: -122.4039 },
  includedPrimaryTypes: ["restaurant"],
  language: "en-US",
  region: "us",
};
// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

Otomatik tamamlama tahminlerini kısıtlama

Yer Otomatik Tamamlama, varsayılan olarak kullanıcının konumuna yakın tahminler için önyargılı bir şekilde tüm yer türlerini sunar ve kullanıcının seçtiği yer için mevcut tüm veri alanlarını getirir. Sonuçları kısıtlayarak veya yönlendirerek daha alakalı tahminler sunmak için Yer Otomatik Tamamlama seçeneklerini ayarlayın.

Sonuçların kısıtlanması, otomatik tamamlama widget'ının kısıtlama alanı dışında kalan sonuçları yoksaymasına neden olur. Sonuçları harita sınırlarıyla kısıtlamak yaygın bir uygulamadır. Sonuçları önyargılı hale getirmek, otomatik tamamlama widget'ının belirtilen alan içindeki sonuçları göstermesine neden olur ancak bazı eşleşmeler bu alanın dışında olabilir.

Hedefe olan jeodezik mesafenin hesaplanacağı başlangıç noktasını belirtmek için origin özelliğini kullanın. Bu değer atlanırsa mesafe döndürülmez.

En fazla beş yer türü belirtmek için includedPrimaryTypes özelliğini kullanın. Tür belirtilmezse tüm türlerdeki yerler döndürülür.

API referansına bakın

Yer ayrıntılarını alma

Bir yer tahmini sonucundan Place nesnesi döndürmek için önce toPlace() işlevini, ardından da sonuçtaki Place nesnesinde fetchFields() işlevini çağırın (yer tahmininden gelen oturum kimliği otomatik olarak eklenir). Calling fetchFields(), otomatik tamamlama oturumunu sonlandırır.

let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});

const placeInfo = document.getElementById("prediction");

placeInfo.textContent =
  "First predicted place: " +
  place.displayName +
  ": " +
  place.formattedAddress;

Oturum jetonları

Oturum jetonları, kullanıcı otomatik tamamlama aramasının sorgu ve seçim aşamalarını faturalandırma amacıyla ayrı bir oturumda gruplandırır. Kullanıcı yazmaya başladığında oturum başlar. Kullanıcı bir yer seçtiğinde ve Yer Ayrıntıları'na çağrı yapıldığında oturum sona erer.

Yeni bir oturum jetonu oluşturup isteğe eklemek için AutocompleteSessionToken örneği oluşturun, ardından aşağıdaki snippet'te gösterildiği gibi jetonları kullanmak üzere isteğin sessionToken özelliğini ayarlayın:

// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

fetchFields() çağrıldığında oturum sonlandırılır. Place örneğini oluşturduktan sonra, oturum jetonunu fetchFields()'ye iletmeniz gerekmez. Bu işlem otomatik olarak yapılır.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});

AutocompleteSessionToken öğesinin yeni bir örneğini oluşturarak bir sonraki oturum için oturum jetonu oluşturun.

Oturum jetonu önerileri:

  • Tüm Yer Otomatik Tamamlama çağrıları için oturum jetonlarını kullanın.
  • Her oturum için yeni bir jeton oluşturun.
  • Her yeni oturum için benzersiz bir oturum jetonu iletin. Aynı jetonun birden fazla oturumda kullanılması, her isteğin ayrı ayrı faturalandırılmasına neden olur.

İsteğe bağlı olarak, bir istekten otomatik tamamlama oturumu jetonunu çıkarabilirsiniz. Oturum jetonu atlanırsa her istek ayrı olarak faturalandırılır ve Otomatik Tamamlama - İstek Başına SKU'su tetiklenir. Oturum jetonunu yeniden kullanırsanız oturum geçersiz sayılır ve istekler, oturum jetonu sağlanmamış gibi ücretlendirilir.

Örnek

Kullanıcı sorgu yazarken birkaç tuş vuruşunda bir (karakter başına değil) otomatik tamamlama isteği çağrılır ve olası sonuçların listesi döndürülür. Kullanıcı sonuç listesinden seçim yaptığında bu seçim istek olarak kabul edilir ve arama sırasında yapılan tüm istekler paketlenip tek bir istek olarak sayılır. Kullanıcı bir yer seçerse arama sorgusu ücretsiz olarak kullanılabilir ve yalnızca yer verileri isteği için ödeme alınır. Kullanıcı, oturumun başlamasından sonraki birkaç dakika içinde seçim yapmazsa yalnızca arama sorgusu için ödeme alınır.

Bir uygulama açısından etkinlik akışı şu şekildedir:

  1. Bir kullanıcı, "Paris, Fransa"yı aramak için sorgu yazmaya başlıyor.
  2. Uygulama, kullanıcı girişini algıladığında yeni bir oturum jetonu ("Jeton A") oluşturur.
  3. Kullanıcı yazarken API, her birkaç karakterde bir otomatik tamamlama isteğinde bulunur ve her biri için olası sonuçların yeni bir listesini gösterir:
    "P"
    "Par"
    "Paris,"
    "Paris, Fr"
  4. Kullanıcı seçim yaptığında:
    • Sorgudan kaynaklanan tüm istekler gruplandırılır ve "A Jetonu" ile temsil edilen oturuma tek bir istek olarak eklenir.
    • Kullanıcının seçimi, Yer Ayrıntısı isteği olarak sayılır ve "A Jetonu" ile temsil edilen oturuma eklenir.
  5. Oturum sona erer ve uygulama "A Jetonu"nu siler.
Oturumların nasıl faturalandırıldığı hakkında bilgi edinin.

Eksiksiz örnek kod

Bu bölümde, Yer Adı Otomatik Tamamlama Verileri API'sinin nasıl kullanılacağını gösteren eksiksiz örnekler yer almaktadır .

Yer otomatik tamamlama tahminleri

Aşağıdaki örnekte, "Tadi" girişi için fetchAutocompleteSuggestions() çağrısı yapılması, ardından ilk tahmin sonucu için toPlace() çağrısı yapılması ve son olarak yer ayrıntılarını almak için fetchFields() çağrısı yapılması gösterilmektedir.

TypeScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
    // @ts-ignore
    const { Place, AutocompleteSessionToken, AutocompleteSuggestion } = await google.maps.importLibrary("places") as google.maps.PlacesLibrary;

    // Add an initial request body.
    let request = {
        input: "Tadi",
        locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
        origin: { lat: 37.7893, lng: -122.4039 },
        includedPrimaryTypes: ["restaurant"],
        language: "en-US",
        region: "us",
    };

    // Create a session token.
    const token = new AutocompleteSessionToken();
    // Add the token to the request.
    // @ts-ignore
    request.sessionToken = token;
    // Fetch autocomplete suggestions.
    const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    const title = document.getElementById('title') as HTMLElement;
    title.appendChild(document.createTextNode('Query predictions for "' + request.input + '":'));

    for (let suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a new list element.
        const listItem = document.createElement('li');
        const resultsElement = document.getElementById("results") as HTMLElement;
        listItem.appendChild(document.createTextNode(placePrediction.text.toString()));
        resultsElement.appendChild(listItem);
    }

    let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });

    const placeInfo = document.getElementById("prediction") as HTMLElement;
    placeInfo.textContent = 'First predicted place: ' + place.displayName + ': ' + place.formattedAddress;

}

init();

JavaScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
  // @ts-ignore
  const { Place, AutocompleteSessionToken, AutocompleteSuggestion } =
    await google.maps.importLibrary("places");
  // Add an initial request body.
  let request = {
    input: "Tadi",
    locationRestriction: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
    origin: { lat: 37.7893, lng: -122.4039 },
    includedPrimaryTypes: ["restaurant"],
    language: "en-US",
    region: "us",
  };
  // Create a session token.
  const token = new AutocompleteSessionToken();

  // Add the token to the request.
  // @ts-ignore
  request.sessionToken = token;

  // Fetch autocomplete suggestions.
  const { suggestions } =
    await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
  const title = document.getElementById("title");

  title.appendChild(
    document.createTextNode('Query predictions for "' + request.input + '":'),
  );

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a new list element.
    const listItem = document.createElement("li");
    const resultsElement = document.getElementById("results");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.toString()),
    );
    resultsElement.appendChild(listItem);
  }

  let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent =
    "First predicted place: " +
    place.displayName +
    ": " +
    place.formattedAddress;
}

init();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Predictions</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="title"></div>
    <ul id="results"></ul>
    <p><span id="prediction"></span></p>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script>
  </body>
</html>

Örneği deneyin

Oturumlarla yer otomatik tamamlama yazarken bulma

Bu örnekte aşağıdaki kavramlar gösterilmektedir:

  • Kullanıcı sorgularına göre fetchAutocompleteSuggestions() arama yapma ve yanıt olarak tahmin edilen yerlerin listesini gösterme
  • Kullanıcı sorgusunu son Yer Ayrıntıları isteğiyle gruplandırmak için oturum jetonlarını kullanma.
  • Seçilen yerin ayrıntılarını alma ve bir işaretçi görüntüleme.
  • Kullanıcı arayüzü öğelerini gmp-map öğesine yerleştirmek için kontrol yerleştirme özelliğini kullanma.

TypeScript

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
let titleElement = document.querySelector('.title') as HTMLElement;
let resultsContainerElement = document.querySelector('.results') as HTMLElement;
let inputElement = document.querySelector('input') as HTMLInputElement;
let tokenStatusElement = document.querySelector('.token-status') as HTMLElement;
let newestRequestId = 0;
let tokenCount = 0;

// Create an initial request body.
const request: google.maps.places.AutocompleteRequest = {
    input: '',
    includedPrimaryTypes: [
        'restaurant',
        'cafe',
        'museum',
        'park',
        'botanical_garden',
    ],
}

async function init() {
    await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    // Update request center and bounds when the map bounds change.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        request.locationRestriction = innerMap.getBounds();
        request.origin = innerMap.getCenter();
    });

    inputElement.addEventListener('input', makeAutocompleteRequest);
}

async function makeAutocompleteRequest(inputEvent) {
    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;

    const { AutocompleteSuggestion } = (await google.maps.importLibrary(
        'places'
    )) as google.maps.PlacesLibrary;

    if (!inputEvent.target?.value) {
        titleElement.textContent = '';
        resultsContainerElement.replaceChildren();
        return;
    }

    // Add the latest char sequence to the request.
    request.input = (inputEvent.target as HTMLInputElement).value;

    // Fetch autocomplete suggestions and show them in a list.
    const { suggestions } =
        await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId) return;

    titleElement.innerText = `Place predictions for "${request.input}"`;

    // Clear the list first.
    resultsContainerElement.replaceChildren();

    for (const suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        if (!placePrediction) {
            continue;
        }

        // Create a link for the place, add an event handler to fetch the place.
        // We are using a button element to take advantage of its a11y capabilities.
        const placeButton = document.createElement('button');
        placeButton.addEventListener('click', () => {
            onPlaceSelected(placePrediction.toPlace());
        });
        placeButton.textContent = placePrediction.text.toString();
        placeButton.classList.add('place-button');

        // Create a new list item element.
        const li = document.createElement('li');
        li.appendChild(placeButton);
        resultsContainerElement.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place: google.maps.places.Place) {
    const { AdvancedMarkerElement } = (await google.maps.importLibrary(
        'marker'
    )) as google.maps.MarkerLibrary;

    await place.fetchFields({
        fields: ['displayName', 'formattedAddress', 'location'],
    });

    resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`;
    titleElement.textContent = 'Selected Place:';
    inputElement.value = '';

    await refreshToken();

    // Remove the previous marker, if it exists.
    if (marker) {
        marker.remove();
    }

    // Create a new marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
        position: place.location,
        title: place.displayName,
    })

    // Center the map on the selected place.
    if (place.location) {
        innerMap.setCenter(place.location);
        innerMap.setZoom(15);
    }
}

// Helper function to refresh the session token.
async function refreshToken() {
    const { AutocompleteSessionToken } = (await google.maps.importLibrary(
        'places'
    )) as google.maps.PlacesLibrary;

    // Increment the token counter.
    tokenCount++;

    // Create a new session token and add it to the request.
    request.sessionToken = new AutocompleteSessionToken();
    tokenStatusElement.textContent = `Session token count: ${tokenCount}`;
}

init();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;
let marker;
let titleElement = document.querySelector('.title');
let resultsContainerElement = document.querySelector('.results');
let inputElement = document.querySelector('input');
let tokenStatusElement = document.querySelector('.token-status');
let newestRequestId = 0;
let tokenCount = 0;
// Create an initial request body.
const request = {
    input: '',
    includedPrimaryTypes: [
        'restaurant',
        'cafe',
        'museum',
        'park',
        'botanical_garden',
    ],
};
async function init() {
    await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });
    // Update request center and bounds when the map bounds change.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        request.locationRestriction = innerMap.getBounds();
        request.origin = innerMap.getCenter();
    });
    inputElement.addEventListener('input', makeAutocompleteRequest);
}
async function makeAutocompleteRequest(inputEvent) {
    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;
    const { AutocompleteSuggestion } = (await google.maps.importLibrary('places'));
    if (!inputEvent.target?.value) {
        titleElement.textContent = '';
        resultsContainerElement.replaceChildren();
        return;
    }
    // Add the latest char sequence to the request.
    request.input = inputEvent.target.value;
    // Fetch autocomplete suggestions and show them in a list.
    const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId)
        return;
    titleElement.innerText = `Place predictions for "${request.input}"`;
    // Clear the list first.
    resultsContainerElement.replaceChildren();
    for (const suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;
        if (!placePrediction) {
            continue;
        }
        // Create a link for the place, add an event handler to fetch the place.
        // We are using a button element to take advantage of its a11y capabilities.
        const placeButton = document.createElement('button');
        placeButton.addEventListener('click', () => {
            onPlaceSelected(placePrediction.toPlace());
        });
        placeButton.textContent = placePrediction.text.toString();
        placeButton.classList.add('place-button');
        // Create a new list item element.
        const li = document.createElement('li');
        li.appendChild(placeButton);
        resultsContainerElement.appendChild(li);
    }
}
// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    const { AdvancedMarkerElement } = (await google.maps.importLibrary('marker'));
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress', 'location'],
    });
    resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`;
    titleElement.textContent = 'Selected Place:';
    inputElement.value = '';
    await refreshToken();
    // Remove the previous marker, if it exists.
    if (marker) {
        marker.remove();
    }
    // Create a new marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
        position: place.location,
        title: place.displayName,
    });
    // Center the map on the selected place.
    if (place.location) {
        innerMap.setCenter(place.location);
        innerMap.setZoom(15);
    }
}
// Helper function to refresh the session token.
async function refreshToken() {
    const { AutocompleteSessionToken } = (await google.maps.importLibrary('places'));
    // Increment the token counter.
    tokenCount++;
    // Create a new session token and add it to the request.
    request.sessionToken = new AutocompleteSessionToken();
    tokenStatusElement.textContent = `Session token count: ${tokenCount}`;
}
init();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.place-button {
  height: 3rem;
  width: 100%;
  background-color: transparent;
  text-align: left;
  border: none;
  cursor: pointer;
}

.place-button:focus-visible {
  outline: 2px solid #0056b3;
  border-radius: 2px;
}

.input {
  width: 300px;
  font-size: small;
  margin-bottom: 1rem;
}

/* Styles for the floating panel */
.controls {
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  font-family: sans-serif;
  font-size: small;
  margin: 12px;
  padding: 1rem;
}

.title {
  font-weight: bold;
  margin-top: 1rem;
  margin-bottom: 0.5rem;
}

.results {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.results li:not(:last-child) {
  border-bottom: 1px solid #ddd;
}

.results li:hover {
  background-color: #eee;
}

HTML

<html>
    <head>
        <title>Place Autocomplete Data API Session</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <!-- prettier-ignore -->
        <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
    </head>
    <body>
        <gmp-map center="37.7893, -122.4039" zoom="12" map-id="DEMO_MAP_ID">
            <div
                class="controls"
                slot="control-inline-start-block-start"
            >
                <input
                    type="text"
                    class="input"
                    placeholder="Search for a place..."
                    autocomplete="off"
                /><!-- Turn off the input's own autocomplete (not supported by all browsers).-->
                <div class="token-status"></div>
                <div class="title"></div>
                <ol class="results"></ol>
            </div>
        </gmp-map>
    </body>
</html>

Örneği deneyin