Skip to content

Commit

Permalink
drop last point from polygon rings, close #35
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Mar 27, 2015
1 parent ded5359 commit 1c5b0b0
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### master

- **Breaking:** removed TopoJSON support. It will likely branch out into a separate repo/project.
- **Breaking:** changed encoding to not include the closing point of a polygon ring.
- Fixed a bug with encoding single-ring single-polygon multipolygon.

### 1.0.1 (Jan 13, 2015)
Expand Down
20 changes: 11 additions & 9 deletions decode.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ function readCoords(geom, pbf, type) {
if (type === 'Point') geom.coordinates = readPoint(pbf);
else if (type === 'MultiPoint') geom.coordinates = readLine(pbf, true);
else if (type === 'LineString') geom.coordinates = readLine(pbf);
else if (type === 'MultiLineString' || type === 'Polygon') geom.coordinates = readMultiLine(pbf);
else if (type === 'MultiLineString') geom.coordinates = readMultiLine(pbf);
else if (type === 'Polygon') geom.coordinates = readMultiLine(pbf, true);
else if (type === 'MultiPolygon') geom.coordinates = readMultiPolygon(pbf);
}

Expand Down Expand Up @@ -116,7 +117,7 @@ function readPoint(pbf) {
return coords;
}

function readLinePart(pbf, end, len) {
function readLinePart(pbf, end, len, closed) {
var i = 0,
coords = [],
p, d;
Expand All @@ -133,33 +134,34 @@ function readLinePart(pbf, end, len) {
coords.push(p);
i++;
}
if (closed) coords.push(coords[0]);

return coords;
}

function readLine(pbf, isMultiPoint) {
return readLinePart(pbf, pbf.readVarint() + pbf.pos, null, isMultiPoint);
function readLine(pbf) {
return readLinePart(pbf, pbf.readVarint() + pbf.pos);
}

function readMultiLine(pbf) {
function readMultiLine(pbf, closed) {
var end = pbf.readVarint() + pbf.pos;
if (!lengths) return [readLinePart(pbf, end)];
if (!lengths) return [readLinePart(pbf, end, null, closed)];

var coords = [];
for (var i = 0; i < lengths.length; i++) coords.push(readLinePart(pbf, end, lengths[i]));
for (var i = 0; i < lengths.length; i++) coords.push(readLinePart(pbf, end, lengths[i], closed));
lengths = null;
return coords;
}

function readMultiPolygon(pbf) {
var end = pbf.readVarint() + pbf.pos;
if (!lengths) return [[readLinePart(pbf, end)]];
if (!lengths) return [[readLinePart(pbf, end, null, true)]];

var coords = [];
var j = 1;
for (var i = 0; i < lengths[0]; i++) {
var rings = [];
for (var k = 0; k < lengths[j]; k++) rings.push(readLinePart(pbf, end, lengths[j + 1 + k]));
for (var k = 0; k < lengths[j]; k++) rings.push(readLinePart(pbf, end, lengths[j + 1 + k], true));
j += lengths[j] + 1;
coords.push(rings);
}
Expand Down
24 changes: 13 additions & 11 deletions encode.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ function writeGeometry(geom, pbf) {
if (geom.type === 'Point') writePoint(coords, pbf);
else if (geom.type === 'MultiPoint') writeLine(coords, pbf, true);
else if (geom.type === 'LineString') writeLine(coords, pbf);
if (geom.type === 'MultiLineString' || geom.type === 'Polygon') writeMultiLine(coords, pbf);
else if (geom.type === 'MultiLineString') writeMultiLine(coords, pbf);
else if (geom.type === 'Polygon') writeMultiLine(coords, pbf, true);
else if (geom.type === 'MultiPolygon') writeMultiPolygon(coords, pbf);
else if (geom.type === 'GeometryCollection') {
for (var i = 0; i < geom.geometries.length; i++) pbf.writeMessage(4, writeGeometry, geom.geometries[i]);
Expand Down Expand Up @@ -171,23 +172,23 @@ function writePoint(point, pbf) {
pbf.writePackedSVarint(3, coords);
}

function writeLine(line, pbf, isMultiPoint) {
function writeLine(line, pbf) {
var coords = [];
populateLine(coords, line, isMultiPoint);
populateLine(coords, line);
pbf.writePackedSVarint(3, coords);
}

function writeMultiLine(lines, pbf) {
function writeMultiLine(lines, pbf, closed) {
var len = lines.length,
i;
if (len !== 1) {
var lengths = [];
for (i = 0; i < len; i++) lengths.push(lines[i].length);
for (i = 0; i < len; i++) lengths.push(lines[i].length - (closed ? 1 : 0));
pbf.writePackedVarint(2, lengths);
// TODO faster with custom writeMessage?
}
var coords = [];
for (i = 0; i < len; i++) populateLine(coords, lines[i]);
for (i = 0; i < len; i++) populateLine(coords, lines[i], closed);
pbf.writePackedSVarint(3, coords);
}

Expand All @@ -198,21 +199,22 @@ function writeMultiPolygon(polygons, pbf) {
var lengths = [len];
for (i = 0; i < len; i++) {
lengths.push(polygons[i].length);
for (j = 0; j < polygons[i].length; j++) lengths.push(polygons[i][j].length);
for (j = 0; j < polygons[i].length; j++) lengths.push(polygons[i][j].length - 1);
}
pbf.writePackedVarint(2, lengths);
}

var coords = [];
for (i = 0; i < len; i++) {
for (j = 0; j < polygons[i].length; j++) populateLine(coords, polygons[i][j]);
for (j = 0; j < polygons[i].length; j++) populateLine(coords, polygons[i][j], true);
}
pbf.writePackedSVarint(3, coords);
}

function populateLine(coords, line) {
var i, j;
for (i = 0; i < line.length; i++) {
function populateLine(coords, line, closed) {
var i, j,
len = line.length - (closed ? 1 : 0);
for (i = 0; i < len; i++) {
for (j = 0; j < dim; j++) coords.push(Math.round((line[i][j] - (i ? line[i - 1][j] : 0)) * e));
}
}
18 changes: 18 additions & 0 deletions test/fixtures/precision.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[
[5425435.733081569895148, 2012689.63544030720368],
[5425333.066045090556145, 2012658.8061882276088],
[5425324.357915714383125, 2012693.518385621719062],
[5425426.5193927353248, 2012720.238697179593146],
[5425435.733081569895148, 2012689.63544030720368]
]]
}
}
]
}
8 changes: 8 additions & 0 deletions test/validate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ for (var name in geojsonFixtures) {
test('roundtrip custom properties', roundtripTest(getJSON('props.json')));
test('roundtrip single-ring MultiPolygon', roundtripTest(getJSON('single-multipoly.json')));

test('roundtrip valid closed polygon with high-precision coordinates', function (t) {
var geojson = getJSON('precision.json');
var pbf = new Pbf(geobuf.encode(geojson, new Pbf()));
var ring = geobuf.decode(pbf).features[0].geometry.coordinates[0];
t.same(ring[0], ring[4]);
t.end();
});

function roundtripTest(geojson) {
return function (t) {
t.same(geobuf.decode(new Pbf(geobuf.encode(geojson, new Pbf()))), geojson);
Expand Down

0 comments on commit 1c5b0b0

Please sign in to comment.