quickmap = function* (data, params = {}) {
const {
width = 800,
height = 400,
tile = "Carto Positron Light",
attrib = "fid",
title = attrib,
method = "quantile",
full = true,
heatmap = {
radius: 40,
blur: 25,
maxZoom: 17,
gradient: { 0.4: "blue", 0.65: "lime", 1: "red" }
},
choropleth = {
numClass: 4,
method: "jenks",
colorScheme: "BuPu"
}
} = params;
let container = htl.html`<div style="height:${height}px; width:${width}px">`;
yield container;
full ? fullscreen(container, { center: true }) : "";
const map = L.map(container, {
renderer: L.canvas(),
zoomSnap: 0.25
}).setView([-7.8, 110.379], 13);
map.preferCanvas = true;
tileProviders(tile).addTo(map);
// -- Helper functions
// Highlight on hover
function highlightFeature(feature) {
var feature_targeted = feature.target;
feature_targeted.setStyle({
color: "#fc0000"
});
if (!L.Browser.ie && !L.Browser.opera) {
feature_targeted.bringToFront(feature.target);
}
info.update(feature_targeted.feature.properties);
}
function resetHighlight(e) {
geolayer.resetStyle(e.target);
info.update();
}
// OnEachFeature
// iterate to all feature. store the data and highlight relevant value
const stored_data = [];
if (params.choropleth) {
for (const feature of data.features) {
const value = feature.properties[attrib];
// console.log(value);
stored_data.push(value);
}
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight
});
}
// Style function
const style = (feature, layer) => {
const value = feature.properties[attrib];
let newvalue;
if (!params.choropleth) {
newvalue = null;
} else {
try {
newvalue = getColor(
value,
discr.breaks(stored_data, {
method: params.choropleth.method,
nb: params.choropleth.numClass,
minmax: true,
precision: 2
}),
params.choropleth.colorScheme
);
} catch (error) {
console.log("error occured during style mapping");
// console.error(error);
}
}
return {
fillColor: newvalue || "lightblue",
weight: 0.5,
fillOpacity: 0.8,
color: "#fff"
};
};
// info on hover
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create("div", "info");
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML =
"<b>" +
title +
"</b><br />" +
(props ? props[attrib] : "Hover over a feature");
};
info.addTo(map);
// console.log(
// discr.breaks(stored_data, {
// method: params.choropleth.method,
// nb: params.choropleth.numClass - 1,
// minmax: true,
// precision: 2
// })
// );
// legend
var legend = L.control({ position: "bottomleft" });
legend.onAdd = function (map) {
var div = L.DomUtil.create("div", "info legend");
var svgString;
try {
svgString = new XMLSerializer().serializeToString(
drawLegend(
title,
discr.breaks([...new Set(stored_data)], {
method: params.choropleth.method,
nb: params.choropleth.numClass - 1,
minmax: true,
precision: 2
}),
params.choropleth.colorScheme
)
);
} catch (error) {
console.log(error);
svgString = "";
}
div.innerHTML = svgString;
return div;
};
legend.addTo(map);
// The Layer
var geolayer = L.geoJson(data, {
// filter: function (feature, layer) {
// if (feature.properties) {
// return feature.properties[filter] !== undefined
// ? !feature.properties[filter]
// : true;
// }
// return false;
// },
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, {
radius: 8,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
});
},
onEachFeature: onEachFeature,
style: style
}).addTo(map);
// Map utilities
map.fitBounds(geolayer.getBounds());
if (params.heatmap) {
// console.log(stored_data);
let heatmapLayer = new heatLayer(geoJson2heat(data), {
radius: heatmap.radius,
blur: heatmap.blur,
maxZoom: heatmap.maxZoom,
gradient: heatmap.gradient
});
heatmapLayer.addTo(map);
map.removeLayer(geolayer);
}
invalidation.then(() => {
// heatLayer.redraw().remove();
map.remove();
});
}