-2

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

1 Answers1

1

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

Falke Design
  • 10,635
  • 3
  • 15
  • 30
  • I've looked into a similar tact but when I load an image as a map layer it suffers from Mercator projection distortion (which I have otherwise coded around for the visual components overlaid on the map for a regularly spaced grid across the world) and when the image scales up to cover the map I get a blurring distortion. I know in CSS I can set the rendering for an image tag to pixelated which prevents the latter issue but as far as I understand there is no way to impose such a style onto an image in the way that it is uploaded as a layer on leaflet. Obviously it would be strictly for HTM tags – John Thummel Jan 06 '23 at 04:05
  • 1
    @JohnThummel check this out https://github.com/robertleeplummerjr/Leaflet.glify – Falke Design Jan 06 '23 at 14:58
  • Okay so in leaflet.glify Im currently successfully rendering over a million rectangles pretty damn well, which is amazing! Thank you so much! but I cannot get any glify features to render in my vue environment. The github works if I pull and use the code directly but the npm package for leaflet.glify (after two days of troubleshooting, still) doesnt seem to be working in my environment for some reason. I could speculate but Im wondering if you have any ideas, theres not much coverage on this package. Tomorrow I will also attempt to post this in the github issues. – John Thummel Jan 14 '23 at 13:10
  • Mostly problems by importing Leaflet plugins are: 1. Leaflet is not initizialized if the plugin is loaded. 2. The plugin is applied to a different `Leaflet` / `window` context. You can try to use `L.noConflict(); console.log(L);` maybe then works – Falke Design Jan 15 '23 at 16:51
  • I tried making a new Vue project and putting the bare leaflet.glify code in to render one test point and unfortunately... it works. So something in one of my packages I assume is somehow crippling it from rendering. In the original project it even throws click events in the expected area but simply doesnt render the actual point visually. So ive decided it probably best to start with this scratch project and move over the components I need and rebuild that way. Thanks so much for your help. Eventually Ill get this puppy in order! lol – John Thummel Jan 19 '23 at 01:04
  • OKAY! for future reference if youre not getting rendering on leaflet.glify but everything else works properly I have found it is likely a CSS issue. Mine came down to just commenting out `import 'vue-material/dist/vue-material.min.css` – John Thummel Jan 21 '23 at 00:51