Search code examples
javascriptgoogle-maps-api-3leafletdrawrectangles

Draw large numbers of rectangles on map (Gmaps API/leaflet.js)


I am trying to draw colored cells on a JS map API, at very large scale ~(70k rectangles).

NOTE: There is no reasonably short amount of example code i can show you for this isnt a "coding issue" so much as it is a request for direction in library usage or suggestions on a more applicable library for my goal.

I have tried to draw cells in a grid in leaflet (bogs down response time to 50,000+ms) I have tried to draw cells in a grid in Google Maps (works well visually, response time is good, but memory usage jumps to over 1GB (and also struggles to release promptly for some reason)

Right now Im rendering just under 70k cells (rectangles) but ideally Id like a drawing method that wont have an upper bound.

=> Maybe drawing to some kind of buffer and overlaying it? - this was my original version using canvas and i cant get it to sync with the "springy" movement nature of panning in modern web maps. Essentially it looks cheap and jumpy.

=> Draw within provided map tools? - this is my current approach and on gmaps memory reaches over 1Gb and on leaflet.js it only hits ~180Mb but is effectively frozen. Its my belief that gmaps has too much overhead in their shapes drawing library and that leaflet has trimmed it but each shape must be being processed in the main loop in some way, as reaction time scales with shapes pretty proportionately.

Please if there is a better way to crack this puppy lmk, I truly appreciate any and all who have taken their time to read of my plight. <3

P.S. If you wish to see the current state rendered in gmaps goto: w4a.care If you wish to look over the code (since I cannot really condense the problem into a post): github dev branch


Solution

  • You can use Leaflet with canvas together but you will always have some performance problems while rendering this on the client. A way would be to prerender this rectangles on the server and only providing one image which will be added to the map. (Or better as tiles).

    Here is an example with 20,000 rectangles rendered on a canvas in Leaflet:

    var rectBounds = [[50.500349511683865, 30.508469939231876],[50.499878630673834, 30.50938725471497]];
    var canvas = L.canvas();
    var rect = L.rectangle(rectBounds, {renderer: canvas}).addTo(map);
    

    https://plnkr.co/edit/tW46Mdr9H3GeyLto