vector-tile-esm
Version:
Parses vector tiles
35 lines (25 loc) • 825 B
JavaScript
export function classifyRings(rings) {
// Classifies an array of rings into polygons with outer rings and holes
if (rings.length <= 1) return [rings];
const polygons = [];
let polygon, ccw;
rings.forEach(ring => {
const area = signedArea(ring);
if (area === 0) return;
if (ccw === undefined) ccw = area < 0;
if (ccw === area < 0) {
if (polygon) polygons.push(polygon);
polygon = [ring];
} else {
polygon.push(ring);
}
});
if (polygon) polygons.push(polygon);
return polygons;
}
function signedArea(ring) {
const xmul = (p1, p2) => (p2.x - p1.x) * (p1.y + p2.y);
const initialValue = xmul(ring[0], ring[ring.length - 1]);
return ring.slice(1) // NOTE: skips ring[0], shifts index
.reduce( (sum, p1, i) => sum + xmul(p1, ring[i]), initialValue );
}