Yer Arama Öğesi

PlaceSearchElement, bir yer aramasının sonuçlarını listede oluşturmak için kullanılan bir HTML öğesidir. gmp-place-search öğesini yapılandırmanın iki yolu vardır:

Yakın çevrede arama isteği

Menüden bir yer türü seçerek bu yer türüyle ilgili yakındaki arama sonuçlarını görebilirsiniz.

Aşağıdaki örnekte, yakındaki bir arama yanıtı olarak Yer Arama öğesi oluşturulur. Basitlik için yalnızca üç yer türü listelenmiştir: kafe, restoran ve elektrikli araç şarj istasyonu. Bir sonuç seçildiğinde, seçilen yer için bir işaretçi ve PlaceDetailsCompactElement görüntülenir. Haritaya Yer Arama öğesini eklemek için aşağıdaki snippet'te gösterildiği gibi HTML sayfasına gmp-place-search öğesi içeren bir gmp-place-nearby-search-request öğesi ekleyin:

<div class="list-container">
  <div id="map-container"></div>
  <div class="controls">
      <select name="types" class="type-select">
      <option value="">Select a place type</option>
      <option value="cafe">Cafe</option>
      <option value="restaurant">Restaurant</option>
      <option value="electric_vehicle_charging_station">EV charging station</option>
      </select>
  </div>

<div class="list-container">
  <gmp-place-search orientation="vertical" selectable>
      <gmp-place-all-content> </gmp-place-all-content>
      <gmp-place-nearby-search-request
      ></gmp-place-nearby-search-request>
  </gmp-place-search>
</div>

<div id="details-container">
   <gmp-place-details-compact orientation="horizontal">
      <gmp-place-details-place-request></gmp-place-details-place-request>
      <gmp-place-all-content></gmp-place-all-content>
  </gmp-place-details-compact>
</div>

Etkileşim için sayfa öğelerini seçmek üzere çeşitli querySelector çağrıları kullanılır:

  const mapContainer = document.getElementById("map-container");
  const placeSearch = document.querySelector("gmp-place-search");
  const placeSearchQuery = document.querySelector("gmp-place-nearby-search-request");
  const detailsContainer = document.getElementById("details-container");
  const placeDetails = document.querySelector("gmp-place-details-compact");
  const placeRequest = document.querySelector("gmp-place-details-place-request");
  const typeSelect = document.querySelector(".type-select");

Kullanıcı menüden bir yer türü seçtiğinde gmp-place-nearby-search-request öğesi güncellenir ve Yer Arama öğesi sonuçları gösterir (addMarkers yardımcı işlevine işaretçiler eklenir):

  typeSelect.addEventListener('change', (event) => {
    event.preventDefault();
    searchPlaces();
});

function searchPlaces(){
  const bounds = gMap.getBounds();
  placeDetailsPopup.map = null;

  if (typeSelect.value) {
  placeSearch.style.display = 'block';
  placeSearchQuery.maxResultCount = 10;
  placeSearchQuery.locationRestriction = { center: cent, radius: 1000 };
  placeSearchQuery.includedTypes = [typeSelect.value];

  placeSearch.addEventListener('gmp-load', addMarkers, { once: true });
  }
}

Tam kod örneğini inceleyin

 
   

