1

I want to add a province layer to Leaflet map, which fetched from 4 php for different UTM zones.

The corresponding sql table has promotion and population and density columns.

I want to fetch the GeoJSON layer once and display the provinces with different styles for each column values on Leaflet map with different names on legend.

then i have 1 multipolygon layer which i want to display in different styles for different column values.

Here is my full code for one case:

var ProvinceLayer = L.layerGroup();

// Fetch the GeoJSON data from multiple PHP files
Promise.all([
    fetch('Add_Province_Polygons_Zone35.php').then(response => response.json()),
    fetch('Add_Province_Polygons_Zone36.php').then(response => response.json()),
    fetch('Add_Province_Polygons_Zone37.php').then(response => response.json()),
    fetch('Add_Province_Polygons_Zone38.php').then(response => response.json())
]).then(data => {
    data.forEach(geojson => {
        L.geoJSON(geojson, {
            style: function (feature) {
                return {
                                weight: 2,
                                color: 'white',
                                dashArray: '3',
                                fillOpacity: 0.9,
                                fillColor: getColor(feature.properties.population_density),
                                interactive: true 
                };
            },
            onEachFeature: function (feature, layer) {

                var popupContent = feature.properties.province ;
                layer.bindTooltip(popupContent, { sticky: true });
            }
        }).addTo(ProvinceLayer);
    });
});

ProvinceLayer.addTo(map);
control.addOverlay( ProvinceLayer, "layer1", {groupName : "Bölge Tipi"} );

I use this code 3 times to display in 3 different styles. Thus it affects the loading speed of web.

Have any suggesstion to solve in fact, fetched once and display in different styles on map?

4
  • In what way these three styles differ? On what data/parameters are differences based? Please edit your question and add some info about that. I also recommend getting a new keyboard where upper case button works :-)
    – TomazicM
    Jan 5 at 8:47
  • i was mentioned, but now add as bold: promotion, population and density.
    – Solmaz
    Jan 5 at 8:58
  • Do you want to have different ProvinceLayer layer for each style, or just show the same ProvinceLayer layer in different styles? Please edit your question and clarify this?
    – TomazicM
    Jan 5 at 10:02
  • i add a simple description as well :) i have just want to display just one geojson with more than one style.
    – Solmaz
    Jan 5 at 10:34

2 Answers 2

1

Logic of your app is not completely clear from your question and code, so answer will be based on the following assumptions:

  • only one overlay style can be displayed at once;
  • when one style is selected, the other is removed.

Answer is based on data for official Leaflet choropleth example data (see https://leafletjs.com/examples/choropleth/). Implementation is done the following way:

  • GeoJSON data is read only once and stored in statesLayer layer.
  • statesLayer layer is styled using stateStyle function, where styling is dependent on global styleSelection variable.
  • Selecting desired style to be shown is done through dummy selectLayer group layers which are not actually displayed on the map but are used just for setting the styleSelection variable and resetting statesLayer layer style to reflect selected style.
  • stateStyle styling function returns style depending on styleSelection variable. For testing purposes it just multiplies density property by styleSelection value.

Here is the complete code:

var map = L.map("map", {zoomControl: false}).setView([41, -99], 5);

L.control.zoom({
    position: 'bottomright'
}).addTo(map);

var osm = L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
  maxZoom: 19,
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
});

var googleStreets = L.tileLayer('http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
  maxZoom: 20,
  subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
});
googleStreets.addTo(map);

var googleSat = L.tileLayer('http://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}', {
  maxZoom: 20,
  subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
});
      
var selectLayer = [];

function getColor(d) {
  return d > 1000 ? '#800026' :
      d > 500  ? '#BD0026' :
      d > 200  ? '#E31A1C' :
      d > 100  ? '#FC4E2A' :
      d > 50   ? '#FD8D3C' :
      d > 20   ? '#FEB24C' :
      d > 10   ? '#FED976' :
                 '#FFEDA0';
}

var styleSelection;
      
function stateStyle(feature) {
  var selValue, fillColor;
  
  fillColor = getColor(feature.properties.density * styleSelection);
  return {
    fillColor: fillColor,
    weight: 2,
    opacity: 1,
    color: 'white',
    dashArray: '3',
    fillOpacity: 0.5
  };
}
     
var statesLayer = L.geoJSON(null, {
  style: stateStyle
});

var baseMaps = {
  "OSM": osm,
  'Google Street': googleStreets,
  "Google Satellite": googleSat,
};

var layerControl = L.control.layers(baseMaps, null, {collapsed: false}).addTo(map);

var url = '../data/us-states.txt';
fetch(url)
  .then(response => {
    return response.json();
  })
  .then(json => {
    statesLayer.addData(json);
    for (var i = 1; i <= 3; i++) {
      selectLayer[i] = L.layerGroup();
      selectLayer[i].myId = i;
      layerControl.addOverlay(selectLayer[i], 'Overlay ' + i);
    }        
  });

map.on('overlayadd', function(evt) {
  var id = evt.layer.myId;
  if (styleSelection) {
    var forRemove = styleSelection;
    setTimeout(function () {
      map.removeLayer(selectLayer[forRemove]);
    }, 0);
  }
  styleSelection = id;
  statesLayer.setStyle(stateStyle);
  if (!map.hasLayer(statesLayer)) {
    map.addLayer(statesLayer);
  }
});

map.on('overlayremove', function(evt) {
  var id = overlayMaps[evt.name].myId;
  if (id == styleSelection) {
    map.removeLayer(statesLayer);
    styleSelection = null;
  }
});

That's how the result looks like for two different selections:

enter image description here

enter image description here

0

If I understand correctly what you want to do is to create 3 different layers that are displaying the same geometries but are styled differently.

You could achieve that like this:

Promise.all(...).then(
  data.forEach(
    L.geoJSON(...
      fillColor: getColorForDensity(feature.properties.population_density)
    ).addTo(ProvinceLayer);

    L.geoJSON(...
      fillColor: getColorForPromition(feature.properties.promotion)
    ).addTo(ProvinceLayer);

    L.geoJSON(...
      fillColor: getColorForPopulation(feature.properties.population)
    ).addTo(ProvinceLayer);


  )
)

You add 3 layers after all the promises resolved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.