I have a LineString geoJSON dataset (about 50000 line strings) which I need to plot in mapbox using leaflet. Currently it takes a lot of time to render the map. Since I need to update the map every 30 seconds with new data, if it is taking 3 minutes to render the whole map then there will be no point to visualizing the data.
So my code for displaying the 50000 LineStrings is below:
var map = L.map('map').setView([36.447488,102.463303], 12);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=token', {
maxZoom: 18,
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(map);
var options = {
position: 'topleft',
title: 'Search',
placeholder: 'enter id ',
maxResultLength: 15,
threshold: 0.5,
showInvisibleFeatures: true,
showResultFct: function(feature,container) {
props = feature.properties;
var name = L.DomUtil.create('b', null, container);
name.innerHTML = props.id;
container.appendChild(L.DomUtil.create('br', null, container));
var cat = props.id
info = '' + cat + ', ' + 'th id';
container.appendChild(document.createTextNode(info));
}
};
var searchCtrl = L.control.fuseSearch(options);
searchCtrl.addTo(map);
var geojson;
function getColor(d) {
if(d==10 || d==9 || d==8){
return '#ff0000';
}
else {
return '#00ff65';
}
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: getColor(feature.properties.points),
fillOpacity: 0.7,
};
}
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 2,
color:'#007d80',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
map.doubleClickZoom.disable();
}
var info = L.control();
info.update = function (props) {
this._div.innerHTML = '<h4><b>Link: <b></h4>' + (props ?
'<b>LineString ' + props.id + '</b><br />'
: 'Hover over a LineSting');
};
function onEachFeature(feature, layer) {
feature.layer = layer;
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
});
var popupContent =
'<b>Link ' + feature.properties.id + '</b>';
layer.bindPopup(popupContent);
feature.layer = layer;
}
function mapupdatecolor(){
$.ajax({
type: "GET",
async : false,
url: 'http:dataurl',
success: function(data) {
console.log("sucess");
for (i = 0; i<40000; i++) {
links['features'][i]['properties']['points']=data[i].points;
}
if (geojson) {
geojson.remove();
console.log("removed");
}
function picnicFilter(feature) {
if (feature.properties.points >= 9) return true
}
geojson = L.geoJson(lines, {
filter: picnicFilter,
style: style,
onEachFeature: onEachFeature
}).addTo(map);
console.log("update done");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
},
complete: function() {
setTimeout(mapupdatecolor, 5000);
}
});
// schedule the first invocation:
}
geojson = L.geoJson(lines, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
this.update();
return this._div;
};
searchCtrl.indexFeatures(links.features, ['id']);
info.addTo(map);
setTimeout( mapupdatecolor, 5000);
My geoJSON data is like below:
var lines=
{
"type":"FeatureCollection",
"features": [
{"type": "Feature","geometry":{"type":"LineString", "coordinates":[[102.463303,36.447488],[102.514114,36.439755],..]},"properties": {"id":"01","points":9}},
{"type": "Feature","geometry":{"type":"LineString", "coordinates":[[102.593765,36.414341],[102.634964,36.402183],..]},"properties": {"id":"02","points":8}},
{"type": "Feature","geometry":{"type":"LineString", "coordinates":[[102.880783,36.485038],[102.882156,36.561187],..]},"properties":{"id":"03","points":10}}
........ and upto id 50000 ]};
By the way My each LineStrings have more than two coordinates (nearly 20-30 coordinates)
What is the way to make the data render fast in my case?