Das PlaceSearchElement ist ein HTML-Element, mit dem die Ergebnisse einer Ortssuche in einer Liste gerendert werden. Es gibt zwei Möglichkeiten, das gmp-place-search
-Element zu konfigurieren:
- Verwenden Sie die Nearby Search-Anfrage, um Suchergebnisse mit dem
PlaceNearbySearchRequestElement
-Parameter zu rendern. - Verwenden Sie search by text request, um Suchergebnisse mit
PlaceTextSearchRequestElement
zu rendern.
Anfrage für die Suche in der Nähe
Wählen Sie im Menü einen Ortstyp aus, um Suchergebnisse in der Nähe für diesen Ortstyp zu sehen.
Im folgenden Beispiel wird das Element „Place Search“ als Reaktion auf eine Suche in der Nähe gerendert. Der Einfachheit halber sind nur drei Ortstypen aufgeführt: Café, Restaurant und Ladestation für Elektrofahrzeuge. Wenn ein Ergebnis ausgewählt wird, werden eine Markierung und
PlaceDetailsCompactElement für den ausgewählten Ort angezeigt. Wenn Sie das Place Search-Element in die Karte einfügen möchten, fügen Sie der HTML-Seite ein gmp-place-search
-Element mit einem gmp-place-nearby-search-request
-Element hinzu, wie im folgenden Snippet gezeigt:
<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>
Mehrere querySelector
-Aufrufe werden verwendet, um die Seitenelemente für die Interaktion auszuwählen:
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");
Wenn der Nutzer einen Ortstyp aus dem Menü auswählt, wird das gmp-place-nearby-search-request
-Element aktualisiert und im Place Search-Element werden die Ergebnisse angezeigt (Markierungen werden in der Hilfsfunktion addMarkers
hinzugefügt):
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 }); } }
Vollständiges Codebeispiel ansehen
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>
Nach Text suchen
Geben Sie einen Suchbegriff in das Eingabefeld ein und klicken Sie auf die Schaltfläche „Suchen“, um eine Liste von Orten zu erhalten, die dem Begriff entsprechen.
In diesem Beispiel wird das Element „Ortssuche“ als Reaktion auf eine Textsuche des Nutzers gerendert. Wenn ein Ergebnis ausgewählt wird, werden eine Markierung und
PlaceDetailsCompactElement für den ausgewählten Ort angezeigt. Wenn Sie das Place Search-Element in die Karte einfügen möchten, fügen Sie der HTML-Seite ein gmp-place-search
-Element mit einem gmp-place-search-text-search-request
-Element hinzu, wie im folgenden Snippet gezeigt:
<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>
Mehrere querySelector
-Aufrufe werden verwendet, um die Seitenelemente für die Interaktion auszuwählen:
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");
Wenn die Suchfunktion ausgeführt wird, nachdem der Nutzer eine Suchanfrage eingegeben hat, wird das gmp-place-text-search-request
-Element aktualisiert und im Element „Ortssuche“ werden die Ergebnisse angezeigt (Markierungen werden in der Hilfsfunktion addMarkers
hinzugefügt):
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 }); } }
Vollständiges Codebeispiel ansehen
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>