0

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.

Amir-Mousavi
  • 4,273
  • 12
  • 70
  • 123
  • 1
    Well, it looks like you aren't using `StreetViewPanorama` at all. I saw that it was imported, but it was never used. [Google Developer Docs explains how to use overlays within street view.](https://developers.google.com/maps/documentation/javascript/examples/streetview-overlays#maps_streetview_overlays-javascript). – Andria May 31 '23 at 21:31
  • @Andria Well the question is about react-google-maps/api library. – Amir-Mousavi Jun 02 '23 at 12:44
  • Yes, but @react-google-maps/api makes direct calls to Google's Maps JavaScript API. So if you need to know what Google Maps JS API calls map to @react-google-maps/api, you can just look at @react-google-maps/api's source code. For example, the Google dev docs tutorial shows multiple `new google.maps.Marker()` calls and a call to `map.getStreetView()`. Calls to these are found in Marker.tsx and StreetViewPanorama.tsx respectively. So you should just be able to use `` and ``. – Andria Jun 02 '23 at 15:52

1 Answers1

1

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 />);

View this example live at CodeSandbox.

The word "Bank" displayed on a white popover in front of some chairs in Google Street View.

Andria
  • 4,712
  • 2
  • 22
  • 38