JavaScript

   
  const mapContainer = document.getElementById("map-container");
  const placeSearch = document.querySelector("gmp-place-search");
  const placeSearchQuery = document.querySelector("gmp-place-nearby-search-request");
  const detailsContainer = document.getElementById("details-container");
  const placeDetails = document.querySelector("gmp-place-details-compact");
  const placeRequest = document.querySelector("gmp-place-details-place-request");
  const typeSelect = document.querySelector(".type-select");

  let markers = {};
  let gMap;
  let placeDetailsPopup;
  let spherical;
  let AdvancedMarkerElement;
  let LatLngBounds;
  let LatLng;

  async function init() {
      console.log("init");
      ({ spherical } = await google.maps.importLibrary('geometry'));
      const {Map} = await google.maps.importLibrary("maps");
      await google.maps.importLibrary("places");
      ({AdvancedMarkerElement} = await google.maps.importLibrary("marker"));
      ({LatLngBounds, LatLng} = await google.maps.importLibrary("core"));

      let mapOptions = {
          center: {lat: -37.813, lng: 144.963},
          zoom: 16,
          mapTypeControl: false,
          clickableIcons: false,
          mapId: 'DEMO_MAP_ID'
      };

      gMap = new Map(mapContainer, mapOptions);

      placeDetailsPopup = new AdvancedMarkerElement({
          map: null,
          content: placeDetails,
          zIndex: 100
      });

      findCurrentLocation();

      gMap.addListener('click', (e) => {
          hidePlaceDetailsPopup();
      });

      typeSelect.addEventListener('change', (event) => {
              event.preventDefault();
              searchPlaces();
      });

      placeSearch.addEventListener("gmp-select", ({ place }) => {
          if (markers[place.id]) {
              markers[place.id].click();
          }
      });
  }

  function searchPlaces(){
      const bounds = gMap.getBounds();
      const cent = gMap.getCenter();
      const ne = bounds.getNorthEast();
      const sw = bounds.getSouthWest();
      const diameter = spherical.computeDistanceBetween(ne, sw);
      const cappedRadius = Math.min((diameter / 2 ), 50000); // Radius cannot be more than 50000.

      placeDetailsPopup.map = null;

      for(const markerId in markers){
          if (Object.prototype.hasOwnProperty.call(markers, markerId)) {
                  markers[markerId].map = null;
              }
      }

      markers = {};
      if (typeSelect.value) {
          mapContainer.style.height = '75vh';
          placeSearch.style.display = 'block';
          placeSearchQuery.maxResultCount = 10;
          placeSearchQuery.locationRestriction = { center: cent, radius: cappedRadius };
          placeSearchQuery.includedTypes = [typeSelect.value];
          placeSearch.addEventListener('gmp-load', addMarkers, { once: true });
          console.log("selection!");
          console.log(cappedRadius);
      }
  }

  async function addMarkers(){
      const bounds = new LatLngBounds();
        placeSearch.style.display = 'block';

      if(placeSearch.places.length > 0){
          placeSearch.places.forEach((place) => {
              let marker = new AdvancedMarkerElement({
                  map: gMap,
                  position: place.location
              });

              marker.metadata = {id: place.id};
              markers[place.id] = marker;
              bounds.extend(place.location);

              marker.addListener('click',(event) => {
                  placeRequest.place = place;
                  placeDetails.style.display = 'block';

                  placeDetailsPopup.position = place.location;
                  placeDetailsPopup.map = gMap;

                  gMap.fitBounds(place.viewport, {top: 0, left: 400});

                  placeDetails.addEventListener('gmp-load',() => {
                      gMap.fitBounds(place.viewport, {top: 0, right: 450});
                  }, { once: true });

              });
              gMap.setCenter(bounds.getCenter());
              gMap.fitBounds(bounds);
          });
      }
  }

  async function findCurrentLocation(){
      const { LatLng } = await google.maps.importLibrary("core");
      if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(
            (position) => {
              const pos = new LatLng(position.coords.latitude,position.coords.longitude);
              gMap.panTo(pos);
              gMap.setZoom(16);
            },
            () => {
              console.log('The Geolocation service failed.');
              gMap.setZoom(16);
            },
          );
        } else {
          console.log("Your browser doesn't support geolocation");
          gMap.setZoom(16);
        }
  }

  function hidePlaceDetailsPopup() {
      if (placeDetailsPopup.map) {
          placeDetailsPopup.map = null;
          placeDetails.style.display = 'none';
      }
  }

  init();
  
 
 
   

