AJAX and Leaflet: Inspect feature properties before styling/adding to map

大城市里の小女人 提交于 2019-12-12 01:25:18

问题


I'm using leaflet-ajax to load geoJSON on demand. I want to find the maximum theProperty value so I can use that to scale the feature's fill colors before I add them to the map.

Here's my general approach:

    function maxBinPropertyValue(theProperty) {
        var theGeoJson = null;
        var maxPropertyValue = 0;
        var propertyValue = null;
        var theGeoJson = new L.GeoJSON.AJAX(binsFileName());
        theGeoJson.on('data:loaded', function() {
            console.log('The data is loaded');
            theGeoJson.eachLayer(function(layer) {
                console.log('Looping through the layers');
                propertyValue = feature.properties[theProperty];
                if (propertyValue > maxPropertyValue) {
                    maxPropertyValue = propertyValue;
                    console.log('Max so far: ' + maxPropertyValue);
                };
            });
        });
        theGeoJson = null;
        console.log('The final maximum value: ' + maxPropertyValue);
        return maxPropertyValue;
    };

I'm trying to wait for the data:loaded event, then loop through all the features to find the maximum value of theProperty, which is returned to the calling routine.

Except it doesn't work. The first console.log says 'The data is loaded'. The second and third console.logs are never reached, and the fourth and final one reports a value of 0 for maxPropertyValue.

How can I examine all the features in a featureset before styling them, in a way guaranteed to not have asynchronous problems?

PS: I'm pretty sure I can't use onEachFeature: instead of the above approach, because I need to examine every feature's property to determine the maximum value in the set before I can style any of the features.


回答1:


As for your issue about inspecting your data and retrieving the maximum value, you are indeed facing the classic asynchronous concept of JavaScript.

See How do I return the response from an asynchronous call?

Asynchronism is a problem if not dealt with properly, but an advantage if correctly handled.

To put the concept shortly, you do not manage asynchronism in a "standard" sequential way, but you should rather consider parts of code (callbacks) that are executed at a later time based on events.

Whenever you provide a function as an argument, it is certainly a callback that will be executed at a later time, but very probably much later than the next instructions.

So in your case, your 2nd and 3rd console.log are within a callback, and will be executed once your data is loaded, which will happen much later than your 4th console.log.

As for your next step (styling and adding to map), you actually do not need to perform an extra AJAX call, since you already have all data available in theGeoJson variable. You simply need to refactor / restyle it properly.

It is a good approach to break your problem in small steps indeed.

Good luck!

PS: that being said, ES7 provides async and await functionalities that will emulate a sequential execution for asynchronous functions. But to be able to use those, you need latest browser versions or transpilation, which is probably more work to learn and configure as of today for a beginner than understanding how to work with async JS.



来源:https://stackoverflow.com/questions/42564103/ajax-and-leaflet-inspect-feature-properties-before-styling-adding-to-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!