Published
Edited
Mar 2, 2021
1 star
Insert cell
Insert cell
Insert cell
// adapted from https://github.com/apburnes/random-points-on-polygon/blob/master/index.js
function randomPointsOnPolygon(number, polygon, properties, fc) {
const t0 = performance.now()
if (typeof properties === 'boolean') {
fc = properties;
properties = {};
}

if (number < 1) {
return new Error('Number must be >= 1');
}

if(polygon.type !== 'Feature') {
return new Error('Polygon parameter must be a Feature<(Polygon|MultiPolygon)>');

if (polygon.geomtry.type !== 'Polygon' || polygon.geomtry.type !== 'MutliPolygon') {
return new Error('Polygon parameter must be a Feature<(Polygon|MultiPolygon)>')
}
}

if (this instanceof randomPointsOnPolygon) {
return new randomPointsOnPolygon(number, polygon, properties);
}

properties = properties || {};
fc = fc || false;
var points = [];
var bbox = turf.bbox(polygon);
var count = Math.round(parseFloat(number));

for (var i = 0; i <= count; i++) {
if (i === count) {
if (fc) {
return turf.featurecollection(points);
}
console.log(`Vector method completed in ${Math.round(performance.now() - t0)}ms`)
return points;
}

var point = turf.randomPoint(1, { bbox: bbox });

if (turf.inside(point.features[0], polygon) === false) {
i = --i;
}

if (turf.inside(point.features[0], polygon) === true) {
point.features[0].properties = properties;
points.push(point.features[0]);
}
}

}

Insert cell
Insert cell
{
const t0 = performance.now()
const randomPoints = randomPointsOnPolygon(10_000, turf.polygon(CHICAGO))
return `100,000 points generated in ${Math.round(performance.now() - t0)}ms`
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function createContext(width, height) {
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
return canvas.getContext("2d");
}
Insert cell
function generatePoints(geom, bounds, count, precision=6, predicate='inside'){
const t0 = performance.now()
const scale = 10**precision;
const letters = 'abcdefghijklmnopqrstuvwxyz';
const bbox = bounds.map(coord => Math.round(coord*scale));
const originX = bbox[0];
const originY = bbox[1];
const width2 = bbox[2]-bbox[0];
const height2 = bbox[3]-bbox[1];
var ctx = createContext(width2, height2)
for (let i=0;i<geom.length;i++){
ctx.beginPath();
ctx.fillStyle = "rgba(255, 0, 0, 1)";
ctx.moveTo(Math.round(geom[i][0][0]*scale)-originX,Math.round(geom[i][0][1]*scale)-originY);
for (let n=1; n<geom[i].length;n++){
ctx.lineTo(Math.round(geom[i][n][0]*scale)-originX,Math.round(geom[i][n][1]*scale)-originY);
}
ctx.fill() // Draw it
};
var canvasData = ctx.getImageData(0, 0, width2, height2);
var returnArray = [];
const pixels = {
check: predicate === 'outside'?
(x,y,n) => {
var index = (x + y * width2) * 4;
if (canvasData.data[index]!==255) returnArray.push({coords:[(x+originX)/scale,(y+originY)/scale], letter:letters[n%26]})
} : (x,y,n) => {
var index = (x + y * width2) * 4;
if (canvasData.data[index]===255) returnArray.push({coords:[(x+originX)/scale,(y+originY)/scale], letter:letters[n%26]})
}
}
while (returnArray.length < count){
pixels.check(Math.floor(Math.random()*width2),Math.floor(Math.random()*height2), returnArray.length)
};
console.log(`Raster method completed in ${Math.round(performance.now() - t0)}ms`)
return returnArray;
}
Insert cell
Insert cell
{
const t0 = performance.now()
const randompoints = generatePoints(CHICAGO, [-87.6241549,41.8809566,-87.6219636790205,41.8843215], 100_000, 6, 'outside')
return `Raster performance completed in ${Math.round(performance.now() - t0)}ms`
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more