使用 "@react-google-maps/api 重叠标记 spiderfier

Overlapping markers spiderfier using "@react-google-maps/api

https://stackblitz.com/edit/react-kam469?file=Map.js

可以按照上面给出的link.

https://stackblitz.com/edit/react-kam469?file=Map.js

您可以通过提供 Google 地图 API 键

来关注此 link
step1: install google map package for react ( npm i @react-google-maps/api ) 

step2: install overlapping marker spiderfier ( npm i npm-overlapping-marker-spiderfier )

Spiderfy.js分量

import React from "react";
import { GoogleMap } from "@react-google-maps/api";

class Spiderfy extends React.Component {
  constructor(props) {
    super(props);
    const oms = require(`npm-overlapping-marker-spiderfier/lib/oms.min`);

    this.oms = new oms.OverlappingMarkerSpiderfier(
      GoogleMap().MapContext._currentValue, // 1*
      {}
    );

    this.markerNodeMounted = this.markerNodeMounted.bind(this);
  }

  async markerNodeMounted(ref) {
    setTimeout(() => { //3*
      this.oms.addMarker(ref.marker); // 2*
      window.google.maps.event.addListener(ref.marker, "spider_click", e => {
        if (this.props.onSpiderClick) this.props.onSpiderClick(e);
      });
    }, 2000);
  }

  render() {
    return React.Children.map(this.props.children, child =>
      React.cloneElement(child, { ref: this.markerNodeMounted })
    );
  }
}

export default Spiderfy;


// note 
// 1*
// if your are not able to get thecontext of google map then you can use MapContext._currentValue 
// and import it instead of Google map i.e ( import { MapContext } from "@react-google-maps/api"; )

// 2*
// if you are not able to get the value with ref.marker then it can be ref.state.marker

// 3* 
// I am using setTimeout as a hack it could be more better but FYI if marker took time to load and you are have trouble with // // markers refs then you can use setTimeout !!! but its not an ideal solution but it works

Map.js分量

import React from "react";
import { GoogleMap, LoadScript } from "@react-google-maps/api";
import Spiderfy from "./Spiderfy";
import MapMarker from "./MapMarker";

const containerStyle = {
  width: "100%",
  height: "400px"
};

const center = {
  lat: -34.2832517,
  lng: 142.6632107
};

let markerData = [
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -38.132245, lng: 144.2994245 }, title: "Geelong" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -38.132245, lng: 144.2994245 }, title: "Geelong" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -38.132245, lng: 144.2994245 }, title: "Geelong" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -37.9716929, lng: 144.772958 }, title: "Melbourne" },
  { position: { lat: -38.132245, lng: 144.2994245 }, title: "Geelong" },

function Map() {
  const [map, setMap] = React.useState(null);

  const onUnmount = React.useCallback(function callback(map) {
    setMap(null);
  }, []);

  return (
    <LoadScript
      googleMapsApiKey="YOUR GOOGLE MAP API KEY"
      libraries={["visualization", "places"]}
    >
      <GoogleMap
        mapContainerStyle={containerStyle}
        center={center}
        zoom={5}
        onUnmount={onUnmount}
      >
          <Spiderfy>
            {markerData.map(data => (
              <MapMarker position={data.position} title={data.title} />
            ))}
          </Spiderfy>

      </GoogleMap>
    </LoadScript>
  );
}

export default Map;

MapMarker.js 组件

import React from "react";
import { Marker } from "@react-google-maps/api";

const MapMarker = React.forwardRef((props, ref) => { // Note below
  return <Marker position={props.position} title={props.title} ref={ref} />;
});

export default MapMarker;

// Note if you are using class base component then you can forwardRef like 
// export default React.forwardRef((props, ref) => <MapMarker innerRef={ref} {...props} />);

index.js分量

import React, { Component } from "react";
import { render } from "react-dom";
import Map from "./Map";
import "./style.css";

const App = () => {
  return <Map />;
};

render(<App />, document.getElementById("root"));