Skip to content

Commit d6a13df

Browse files
committed
Updated Places UI Kit Nearby Search
1 parent 8274921 commit d6a13df

File tree

3 files changed

+239
-208
lines changed

3 files changed

+239
-208
lines changed

samples/ui-kit-place-search-nearby/index.html

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,79 @@
66
<!--[START maps_ui_kit_place_search_nearby] -->
77
<!DOCTYPE html>
88
<html>
9-
<head>
10-
<title>Place List Nearby Search with Google Maps</title>
11-
<meta charset="utf-8">
12-
<link rel="stylesheet" type="text/css" href="style.css">
13-
<script type="module" src="./index.js"></script>
14-
</head>
15-
<body>
16-
<!--[START maps_ui_kit_place_search_nearby_map] -->
17-
<gmp-map center="-37.813,144.963" zoom="10" map-id="DEMO_MAP_ID">
18-
<div class="overlay" slot="control-inline-start-block-start">
19-
<div class="controls">
20-
<select name="types" class="type-select">
21-
<option value="">Select a place type</option>
22-
<option value="cafe">Cafe</option>
23-
<option value="restaurant">Restaurant</option>
24-
<option value="electric_vehicle_charging_station">
25-
EV charging station
26-
</option>
27-
</select>
9+
<head>
10+
<title>Place Search Nearby with Google Maps</title>
11+
<meta charset="utf-8" />
12+
<link rel="stylesheet" type="text/css" href="style.css" />
13+
<script type="module" src="./index.js" defer></script>
14+
<!-- prettier-ignore -->
15+
<script>
16+
(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))})
17+
({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly", internalUsageAttributionIds: "gmp_mcp_codeassist_v0.1_github"});
18+
</script>
19+
</head>
20+
<body>
21+
<!--[START maps_ui_kit_place_search_nearby_map] -->
22+
<div class="container">
23+
<gmp-map
24+
center="-37.813,144.963"
25+
zoom="16"
26+
map-id="DEMO_MAP_ID"
27+
disable-default-ui>
28+
<!--
29+
The gmp-place-details-compact element is styled inline because it is
30+
conditionally rendered and moved into the info window, which is
31+
part of the map's shadow DOM.
32+
-->
33+
<gmp-place-details-compact
34+
orientation="horizontal"
35+
truncation-preferred
36+
style="
37+
width: 400px;
38+
padding: 0;
39+
margin: 0;
40+
border: none;
41+
background-color: transparent;
42+
color-scheme: light;
43+
">
44+
<gmp-place-details-place-request></gmp-place-details-place-request>
45+
<gmp-place-content-config>
46+
<gmp-place-media></gmp-place-media>
47+
<gmp-place-rating></gmp-place-rating>
48+
<gmp-place-price></gmp-place-price>
49+
<gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
50+
<gmp-place-open-now-status></gmp-place-open-now-status>
51+
<gmp-place-attribution
52+
light-scheme-color="gray"
53+
dark-scheme-color="white"></gmp-place-attribution>
54+
</gmp-place-content-config>
55+
</gmp-place-details-compact>
56+
</gmp-map>
57+
<div class="ui-panel">
58+
<div class="controls">
59+
<label for="type-select">
60+
Select a place type:
61+
<select id="type-select" class="type-select">
62+
<option value="restaurant">Restaurant</option>
63+
<option value="cafe" selected>Cafe</option>
64+
<option value="electric_vehicle_charging_station">
65+
EV charging station
66+
</option>
67+
</select>
68+
</label>
69+
</div>
70+
<div class="list-container">
71+
<gmp-place-search orientation="vertical" selectable>
72+
<gmp-place-all-content></gmp-place-all-content>
73+
<gmp-place-nearby-search-request
74+
location-restriction="[email protected], 144.963">
75+
</gmp-place-nearby-search-request>
76+
</gmp-place-search>
77+
</div>
78+
</div>
2879
</div>
29-
<div class="list-container">
30-
<gmp-place-list selectable style="display: none;"></gmp-place-list>
31-
</div>
32-
</div>
33-
</gmp-map>
34-
35-
<gmp-place-details style="display: none;">
36-
<gmp-place-details-place-request></gmp-place-details-place-request>
37-
<gmp-place-all-content></gmp-place-all-content>
38-
</gmp-place-details>
3980

40-
<!--[END maps_ui_kit_place_search_nearby_map] -->
41-
<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))})
42-
({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "alpha"});</script>
43-
</body>
81+
<!--[END maps_ui_kit_place_search_nearby_map] -->
82+
</body>
4483
</html>
4584
<!--[END maps_ui_kit_place_search_nearby] -->

samples/ui-kit-place-search-nearby/index.ts

Lines changed: 118 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -6,132 +6,137 @@
66
/* [START maps_ui_kit_place_search_nearby] */
77

