diff --git a/samples/ui-kit-place-search-nearby/index.html b/samples/ui-kit-place-search-nearby/index.html index 660d5f51..4cb551cd 100644 --- a/samples/ui-kit-place-search-nearby/index.html +++ b/samples/ui-kit-place-search-nearby/index.html @@ -7,83 +7,76 @@ - Place List Nearby Search with Google Maps + Place Search Nearby with Google Maps - + + + - -
+ +
+ + + +
- +
- + + + +
- +
- + + - - + + + + + + + + + - diff --git a/samples/ui-kit-place-search-nearby/index.ts b/samples/ui-kit-place-search-nearby/index.ts index 209c3e81..01eb57c0 100644 --- a/samples/ui-kit-place-search-nearby/index.ts +++ b/samples/ui-kit-place-search-nearby/index.ts @@ -6,153 +6,120 @@ /* [START maps_ui_kit_place_search_nearby] */ /* [START maps_ui_kit_place_search_nearby_query_selectors] */ -const map = document.querySelector('gmp-map') as any; -const placeList = document.querySelector('gmp-place-list') as any; -const typeSelect = document.querySelector('.type-select') as any; -const placeDetails = document.querySelector('gmp-place-details') as any; -const placeDetailsRequest = document.querySelector( +// Query selectors for various elements in the HTML file. +const map = document.querySelector('gmp-map') as google.maps.MapElement; +const placeSearch = document.querySelector('gmp-place-search') as any; +const placeSearchQuery = document.querySelector( + 'gmp-place-nearby-search-request' +) as any; +const placeDetails = document.querySelector('gmp-place-details-compact') as any; +const placeRequest = document.querySelector( 'gmp-place-details-place-request' ) as any; +const typeSelect = document.querySelector('.type-select') as HTMLSelectElement; /* [END maps_ui_kit_place_search_nearby_query_selectors] */ -let markers = {}; -let infoWindow; - -async function initMap(): Promise { - await google.maps.importLibrary('places'); - const { LatLngBounds } = (await google.maps.importLibrary( - 'core' - )) as google.maps.CoreLibrary; - const { InfoWindow } = (await google.maps.importLibrary( - 'maps' - )) as google.maps.MapsLibrary; - const { spherical } = (await google.maps.importLibrary( - 'geometry' - )) as google.maps.GeometryLibrary; - - infoWindow = new InfoWindow(); - let marker; - - function getContainingCircle(bounds) { - const diameter = spherical.computeDistanceBetween( - bounds.getNorthEast(), - bounds.getSouthWest() - ); - const calculatedRadius = diameter / 2; - const cappedRadius = Math.min(calculatedRadius, 50000); // Radius cannot be more than 50000. - return { center: bounds.getCenter(), radius: cappedRadius }; - } - findCurrentLocation(); +// Global variables for the map, markers, and info window. +const markers: Map = + new Map(); +let infoWindow: google.maps.InfoWindow; + +// The init function is called when the page loads. +async function init(): Promise { + // Import the necessary libraries from the Google Maps API. + const [{ InfoWindow }, { Place }] = await Promise.all([ + google.maps.importLibrary('maps') as Promise, + google.maps.importLibrary( + 'places' + ) as Promise, + ]); + + // Create a new info window and set its content to the place details element. + placeDetails.remove(); // Hide the place details element because it is not needed until the info window opens + infoWindow = new InfoWindow({ + content: placeDetails, + ariaLabel: 'Place Details', + }); + // Set the map options. map.innerMap.setOptions({ - mapTypeControl: false, clickableIcons: false, + mapTypeControl: false, + streetViewControl: false, }); /* [START maps_ui_kit_place_search_nearby_event] */ - placeDetails.addEventListener('gmp-load', (event) => { - // Center the info window on the map. - map.innerMap.fitBounds(placeDetails.place.viewport, { - top: 500, - left: 400, - }); - }); + // Add event listeners to the type select and place search elements. + typeSelect.addEventListener('change', () => searchPlaces()); - typeSelect.addEventListener('change', (event) => { - // First remove all existing markers. - for (marker in markers) { - markers[marker].map = null; - } - markers = {}; - - if (typeSelect.value) { - placeList.style.display = 'block'; - placeList - .configureFromSearchNearbyRequest({ - locationRestriction: getContainingCircle( - map.innerMap.getBounds() - ), - includedPrimaryTypes: [typeSelect.value], - }) - .then(addMarkers); - // Handle user selection in Place Details. - placeList.addEventListener('gmp-placeselect', ({ place }) => { - markers[place.id].click(); - }); - } + placeSearch.addEventListener('gmp-select', (event: Event) => { + const { place } = event as any; + markers.get(place.id)?.click(); + }); + placeSearch.addEventListener('gmp-load', () => { + addMarkers(); }); - /* [END maps_ui_kit_place_search_nearby_event] */ + + searchPlaces(); +} +/* [END maps_ui_kit_place_search_nearby_event] */ +// The searchPlaces function is called when the user changes the type select or when the page loads. +async function searchPlaces() { + // Close the info window and clear the markers. + infoWindow.close(); + for (const marker of markers.values()) { + marker.remove(); + } + markers.clear(); + + // Set the place search query and add an event listener to the place search element. + if (typeSelect.value) { + const center = map.center!; + placeSearchQuery.locationRestriction = { + center, + radius: 50000, // 50km radius + }; + placeSearchQuery.locationBias = { + center, + }; + placeSearchQuery.includedTypes = [typeSelect.value]; + } } +// The addMarkers function is called when the place search element loads. async function addMarkers() { - const { AdvancedMarkerElement } = (await google.maps.importLibrary( - 'marker' - )) as google.maps.MarkerLibrary; - const { LatLngBounds } = (await google.maps.importLibrary( - 'core' - )) as google.maps.CoreLibrary; - + // Import the necessary libraries from the Google Maps API. + const [{ AdvancedMarkerElement }, { LatLngBounds }] = await Promise.all([ + google.maps.importLibrary( + 'marker' + ) as Promise, + google.maps.importLibrary('core') as Promise, + ]); const bounds = new LatLngBounds(); - if (placeList.places.length > 0) { - placeList.places.forEach((place) => { - let marker = new AdvancedMarkerElement({ - map: map.innerMap, - position: place.location, - }); - - markers[place.id] = marker; - bounds.extend(place.location); - - /* [START maps_ui_kit_place_search_nearby_click_event] */ - marker.addListener('gmp-click', (event) => { - if (infoWindow.isOpen) { - infoWindow.close(); - } - - placeDetailsRequest.place = place.id; - placeDetails.style.display = 'block'; - placeDetails.style.width = '350px'; - infoWindow.setOptions({ - content: placeDetails, - }); - infoWindow.open({ - anchor: marker, - map: map.innerMap, - }); - }); - /* [END maps_ui_kit_place_search_nearby_click_event] */ - - map.innerMap.setCenter(bounds.getCenter()); - map.innerMap.fitBounds(bounds); - }); + if (placeSearch.places.length === 0) { + return; } -} -async function findCurrentLocation() { - const { LatLng } = (await google.maps.importLibrary( - 'core' - )) as google.maps.CoreLibrary; - if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition( - (position) => { - const pos = new LatLng( - position.coords.latitude, - position.coords.longitude - ); - map.innerMap.panTo(pos); - map.innerMap.setZoom(14); - }, - () => { - console.log('The Geolocation service failed.'); - map.innerMap.setZoom(14); - } - ); - } else { - console.log("Your browser doesn't support geolocation"); - map.innerMap.setZoom(14); + for (const place of placeSearch.places) { + const marker = new AdvancedMarkerElement({ + map: map.innerMap, + position: place.location, + collisionBehavior: + google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL, + }); + + markers.set(place.id, marker); + bounds.extend(place.location); + + marker.addListener('click', () => { + placeRequest.place = place; + infoWindow.open(map.innerMap, marker); + }); } + + map.innerMap.fitBounds(bounds); } -initMap(); +init(); /* [END maps_ui_kit_place_search_nearby] */ diff --git a/samples/ui-kit-place-search-nearby/style.css b/samples/ui-kit-place-search-nearby/style.css index e3e5d831..fbbf7449 100644 --- a/samples/ui-kit-place-search-nearby/style.css +++ b/samples/ui-kit-place-search-nearby/style.css @@ -16,54 +16,34 @@ body { font-family: Arial, Helvetica, sans-serif; } -h1 { - font-size: large; - text-align: center; +.container { + display: flex; + height: 100vh; + width: 100%; } gmp-map { - box-sizing: border-box; - height: 600px; + flex-grow: 1; } -.overlay { - position: relative; - top: 40px; - margin: 20px; +.ui-panel { width: 400px; + margin-left: 20px; + margin-top: 10px; + overflow-y: auto; + font-family: Arial, Helvetica, sans-serif; } -.controls { +.list-container { display: flex; - gap: 10px; - margin-bottom: 10px; - height: 32px; -} - -.search-button { - background-color: #5491f5; - color: #fff; - border: 1px solid #ccc; - border-radius: 5px; - width: 100px; - cursor: pointer; -} - -.type-select { - border: 1px solid #ccc; - border-radius: 5px; - flex-grow: 1; - padding: 0 10px; + flex-direction: column; } -.list-container { - height: 400px; - overflow: auto; - border-radius: 10px; +gmp-place-search { + width: 100%; + margin: 0; + border: none; + color-scheme: light; } -gmp-place-list { - background-color: #fff; - font-size: large; -} /* [END maps_ui_kit_place_search_nearby] */