CSS

   
  html,
  body {
      height: 100%;
      margin: 0;
  }

  body {
      display: flex;
      flex-direction: column;
      font-family: Arial, Helvetica, sans-serif;
  }

  h1 {
      font-size: large;
      text-align: center;
  }

  #map-container {
      flex-grow: 1;
      max-height:600px;
      box-sizing: border-box;
      width: 100%;
      height: 100vh;
  }

  .controls {
      position: absolute;
      top: 40px;
      right: 40px;
  }

  .list-container {
      display: flex;
      position: absolute;
      max-height: 500px;
      top: 80px;
      right: 40px;
      overflow-y: none;
  }

  .type-select {
      width: 400px;
      height: 32px;
      border: 1px solid #000;
      border-radius: 10px;
      flex-grow: 1;
      padding: 0 10px;
    }

  gmp-place-search {
        width: 400px;
        margin: 0;
        border-radius: 10px;
        display: none;
        border: none;
  }

  gmp-place-details-compact {
      width: 350px;
      max-height: 800px;
      margin-right: 20px;
      display: none;
      border: none;
  }

  gmp-place-details-compact::after {
      content: '';
      position: absolute;
      bottom: -18px;
      left: 50%;
      transform: translateX(-50%);
      width: 20px;
      height: 20px;
      background-color: white;
      box-shadow: 2px 2px 5px 0 rgba(0,0,0,0.2);
      z-index: 1;
      clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
      transform-origin: center center;
  }

  @media (prefers-color-scheme: dark) {
      /* Style for Dark mode */
      gmp-place-details-compact::after {
          background-color: #131314;
      }
  }

  
 
 
   

HTML

   
<!DOCTYPE html>
  <html>
    <head>
      <title>Place Search with Compact Place Details Element</title>
      <meta charset="utf-8">
      <link rel="stylesheet" href="style.css">
      <script type="module" src="./index.js"></script>
    </head>
    <body>
      <div id="map-container"></div>
      <div class="controls">
          <select name="types" class="type-select">
          <option value="">Select a place type</option>
          <option value="cafe">Cafe</option>
          <option value="restaurant">Restaurant</option>
          <option value="electric_vehicle_charging_station">EV charging station</option>
          </select>
      </div>
      <div class="list-container">
          <gmp-place-search orientation="vertical" selectable>
              <gmp-place-all-content> </gmp-place-all-content>
              <gmp-place-nearby-search-request
              ></gmp-place-nearby-search-request>
          </gmp-place-search>
      </div>
      <div id="details-container">
          <gmp-place-details-compact orientation="horizontal">
            <gmp-place-details-place-request></gmp-place-details-place-request>
            <gmp-place-all-content></gmp-place-all-content>
          </gmp-place-details-compact>
      </div>
      <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: "YOUR_API_KEY", v: "weekly"});
      </script>
    </body>
  </html>
 

Metin isteğiyle arama

Giriş alanına bir arama terimi girin ve terimle eşleşen yerlerin listesini almak için Arama düğmesini tıklayın.

Bu örnek, kullanıcı metin aramasına yanıt olarak yer arama öğesini oluşturur. Bir sonuç seçildiğinde, seçilen yer için bir işaretçi ve PlaceDetailsCompactElement gösterilir. Haritaya Yer Arama öğesini eklemek için aşağıdaki snippet'te gösterildiği gibi HTML sayfasına gmp-place-search öğesi içeren bir gmp-place-search-text-search-request öğesi ekleyin:

  <div id="map-container"></div>
  <div class="controls">
  <input type="text" class="query-input" />
  <button class="search-button">Search</button>
  </div>

  <div class="list-container">
    <gmp-place-search orientation="vertical" selectable>
        <gmp-place-all-content> </gmp-place-all-content>
        <gmp-place-text-search-request></gmp-place-text-search-request>
    </gmp-place-search>
  </div>

  <div id="details-container">
      <gmp-place-details-compact orientation="horizontal">
          <gmp-place-details-place-request></gmp-place-details-place-request>
          <gmp-place-all-content></gmp-place-all-content>
      </gmp-place-details-compact>
  </div>
  

