Reputation: 6117
I'm using react-leaflet to render a geojson feature collection that has points and linestrings:
I was able to get the click and hover events on the actual features themselves to work just fine. But I'd like to be able to hover on a list item (related to the items on the map) and have the popup open. I've been sorting through the docs, github, and trying different things out. But it seems there's no way to do this. Or that I'll have to render my linestrings and points manually vs. using the <GeoJSON data=
My map works well with the click events:
return (
<Map
style={{
height: '100%',
width: '100%',
margin: '0 auto'
}}
ref={(el) => {
this.leafletMap = el;
}}
center={position}
zoom={10}>
<TileLayer url='https://api.mapbox.com/v4/mapbox.outdoors/{z}/{x}/{y}@2x.png?access_token=pk.eyJ1IjoiYWJlbnMwefwefEiOiJjajJ1bDRtMzcwMDssmMzJydHdvcjF6ODA5In0.xdZi4pmkhj1zb9Krr64CXw' attribution='© <a href="https://www.mapbox.com/about/maps/">Mapbox</a>' />
<GeoJSON data={locations} onEachFeature={this.onEachFeature} />{' '}
</Map>
);
onEachFeature works as it should
onEachFeature = (feature, layer) => {
console.log('onEachFeature fired: ');
layer.on({
mouseover: (e) => this.MouseOverFeature(e, feature),
mouseout: (e) => this.MouseOutFeature(e, feature)
});
};
But I don't see how to call the layer.bindPopup without using onEachFeature
. How does one change call these methods using prop values? I'd like to let people hover on a list item and have it toggle the popups.
Upvotes: 2
Views: 2405
Reputation: 59358
You could consider to extend GeoJSON
component, for example:
const GeoJSONWithLayer = props => {
const handleOnEachFeature = (feature, layer) => {
let popupContent = "";
if (props.popupContent.length) popupContent = props.popupContent;
else if (feature.properties && feature.properties.popupContent) {
popupContent = feature.properties.popupContent;
}
layer.bindPopup(popupContent);
layer.on({
mouseover: e => {
layer.openPopup();
},
mouseout: e => {
layer.closePopup();
}
});
};
return <GeoJSON {...props} onEachFeature={handleOnEachFeature} />;
}
GeoJSONWithLayer.defaultProps = {
popupContent: '',
}
It supports passing extra props along with default properties and contains popup binding logic for a layer. Now it could be utilized like this:
const MapExample = props => {
const style = () => ({
color: "green",
weight: 20
});
const freeBus = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "LineString",
coordinates: [
[-105.00341892242432, 39.75383843460583],
[-105.0008225440979, 39.751891803969535],
[-104.99820470809937, 39.74979664004068],
[-104.98689651489258, 39.741052354709055]
]
},
properties: {
popupContent:
"This is a free bus line that will take you across downtown.",
underConstruction: false
},
id: 1
}
]
};
return (
<Map zoom={14} center={{ lat: 39.74739, lng: -105 }}>
<TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
<GeoJSONWithLayer
popupContent={"Some content goes here..."}
data={freeBus}
style={style}
/>
</Map>
);
};
Upvotes: 5