react-leaflet add layers dynamically - react-leaflet

I'm starting to use react-leaflet and I came across a question: In my application the user fills out a form that then requests a rest service that returns a GeoJSON, which is then added as a new layer on my map. My question: How do I implement adding layers dynamically in react-leaflet?
Thank you.

The best approach is to create GeoJSON Layer wrapper for react-leaflet. There is a similar implementation of GeoJSON layer with clustering available in react-leaflet's plugins section.
Then you should add this layer to your map component and change it's data when you need to. So there is no need to add the layer dynamically but dynamically change data for it.
Check the leaflet's GeoJSON example to get the idea http://leafletjs.com/examples/geojson/.
The approach will work if you have one layer with changing data. But if you have different data sets you will need to add a GeoJSON layer for each of them.
<Map ...>
{this.props.datasets.map((ds, ix) => {
return (<GeoJSONOverlay data={ds} key={ix} />);
})}
</Map>

I have similar problem. I would like to clear and create marker layers dynamically. I think you can do it by getting reference to the actual map view react refs e.g.
<Map ref={Map => this.map = Map}>
later on you can then use this.map with normal Leaflet functions. Other option could be that you create layers in JSX same way I create markers:
{this.props.markers.map((i,index) => {
return (
<Marker key={i} position={i}>
<Popup>
<span>Great marker!</span>
</Popup>
</Marker>);
})}

Related

How to get the feature geojson from the result of queryRenderedFeatures on a layer whose source is a vector tile in mapbox gl js?

I have a layer called "Searched LayerX" having a vector tile source. I am having a simple requirement of highlighting a feature inside this "Searched LayerX" at runtime.
I was thinking of using the result of queryRenderedFeatures on "Searched LayerX" with the filter of unique ID of this particular feature and using this feature's geojson as a separate source to the new layer which I will be adding as "Selected LayerX".
var features = mapBox.queryRenderedFeatures({layers:['Searched LayerX'], filter : ["==",'gid','7818_2_CA']})
var selectedFeature = features[0];
Resultant feature set does not provide any geojson which I can use to create a new geojson source.
So my question is, how do I use the result as a different source to my "Selected LayerX"?
You can use the method described in the first link below - but understand that the returned feature is not the same as the source GeoJSON feature - it is the vector tile representation of that feature at that zoom level, which means it might be highly simplified.
https://gis.stackexchange.com/questions/186533/highlight-feature-with-click-in-mapbox-gl
Another method is to add another layer with the same source, and use the filter function for the highlight as shown in the two links below -
http://www.mapbox.com.s3-website-us-east-1.amazonaws.com/mapbox-gl-js/example/query-similar-features/
highlighting polyline features in mapbox-gl.js
Try this post, I have added the code which will let you have the features using querySourceFeatures() https://stackoverflow.com/a/66308173/9185662

Leaflet Layer Control: Ordering

We use the standard "layer control" from Leaflet. Instantiation is as follows:
this.controls[id] = L.control.layers({}, {}, {
collapsed: false
});
Layers are added dynamically and in random order (depending on when xhr requests complete). However it seems that leaflet implicity uses the _leaflet_id of the respective layer for ordering in the layer control and thus our layers appear in random order.
Is there any way to tell leaflet in which order it should display the layers in the control? E.g. by passing some additional parameter when calling the .addOverlay or .addBaseLayer methods?
Leaflet version is 1.0-dev
I found some hack-fix for the problem. However this is not a clean solution so feel free to post better answers.
Leaflet uses the _leaflet_id of the layer object for sorting. Thus the layer created first will always be on top. In order to sort the layers you will have to wrap the actual layer in a layer/feature group.
|- dummy layer group
|- some dummy geojson layer
|- your actual layer (will be added later)
Programatically:
var oFeatureGroup = L.featureGroup([
L.geoJson({
"type": "FeatureCollection",
"features": []
})
]);
Then we do some async loading and once we are ready we add the layer to the - more or less empty - layer group:
oFeatureGroup.addLayer(oMyMagicAsyncLoadedLayer)
We can then add the layer to the layer control and it will be sorted as "expected" where the order depends on the order of creation of the oFeatureGroup layers instead of the oMyMagicAsyncLoadedLayer.

How to loop through geojson layers on leaflet map?

I have already added geojson features to my leaflet map. I want to be able to loop through those geojson features. WHen I do map.eachLayer(function(layer) {...}) it only shows be the tile layer and none of the geojson that are added.
Rather than map.eachLayer, you should be using the .eachLayer method on the L.geoJson itself. For example:
var geoJsonLayer = L.geoJson(myGeoJson).addTo(map);
geoJsonLayer.eachLayer(function(layer) {
layer.bindPopup(layer.feature.properties.name);
});
You can also specify a function to be applied to each feature at the time you create the L.geoJson, using the onEachFeature option.

Loading geoJson with simplestyle into leaflet

Is there any way to load a GeoJson file with "simplestyle" (for example, created with geojsonio) directly into Leaflet, so it could use the color, stroke and other properties?
It seems that it is supported in the mapbox, but what about leaflet itself?
Thanks,
Alex
This isn't supported out-of-the-box by Leaflet but you could write your own logic using the pointToLayer function of L.GeoJSON:
Function that will be used for creating layers for GeoJSON points (if not specified, simple markers will be created)
http://leafletjs.com/reference.html#geojson-pointtolayer
new L.GeoJSON(collection, {
pointToLayer: function (feature, latlng) {
// Return a custom marker
}
});
In that function you have access to each feature's properties so you can return a custom marker based on them. Hope that helps, also found the following gist on github which shows a implementation which might do what you are looking for:
https://gist.github.com/tmcw/3861338

Markercluster in Mapbox

I am following markercluster examples from Mapbox library, but can't solve my problem. If you guys take a look at my working example here, you will notice this line of code:
L.mapbox.featureLayer(markerLayer).on('ready', function(e) {
What I initally thought was I could put markers inside of markercluster featureLayer, but I guess it was a wrong approach. Any solutions? Thanks.
Example following here
The mapbox example you refer to makes an AJAX call to retrieve the GeoJSON data, hence it needs to attach an on "ready" listener.
In your case your GeoJSON data is defined in your scripts, so the "ready" event will not be triggered (besides, you should use L.mapbox.featureLayer with your GeoJSON object directly, not a Feature Layer).
You can simply use the eachLayer method to iterate through all created markers within the Feature Layer, and add them into your Marker Cluster Group.
var clusterGroup = new L.MarkerClusterGroup();
var markerLayer = L.mapbox.featureLayer(markers).eachLayer(function(layer) {
clusterGroup.addLayer(layer);
});
map.addLayer(clusterGroup);
Updated Plunker: http://plnkr.co/edit/fN6xYcn1Lg532eLe39IS?p=preview