英文:
Show InfoBox/InfoWindow on the streetView with react-google-maps-api
问题
在这个代码沙箱中,我有一些带有在点击时显示的 InfoBox 嵌套在标记中的标记。
如何在切换到 StreetView 模式时也显示该 InfoBox?
// 导入部分
import { GoogleMap, InfoBox, Marker, OverlayView, Polyline, useJsApiLoader } from '@react-google-maps/api';
{data.map(({ source, destination, distance }, index) => (
<InfoBox
options={{
enableEventPropagation: true,
boxStyle: {...}
}}
>
这里有一些文本
))}
注意:在代码沙箱中没有提供 API 密钥。提供 API 密钥将显示可在地图附近拖放到标记附近的 StreetView 图标。
英文:
In this code sandbox, I have some markers with InfoBox nested in the marker that is shown on click.
How can I also show that InfoBox when switching into the StreetView mode?
// The imports
import { GoogleMap, InfoBox, Marker, OverlayView, Polyline, useJsApiLoader } from '@react-google-maps/api';
{data.map(({ source, destination, distance }, index) => (
<Marker key={index} position={source}>
<InfoBox
options={{
enableEventPropagation: true,
boxStyle: {...}
}}
>
<div
style={{...}}
>
<p>Some text here</p>
</div>
</InfoBox>
</Marker>
))}
Note: No API key is provided in the code sandbox. Providing the API key will show the StreetView icon that can be dragged-dropped on the map close to a Marker.
答案1
得分: 1
在调用 InfoWindow#open
方法时,将 Map
替换为 StreetViewPanorama
在Google地图JavaScript API关于街景中叠加物的文档中提到,可以通过在调用 open()
方法时传递 StreetViewPanorama
而不是 Map
,在 StreetViewPanorama
内打开一个 InfoWindow
。
在 @react-google-maps/api
代码库中,InfoWindow.tsx
文件通过React的Context API获取了 Map
实例,并使用它来打开 InfoWindow
实例:
const map = useContext<google.maps.Map | null>(MapContext)
// ...
instance.open(map)
因此,我们可以导入 MapContext
并在 <InfoWindow>
包装它,以替换 map
为 StreetViewPanorama
实例,可以通过 <StreetViewPanorama>
的 onLoad
事件获取。
import { createRoot } from "react-dom/client";
import {
useLoadScript,
GoogleMap,
StreetViewPanorama,
Marker,
InfoWindow,
MapContext,
} from "@react-google-maps/api";
import React, { useContext, useState } from "react";
function App() {
const astorPlace = { lat: 40.729884, lng: -73.990988 };
const [panorama, setPanorama] =
useState<google.maps.StreetViewPanorama | null>(null);
const markers = [
{
position: { lat: 40.730031, lng: -73.991428 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00",
title: "Cafe",
},
{
position: { lat: 40.729681, lng: -73.991138 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00",
title: "Bank",
},
{
position: { lat: 40.729559, lng: -73.990741 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00",
title: "Bus Stop",
},
];
function onPanoramaLoad(panorama: google.maps.StreetViewPanorama) {
panorama.setPosition(astorPlace);
panorama.setPov({
heading: 265,
pitch: 0,
});
panorama.setVisible(true);
setPanorama(panorama);
}
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
});
return (
<>
{isLoaded ? (
<GoogleMap center={astorPlace} zoom={18} id="map">
<StreetViewPanorama onLoad={onPanoramaLoad} />
{panorama ? (
// @ts-ignore
<MapContext.Provider value={panorama}>
{markers.map((marker) => (
<Marker key={marker.title} {...marker}>
<InfoWindow position={marker.position}>
<div
style={{
backgroundColor: "white",
opacity: 0.8,
}}
>
<h2>{marker.title}</h2>
</div>
</InfoWindow>
</Marker>
))}
</MapContext.Provider>
) : null}
</GoogleMap>
) : null}
{loadError ? <p>{loadError.message}</p> : null}
</>
);
}
createRoot(document.getElementById("app")!).render(<App />);
英文:
Replace the Map
in calls to the InfoWindow#open
method with a StreetViewPanorama
In Google's documentation for the Maps JavaScript API on overlays within street view, it is noted that an InfoWindow
may be opened within a StreetViewPanorama
by passing the StreetViewPanorama
instead of a Map
when calling the open()
method.
In the @react-google-maps/api
codebase, the InfoWindow.tsx
file gets the Map
instance through React's Context API and uses it to open the InfoWindow
instance:
const map = useContext<google.maps.Map | null>(MapContext)
// ...
instance.open(map)
With that, we can import MapContext
and wrap our <InfoWindow>
with it to replace the map
with a StreetViewPanorama
instance, which we can get by using <StreetViewPanorama>
's onLoad
event.
import { createRoot } from "react-dom/client";
import {
useLoadScript,
GoogleMap,
StreetViewPanorama,
Marker,
InfoWindow,
MapContext,
} from "@react-google-maps/api";
import React, { useContext, useState } from "react";
function App() {
const astorPlace = { lat: 40.729884, lng: -73.990988 };
const [panorama, setPanorama] =
useState<google.maps.StreetViewPanorama | null>(null);
const markers = [
{
position: { lat: 40.730031, lng: -73.991428 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00",
title: "Cafe",
},
{
position: { lat: 40.729681, lng: -73.991138 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00",
title: "Bank",
},
{
position: { lat: 40.729559, lng: -73.990741 },
icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00",
title: "Bus Stop",
},
];
function onPanoramaLoad(panorama: google.maps.StreetViewPanorama) {
panorama.setPosition(astorPlace);
panorama.setPov({
heading: 265,
pitch: 0,
});
panorama.setVisible(true);
setPanorama(panorama);
}
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
});
return (
<>
{isLoaded ? (
<GoogleMap center={astorPlace} zoom={18} id="map">
<StreetViewPanorama onLoad={onPanoramaLoad} />
{panorama ? (
// @ts-ignore
<MapContext.Provider value={panorama}>
{markers.map((marker) => (
<Marker key={marker.title} {...marker}>
<InfoWindow position={marker.position}>
<div
style={{
backgroundColor: "white",
opacity: 0.8,
}}
>
<h2>{marker.title}</h2>
</div>
</InfoWindow>
</Marker>
))}
</MapContext.Provider>
) : null}
</GoogleMap>
) : null}
{loadError ? <p>{loadError.message}</p> : null}
</>
);
}
createRoot(document.getElementById("app")!).render(<App />);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论