88
/* [START maps_ui_kit_place_search_nearby_query_selectors] */
9-
const map = document.querySelector("gmp-map") as any;
10-
const placeList = document.querySelector("gmp-place-list") as any;
11-
const typeSelect = document.querySelector(".type-select") as any;
12-
const placeDetails = document.querySelector("gmp-place-details") as any;
13-
const placeDetailsRequest = document.querySelector('gmp-place-details-place-request') as any;
9+
// Query selectors for various elements in the HTML file.
10+
const map = document.querySelector('gmp-map') as google.maps.MapElement
11+
const placeSearch = document.querySelector('gmp-place-search') as any
12+
const placeSearchQuery = document.querySelector(
13+
'gmp-place-nearby-search-request'
14+
) as any
15+
const placeDetails = document.querySelector('gmp-place-details-compact') as any
16+
const placeRequest = document.querySelector(
17+
'gmp-place-details-place-request'
18+
) as any
19+
const typeSelect = document.querySelector('.type-select') as HTMLSelectElement
1420
/* [END maps_ui_kit_place_search_nearby_query_selectors] */
15-
let markers = {};
16-
let infoWindow;
17-
18-
async function initMap(): Promise<void> {
19-
await google.maps.importLibrary('places');
20-
const { LatLngBounds } = await google.maps.importLibrary('core') as google.maps.CoreLibrary;
21-
const { InfoWindow } = await google.maps.importLibrary('maps') as google.maps.MapsLibrary;
22-
const { spherical } = await google.maps.importLibrary('geometry') as google.maps.GeometryLibrary;
23-
24-
infoWindow = new InfoWindow;
25-
let marker;
26-
27-
function getContainingCircle(bounds) {
28-
const diameter = spherical.computeDistanceBetween(
29-
bounds.getNorthEast(),
30-
bounds.getSouthWest()
31-
);
32-
const calculatedRadius = diameter / 2;
33-
const cappedRadius = Math.min(calculatedRadius, 50000); // Radius cannot be more than 50000.
34-
return { center: bounds.getCenter(), radius: cappedRadius };
35-
}
36-
37-
findCurrentLocation();
3821

22+
// Global variables for the map, markers, and info window.
23+
const markers: Map<string, google.maps.marker.AdvancedMarkerElement> = new Map()
24+
let infoWindow: google.maps.InfoWindow
25+
let AdvancedMarkerElement: typeof google.maps.marker.AdvancedMarkerElement
26+
let LatLngBounds: typeof google.maps.LatLngBounds
27+
28+
// The init function is called when the page loads.
29+
async function init(): Promise<void> {
30+
// Import the necessary libraries from the Google Maps API.
31+
const [{ InfoWindow }, { Place }, markerLib, coreLib] = await Promise.all([
32+
google.maps.importLibrary('maps') as Promise<google.maps.MapsLibrary>,
33+
google.maps.importLibrary(
34+
'places'
35+
) as Promise<google.maps.PlacesLibrary>,
36+
google.maps.importLibrary(
37+
'marker'
38+
) as Promise<google.maps.MarkerLibrary>,
39+
google.maps.importLibrary('core') as Promise<google.maps.CoreLibrary>,
40+
])
41+
42+
AdvancedMarkerElement = markerLib.AdvancedMarkerElement
43+
LatLngBounds = coreLib.LatLngBounds
44+
45+
// Create a new info window and set its content to the place details element.
46+
infoWindow = new InfoWindow({
47+
content: placeDetails,
48+
ariaLabel: 'Place Details',
49+
headerDisabled: true,
50+
pixelOffset: new google.maps.Size(0, -40),
51+
})
52+
53+
// Set the map options.
3954
map.innerMap.setOptions({
40-
mapTypeControl: false,
4155
clickableIcons: false,
42-
});
56+
mapTypeControl: false,
57+
streetViewControl: false,
58+
})
4359

