Wednesday, 23 January 2019

javascript - Leflet js style geojson layer according to zoom level


Leaflet js beginner following/adapting the choropleth example. I need to get something like this mapbox map where the feature styles change according to zoom level. I am loading a line geojson that gets style from getColor / getWidth functions related to feature.properties. How do I get the weight to be 1 when currentZoom is <= 16?


var geojson = L.geoJson(roads, {
style: style
}).addTo(map);

function getColor(p) {

return p >= 100 ? '#00F7BD' :
p >= 40 ? '#24abc9' :
p >= 20 ? '#ef561a' :
p >= 0 ? '#4D2A2D' :
'#feffbd';
}

function getWidth(w) {
return w > 20 ? 4.8 :
w > 17 ? 4.5 :

w > 16 ? 4 :
w > 15 ? 3.5 :
w > 14 ? 2.5 :
w > 10 ? 1.5 :
w > 0 ? 0.5 :
0;
}

// map.on('zoomend', function () {
var currentZoom = map.getZoom();


function style(feature) {
if (currentZoom <= 16) {
return {
color: getColor(feature.properties.paP),
weight: 1,
opacity: 0.5,
};
}
else {

return {
weight: getWidth(feature.properties.stW),
color: getColor(feature.properties.paP),
};
}
}
// });

Second approach inspired by Stephen's answer @Stephen Lead


   function style(feature) {

var fa;
return {
color: getColor(feature.properties.paP),
weight: fa * getWidth(feature.properties.stW),
opacity: 0.6,
lineCap: 'square',
lineJoin: 'square',
};
}


map.on('zoomend', function () {
var currentZoom = map.getZoom();
if (currentZoom <= 16) {
fa = 0.5;
}
else {
fa = 3;
}
});

Answer




One approach is to set the style's width property based on the current map scale, and update this whenever the scale changes.


See the JS Fiddle for an example, and zoom in to see the width increase:


enter image description here


function addStates() {
// this function adds the states layer with the style's weight determined
// by the current zoom level
geojson = L.geoJson(statesData, {
style: style
}).addTo(map);
}


function style(feature) {
// the weight is a function of the current map scale
var wt;
if (map.getZoom() <= 6) {
wt = 1;
} else {
wt = 20;
}
return {

weight: wt,
....
};
}

// whenever the zoom level changes, remove the layer and re-add it to
// force the style to update based on the current map scale
map.on("zoomend", function(){
geojson.removeFrom(map);
addStates();

});

This suggested approach removes the layer each time the scale changes, then adds it again to force the setStyle function to recalculate based on the current map scale. It may be possible to make this more efficient, but it seems to work reasonably well.


(I picked zoom level 6 and a width of 20 for an easy demonstration of the effects - it's difficult to determine the difference between a width of 1 and 2 visually)


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...