1

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

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

标记

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

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)我发现这篇文章对理解程序很有用。但不幸的是,我无法解决它。

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

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

请有没有人经历过这个,指导正确的方向来解决它,因为我已经没有想法了。

4

2 回答 2

5

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

第 1 步:创建一个标准react组件,我们将其命名为<Popup />.

第 2 步,选项 A:使用 CSS 定位

分配position: absolute<Popup />。这将允许您避免数学来确定弹出窗口何时呈现屏幕外/视口外)。将<Popup />相邻的 (sibling of)放置<GoogleMapReact>,并将父容器分配为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>.

<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>
于 2020-07-28T15:19:29.100 回答
0

我在 reactjs 中成功创建了这个,但是我没有使用 google-map-react。我只是简单地使用了这个答案中的一些片段,并在我的示例反应代码中使用它。您可以在提供的链接中看到它,然后才能看到它的工作,您必须在此行中更改 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”错误,但是如果您在任何地方放置空格,您仍然可以继续。

于 2020-02-25T03:01:01.053 回答