Skip to content

Commit

Permalink
rewind polygons for vt2 compliance
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Jun 9, 2016
1 parent aa3741e commit 51be287
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 10 deletions.
14 changes: 8 additions & 6 deletions src/clip.js
Expand Up @@ -78,6 +78,7 @@ function clipGeometry(geometry, k1, k2, axis, intersect, closed) {
points = geometry[i],
area = points.area,
dist = points.dist,
outer = points.outer,
len = points.length,
a, j, last;

Expand All @@ -93,15 +94,15 @@ function clipGeometry(geometry, k1, k2, axis, intersect, closed) {

if ((bk > k2)) { // ---|-----|-->
slice.push(intersect(a, b, k1), intersect(a, b, k2));
if (!closed) slice = newSlice(slices, slice, area, dist);
if (!closed) slice = newSlice(slices, slice, area, dist, outer);

} else if (bk >= k1) slice.push(intersect(a, b, k1)); // ---|--> |

} else if (ak > k2) {

if ((bk < k1)) { // <--|-----|---
slice.push(intersect(a, b, k2), intersect(a, b, k1));
if (!closed) slice = newSlice(slices, slice, area, dist);
if (!closed) slice = newSlice(slices, slice, area, dist, outer);

} else if (bk <= k2) slice.push(intersect(a, b, k2)); // | <--|---

Expand All @@ -111,11 +112,11 @@ function clipGeometry(geometry, k1, k2, axis, intersect, closed) {

if (bk < k1) { // <--|--- |
slice.push(intersect(a, b, k1));
if (!closed) slice = newSlice(slices, slice, area, dist);
if (!closed) slice = newSlice(slices, slice, area, dist, outer);

} else if (bk > k2) { // | ---|-->
slice.push(intersect(a, b, k2));
if (!closed) slice = newSlice(slices, slice, area, dist);
if (!closed) slice = newSlice(slices, slice, area, dist, outer);
}
// | --> |
}
Expand All @@ -132,18 +133,19 @@ function clipGeometry(geometry, k1, k2, axis, intersect, closed) {
if (closed && last && (slice[0][0] !== last[0] || slice[0][1] !== last[1])) slice.push(slice[0]);

// add the final slice
newSlice(slices, slice, area, dist);
newSlice(slices, slice, area, dist, outer);
}

return slices;
}

function newSlice(slices, slice, area, dist) {
function newSlice(slices, slice, area, dist, outer) {
if (slice.length) {
// we don't recalculate the area/length of the unclipped geometry because the case where it goes
// below the visibility threshold as a result of clipping is rare, so we avoid doing unnecessary work
slice.area = area;
slice.dist = dist;
if (outer !== undefined) slice.outer = outer;

slices.push(slice);
}
Expand Down
10 changes: 7 additions & 3 deletions src/convert.js
Expand Up @@ -33,7 +33,7 @@ function convertFeature(features, feature, tolerance) {
type = geom.type,
coords = geom.coordinates,
tags = feature.properties,
i, j, rings;
i, j, rings, projectedRing;

if (type === 'Point') {
features.push(create(tags, 1, [projectPoint(coords)]));
Expand All @@ -47,15 +47,19 @@ function convertFeature(features, feature, tolerance) {
} else if (type === 'MultiLineString' || type === 'Polygon') {
rings = [];
for (i = 0; i < coords.length; i++) {
rings.push(project(coords[i], tolerance));
projectedRing = project(coords[i], tolerance);
if (type === 'Polygon') projectedRing.outer = (i === 0);
rings.push(projectedRing);
}
features.push(create(tags, type === 'Polygon' ? 3 : 2, rings));

} else if (type === 'MultiPolygon') {
rings = [];
for (i = 0; i < coords.length; i++) {
for (j = 0; j < coords[i].length; j++) {
rings.push(project(coords[i][j], tolerance));
projectedRing = project(coords[i][j], tolerance);
projectedRing.outer = (j === 0);
rings.push(projectedRing);
}
}
features.push(create(tags, 3, rings));
Expand Down
17 changes: 17 additions & 0 deletions src/tile.js
Expand Up @@ -71,6 +71,8 @@ function addFeature(tile, feature, tolerance, noSimplify) {
tile.numPoints++;
}

if (type === 3) rewind(simplifiedRing, ring.outer);

simplified.push(simplifiedRing);
}
}
Expand All @@ -83,3 +85,18 @@ function addFeature(tile, feature, tolerance, noSimplify) {
});
}
}

function rewind(ring, clockwise) {
var area = signedArea(ring);
if (area < 0 === clockwise) ring.reverse();
}

function signedArea(ring) {
var sum = 0;
for (var i = 0, len = ring.length, j = len - 1, p1, p2; i < len; j = i++) {
p1 = ring[i];
p2 = ring[j];
sum += (p2[0] - p1[0]) * (p1[1] + p2[1]);
}
return sum;
}
2 changes: 1 addition & 1 deletion test/fixtures/feature-tiles.json
@@ -1 +1 @@
{"z0-0-0":[{"geometry":[[[3186,2048],[3197,2048],[3197,2037],[3186,2037],[3186,2048]]],"type":3,"tags":{"prop0":"value0","prop1":{"this":"that"}}}]}
{"z0-0-0":[{"geometry":[[[3186,2048],[3186,2037],[3197,2037],[3197,2048],[3186,2048]]],"type":3,"tags":{"prop0":"value0","prop1":{"this":"that"}}}]}

0 comments on commit 51be287

Please sign in to comment.