45 lines
1.2 KiB
JavaScript
45 lines
1.2 KiB
JavaScript
|
|
module.exports = rewind;
|
|
|
|
function rewind(gj, outer) {
|
|
var type = gj && gj.type, i;
|
|
|
|
if (type === 'FeatureCollection') {
|
|
for (i = 0; i < gj.features.length; i++) rewind(gj.features[i], outer);
|
|
|
|
} else if (type === 'GeometryCollection') {
|
|
for (i = 0; i < gj.geometries.length; i++) rewind(gj.geometries[i], outer);
|
|
|
|
} else if (type === 'Feature') {
|
|
rewind(gj.geometry, outer);
|
|
|
|
} else if (type === 'Polygon') {
|
|
rewindRings(gj.coordinates, outer);
|
|
|
|
} else if (type === 'MultiPolygon') {
|
|
for (i = 0; i < gj.coordinates.length; i++) rewindRings(gj.coordinates[i], outer);
|
|
}
|
|
|
|
return gj;
|
|
}
|
|
|
|
function rewindRings(rings, outer) {
|
|
if (rings.length === 0) return;
|
|
|
|
rewindRing(rings[0], outer);
|
|
for (var i = 1; i < rings.length; i++) {
|
|
rewindRing(rings[i], !outer);
|
|
}
|
|
}
|
|
|
|
function rewindRing(ring, dir) {
|
|
var area = 0, err = 0;
|
|
for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
|
|
var k = (ring[i][0] - ring[j][0]) * (ring[j][1] + ring[i][1]);
|
|
var m = area + k;
|
|
err += Math.abs(area) >= Math.abs(k) ? area - m + k : k - m + area;
|
|
area = m;
|
|
}
|
|
if (area + err >= 0 !== !!dir) ring.reverse();
|
|
}
|