Google-map-react - reactjs:如何在单击标记后动态显示弹出窗口 window

Google-map-react - reactjs: How to dynamically show pop-up window after clicking on a marker

我正在使用 AISHub 构建船只可视化工具。我能够使用 latitude/longitude 找到我想要的船只并将它们显示在地图上。但是船只(标记)太多了,我不知道谁是谁。

问题:如何在单击如下标记后动态显示弹出窗口window?

下面是我正在使用的代码中最重要的部分:

class BoatMap extends Component {
    constructor(props) {
        super(props);
        this.state = {
            buttonEnabled: true,
            buttonClickedAt: null,
            progress: 0,
            ships: [],
            type: 'All',
            shipTypes: [],
            activeShipTypes: [],
            logoMap: {}
        };
        this.updateRequest = this.updateRequest.bind(this);
        this.countDownInterval = null;
    }

// ... other operations
// ... other operations

    render() {
        return (
            <div className="google-map">
                <GoogleMapReact
                    bootstrapURLKeys={{ key: 'My_KEY' }}
                    center={{
                        lat: this.props.activeShip ? this.props.activeShip.latitude : 42.4,
                        lng: this.props.activeShip ? this.props.activeShip.longitude : -71.1
                    }}
                    zoom={8}
                >
                    {/* Rendering all the markers here */}
                    {this.state.ships.map((ship) => (
                        <Ship
                            ship={ship}
                            key={ship.CALLSIGN}
                            lat={ship.LATITUDE}
                            lng={ship.LONGITUDE}
                            logoMap={this.state.logoMap}
                        />
                    ))}

                    <select className="combo-companies" onClick={this.props.handleDropdownChange}>
                        <option value="All">All</option>

                        {this.state.shipTypes.map((type) => (
                            <option
                                className={this.state.activeShipTypes.includes(type) ? 'active' : ''}
                                key={type}
                                value={type}
                            >
                                {type}
                            </option>
                        ))}
                    </select>
                </GoogleMapReact>
            </div>
        );
    }
}

到目前为止我做了什么:

1) 我发现 this post 这对理解程序很有用。但不幸的是我无法解决它。

2) 我还发现 非常有用,但有两个问题使我无法使用它:a) 信息框不是动态的,b) 我正在使用 google-map-react 但 post 不是:

3) 最后我尝试编写自己的组件 InfoWindowBox.js 下面是我到目前为止所做的但不知道我是否朝着正确的方向前进以及是否应该在初始代码:

InfoWindowBox.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { InfoWindow } from 'google-maps-react';

export default class InfoWindowEx extends Component {
    constructor(props) {
        super(props);
        this.infoWindowRef = React.createRef();
        this.contentElement = document.createElement(`div`);
    }

    componentDidUpdate(prevProps) {
        if (this.props.children !== prevProps.children) {
            ReactDOM.render(React.Children.only(this.props.children), this.contentElement);
            this.infoWindowRef.current.infowindow.setContent(this.contentElement);
        }
    }

    render() {
        return <InfoWindow ref={this.infoWindowRef} {...this.props} />;
    }
}

请问有没有人通过这个,指导正确的方向解决它,因为我 运行 没有想法。

我在 reactjs 中成功创建了这个但是我没有使用 google-map-react。我只是简单地使用了这个 and use it in my sample react code 中的一些片段。您可以在提供的 link 中看到它,然后才能看到它起作用,您必须更改此行中的 API 键

const API_KEY = "CHANGE_YOUR_API_KEY";

供您参考,以下是我在代码中的实现方式:

import React from "react";
import ReactDOM from 'react-dom';

var map;
var markers=[];
var infowindow;
const API_KEY = "CHANGE_YOUR_API_KEY" ;

class Map extends React.Component {
  constructor(props) { 
    super(props);
    this.onScriptLoad = this.onScriptLoad.bind(this);
  }


