2

A project I am working on contains 15 different layers with 5 containing over 50,000 polygons in each layer. Some of these layers must be "queryable" for data (ex: click to get more information of layer). An exported image of the layers, basemap, and client side drawings is a requirement. I am at a crossroads of selecting client side or server side rendering for this project. I need to know if my logic is correct on this? Any libraries that could be used to solve issues I have (Ex: see Click Query or Image Export)? This question focuses on the client side. See Leaflet Server Side rendering for server side perspective.

Client Side Rendering

Layers

To handle this many layers with some larger polygon files we will probably export the layers as topoJSON. Perhaps we could use vector tiles because certain layers contain labels that need to follow polylines (ex: street names) or points that needs to be labeled with the label matching a rotation angle from the JSON.

Chunked Client Side Rendering Layers

We could load the geoJSON that is visible in the browser as the map moves around and remove the geoJSON that is no longer visible using a code like this:

geojson7 = L.geoJSON(null, {
 table: 'bore_lines4326'
}).addTo(map);

geojson8 = L.geoJSON(null, {
 table: 'facility_lines4326'
}).addTo(map);

var overlays = {
    "Bore Lines": geojson7,
    "Facility Lines": geojson8
};

map.on('moveend', function() {
  for(i in overlays){
    if (map.hasLayer(overlays[i]) && overlays[i].options.table){
      findgJSON(overlays[i], printgJSON);
      };
  }
});

function findgJSON(selectedlayer, callback) {
  var dreak = map.getBounds();
  $.ajax({ ***call stuff here***
      },
      success: function (drawpoly){
            callback(selectedlayer, drawpoly);
        }
    });
}

function printgJSON(selectedlayer, drawpoly) {

catdd = [];
for(n in selectedlayer._layers){
   //pid is a primary key
   catdd.push(selectedlayer._layers[n].feature.properties.pid);
 }

 var deletes = catdd.filter(function(o1){
       // filter out (!) items in result2
       return !drawpoly.features.some(function(o2){
           return o1 === o2.properties.pid;          // assumes unique id
       });
  });

  var addpear = drawpoly.features.filter(function(o1){
    // filter out (!) items in result2
     return !catdd.some(function(o2){
     return o1.properties.pid === o2;          // assumes unique id
    });
   });

    selectedlayer.eachLayer(function(layer){
      for(m = 0; m < deletes.length; m++){
       if (layer.feature.properties.pid === deletes[m]){
         selectedlayer.removeLayer(layer);
       }
      }
    });

    selectedlayer.addData(addpear);
};

Click Query

The click function will have to be a point with a buffer around it to grab anything close by the clicked point. Have you ever tried clicking a polyline in Leaflet especially when it is thin ... :/. Also this will allow us to grab overlapping layers. ex: https://github.com/openplans/Leaflet.FeatureSelect or https://github.com/mapbox/leaflet-pip or maybe turfjs.org

Image Export

To export an image client side we would need to use a library like github.com/niklasvh/html2canvas or github.com/mapbox/leaflet-image

*Apparently there has been a bug introduced by the latest version of leaflet that causes the exported image to be misaligned if the map is moved from its original loaded state github.com/mapbox/leaflet-image/issues/66 ... if i remember correctly the same issue occurs with html2canvas also. Away around this issue would be reload the map in another window and fire off the javascript to create the image once the canvas or geoJSON has fully rendered. How to determine this or perhaps a solution to the problem? The problem might lie with tranform: tranlate3d(xx px, xx px, xx px) style of leaflet

1 Answer 1

2

Those are like three questions. I will answer the part about client-side rendering of large files.

Large-scale rendering is difficult in Leaflet, partially due to loading large files in the browser. Once you approach 50k polygons you get start to hit the limit and should think about image tiles, a GIS server pushing WMS/Vector Tiles, or Mapbox/Carto/Others. That said, I have built (stitched together google searches more like it) an Open Parcel Viewer based on Leaflet using client-side rendering. It loads 32k polygons in under 5 seconds on my desktop and 19 seconds on my phone. It has identify, search and the very basic Leaflet Print plugin. You may run into browser memory limits though if you want to add many different 50k polygon layers.

Simplifying as much as possible via mapshaper and exporting as topojson is key.

There are a few more examples here. Also there is a plugin for Leaflet 1.0 that renders vector tiles on the fly from topojson or geojson, but I have found it to be slightly inferior performance wise to the above examples - (Vector Grid version coming soon to compare).

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