最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Leaflet : ordering GeoJSON elements inside a layer - Stack Overflow

programmeradmin0浏览0评论

I'm displaying a GeoJSON layer using leaflet, with the pointToLayer function. Everything works ok so far.

But I would like to display my points in a certain order, based on a property of the GeoJSON. This is important because the radiuses of my points varies with this property, and I need to display the smaller circles on top. I hope I make myself clear.

I've tried many things, but here's what I think is my best try :

var pointLayer = L.geoJson(centroids, {
                pointToLayer: function (feature, latlng) {
                    return L.circleMarker(latlng, {
                        fillColor: "#76C551",
                        color: "#000",
                        weight: 1,
                        fillOpacity: 1
                    });
                },
                onEachFeature: function (feature, layer) {
                    var radius = calcPropRadius(feature.properties.nb);
                    layer.setRadius(radius);
                    feature.zIndexOffset = 1/feature.properties.nb*1000;
                    layer.bindPopup(feature.properties.name + " : " + String(feature.zIndexOffset));
                }
            });

You can notice that the zIndexOffset of features can be read in the popups, and they look ok. But the displaying order of the circles doesn't reflect the zIndexOffset. I've tried using the setZIndexOffset method, but as I understand it it works only with markers.

Does anyone know how to do this ? Thanks a lot for any insight !

I'm displaying a GeoJSON layer using leaflet, with the pointToLayer function. Everything works ok so far.

But I would like to display my points in a certain order, based on a property of the GeoJSON. This is important because the radiuses of my points varies with this property, and I need to display the smaller circles on top. I hope I make myself clear.

I've tried many things, but here's what I think is my best try :

var pointLayer = L.geoJson(centroids, {
                pointToLayer: function (feature, latlng) {
                    return L.circleMarker(latlng, {
                        fillColor: "#76C551",
                        color: "#000",
                        weight: 1,
                        fillOpacity: 1
                    });
                },
                onEachFeature: function (feature, layer) {
                    var radius = calcPropRadius(feature.properties.nb);
                    layer.setRadius(radius);
                    feature.zIndexOffset = 1/feature.properties.nb*1000;
                    layer.bindPopup(feature.properties.name + " : " + String(feature.zIndexOffset));
                }
            });

You can notice that the zIndexOffset of features can be read in the popups, and they look ok. But the displaying order of the circles doesn't reflect the zIndexOffset. I've tried using the setZIndexOffset method, but as I understand it it works only with markers.

Does anyone know how to do this ? Thanks a lot for any insight !

Share Improve this question asked Aug 23, 2016 at 13:02 J. PiersonJ. Pierson 1036 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

Whereas ghybs answer works perfectly for leaflet 0.7, switching to leaflet 1.0 allows the use of panes which makes for an easier solution :

var pointLayer = L.geoJson(centroids, {
            pointToLayer: function (feature, latlng) {
                return L.circleMarker(latlng, {
                    fillColor: "#76C551",
                    color: "#000",
                    weight: 1,
                    fillOpacity: 1
                });
            },
            onEachFeature: function (feature, layer) {
                var radius = calcPropRadius(feature.properties.nb);
                layer.setRadius(radius);
                layer.setStyle({pane: 'pane'+ feature.properties.nb});
                var currentPane = map.createPane('pane' + feature.properties.nb);
                currentPane.style.zIndex = Math.round(1/feature.properties.nb*10000);
                layer.bindPopup(feature.properties.name + " : " + String(feature.zIndexOffset));
            }
        });

Hope it can be of use to someone else !

As you figured out, the zIndexOffset option is only for L.marker's.

L.circleMarker's go into the overlayPane and you can re-order them one to each other using .bringToFront() and .bringToBack() methods.

I'd like to offer an alternative which worked for me on a similar problem.

In my case, my data had a "status" which changed over time and I needed the most critical ones to always be on top. So I ordered the data before drawing, something like:

myData.features.sort((a,b) => a.properties.status <= b.properties.status ? -1 : 1);
return (<GeoJSON data={myData}/>);

This way the critical ones were drawn last.

In your case, I believe you can order your centroids before the draw.

发布评论

评论列表(0)

  1. 暂无评论