问题
I am rewriting an existing web app to a React app. In the original, leaflet is used for maps, along with OverlappingMarkerSpiderfier to create a distinction between map markers. In the new app, I'm using react-leaflet. All the other plugins used are available to react, but I want to create a leaflet custom component for OverlappingMarkerSpiderfier. I am a bit out of my depth with creating this component.
Ideally, I'd like to call the component like this in the React render loop.
return (
<Map>
<Spiderfy >
<Marker>
<Popup>
</Popup>
</Marker>
<Marker>
<Popup>
</Popup>
</Marker>
</Spiderfy>
</Map>
)
The OverlappingMarkerSpiderfier example shows an instance of the object being created, an event listener is added to the map, and all the Markers are added to the OMS instance. I've tried squeezing this into a ReactLeaflet class but had no success so far.
class _Spiderfy extends MapLayer {
constructor(props) {
super(props)
this.oms = null
}
createLeafletElement ({children, leaflet: {map, ...props}}) {
let newLayer = L.featureGroup()
this.oms = new OverlappingMarkerSpiderfier(map);
var popup = new L.Popup();
this.oms.addListener('click', function(marker) {
popup.setContent(marker.desc);
popup.setLatLng(marker.getLatLng());
map.openPopup(popup);
});
this.oms.addListener('spiderfy', function(markers) {
map.closePopup();
});
return newLayer
}
}
export default withLeaflet(_Spiderfy);
This is the wrapper I currently have. It renders the children (all the markers and their popups), but the event listener doesn't execute when the map is clicked. I also don't know how to get the Marker objects from the children list and add them to the oms instance.
Does anyone have some advice to create this class or some other library which does something very similar?
回答1:
You was close enough, here is an updated component version which demonstrates how to integrate OverlappingMarkerSpiderfier-Leaflet into React-Leaflet
class Spiderfy extends MapLayer {
createLeafletElement(props) {
const { map } = props.leaflet;
this.oms = this.createOverlappingMarkerSpiderfier(map);
const el = L.layerGroup();
this.contextValue = { ...props.leaflet, layerContainer: el };
return el;
}
componentDidMount() {
super.componentDidMount();
this.leafletElement.eachLayer(layer => {
if (layer instanceof L.Marker) {
this.oms.addMarker(layer);
}
});
}
createOverlappingMarkerSpiderfier(map) {
const oms = new window.OverlappingMarkerSpiderfier(map);
oms.addListener("spiderfy", markers => {
markers.forEach(m => m.closePopup())//force to close popup
if (this.props.onSpiderfy) this.props.onSpiderfy(markers);
});
oms.addListener("unspiderfy", markers => {
if (this.props.onUnspiderfy) this.props.onUnspiderfy(markers);
});
oms.addListener("click", marker => {
if (this.props.onClick) this.props.onClick(marker);
});
return oms;
}
}
export default withLeaflet(Spiderfy);
The list of missing parts:
- initialization from markers list via
OverlappingMarkerSpiderfier.addMarker
method - event handlers implementation
And here is a demo for your reference
来源:https://stackoverflow.com/questions/55521219/how-should-i-use-overlappingmarkerspiderfier-with-react-leaflet