60+
// Add a click listener to the map to hide the info window when the map is clicked.
61+
map.innerMap.addListener('click', () => infoWindow.close())
4462
/* [START maps_ui_kit_place_search_nearby_event] */
45-
placeDetails.addEventListener('gmp-load', (event) => {
46-
// Center the info window on the map.
47-
map.innerMap.fitBounds(placeDetails.place.viewport, { top: 500, left: 400 });
48-
});
49-
50-
typeSelect.addEventListener('change', (event) => {
51-
// First remove all existing markers.
52-
for(marker in markers){
53-
markers[marker].map = null;
63+
// Add event listeners to the type select and place search elements.
64+
typeSelect.addEventListener('change', searchPlaces)
65+
66+
placeSearch.addEventListener('gmp-select', (event: Event) => {
67+
const { place } = event as any
68+
if (markers.has(place.id)) {
69+
markers.get(place.id)!.click()
5470
}
55-
markers = {};
56-
57-
if (typeSelect.value) {
58-
placeList.style.display = 'block';
59-
placeList.configureFromSearchNearbyRequest({
60-
locationRestriction: getContainingCircle(
61-
map.innerMap.getBounds()
62-
),
63-
includedPrimaryTypes: [typeSelect.value],
64-
}).then(addMarkers);
65-
// Handle user selection in Place Details.
66-
placeList.addEventListener('gmp-placeselect', ({ place }) => {
67-
markers[place.id].click();
68-
});
71+
if (place.location) {
72+
map.innerMap.setCenter(place.location)
6973
}
70-
});
71-
/* [END maps_ui_kit_place_search_nearby_event] */
74+
})
75+
placeSearch.addEventListener(
76+
'gmp-load',
77+
() => {
78+
searchPlaces()
79+
},
80+
{ once: true }
81+
)
7282
}
73-
74-
async function addMarkers(){
75-
const { AdvancedMarkerElement } = await google.maps.importLibrary('marker') as google.maps.MarkerLibrary;
76-
const { LatLngBounds } = await google.maps.importLibrary('core') as google.maps.CoreLibrary;
77-
78-
const bounds = new LatLngBounds();
79-
80-
if(placeList.places.length > 0){
81-
placeList.places.forEach((place) => {
82-
let marker = new AdvancedMarkerElement({
83-
map: map.innerMap,
84-
position: place.location
85-
});
86-
87-
markers[place.id] = marker;
88-
bounds.extend(place.location);
89-
90-
/* [START maps_ui_kit_place_search_nearby_click_event] */
91-
marker.addListener('gmp-click', (event) => {
92-
if(infoWindow.isOpen){
93-
infoWindow.close();
94-
}
95-
96-
placeDetailsRequest.place = place.id;
97-
placeDetails.style.display = 'block';
98-
placeDetails.style.width = '350px';
99-
infoWindow.setOptions({
100-
content: placeDetails,
101-
});
102-
infoWindow.open({
103-
anchor: marker,
104-
map: map.innerMap
105-
});
106-
});
107-
/* [END maps_ui_kit_place_search_nearby_click_event] */
108-
109-
map.innerMap.setCenter(bounds.getCenter());
110-
map.innerMap.fitBounds(bounds);
111-
});
83+
/* [END maps_ui_kit_place_search_nearby_event] */
84+
// The searchPlaces function is called when the user changes the type select or when the page loads.
85+
function searchPlaces() {
86+
// Close the info window and clear the markers.
87+
infoWindow.close()
88+
for (const marker of markers.values()) {
89+
marker.map = null
90+
}
91+
markers.clear()
92+
93+
// Set the place search query and add an event listener to the place search element.
94+
if (typeSelect.value) {
95+
const center = map.innerMap.getCenter()!
96+
placeSearchQuery.maxResultCount = 5
97+
placeSearchQuery.locationRestriction = {
98+
center: { lat: center.lat(), lng: center.lng() },
99+
radius: 50000, // 50km radius
100+
}
101+
placeSearchQuery.locationBias = {
102+
center: { lat: center.lat(), lng: center.lng() },
103+
}
104+
placeSearchQuery.includedTypes = [typeSelect.value]
105+
placeSearch.addEventListener('gmp-load', addMarkers, { once: true })
112106
}
113107
}
114108

115-
async function findCurrentLocation(){
116-
const { LatLng } = await google.maps.importLibrary('core') as google.maps.CoreLibrary;
117-
if (navigator.geolocation) {
118-
navigator.geolocation.getCurrentPosition(
119-
(position) => {
120-
const pos = new LatLng(position.coords.latitude,position.coords.longitude);
121-
map.innerMap.panTo(pos);
122-
map.innerMap.setZoom(14);
123-
},
124-
() => {
125-
console.log('The Geolocation service failed.');
126-
map.innerMap.setZoom(14);
127-
},
128-
);
129-
} else {
130-
console.log('Your browser doesn\'t support geolocation');
131-
map.innerMap.setZoom(14);
132-
}
109+
// The addMarkers function is called when the place search element loads.
110+
async function addMarkers() {
111+
const bounds = new LatLngBounds()
112+
113+
if (placeSearch.places.length === 0) {
114+
return
115+
}
133116

117+
placeSearch.places.forEach((place) => {
118+
const marker = new AdvancedMarkerElement({
119+
map: map.innerMap,
120+
position: place.location,
121+
collisionBehavior:
122+
google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL,
123+
})
124+
125+
markers.set(place.id, marker)
126+
bounds.extend(place.location)
127+
128+
marker.addListener('click', () => {
129+
if (place.location) {
130+
map.innerMap.setCenter(place.location)
131+
}
132+
placeRequest.place = place
133+
infoWindow.setPosition(place.location)
134+
infoWindow.open(map.innerMap)
135+
})
136+
})
137+
138+
map.innerMap.fitBounds(bounds)
134139
}
135140

136-
initMap();
141+
init()
137142
/* [END maps_ui_kit_place_search_nearby] */

0 commit comments

Comments
 (0)