Etkileşim için sayfa öğelerini seçmek üzere çeşitli querySelector çağrıları kullanılır:

  const mapContainer = document.getElementById("map-container");
  const placeSearch = document.querySelector("gmp-place-search");
  const placeSearchQuery = document.querySelector("gmp-place-text-search-request");
  const queryInput = document.querySelector(".query-input");
  const searchButton = document.querySelector(".search-button");
  const detailsContainer = document.getElementById("details-container");
  const placeDetails = document.querySelector("gmp-place-details-compact");
  const placeRequest = document.querySelector("gmp-place-details-place-request");

Kullanıcı bir arama sorgusu girdikten sonra arama işlevi çalıştırıldığında gmp-place-text-search-request öğesi güncellenir ve yer arama öğesi sonuçları gösterir (addMarkers yardımcı işlevine işaretçiler eklenir):

searchButton.addEventListener("click", searchPlaces);
queryInput.addEventListener("keydown", (event) => {
    if (event.key == 'Enter') {
        event.preventDefault();
        searchPlaces();
    }
  });

function searchPlaces(){
  if (queryInput.value) {
      placeSearch.style.display = 'block';
      placeSearchQuery.textQuery = queryInput.value;
      placeSearchQuery.locationBias = gMap.getBounds();
      placeSearch.addEventListener('gmp-load', addMarkers, { once: true });
  }
}

Tam kod örneğini inceleyin

 
   

JavaScript

   
  const mapContainer = document.getElementById("map-container");
  const placeSearch = document.querySelector("gmp-place-search");
  const placeSearchQuery = document.querySelector("gmp-place-text-search-request");
  const queryInput = document.querySelector(".query-input");
  const searchButton = document.querySelector(".search-button");
  const detailsContainer = document.getElementById("details-container");
  const placeDetails = document.querySelector("gmp-place-details-compact");
  const placeRequest = document.querySelector("gmp-place-details-place-request");
  let markers = {};
  let previousSearchQuery = '';
  let gMap;
  let placeDetailsPopup;

  let AdvancedMarkerElement;
  let LatLngBounds;
  let LatLng;

  async function init() {
      const {Map} = await google.maps.importLibrary("maps");
      await google.maps.importLibrary("places");
      ({AdvancedMarkerElement} = await google.maps.importLibrary("marker"));
      ({LatLngBounds, LatLng} = await google.maps.importLibrary("core"));

      let mapOptions = {
          center: {lat: 37.422, lng: -122.085},
          zoom: 2,
          mapTypeControl: false,
          clickableIcons: false,
          mapId: 'DEMO_MAP_ID'
      };

      gMap = new Map(mapContainer, mapOptions);

      placeDetailsPopup = new AdvancedMarkerElement({
          map: null,
          content: placeDetails,
          zIndex: 100
      });

      findCurrentLocation();

      gMap.addListener('click', (e) => {
          hidePlaceDetailsPopup();
      });

      searchButton.addEventListener("click", searchPlaces);
      queryInput.addEventListener("keydown", (event) => {
          if (event.key == 'Enter') {
              event.preventDefault();
              searchPlaces();
          }
      });

      placeSearch.addEventListener("gmp-select", ({ place }) => {
          if (markers[place.id]) {
              markers[place.id].click();
          }
      });
  }

  function searchPlaces(){
      if (queryInput.value.trim() === previousSearchQuery) {
          return;
      }
      previousSearchQuery = queryInput.value.trim();
      placeDetailsPopup.map = null;

      for(const markerId in markers){
          if (Object.prototype.hasOwnProperty.call(markers, markerId)) {
                  markers[markerId].map = null;
              }
      }
      markers = {};
      if (queryInput.value) {
          // mapContainer.style.height = '75vh';
          placeSearch.style.display = 'block';
          placeSearchQuery.textQuery = queryInput.value;
          placeSearchQuery.locationBias = gMap.getBounds();
          placeSearch.addEventListener('gmp-load', addMarkers, { once: true });
      }
  }

  async function addMarkers(){
      const bounds = new LatLngBounds();

      if(placeSearch.places.length > 0){
          placeSearch.places.forEach((place) => {
              let marker = new AdvancedMarkerElement({
                  map: gMap,
                  position: place.location
              });

              marker.metadata = {id: place.id};
              markers[place.id] = marker;
              bounds.extend(place.location);

              marker.addListener('click',(event) => {
                  placeRequest.place = place;
                  placeDetails.style.display = 'block';

                  placeDetailsPopup.position = place.location;
                  placeDetailsPopup.map = gMap;

                  gMap.fitBounds(place.viewport, {top: 200, right: 450});

              });

              gMap.setCenter(bounds.getCenter());
              gMap.fitBounds(bounds);
          });
      }
  }

  async function findCurrentLocation(){
      const { LatLng } = await google.maps.importLibrary("core");
      if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(
            (position) => {
              const pos = new LatLng(position.coords.latitude,position.coords.longitude);
              gMap.panTo(pos);
              gMap.setZoom(16);
            },
            () => {
              console.log('The Geolocation service failed.');
              gMap.setZoom(16);
            },
          );
        } else {
          console.log("Your browser doesn't support geolocation");
          gMap.setZoom(16);
        }
  }

  function hidePlaceDetailsPopup() {
      if (placeDetailsPopup.map) {
          placeDetailsPopup.map = null;
          placeDetails.style.display = 'none';
      }
  }

  init();
 
 
   

