I'm learning maps and using Leaflet which is great, and now I'm digging into some extensions. I'm trying to get leaflet-velocity to work as a React Component, but I seem to be missing something. Running it as a standard index.html with the associated files works fine, but that doesn't integrate into an existing project. Ideally I would like to be able to add in Velocity as an Overlay layer with dynamic markers.
Here is code I have
<LayerGroup>
{datas.length > 0 && datas.map((data, index) => {
return(
<div key={index}>
<Marker position={[data.lat, data.long]} icon={color}>
</Marker>
</div>
)})}
</LayerGroup>
</LayersControl.Overlay>
<LayersControl.Overlay>
# I was thinking it would be something like this...but nope
<L.velocityLayer data={windGBR} displayValues={true}></L.velocityLayer>
</LayersControl.Overlay>
Error:
Objects are not valid as a React child (found: object with keys {options, _initHooksCalled}). If you meant to render a collection of children, use an array instead
So my question is how can I take demo.js and integrate it into React as if it was a regular component? Thanks in advance
P.S. Let me know if I should post the full demo file here or if providing the github link is sufficient...
You cannot include react-leaflet code in combination with vanilla js leaflet code because simply it is not supported
You need to do the following steps:
Map component:
export default function Map() {
const layerControlRef = useRef();
return (
<MapContainer center={position} zoom={5} style={{ height: "100vh" }}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<LayersControl position="topright" ref={layerControlRef}>
<LayersControl.Overlay name="Satellite">
<TileLayer
attribution="Tiles © Esri — Source: Esri, i-cubed, USDA, USGS
AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
/>
...
}
Leaflet Velocity component:
const LeafletVelocity = forwardRef((props, ref) => {
const map = useMap();
useEffect(() => {
if (!map) return;
let mounted = true;
let windGbrLayer;
let waterGbrLayer;
let windGlobalLayer;
fetch("https://onaci.github.io/leaflet-velocity/wind-global.json")
.then((response) => response.json())
.then((data) => {
if (!mounted) return;
windGlobalLayer = L.velocityLayer({
displayValues: true,
displayOptions: {
velocityType: "GBR Water",
position: "bottomleft",
emptyString: "No water data"
},
data: data,
maxVelocity: 0.6,
velocityScale: 0.1 // arbitrary default 0.005
});
if (ref.current && windGlobalLayer)
ref.current.addOverlay(windGlobalLayer, "Wind - Global");
})
.catch((err) => console.log(err));
return () => {
mounted = false;
if (ref.current) {
ref.current.removeOverlay(windGbrLayer);
}
};
}, [map]);
return null;
});
export default LeafletVelocity;
Similar approach for the other two api calls.
For more check the demo