嗨,我正在制作一个反应位点,理想情况下应该包括标记的聚类。
我使用了两种不同的技术来实现这一点,两种技术都能有效地显示在地图上,一种甚至可以聚类,但我希望我能将这些技术结合起来。
原因是这两种技术略有不同,使用有效集群的技术不会让我映射出组件,而是必须返回一个谷歌标记。
这是我使用的第一种技术。
import React, { Component, useState } from "react";
import GoogleMapReact from "google-map-react";
import TravelAlert from "./TravelAlerts/TravelAlerts";
import IntelAlert from "./IntelAlerts/IntelAlerts";
import "./GoogleMap.css";
//class component
export class GoogleMap extends Component {
constructor(props) {
super(props);
}
componentDidMount() {}
static defaultProps = {
center: {
lat: 59.955413,
lng: 30.337844,
},
zoom: 11,
};
render() {
return (
<>
<GoogleMapReact
style={{ height: "100vh", width: "100%", zIndex: -1 }}
bootstrapURLKeys={{
key: process.env.REACT_APP_MAP_API_KEY,
}}
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
>
//Simply .mapping a bunch of props (if done this way component just needs a lat and a lng prop for each component )
{this.props.travelAlerts.map((ta) => (
<TravelAlert
lat={ta.latitude}
lng={ta.longitude}
title={ta.title}
description={ta.description}
notes={ta.notes}
riskId={ta.riskId}
startDate={ta.startDate}
endDate={ta.endDate}
/>
))}
{this.props.intelAlerts.map((ta) => (
<IntelAlert
lat={ta.latitude}
lng={ta.longitude}
title={ta.title}
description={ta.description}
notes={ta.notes}
riskId={ta.riskId}
startDate={ta.startDate}
endDate={ta.endDate}
/>
))}
</GoogleMapReact>
</>
);
}
}
export default GoogleMap;
我真的很喜欢这种技术,因为它只允许你将任何组件映射到屏幕的lat和lng。然而,使用这种技术,我无法使这些标记的聚类工作。
这是第二种技术,但这不允许我绘制出任何自定义标记,这意味着我必须在加载地图之前绘制出地图的标记。这不是首选,因为我无法映射自己的自定义标记。
import React, { Component } from "react";
import GoogleMapReact from "google-map-react";
import intelAlert from "../../../components/Map/MapContainer/GoogleMap/IntelAlerts/IntelAlerts";
// import MarkerClusterer from "@google/markerclusterer";
export default class GoogleMapContainer extends Component {
componentDidMount() {
const script = document.createElement("script");
script.src =
"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js";
script.async = true;
document.body.appendChild(script);
}
setGoogleMapRef(map, maps) {
this.googleMapRef = map;
this.googleRef = maps;
let markers =
this.props.intelAlerts &&
this.props.intelAlerts.map((location) => {
var loc = { lat: location.latitude, lng: location.longitude };
return new this.googleRef.Marker({ position: loc });
});
let markerCluster = new MarkerClusterer(map, markers, {
imagePath:
"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
gridSize: 10,
minimumClusterSize: 2,
});
}
static defaultProps = {
center: {
lat: 59.95,
lng: 30.33,
},
zoom: 11,
};
render() {
if (this.props.intelAlerts.length) {
return (
<GoogleMapReact
style={{ height: "100vh", width: "100%", zIndex: -1 }}
bootstrapURLKeys={{ key: process.env.REACT_APP_MAP_API_KEY }}
yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={({ map, maps }) => this.setGoogleMapRef(map, maps)}
defaultCenter={{ lat: -31.56391, lng: 147.154312 }}
defaultZoom={15}
options={{ streetViewControl: true }}
/>
);
} else {
return <></>;
}
}
}
有没有一种方法仍然能够映射出我自己的自定义标记并包括标记聚类。
任何帮助或指示都意味着分配,因为关于这个问题的文件很少。
我正在使用谷歌地图反应npm包。
编辑我在角度上做过类似的事情。在Angular中,您可以简单地执行此操作。
<div ng-if="showTravellers" >
<agm-marker-cluster [minimumClusterSize]= "minClusterSize">
<agm-marker *ngFor="let m of intelligenceAlerts;let i = index;" [visible]="showIntelligence" [latitude]="m.latitude" [longitude]="m.longitude" [iconUrl]= 'getTheIcon(m.riskId)' >
<agm-snazzy-info-window [maxWidth]="600" maxHeight="200px" [closeWhenOthersOpen]="true" backgroundColor="getTheColor(m.colour);">
<ng-template>
<mat-form-field appearance="standard">
<mat-card> <h3><b>{{m.colour}}</b> </h3></mat-card>
<mat-card> <h3><b>{{m.title}}</b> </h3></mat-card>
<mat-card> <p>{{m.notes}} </p></mat-card>
<button>Description</button> <button>Start Date</button><button>End Date</button><button>Notes</button>
</mat-form-field>
</ng-template>
</agm-snazzy-info-window>
</agm-marker>
</agm-marker-cluster>
</div>
reactjs中有等价物吗?
您可以动态加载Maps JS API,而不依赖于第三方库/包。这样,你就可以简单地遵循他们的官方文件。对于这个例子,我遵循这两个来集群地图标记以及添加自定义标记:
- https://developers.google.com/maps/documentation/javascript/marker-clustering
- https://developers.google.com/maps/documentation/javascript/custom-markers
以下是我为您制作的Stacklitz样本,供您参考:https://stackblitz.com/edit/react-map-cluster-64766101
App.js
import React, { Component } from "react";
import { render } from "react-dom";
import Map from "./components/map";
import "./style.css";
class App extends Component {
render() {
return (
<Map
id="myMap"
options={{
center: { lat: -28.024, lng: 140.887 },
zoom: 3
}}
/>
);
}
}
export default App;
map.js
import React, { Component } from "react";
import { render } from "react-dom";
const locations = [
{ lat: -31.56391, lng: 147.154312 },
{ lat: -33.718234, lng: 150.363181 },
{ lat: -33.727111, lng: 150.371124 },
{ lat: -33.848588, lng: 151.209834 },
{ lat: -33.851702, lng: 151.216968 },
{ lat: -34.671264, lng: 150.863657 },
{ lat: -35.304724, lng: 148.662905 },
{ lat: -36.817685, lng: 175.699196 },
{ lat: -36.828611, lng: 175.790222 },
{ lat: -37.75, lng: 145.116667 },
{ lat: -37.759859, lng: 145.128708 },
{ lat: -37.765015, lng: 145.133858 },
{ lat: -37.770104, lng: 145.143299 },
{ lat: -37.7737, lng: 145.145187 },
{ lat: -37.774785, lng: 145.137978 },
{ lat: -37.819616, lng: 144.968119 },
{ lat: -38.330766, lng: 144.695692 },
{ lat: -39.927193, lng: 175.053218 },
{ lat: -41.330162, lng: 174.865694 },
{ lat: -42.734358, lng: 147.439506 },
{ lat: -42.734358, lng: 147.501315 },
{ lat: -42.735258, lng: 147.438 },
{ lat: -43.999792, lng: 170.463352 }
];
class Map extends Component {
constructor(props) {
super(props);
this.state = {
map: ""
};
}
onScriptLoad() {
this.state.map = new window.google.maps.Map(
document.getElementById(this.props.id),
this.props.options
);
this.addMarker();
}
componentDidMount() {
if (!window.google) {
var s = document.createElement("script");
s.type = "text/javascript";
s.src = `https://maps.google.com/maps/api/js?key=YOUR_API_KEY`;
var x = document.getElementsByTagName("script")[0];
x.parentNode.insertBefore(s, x);
var s2 = document.createElement("script");
s2.type = "text/javascript";
s2.src = `https://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js`;
var x2 = document.getElementsByTagName("script")[0];
x2.parentNode.insertBefore(s2, x2);
s.addEventListener("load", e => {
this.onScriptLoad();
});
} else {
this.onScriptLoad();
}
}
// Add some markers to the map.
addMarker() {
const markers = locations.map((location, i) => {
return new google.maps.Marker({
position: location,
icon:
"https://developers.google.com/maps/documentation/javascript/examples/full/images/info-i_maps.png",
map: this.state.map
});
});
// Add a marker clusterer to manage the markers.
new MarkerClusterer(this.state.map, markers, {
imagePath:
"https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m"
});
}
render() {
return <div className="map" id={this.props.id} />;
}
}
export default Map;
注意:用实际的API密钥替换API密钥占位符