Skip to content

Commit

Permalink
add feature id support (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner authored Aug 9, 2016
1 parent 792d924 commit 9ec3ea8
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 66 deletions.
10 changes: 3 additions & 7 deletions src/clip.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

module.exports = clip;

var createFeature = require('./feature');

/* clip features between two axis-parallel lines:
* | |
* ___|___ | /
Expand Down Expand Up @@ -41,13 +43,7 @@ function clip(features, scale, k1, k2, axis, intersect, minAll, maxAll) {
if (slices.length) {
// if a feature got clipped, it will likely get clipped on the next zoom level as well,
// so there's no need to recalculate bboxes
clipped.push({
geometry: slices,
type: type,
tags: features[i].tags || null,
min: feature.min,
max: feature.max
});
clipped.push(createFeature(feature.tags, type, slices, feature.id));
}
}

Expand Down
46 changes: 7 additions & 39 deletions src/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module.exports = convert;

var simplify = require('./simplify');
var createFeature = require('./feature');

// converts GeoJSON feature into an intermediate projected JSON vector format with simplification data

Expand Down Expand Up @@ -33,16 +34,17 @@ function convertFeature(features, feature, tolerance) {
type = geom.type,
coords = geom.coordinates,
tags = feature.properties,
id = feature.id,
i, j, rings, projectedRing;

if (type === 'Point') {
features.push(create(tags, 1, [projectPoint(coords)]));
features.push(createFeature(tags, 1, [projectPoint(coords)], id));

} else if (type === 'MultiPoint') {
features.push(create(tags, 1, project(coords)));
features.push(createFeature(tags, 1, project(coords), id));

} else if (type === 'LineString') {
features.push(create(tags, 2, [project(coords, tolerance)]));
features.push(createFeature(tags, 2, [project(coords, tolerance)], id));

} else if (type === 'MultiLineString' || type === 'Polygon') {
rings = [];
Expand All @@ -51,7 +53,7 @@ function convertFeature(features, feature, tolerance) {
if (type === 'Polygon') projectedRing.outer = (i === 0);
rings.push(projectedRing);
}
features.push(create(tags, type === 'Polygon' ? 3 : 2, rings));
features.push(createFeature(tags, type === 'Polygon' ? 3 : 2, rings, id));

} else if (type === 'MultiPolygon') {
rings = [];
Expand All @@ -62,7 +64,7 @@ function convertFeature(features, feature, tolerance) {
rings.push(projectedRing);
}
}
features.push(create(tags, 3, rings));
features.push(createFeature(tags, 3, rings, id));

} else if (type === 'GeometryCollection') {
for (i = 0; i < geom.geometries.length; i++) {
Expand All @@ -77,18 +79,6 @@ function convertFeature(features, feature, tolerance) {
}
}

function create(tags, type, geometry) {
var feature = {
geometry: geometry,
type: type,
tags: tags || null,
min: [2, 1], // initial bbox values;
max: [-1, 0] // note that coords are usually in [0..1] range
};
calcBBox(feature);
return feature;
}

function project(lonlats, tolerance) {
var projected = [];
for (var i = 0; i < lonlats.length; i++) {
Expand Down Expand Up @@ -129,25 +119,3 @@ function calcSize(points) {
points.area = Math.abs(area / 2);
points.dist = dist;
}

// calculate the feature bounding box for faster clipping later
function calcBBox(feature) {
var geometry = feature.geometry,
min = feature.min,
max = feature.max;

if (feature.type === 1) calcRingBBox(min, max, geometry);
else for (var i = 0; i < geometry.length; i++) calcRingBBox(min, max, geometry[i]);

return feature;
}

function calcRingBBox(min, max, points) {
for (var i = 0, p; i < points.length; i++) {
p = points[i];
min[0] = Math.min(p[0], min[0]);
max[0] = Math.max(p[0], max[0]);
min[1] = Math.min(p[1], min[1]);
max[1] = Math.max(p[1], max[1]);
}
}
43 changes: 43 additions & 0 deletions src/feature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

module.exports = createFeature;

function createFeature(tags, type, geom, id) {
var feature = {
id: id || null,
type: type,
geometry: geom,
tags: tags || null,
min: [Infinity, Infinity], // initial bbox values
max: [-Infinity, -Infinity]
};
calcBBox(feature);
return feature;
}

// calculate the feature bounding box for faster clipping later
function calcBBox(feature) {
var geometry = feature.geometry,
min = feature.min,
max = feature.max;

if (feature.type === 1) {
calcRingBBox(min, max, geometry);
} else {
for (var i = 0; i < geometry.length; i++) {
calcRingBBox(min, max, geometry[i]);
}
}

return feature;
}

function calcRingBBox(min, max, points) {
for (var i = 0, p; i < points.length; i++) {
p = points[i];
min[0] = Math.min(p[0], min[0]);
max[0] = Math.max(p[0], max[0]);
min[1] = Math.min(p[1], min[1]);
max[1] = Math.max(p[1], max[1]);
}
}
8 changes: 6 additions & 2 deletions src/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,15 @@ function addFeature(tile, feature, tolerance, noSimplify) {
}

if (simplified.length) {
tile.features.push({
var tileFeature = {
geometry: simplified,
type: type,
tags: feature.tags || null
});
};
if (feature.id !== null) {
tileFeature.id = feature.id;
}
tile.features.push(tileFeature);
}
}

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

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

module.exports = wrap;

Expand Down Expand Up @@ -37,13 +38,7 @@ function shiftFeatureCoords(features, 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]]
});
newFeatures.push(createFeature(feature.tags, type, newGeometry, feature.id));
}

return newFeatures;
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/us-states-tiles.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/fixtures/us-states-z7-37-48.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"geometry":[[[3415,-64],[3323,-15],[3300,-64],[3415,-64]]],"type":3,"tags":{"name":"Connecticut","density":739.1}},{"geometry":[[[762,2248],[627,2476],[475,2600],[507,2900],[722,3179],[778,3642],[1089,4124],[1233,4144],[1234,4160],[321,4160],[220,2403],[467,2196],[762,2248]]],"type":3,"tags":{"name":"Delaware","density":464.3}},{"geometry":[[[-64,2403],[220,2403],[321,4160],[-64,4160],[-64,2829],[-51,2714],[-64,2717],[-64,2403]]],"type":3,"tags":{"name":"Maryland","density":596.3}},{"geometry":[[[2914,-64],[2964,-36],[2788,523],[2549,649],[2421,943],[2820,1090],[2852,1310],[2677,2331],[2222,3086],[1927,3303],[1664,3775],[1528,3467],[1105,3313],[587,2900],[547,2580],[627,2476],[762,2248],[1153,2092],[1177,1946],[1624,1634],[1696,1467],[1281,1080],[1265,838],[1081,775],[1065,555],[1289,218],[1169,17],[1243,-64],[2914,-64]]],"type":3,"tags":{"name":"New Jersey","density":1189}},{"geometry":[[[3300,-64],[3323,-15],[3945,144],[4072,28],[4160,28],[4160,594],[3929,681],[3458,765],[3147,744],[2916,838],[2788,523],[2964,-36],[2914,-64],[3300,-64]]],"type":3,"tags":{"name":"New York","density":412.3}},{"geometry":[[[1243,-64],[1169,17],[1289,218],[1065,555],[1081,775],[1265,838],[1281,1080],[1696,1467],[1624,1634],[1177,1946],[1153,2092],[762,2248],[467,2196],[220,2403],[-64,2403],[-64,-64],[1243,-64]]],"type":3,"tags":{"name":"Pennsylvania","density":284.3}}]
[{"geometry":[[[3415,-64],[3323,-15],[3300,-64],[3415,-64]]],"type":3,"tags":{"name":"Connecticut","density":739.1},"id":"09"},{"geometry":[[[762,2248],[627,2476],[475,2600],[507,2900],[722,3179],[778,3642],[1089,4124],[1233,4144],[1234,4160],[321,4160],[220,2403],[467,2196],[762,2248]]],"type":3,"tags":{"name":"Delaware","density":464.3},"id":"10"},{"geometry":[[[-64,2403],[220,2403],[321,4160],[-64,4160],[-64,2829],[-51,2714],[-64,2717],[-64,2403]]],"type":3,"tags":{"name":"Maryland","density":596.3},"id":"24"},{"geometry":[[[2914,-64],[2964,-36],[2788,523],[2549,649],[2421,943],[2820,1090],[2852,1310],[2677,2331],[2222,3086],[1927,3303],[1664,3775],[1528,3467],[1105,3313],[587,2900],[547,2580],[627,2476],[762,2248],[1153,2092],[1177,1946],[1624,1634],[1696,1467],[1281,1080],[1265,838],[1081,775],[1065,555],[1289,218],[1169,17],[1243,-64],[2914,-64]]],"type":3,"tags":{"name":"New Jersey","density":1189},"id":"34"},{"geometry":[[[3300,-64],[3323,-15],[3945,144],[4072,28],[4160,28],[4160,594],[3929,681],[3458,765],[3147,744],[2916,838],[2788,523],[2964,-36],[2914,-64],[3300,-64]]],"type":3,"tags":{"name":"New York","density":412.3},"id":"36"},{"geometry":[[[1243,-64],[1169,17],[1289,218],[1065,555],[1081,775],[1265,838],[1281,1080],[1696,1467],[1624,1634],[1177,1946],[1153,2092],[762,2248],[467,2196],[220,2403],[-64,2403],[-64,-64],[1243,-64]]],"type":3,"tags":{"name":"Pennsylvania","density":284.3},"id":"42"}]
18 changes: 10 additions & 8 deletions test/test-clip.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ test('clips polylines', function (t) {
], 1, 10, 40, 0, intersectX, -Infinity, Infinity);

var expected = [
{geometry: [
{id: null, type: 2, geometry: [
[[10,0],[40,0]],
[[40,10],[20,10],[20,20],[30,20],[30,30],[40,30]],
[[40,40],[25,40],[25,50],[10,50]],
[[10,60],[25,60]]], type: 2, tags: 1, min: min1, max: max1},
{geometry: [
[[10,60],[25,60]]], tags: 1, min: [10,0], max: [40,60]},
{id: null, type: 2, geometry: [
[[10,0],[40,0]],
[[40,10],[10,10]]], type: 2, tags: 2, min: min2, max: max2}];
[[40,10],[10,10]]], tags: 2, min: [10,0], max: [40,10]}
];

t.equal(JSON.stringify(clipped), JSON.stringify(expected));

Expand All @@ -54,9 +55,9 @@ test('clips polygons', function (t) {
], 1, 10, 40, 0, intersectX, -Infinity, Infinity);

var expected = [
{geometry: [[[10,0],[40,0],[40,10],[20,10],[20,20],[30,20],[30,30],[40,30],
[40,40],[25,40],[25,50],[10,50],[10,60],[25,60],[10,24],[10,0]]], type: 3, tags: 1, min: min1, max: max1},
{geometry: [[[10,0],[40,0],[40,10],[10,10],[10,0]]], type: 3, tags: 2, min: min2, max: max2}
{id: null, type: 3, geometry: [[[10,0],[40,0],[40,10],[20,10],[20,20],[30,20],[30,30],[40,30],
[40,40],[25,40],[25,50],[10,50],[10,60],[25,60],[10,24],[10,0]]], tags: 1, min: [10,0], max: [40,60]},
{id: null, type: 3, geometry: [[[10,0],[40,0],[40,10],[10,10],[10,0]]], tags: 2, min: [10,0], max: [40,10]}
];

t.equal(JSON.stringify(clipped), JSON.stringify(expected));
Expand All @@ -71,7 +72,8 @@ test('clips points', function (t) {
{geometry: geom2[0], type: 1, tags: 2, min: min2, max: max2}
], 1, 10, 40, 0, intersectX, -Infinity, Infinity);

t.same(clipped, [{geometry: [[20,10],[20,20],[30,20],[30,30],[25,40],[25,50],[25,60]], type: 1, tags: 1, min: min1, max: max1}]);
t.same(clipped, [{id: null, type: 1,
geometry: [[20,10],[20,20],[30,20],[30,30],[25,40],[25,50],[25,60]], tags: 1, min: [20,10], max: [30,60]}]);

t.end();
});
3 changes: 2 additions & 1 deletion test/test-get-tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ var geojsonvt = require('../src/index');
var square = [{
geometry: [[[-64, 4160], [-64, -64], [4160, -64], [4160, 4160], [-64, 4160]]],
type: 3,
tags: {name: 'Pennsylvania', density: 284.3}
tags: {name: 'Pennsylvania', density: 284.3},
id: '42'
}];

test('getTile: us-states.json', function (t) {
Expand Down

0 comments on commit 9ec3ea8

Please sign in to comment.