Skip to content

Commit

Permalink
Merge pull request #33 from mapbox/dateline
Browse files Browse the repository at this point in the history
Date line handling
  • Loading branch information
mourner committed Jun 15, 2015
2 parents 5025d29 + 499a033 commit 770feee
Show file tree
Hide file tree
Showing 7 changed files with 331 additions and 1 deletion.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ npm run build-min # minified production build

### Changelog

##### 2.1.0 (June 15, 2015)

- Added proper handling for features crossing or near the date line.

##### 2.0.1 (June 9, 2015)

- 10-20% faster tile indexing.
Expand Down
6 changes: 6 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = geojsonvt;

var convert = require('./convert'), // GeoJSON conversion and preprocessing
clip = require('./clip'), // stripe clipping algorithm
wrap = require('./wrap'), // date line processing
createTile = require('./tile'); // final simplified tile generation


Expand Down Expand Up @@ -31,6 +32,8 @@ function GeoJSONVT(data, options) {
this.total = 0;
}

features = wrap(features, options.buffer / options.extent, intersectX);

// start slicing from the top tile down
this.splitTile(features, 0, 0, 0);

Expand Down Expand Up @@ -150,6 +153,9 @@ GeoJSONVT.prototype.getTile = function (z, x, y) {
extent = options.extent,
debug = options.debug;

var z2 = 1 << z;
x = ((x % z2) + z2) % z2; // wrap tile x coordinate

var id = toID(z, x, y);
if (this.tiles[id]) return transformTile(this.tiles[id], extent);

Expand Down
61 changes: 61 additions & 0 deletions src/wrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict';

var clip = require('./clip');

module.exports = wrap;

function wrap(features, buffer, intersectX) {
var merged = features,
left = clip(features, 1, -1 - buffer, buffer, 0, intersectX, -1, 2), // left world copy
right = clip(features, 1, 1 - buffer, 2 + buffer, 0, intersectX, -1, 2); // right world copy

if (left || right) {
merged = clip(features, 1, -buffer, 1 + buffer, 0, intersectX, -1, 2); // center world copy

if (left) merged = shiftFeatureCoords(left, 1).concat(merged); // merge left into center
if (right) merged = merged.concat(shiftFeatureCoords(right, -1)); // merge right into center
}

return merged;
}

function shiftFeatureCoords(features, offset) {
var newFeatures = [];

for (var i = 0; i < features.length; i++) {
var feature = features[i],
type = feature.type;

var newGeometry;

if (type === 1) {
newGeometry = shiftCoords(feature.geometry, offset);
} else {
newGeometry = [];
for (var j = 0; j < feature.geometry.length; j++) {
newGeometry.push(shiftCoords(feature.geometry[j], offset));
}
}

newFeatures.push({
geometry: newGeometry,
type: type,
tags: feature.tags,
min: [feature.min[0] + offset, feature.min[1]],
max: [feature.max[0] + offset, feature.max[1]]
});
}

return newFeatures;
}

function shiftCoords(points, offset) {
var newPoints = [];
newPoints.area = points.area;
newPoints.dist = points.dist;

for (var i = 0; i < points.length; i++) {
newPoints.push([points[i][0] + offset, points[i][1], points[i][2]]);
}
return newPoints;
}
1 change: 1 addition & 0 deletions test/fixtures/dateline-tiles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"z0-0-0":[{"geometry":[[[4160,1532],[4088,1464],[3952,1456],[3984,896],[4160,1217],[4160,1532]]],"type":3,"tags":{}},{"geometry":[[3312,1168]],"type":1,"tags":{}},{"geometry":[[[3472,2792],[4160,2782]],[[4160,2953],[3800,3112],[4160,3087]]],"type":2,"tags":{}},{"geometry":[[[3472,1488],[3992,2216],[4160,2370],[4160,2495],[3856,2384],[3616,2064],[3384,1744],[2744,1448],[2200,1736],[1672,2032],[1152,2384],[992,1904],[952,1520],[1400,1608],[1480,1800],[1840,1696],[1656,1384],[1232,1168],[616,1272],[152,1616],[-8,1464],[-64,1461],[-64,983],[112,1304],[280,1112],[680,816],[2304,816],[2792,1000],[2168,992],[1560,976],[2008,1216],[2896,1232],[3280,1168],[3472,1488],[3472,1488]]],"type":3,"tags":{}},{"geometry":[[2248,2808]],"type":1,"tags":{}},{"geometry":[[2968,2272]],"type":1,"tags":{}},{"geometry":[[488,1736]],"type":1,"tags":{}},{"geometry":[[[3456,280],[4160,280]],[[4160,378],[3752,464],[4160,526]]],"type":2,"tags":{}},{"geometry":[[[-64,2784],[464,2776],[-64,3009]],[[-64,3096],[624,3048]]],"type":2,"tags":{}},{"geometry":[[[-64,2253],[288,2576],[-64,2448],[-64,2253]]],"type":3,"tags":{}},{"geometry":[[368,2176]],"type":1,"tags":{}},{"geometry":[[[-64,280],[528,280],[-64,405]],[[-64,506],[344,568]]],"type":2,"tags":{}}]}
257 changes: 257 additions & 0 deletions test/fixtures/dateline.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
125.15625000000001,
44.08758502824518
],
[
170.859375,
-14.604847155053886
],
[
205.3125,
-42.0329743324414
],
[
158.90625,
-28.30438068296277
],
[
137.8125,
-1.4061088354351468
],
[
117.42187500000001,
25.799891182088334
],
[
61.17187499999999,
46.55886030311719
],
[
13.359375,
26.43122806450644
],
[
-33.046875,
1.4061088354351594
],
[
-78.75,
-28.30438068296277
],
[
-92.8125,
12.554563528593656
],
[
-96.328125,
42.032974332441405
],
[
-56.953125,
36.03133177633189
],
[
-49.92187499999999,
21.28937435586041
],
[
-18.28125,
29.53522956294847
],
[
-34.453125,
50.28933925329178
],
[
-71.71875,
60.930432202923335
],
[
-125.859375,
56.17002298293205
],
[
-166.640625,
35.460669951495305
],
[
-180.703125,
45.583289756006316
],
[
-192.65625,
46.07323062540838
],
[
-189.84375,
70.61261423801925
],
[
-170.15625,
54.57206165565852
],
[
-155.390625,
63.23362741232569
],
[
-120.234375,
72.81607371878991
],
[
-72.421875,
72.81607371878991
],
[
22.5,
72.81607371878991
],
[
65.390625,
67.33986082559095
],
[
10.546875,
67.60922060496382
],
[
-42.890625,
68.13885164925573
],
[
-3.515625,
58.81374171570782
],
[
74.53125,
58.07787626787517
],
[
108.28125,
60.930432202923335
],
[
125.15625000000001,
44.08758502824518
]
]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
17.578125,
-55.379110448010486
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
80.85937499999999,
-19.31114335506463
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
-137.109375,
26.43122806450644
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
-248.90624999999997,
60.930432202923335
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
212.34375,
-11.178401873711785
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
123.74999999999999,
82.40242347938855
],
[
226.40625,
82.40242347938855
],
[
149.765625,
79.93591824625466
],
[
210.234375,
78.20656311074711
]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
-234.84375000000003,
-54.572061655658516
],
[
-139.21874999999997,
-53.748710796898976
],
[
-206.015625,
-67.87554134672943
],
[
-125.15625000000001,
-65.6582745198266
]
]
}
}
]
}
2 changes: 1 addition & 1 deletion test/fixtures/us-states-tiles.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions test/test-full.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var path = require('path');
var genTiles = require('./gen-tiles');

testTiles('us-states.json', 'us-states-tiles.json', 7, 200);
testTiles('dateline.json', 'dateline-tiles.json', 7, 200);

function testTiles(inputFile, expectedFile, maxZoom, maxPoints) {
test('full tiling test: ' + inputFile, function (t) {
Expand Down

0 comments on commit 770feee

Please sign in to comment.