CSS

   
  html,
  body {
      height: 100%;
      margin: 0;
  }

  body {
      display: flex;
      flex-direction: column;
      font-family: Arial, Helvetica, sans-serif;
  }

  h1 {
      font-size: large;
      text-align: center;
  }

  #map-container {
      flex-grow: 1;
      max-height:600px;
      box-sizing: border-box;
      width: 100%;
      height: 100vh;
  }

  .controls {
      border-radius: 5px;
      position: absolute;
      top: 40px;
      right: 40px;
  }

  .search-button {
      background-color: #4b4b4b;
      color: #fff;
      border: 1px solid #000;
      border-radius: 10px;
      width: 80px;
      height: 40px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.35);
  }

  .query-input {
      border: 1px solid #ccc;
      border-radius: 10px;
      width: 315px;
      height: 40px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.35);
  }

  .list-container {
      display: flex;
      position: absolute;
      max-height: 500px;
      top: 100px;
      right: 40px;
      overflow-y: none;
  }

  gmp-place-search {
       width: 400px;
       margin: 0;
        border-radius: 10px;
       display: none;
       border: none;
  }

  gmp-place-details-compact {
      width: 350px;
      max-height: 800px;
      display: none;
      border: none;
      transform: translateY(calc(-40%));
  }

  gmp-place-details-compact::after {
      content: '';
      position: absolute;
      bottom: -18px;
      left: 50%;
      transform: translateX(-50%);
      width: 20px;
      height: 20px;
      background-color: white;
      box-shadow: 2px 2px 5px 0 rgba(0,0,0,0.2);
      z-index: 1;
      clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
      transform-origin: center center;
  }

  @media (prefers-color-scheme: dark) {
      /* Style for Dark mode */
      gmp-place-details-compact::after {
          background-color: #131314;
      }
  }
 
 
   

HTML

   
<!DOCTYPE html>
<html>
  <head>
    <title>Place Search with a Details Popup</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <script type="module" src="./index.js"></script>
  </head>

  <body>
    <div id="map-container"></div>
    <div class="controls">
    <input type="text" class="query-input" />
    <button class="search-button">Search</button>
    </div>

    <div class="list-container">
      <gmp-place-search orientation="vertical" selectable>
          <gmp-place-all-content> </gmp-place-all-content>
          <gmp-place-text-search-request></gmp-place-text-search-request>
      </gmp-place-search>
    </div>

    <div id="details-container">
        <gmp-place-details-compact orientation="horizontal">
            <gmp-place-details-place-request></gmp-place-details-place-request>
            <gmp-place-all-content></gmp-place-all-content>
        </gmp-place-details-compact>
    </div>

    <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: "YOUR_API_KEY", v: "weekly"});
    </script>

  </body>
</html>