  onScriptLoad() {
      var locations = [
            ['Bondi Beach', -33.890542, 151.274856, 4],
            ['Coogee Beach', -33.923036, 151.259052, 5],
            ['Cronulla Beach', -34.028249, 151.157507, 3],
            ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
            ['Maroubra BeachManly Beach Manly Beach Manly Beach', -33.950198, 151.259302, 1]
        ];
      var mapOptions = {
            zoom: 10,
            center: new google.maps.LatLng(locations[0][1], locations[0][2]),
            scrollwheel: true,
        };   
    map = new window.google.maps.Map(document.getElementById(this.props.id), mapOptions);
    this.props.onMapLoad(map)

       for (var count = 0; count < locations.length; count++) {
         var name = locations[count][0];
         var loc =  new google.maps.LatLng(locations[count][1], locations[count][2]);
            this.createMarker(name,loc);
        }
  }

  componentDidMount() {
    if (!window.google) {
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = `https://maps.googleapis.com/maps/api/js?key=`+API_KEY+`&libraries=places,geometry`;
      script.id = 'googleMaps';
      script.async = true;
      script.defer = true;
      document.body.appendChild(script);
      script.addEventListener('load', e => {
        this.onScriptLoad()
      })
    }
    else {
      this.onScriptLoad()
    }
    var marker = new google.maps.Marker({
      position: { lat: -25.344, lng: 131.036 },
      map: map
    });
  }

  createMarker(name,loc) {
    var marker = new google.maps.Marker({
      map: map,
      position: loc,
      title: name

    });
    markers.push(marker);

    infowindow = new google.maps.InfoWindow();
    var content =
      'Location: ' + name +
      '<br/>Lat: ' + loc.lat() +
      '<br/>Long: ' + loc.lng() ;

    marker.addListener('click', ()=>{     
      infowindow.setContent(content);  
      infowindow.open(map, marker); 
    });
  }

  render() {
    return (
      <div id="root">
      <div className="map" id={this.props.id} />
      </div>
    )
  }
}

export default Map;

注意:有时我的代码在 Stackblitz 中显示 'google is not defined' 错误,但是如果您在任何地方放置 space 仍然可以继续。

据我所知,有 2 种方法可以添加到 Popups,这两种方法都不是 google-map-react 包的原生方法(建议在地图上使用 React 组件)。您可以将 <Popup /> 定位为 position: absolute,或者将 lnglat 传递给 <Popup />

第 1 步: 创建一个标准 react 组件,我们称之为 <Popup />.

步骤 2,选项 A:位置 CSS

position: absolute 分配给 <Popup />。这将允许您避免数学来确定弹出窗口何时呈现 off-screen/outside 视口)。将 <Popup /> 放置在 <GoogleMapReact> 的(兄弟)附近,并将 parent 容器指定为 position: relative

<div style={{ height: '100vh', width: '100%', position: 'relative' }}>
  <GoogleMapReact
    bootstrapURLKeys={{ key: 'SECRETS' }}
    defaultCenter={defaults.center}
    defaultZoom={defaults.zoom}
  >
    {markers.map((marker) => (
      <Marker
        key={marker.id}
        lat={marker.latitude}
        lng={marker.longitude}
        onClick={() => setPopupInfo(marker)}
      />
    ))}
  </GoogleMapReact>
  {popupInfo && (<Popup store={popupInfo} style={{ position: 'absolute', top: 0, left: 0, width: '200px' }} />)}
</div>

步骤 2,选项 B:根据地图定位 lat/lng

或者,您可以将 latlng 作为属性传递给 <Popup />。为此,Popup 应该是 <GoogleMapReact> 的 child。

<div>
  <GoogleMapReact
    bootstrapURLKeys={{ key: 'SECRETS' }}
    defaultCenter={defaults.center}
    defaultZoom={defaults.zoom}
  >
    {markers.map((marker) => (
      <Marker
        key={marker.id}
        lat={marker.latitude}
        lng={marker.longitude}
        onClick={() => setPopupInfo(marker)}
      />
    ))}
    {popupInfo && (<Popup
      store={popupInfo}
      lat={popupInfo.latitude}
      lng={popupInfo.longitude}
     />)}
  </GoogleMapReact>
</div>