当您使用 Google Maps API 单击地图内的某个位置时,它会显示一个信息窗口,其中包含名称、地址和用于在 Google 地图上查看该位置的链接。
有没有办法覆盖此事件并为其提供我自己的数据和样式?
到目前为止,我添加了一个 onClick 侦听器,它查找具有 placeId 属性的事件,获取该地点的数据,并将其显示在 InfoWindow 组件中。
但是,这并不会阻止默认窗口的打开。它仍然打开,然后被我的覆盖。有效,但不完全是我希望实现的目标。
我要么想完全阻止默认事件的显示,要么直接将我的更改应用于它,而不需要这个单独的事件处理程序。
async function handleOnClick(event) {
setContent(undefined);
const latitude = event.latLng.lat();
const longitude = event.latLng.lng();
if (event.placeId) {
const request = {
placeId: event.placeId,
fields: ['name', 'formatted_address', 'place_id', 'geometry', 'photo'],
};
const placesService = new google.maps.places.PlacesService(map);
placesService.getDetails(request, (place, status) => {
if (status === 'OK') {
const info = (
<InfoWindow
position={{
lat: place?.geometry?.location?.lat(),
lng: place?.geometry?.location?.lng(),
}}
onCloseClick={() => setContent(undefined)}
>
<div>
<h3>{place.name}</h3>
<div className='photo-gallery'>
{place?.photos.map((photo) => {
return <img className='photo' src={photo.getUrl()} />;
})}
</div>
</div>
</InfoWindow>
);
setContent(info);
}
});
}
}
我这样做是为了与 @react-google-maps/api 库做出反应
MapOptions
上有一个名为 clickableIcons
的选项,您可以将其设置为 false
,这将禁用默认 POI 图标/标记上的点击功能。
不幸的是,这也会禁用您可以使用
placeId
获得图标
map.addListener()
的功能
我建议您提交功能请求,这将使开发人员能够在单击时修改默认 POI 的内容。 https://developers.google.com/maps/support#issue_tracker
但由于 Google Maps API 目前没有此功能,您可以采取以下解决方法:
clickableIcons
设置为 false
,然后将 NearbySearch 与返回的 event.latLng
一起使用(因为您现在无法拥有 placeId
)。然后使用它可以找到的最近的 POI
并在信息窗口上显示该详细信息。它的工作原理如下:
创建一个信息窗口状态挂钩以稍后存储内容并生成组件。
const [infoWindow, setInfoWindow] = React.useState(null);
在 onLoad 回调定义中,将
clickableIcons
设置为 false,然后添加一个地图单击侦听器,该侦听器将处理单击事件返回的 latLng
到 NearbySearch 中,并获取最近的 POI,并将这些详细信息放在您想要的 InfoWindow 组件上将您的地图放在点击/POI 位置上。
const onLoad = React.useCallback(function callback(map) {
map.setClickableIcons(false);
console.log(map.getClickableIcons());
map.addListener("click", (event) => {
let request = {
location: event.latLng,
radius: 5,
types: ["point_of_interest"],
};
placeService = new google.maps.places.PlacesService(map);
placeService.nearbySearch(request, (results, status) => {
if (status === google.maps.places.PlacesServiceStatus.OK) {
const info = (
<InfoWindow
position={{
lat: results[0]?.geometry?.location?.lat(),
lng: results[0]?.geometry?.location?.lng(),
}}
onCloseClick={() => setInfoWindow(null)}
>
<div>
<h3>{results[0].name}</h3>
<div className="photo-gallery">
{results[0]?.photos?.map((photo) => {
return (
<img
className="photo"
src={photo.getUrl()}
height="100px"
width="100px"
/>
);
})}
</div>
</div>
</InfoWindow>
);
setInfoWindow(info);
}
});
});
}, []);
然后,您只需将
infoWindow
状态挂钩放在 GoogleMap
组件内即可在提供详细信息时显示信息窗口。
return isLoaded ? (
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={15}
onLoad={onLoad}
onUnmount={onUnmount}
>
{infoWindow ? infoWindow : null}
</GoogleMap>
) : (
<></>
);
因此,单击 POI 图标附近的某处后,它应该看起来像这样:
注意:有时它会检测到不同的 POI,因此您可以尝试调整附近搜索的类型和半径以及缩放级别。