kerala-flood-map icon indicating copy to clipboard operation
kerala-flood-map copied to clipboard

use Leaflet's L.circleMarker to deal with performance issues

Open answerquest opened this issue 6 years ago • 6 comments

For performance issues, Suggestion: use Leaflet's L.divIcon. Enables much higher number of points on map (several thousands or more). Can assign it classes based on metadata and use CSS to give it any shape/color (I recommend small colored dots instead of large markers). Sharing a snippet.

var stopmarker = L.marker([lat,lon], { 
	icon: L.divIcon({
		className: `stop-divicon`,
		iconSize: [17, 17],
		html: labelShort
	}) 
});
stopmarker.addTo(stopsLayer);

Will try to make a PR, but might just share the proposed snippet here if there's other things to change (like css) and I can't figure things out. Apologies but I haven't worked on react js yet.

answerquest avatar Aug 16 '18 19:08 answerquest

Hey @answerquest glad you have you here

aswinmohanme avatar Aug 16 '18 19:08 aswinmohanme

I think I found where the markers code is: https://github.com/aswinmohanme/kerala-flood-map/blob/master/src/components/mainPage/mainPageMap.js#L30

answerquest avatar Aug 16 '18 19:08 answerquest

Yeah, the custom marker images are one of the major performance issues

aswinmohanme avatar Aug 16 '18 19:08 aswinmohanme

Yikes, my bad, the L.divIcon isn't the way to improve page performance; it's by using L.circleMarker and a custom SVG renderer. Its explained on this stackoverflow post. The jsfiddle linked has 100k points rendered with no drag on page.

This would require changes other than just replacing the icon declarations as I'd assumed earlier.

answerquest avatar Aug 16 '18 19:08 answerquest

This is how the code for L.circleMarker would look in Vanilla JS.

var myRenderer = L.canvas({ padding: 0.5 });
// from https://stackopverflow.com/a/43019740/4355695

var redcircleMarkerOptions = {
  renderer: myRenderer,
  radius: 5,
  fillColor: 'red',
  color: 'black',
  weight: 1,
  opacity: 1,
  fillOpacity: 0.5
};
var bluecircleMarkerOptions = {
  renderer: myRenderer,
  radius: 5,
  fillColor: 'blue',
  color: 'black',
  weight: 1,
  opacity: 1,
  fillOpacity: 0.5
};
var greencircleMarkerOptions = {
  renderer: myRenderer,
  radius: 5,
  fillColor: 'green',
  color: 'black',
  weight: 1,
  opacity: 1,
  fillOpacity: 0.5
};

var stopmarker = L.circleMarker([lat,lon], redcircleMarkerOptions);
stopmarker.addTo(stopsLayer);

Trying to see how it can be done in react. Docs.

answerquest avatar Aug 16 '18 20:08 answerquest

Also, better to add the different colors markers to different layers entirely, then the user can switch them on/off. If anyone knows react-leaflet, I'd love some translation help! I can do it all in simple leaflet js.

answerquest avatar Aug 17 '18 03:08 answerquest