mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-14 15:49:31 -07:00
initial data and graph
This commit is contained in:
51
server/scripts/modules/utils/polygon.mjs
Normal file
51
server/scripts/modules/utils/polygon.mjs
Normal file
@@ -0,0 +1,51 @@
|
||||
// handle multi-polygon and holes
|
||||
const testPolygon = (point, _polygons) => {
|
||||
// turn everything into a multi polygon for ease of processing
|
||||
let polygons = [[..._polygons.coordinates]];
|
||||
if (_polygons.type === 'MultiPolygon') polygons = [..._polygons.coordinates];
|
||||
|
||||
let inArea = false;
|
||||
|
||||
polygons.forEach((_polygon) => {
|
||||
// copy the polygon
|
||||
const polygon = [..._polygon];
|
||||
// if a match has been found don't do anything more
|
||||
if (inArea) return;
|
||||
|
||||
// polygons are defined as [[area], [optional hole 1], [optional hole 2], ...]
|
||||
const area = polygon.shift();
|
||||
// test if inside the initial area
|
||||
inArea = pointInPolygon(point, area);
|
||||
|
||||
// if not in the area return false
|
||||
if (!inArea) return;
|
||||
|
||||
// test the holes, if in any hole return false
|
||||
polygon.forEach((hole) => {
|
||||
if (pointInPolygon(point, hole)) {
|
||||
inArea = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
return inArea;
|
||||
};
|
||||
|
||||
const pointInPolygon = (point, polygon) => {
|
||||
// ray casting method from https://github.com/substack/point-in-polygon
|
||||
const x = point[0];
|
||||
const y = point[1];
|
||||
let inside = false;
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
||||
const xi = polygon[i][0];
|
||||
const yi = polygon[i][1];
|
||||
const xj = polygon[j][0];
|
||||
const yj = polygon[j][1];
|
||||
const intersect = ((yi > y) !== (yj > y))
|
||||
&& (x < ((xj - xi) * (y - yi)) / (yj - yi) + xi);
|
||||
if (intersect) inside = !inside;
|
||||
}
|
||||
return inside;
|
||||
};
|
||||
|
||||
export default testPolygon;
|
||||
Reference in New Issue
Block a user