使用React的Google Maps v3自定义叠加层

时间:2016-01-09 18:21:20

标签: javascript google-maps google-maps-api-3 reactjs

我们正在构建一个简单的React应用程序,它使用谷歌地图在地图上显示各种事件。我们正在使用此回购:https://github.com/tomchentw/react-google-maps

这是我们想要创建的场景:在地图上显示一堆标记,并在标记上方始终显示自定义OverlayView。

这是问题所在: 我们也使用谷歌MarkerClusterer。当我们缩小时,标记会聚集,但仍会显示自定义叠加层。

我们需要什么: 在标记聚类时隐藏自定义叠加层。

以下是显示我们的Google地图呈现的代码。请参阅<OverlayView>组件。它在此示例中不显示任何内容。 有没有办法使用react来检测标记在地图上不再可见的时间,然后将自定义叠加的可见性设置为隐藏?

谢谢。

 return ( < div >
   < GoogleMapLoader containerElement = { < div {...this.props
     }
     style = {
       {
         height: "70vh"
       }
     }
     />}
                    googleMapElement={
                        <GoogleMap
                            containerProps={{...this.props}}
                            ref="map"
                            onBoundsChanged={this.handleBoundsChanged}
                            defaultZoom={12}
                            center={
                                center ? center: userPosition
                            }
                        >{contents}
                          <MarkerClusterer
                            averageCenter={true}
                            enableRetinaIcons={true}
                            gridSize={20}>

                                {this.data.Missions.map((marker, index) => {
    const position = marker.startLocationGeo ? {lat:marker.startLocationGeo.latitude, lng: marker.startLocationGeo.longitude} : null;
    const ref = `marker_${index}`;
    if(position){
        let icon = '';
    switch (marker.type) {
        case "hit":
         icon = "https:/ / www.dropbox.com / s / likbnwqx8y5kywv / shooting.png ? dl = 1 ";
         break;
         case "
     transport ":
         icon = "
     https: //www.dropbox.com/s/r22dfeh8lutpwv1/fourbyfour.png?dl=1";
       break;
     default: icon = "https://www.dropbox.com/s/dfjpx65j5v3wlih/pirates.png?dl=1";
     break;
   }
   return ( < Marker key = {
       ref
     }
     ref = {
       ref
     }
     icon = {
       icon
     }
     position = {
       position
     }
     title = {
       marker.title
     }
     onClick = {
       this.handleMarkerClick.bind(this, marker)
     }
     onShapeChanged = {
       this.testFunction.bind(this, marker)
     } >

     { < OverlayView > THIS COMPONENT SHOULD NOT BE VISIBLE WHEN MARKERS ARE CLUSTERED < /OverlayView>}
                

                {<InfoWindow key={`infoWindow_${index}`} position={position} content={marker.value} ref={`infoWindow_${index}`}/ >
     } {
       this.state.openedMissions.indexOf(marker.id.objectId) > -1 ? this.renderInfoWindow(ref, marker) : null
     } < /Marker>
    );
    }
})}
                            </MarkerClusterer >
     < SearchBox bounds = {
       this.state.bounds
     }
     controlPosition = {
       google.maps.ControlPosition.TOP_LEFT
     }
     onPlacesChanged = {
       this.handlePlacesChanged
     }
     ref = "searchBox"
     placeholder = "Search address"
     style = {
       inputStyle
     }
     />
                        </GoogleMap >
   }
   />
            </div >
 )

1 个答案:

答案 0 :(得分:3)

我遇到了同样的问题,并且即使在将近1.5年之后也想发布我的答案。我希望我的经验会帮助别人!

那么,我做了什么: 1)我创建了反应custom marker反应组分

showMarkerContent() {
    this.setState({
        isShown: true
    });
}

hideMarkerContent() {
    this.setState({
        isShown: false
    });
}

render() {
    return (
        <Marker
            key={this.props.key}
            position={this.props.position}
            icon={this.props.icon}
        >
            {
                this.state.isShown &&
                <OverlayView
                    /* https://github.com/tomchentw/react-google-maps/issues/482 */
                    key={ Math.random() }
                    position={this.props.position}
                    mapPaneName={"overlayMouseTarget"}
                    getPixelPositionOffset={this._getPixelPositionOffset}
                >
                    <div style={this.props.styles}>
                        {this.props.children}
                    </div>
                </OverlayView>
            }
        </Marker>
    );
}

2)在我的地图组件中我添加了所有标记,而在MarkerClusterer中我实现了2个钩子

<MarkerClusterer
    onClusteringBegin={this._handleClusteringBegin}
    onClusteringEnd={this._handleClusteringEnd}
>
    {markers}
</MarkerClusterer>

3)Hooks看起来像这样:在聚类之前清除所有叠加内容

_handleClusteringBegin() {
    this.markers.forEach((marker) => {
        if(!marker) {
            return;
        }
        marker.hideMarkerContent();
    });
}

4)如果群集中只有1个arker,则绘制叠加内容

_handleClusteringEnd(event) {
    const clusters = event.clusters_;
    clusters.forEach((cluster) => {
        if (cluster.markers_.length == 1) {
            const notClusteredMarker = cluster.markers_[0];
            const notClusteredMarkerPosition = notClusteredMarker.position;
            this.markers.forEach((marker) => {
                if(!marker) {
                    return;
                }
                const markerPosition = new google.maps.LatLng(marker.props.position.lat, marker.props.position.lng);
                if (
                    markerPosition.lat() == notClusteredMarkerPosition.lat()
                    && markerPosition.lng() == notClusteredMarkerPosition.lng()
                ) {
                    marker.showMarkerContent();
                }
            });
        }
    });
}

我希望这会有所帮助!