Published
Edited
Jul 19, 2021
Fork of 🍃 Leaflet
1 star
Insert cell
Insert cell
L = require('leaflet@1.4.0')
Insert cell
Insert cell
Insert cell
html`<link href='${resolve('leaflet@1.4.0/dist/leaflet.css')}' rel='stylesheet' />`
Insert cell
Insert cell
geojson = FileAttachment("london-boroughs.geojson").json()
Insert cell
map = {
// yield container early: allows div to be placed on the page.
let container = DOM.element('div', {
style: `width:${width}px; height:${width / 1.6}px`
});
yield container;

// Leaflet uses div .offsetWidth and .offsetHeight to size the map.
let map = L.map(container, { renderer: L.canvas() });

let osmLayer = L.tileLayer(
'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png',
{
attribution:
'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}
).addTo(map);

// dot density generation options
let options = { maxIterations: 50, distance: 20, numDots: 20 };
// geneerate dots
let dots = [];

let geojsonLayer = L.geoJson(geojson, {
weight: 1,
color: '#432',
onEachFeature: (feature, layer) => {
layer.bindPopup(feature.properties.name);
layer.bindTooltip(feature.properties.name);

let bounds = layer.getBounds();
let width = Math.abs(bounds._northEast.lng - bounds._southWest.lng);
let height = Math.abs(bounds._northEast.lat - bounds._southWest.lat);

outer: for (let i = 0; i < options.maxIterations; i++) {
let p = [
bounds._southWest.lat + Math.random() * height,
bounds._southWest.lng + Math.random() * width
];
if (
pip.pointInLayer(p, L.geoJSON(layer.toGeoJSON()), true).length > 0
) {
// // check distance to other dots
// for (let j = 0; j < dots.length; j++) {
// let dx = p[0] - dots[j][0],
// dy = p[1] - dots[j][1];
// if (Math.sqrt(dx * dx + dy * dy) < options.distance) continue outer;
// }
// // check distance to polygon edge
// for (let j = 0; j < feature.geometry.coordinates[0].length - 1; j++) {
// if (
// distPointEdge(
// p,
// feature.geometry.coordinates[0][j],
// feature.geometry.coordinates[0][j + 1]
// ) < options.edgeDistance
// )
// continue outer;
// }
dots.push(p);
L.circleMarker(p, { radius: 1, weight: 1, color: 'black' }).addTo(
map
);
if (dots.length == options.numDots) break;
}
}
}
}).addTo(map);
map.fitBounds(geojsonLayer.getBounds());
}
Insert cell
// ported from https://stackoverflow.com/q/30559799
function distPointEdge(p, l1, l2) {
let A = p[0] - l1[0],
B = p[1] - l1[1],
C = l2[0] - l1[0],
D = l2[1] - l1[1];

let dot = A * C + B * D;
let len_sq = C * C + D * D;

// alpha is proportion of closest point on the line between l1 and l2
let alpha = -1;
if (len_sq != 0)
//in case of 0 length line
alpha = dot / len_sq;

// points on edge closest to p
let X, Y;

if (alpha < 0) {
X = l1[0];
Y = l1[1];
} else if (alpha > 1) {
X = l2[0];
Y = l2[1];
} else {
X = l1[0] + alpha * C;
Y = l1[1] + alpha * D;
}

let dx = p[0] - X;
let dy = p[1] - Y;

return Math.sqrt(dx * dx + dy * dy);
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more