osmtogeojson
Advanced tools
Comparing version 1.2.1 to 1.3.0
@@ -0,1 +1,7 @@ | ||
1.3.0 | ||
----- | ||
* more versatile cli tool (can read osm json, optionally enhanced output) | ||
* many more unit tests | ||
* fixed bugs with some partially incomplete data | ||
1.2.1 | ||
@@ -8,3 +14,3 @@ ----- | ||
* add [demo](http://tyrasd.github.io/osmtogeojson/) page | ||
* support for pipes in cli tool: `echo '<osm><node lat="1.23" lon="3.21" id='-1' /></osm>' | osmtogeojson` | ||
* support for pipes in cli tool: `echo '<osm><node lat="1.23" lon="3.21" id="-1" /></osm>' | osmtogeojson` | ||
* add flat-properties output mode (default for the cli tool) | ||
@@ -11,0 +17,0 @@ * add options to override default `uninterestingTags` and `polygonFeatures` |
@@ -1,4 +0,4 @@ | ||
try { | ||
if (typeof require !== "undefined") { | ||
_ = require("lodash"); | ||
} catch(e) {} | ||
} | ||
@@ -348,4 +348,5 @@ var osmtogeojson = {}; | ||
if (wayids[m.ref]) { | ||
// TODO: this may not work in the following corner case: | ||
// this even works in the following corner case: | ||
// a multipolygon amenity=xxx with outer line tagged amenity=yyy | ||
// see https://github.com/tyrasd/osmtogeojson/issues/7 | ||
if (m.role==="outer" && !has_interesting_tags(wayids[m.ref].tags,rels[i].tags)) | ||
@@ -422,3 +423,3 @@ wayids[m.ref].is_multipolygon_outline = true; | ||
if (!what) | ||
break; // Invalid geometry (unclosed ring) | ||
break; // Invalid geometry (dangling way, unclosed ring) | ||
ways.splice(i, 1); | ||
@@ -441,6 +442,4 @@ how.apply(current, what); | ||
} | ||
var _pluck = function(from) { | ||
var mapCoordinates = function(from) { | ||
return _.map(from, function(n) { | ||
if (n === undefined) | ||
return; | ||
return [+n.lat,+n.lon]; | ||
@@ -465,5 +464,7 @@ }); | ||
var o, outer; | ||
inner = _pluck(inner); | ||
// todo: all this coordinate mapping makes this unneccesarily slow. | ||
// see the "todo: this is slow! :(" above. | ||
inner = mapCoordinates(inner); | ||
/*for (o = 0; o < outers.length; o++) { | ||
outer = _pluck(outers[o]); | ||
outer = mapCoordinates(outers[o]); | ||
if (polygonContainsPolygon(outer, inner)) | ||
@@ -473,3 +474,3 @@ return o; | ||
for (o = 0; o < outers.length; o++) { | ||
outer = _pluck(outers[o]); | ||
outer = mapCoordinates(outers[o]); | ||
if (polygonIntersectsPolygon(outer, inner)) | ||
@@ -485,26 +486,21 @@ return o; | ||
else | ||
;//mp.push(inners[j]); // invalid geometry // tyr: why? | ||
// so, no outer ring for this inner ring is found. | ||
// We're going to ignore holes in empty space. | ||
; | ||
} | ||
// sanitize mp-coordinates (remove empty clusters or rings, {lat,lon,...} to [lon,lat] | ||
var mp_coords = []; | ||
mp_coords = _.map(mp, function(cluster) { | ||
var cl = _.map(cluster, function(ring) { | ||
if (ring === undefined || ring.length <= 1) { | ||
is_tainted = true; | ||
mp_coords = _.compact(_.map(mp, function(cluster) { | ||
var cl = _.compact(_.map(cluster, function(ring) { | ||
if (ring.length < 4) // todo: is this correct: ring.length < 4 ? | ||
return; | ||
} | ||
return _.map(ring, function(node) { | ||
if (node === undefined || node.lat === undefined) { | ||
is_tainted = true; | ||
return; | ||
} | ||
return _.compact(_.map(ring, function(node) { | ||
return [+node.lon,+node.lat]; | ||
}); | ||
}); | ||
if (cl.length == 0) { | ||
is_tainted = true; | ||
})); | ||
})); | ||
if (cl.length == 0) | ||
return; | ||
} | ||
return cl; | ||
}); | ||
})); | ||
if (mp_coords.length == 0) | ||
@@ -511,0 +507,0 @@ continue; // ignore multipolygons without coordinates |
{ | ||
"name": "osmtogeojson", | ||
"version": "1.2.1", | ||
"version": "1.3.0", | ||
"description": "convert OSM to geojson", | ||
"main": "osmtogeojson.js", | ||
"scripts": { | ||
"test": "mocha-phantomjs test/index.html" | ||
"test": "mocha -R spec" | ||
}, | ||
@@ -33,5 +33,4 @@ "bin": { | ||
"expect.js": "~0.2.0", | ||
"mocha": "~1.12.0", | ||
"mocha-phantomjs": "~3.1.5" | ||
"mocha": "~1.12.0" | ||
} | ||
} |
@@ -7,5 +7,5 @@ osmtogeojson | ||
* stable | ||
* real OSM [polygon support](https://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features) | ||
* real OSM [polygon detection](https://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features) | ||
* real OSM multipolygon support | ||
* well [tested](http://github.com/tyrasd/osmtogeojson/tree/master/test/) and proven | ||
* well [tested](https://github.com/tyrasd/osmtogeojson/tree/gh-pages/test/) and proven | ||
* ~~fast~~ not slow | ||
@@ -25,3 +25,3 @@ | ||
* as a nodejs libary: | ||
* as a nodejs library: | ||
@@ -71,4 +71,5 @@ npm install osmtogeojson | ||
* `relations`: an array of relations the feature is member of. Each relation is encoded as an object literal containing the following properties: `role` (membership role), `rel` (the relation's id) and `reltags` (contains all tags of the relation) | ||
* `tainted`: this flag is set when the feature's geometry is incomplete (e.g. missing nodes of a way or missing ways of a multipolygon) | ||
If the [option](#api) `flatProperties` is set to true, the `properties` object will not contain any nested object literals, but directly provide a concise id, meta data and the tags of the respective OSM object. | ||
1641
test/osm.test.js
@@ -0,1 +1,7 @@ | ||
if (typeof require !== "undefined") { | ||
var expect = require("expect.js"); | ||
var DOMParser = require("xmldom").DOMParser; | ||
var osmtogeojson = require("../"); | ||
} | ||
describe("osm (xml)", function () { | ||
@@ -657,135 +663,2 @@ | ||
}); | ||
// tainted geometries | ||
it("tainted geometries", function () { | ||
var json, geojson; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 10, | ||
nodes: [2,3,5] | ||
}, | ||
{ | ||
type: "way", | ||
id: 11, | ||
nodes: [2,3,4,5,2], | ||
tags: {"area":"yes"} | ||
}, | ||
{ | ||
type: "way", | ||
id: 12, | ||
nodes: [2,3,4,2], | ||
}, | ||
{ | ||
type: "relation", | ||
id: 100, | ||
tags: {"type":"multipolygon"}, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 12, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 13, | ||
role: "inner" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 1.0, | ||
lon: 1.0 | ||
} | ||
] | ||
}; | ||
geojson = { | ||
type: "FeatureCollection", | ||
features: [ | ||
{ | ||
type: "Feature", | ||
id: "way/12", | ||
properties: { | ||
type: "way", | ||
id: 12, | ||
tags: {}, | ||
relations: [ | ||
{ | ||
rel: 100, | ||
role: "outer", | ||
reltags: {"type":"multipolygon"} | ||
} | ||
], | ||
meta: {}, | ||
tainted: true | ||
}, | ||
geometry: { | ||
type: "Polygon", | ||
coordinates: [[ | ||
[0.0,1.0], | ||
[1.0,0.0], | ||
[1.0,1.0], | ||
[0.0,1.0] | ||
]] | ||
} | ||
}, | ||
{ | ||
type: "Feature", | ||
id: "way/11", | ||
properties: { | ||
type: "way", | ||
id: 11, | ||
tags: {"area":"yes"}, | ||
relations: [], | ||
meta: {}, | ||
tainted: true | ||
}, | ||
geometry: { | ||
type: "Polygon", | ||
coordinates: [[ | ||
[0.0,1.0], | ||
[1.0,0.0], | ||
[1.0,1.0], | ||
[0.0,1.0] | ||
]] | ||
} | ||
}, | ||
{ | ||
type: "Feature", | ||
id: "way/10", | ||
properties: { | ||
type: "way", | ||
id: 10, | ||
tags: {}, | ||
relations: [], | ||
meta: {}, | ||
tainted: true | ||
}, | ||
geometry: { | ||
type: "LineString", | ||
coordinates: [ | ||
[0.0,1.0], | ||
[1.0,0.0] | ||
] | ||
} | ||
} | ||
] | ||
}; | ||
var result = osmtogeojson.toGeojson(json); | ||
expect(result).to.eql(geojson); | ||
}); | ||
// tags & pois | ||
@@ -887,2 +760,40 @@ it("tags: ways and nodes / pois", function () { | ||
}); | ||
// invalid one-node-ways | ||
it("one-node-ways", function () { | ||
var json, result; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [2], | ||
tags: {"foo":"bar"} | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 0.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
}); | ||
// invalid empty multipolygon | ||
it("empty multipolygon", function () { | ||
var json, result; | ||
// empty multipolygon | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
id: 1, | ||
tags: {"type":"multipolygon"} | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
}); | ||
// relations | ||
@@ -896,5 +807,11 @@ it("relations and id-spaces", function () { | ||
id: 1, | ||
nodes: [1,2] | ||
tags: {"foo":"bar"}, | ||
nodes: [1,2,3] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [3,1] | ||
}, | ||
{ | ||
type: "node", | ||
@@ -912,2 +829,8 @@ id: 1, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 1.0, | ||
lon: 2.0 | ||
}, | ||
{ | ||
type: "relation", | ||
@@ -926,4 +849,26 @@ id: 1, | ||
role: "fasd" | ||
}, | ||
{ | ||
type: "relation", | ||
ref: 2, | ||
role: "" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "relation", | ||
id: 2, | ||
tags: {"type":"multipolygon"}, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 1, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
} | ||
] | ||
} | ||
@@ -937,2 +882,28 @@ ] | ||
type: "Feature", | ||
id: "relation/2", | ||
properties: { | ||
type: "relation", | ||
id: 2, | ||
tags: {"type":"multipolygon"}, | ||
relations: [ | ||
{ | ||
rel: 1, | ||
role: "", | ||
reltags: {"foo":"bar"} | ||
} | ||
], | ||
meta: {} | ||
}, | ||
geometry: { | ||
type: "MultiPolygon", | ||
coordinates: [[[ | ||
[2.0,1.0], | ||
[1.0,1.0], | ||
[2.0,2.0], | ||
[2.0,1.0] | ||
]]] | ||
} | ||
}, | ||
{ | ||
type: "Feature", | ||
id: "way/1", | ||
@@ -942,3 +913,3 @@ properties: { | ||
id: 1, | ||
tags: {}, | ||
tags: {"foo":"bar"}, | ||
relations: [ | ||
@@ -949,2 +920,7 @@ { | ||
reltags: {"foo":"bar"} | ||
}, | ||
{ | ||
rel: 2, | ||
role: "outer", | ||
reltags: {"type":"multipolygon"} | ||
} | ||
@@ -958,3 +934,4 @@ ], | ||
[1.0,1.0], | ||
[2.0,2.0] | ||
[2.0,2.0], | ||
[2.0,1.0] | ||
] | ||
@@ -991,3 +968,4 @@ } | ||
it("meta data", function () { | ||
var json, geojson; | ||
var json, geojson, result; | ||
// node with meta data | ||
json = { | ||
@@ -1034,7 +1012,55 @@ elements: [ | ||
}; | ||
var result = osmtogeojson.toGeojson(json); | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result).to.eql(geojson); | ||
// ways and relsvar json, geojson; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.234, | ||
lon: 4.321, | ||
tags: {"amenity": "yes"}, | ||
user: "johndoe", | ||
}, | ||
{ | ||
type: "way", | ||
id: 1, | ||
tags: {"highway": "road"}, | ||
user: "johndoe", | ||
nodes: [1,1,1,1] | ||
}, | ||
{ | ||
type: "relation", | ||
id: 1, | ||
tags: {"type": "multipolygon"}, | ||
user: "johndoe", | ||
members: [{type:"way",ref:1,role:"outer"},{type:"way",ref:1,role:"outer"}] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
tags: {"highway": "road"}, | ||
user: "johndoe", | ||
nodes: [1,1,1,1] | ||
}, | ||
{ | ||
type: "relation", | ||
id: 2, | ||
tags: {"type": "multipolygon"}, | ||
user: "johndoe", | ||
members: [{type:"way",ref:2,role:"outer"}] | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(4); | ||
expect(result.features[0].properties.meta).to.have.property("user"); | ||
expect(result.features[1].properties.meta).to.have.property("user"); | ||
expect(result.features[2].properties.meta).to.have.property("user"); | ||
expect(result.features[3].properties.meta).to.have.property("user"); | ||
}); | ||
// multipolygon detection corner case | ||
it("multipolygon detection corner case", function () { | ||
// see https://github.com/tyrasd/osmtogeojson/issues/7 | ||
it("multipolygon: outer way tagging", function () { | ||
var json; | ||
@@ -1121,4 +1147,540 @@ json = { | ||
}); | ||
// non-matching inner and outer rings | ||
it("multipolygon: non-matching inner and outer rings", function() { | ||
// complex multipolygon | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: -1, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "inner" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [4,5,6,7,4] | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 6, | ||
lat: 1.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 7, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "way", | ||
id: 3, | ||
nodes: [8,9,10,8] | ||
}, | ||
{ | ||
type: "node", | ||
id: 8, | ||
lat: 3.0, | ||
lon: 3.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 9, | ||
lat: 4.0, | ||
lon: 3.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 10, | ||
lat: 3.0, | ||
lon: 4.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].geometry.type).to.equal("MultiPolygon"); | ||
expect(result.features[0].geometry.coordinates).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0]).to.have.length(1); | ||
/* | ||
// simple multipolygon | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "inner" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [4,5,6,7,4] | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 6, | ||
lat: 1.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 7, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "way", | ||
id: 3, | ||
nodes: [8,9,10,8] | ||
}, | ||
{ | ||
type: "node", | ||
id: 8, | ||
lat: 3.0, | ||
lon: 3.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 9, | ||
lat: 4.0, | ||
lon: 3.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 10, | ||
lat: 3.0, | ||
lon: 4.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(2); | ||
expect(result.features[0].geometry.type).to.equal("Polygon"); | ||
expect(result.features[0].geometry.coordinates).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0]).to.have.length(1); | ||
*/ | ||
}); | ||
// non-trivial ring building (way order and direction) | ||
it("multipolygon: non-trivial ring building", function() { | ||
// way order | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 1, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [1,2] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [2,3] | ||
}, | ||
{ | ||
type: "way", | ||
id: 3, | ||
nodes: [3,1] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 3.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].geometry.type).to.equal("MultiPolygon"); | ||
expect(result.features[0].geometry.coordinates).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0]).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0][0]).to.have.length(4); | ||
// way directions | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 1, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 4, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 5, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 6, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [1,2] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [2,3] | ||
}, | ||
{ | ||
type: "way", | ||
id: 3, | ||
nodes: [4,3] | ||
}, | ||
{ | ||
type: "way", | ||
id: 4, | ||
nodes: [5,4] | ||
}, | ||
{ | ||
type: "way", | ||
id: 5, | ||
nodes: [5,6] | ||
}, | ||
{ | ||
type: "way", | ||
id: 6, | ||
nodes: [1,6] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 3.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 4.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 5.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 6, | ||
lat: 6.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].geometry.type).to.equal("MultiPolygon"); | ||
expect(result.features[0].geometry.coordinates).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0]).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0][0]).to.have.length(7); | ||
}); | ||
// unclosed rings | ||
it("multipolygon: unclosed ring", function() { | ||
// non-matching ways, unclosed rings | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 1, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [1,2,3,4] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [3,2] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 3.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 4.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].geometry.type).to.equal("MultiPolygon"); | ||
expect(result.features[0].geometry.coordinates).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0]).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0][0]).to.have.length(4); | ||
expect(result.features[0].properties.tainted).to.not.equal(true); | ||
// matching ways, but unclosed ring | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 1, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [1,2] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [2,3,4] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 3.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 4.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].geometry.type).to.equal("MultiPolygon"); | ||
expect(result.features[0].geometry.coordinates).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0]).to.have.length(1); | ||
expect(result.features[0].geometry.coordinates[0][0]).to.have.length(4); | ||
expect(result.features[0].properties.tainted).to.not.equal(true); | ||
}); | ||
// overpass area | ||
it("overpass area", function () { | ||
var json, geojson_properties; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "area", | ||
id: 1, | ||
} | ||
] | ||
}; | ||
var result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
}); | ||
}); | ||
describe("defaults", function() { | ||
// interesting objects | ||
it("interesting objects", function() { | ||
it("interesting objects", function () { | ||
var json, result; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [1,2] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
tags: {"created_by": "foo"}, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
tags: {"interesting": "yes"}, | ||
lat: 2.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
var result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(2); | ||
expect(result.features[0].geometry.type).to.equal("LineString"); | ||
expect(result.features[1].geometry.type).to.equal("Point"); | ||
expect(result.features[1].properties.id).to.equal(2); | ||
}); | ||
// interesting objects | ||
it("interesting objects: relation members", function() { | ||
// complex example containing a generic relation, several ways as well as | ||
@@ -1181,6 +1743,83 @@ // tagged, uninteresting and untagged nodes | ||
}); | ||
// polygon detection | ||
// see: http://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features | ||
it("polygon detection", function () { | ||
var json, result; | ||
// basic tags: area=yes | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
tags: {"foo":"bar", "area": "yes"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
tags: {"area": "yes"}, | ||
nodes: [1,2,3] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 3.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(2); | ||
expect(result.features[0].geometry.type).to.equal("Polygon"); | ||
expect(result.features[1].geometry.type).to.equal("LineString"); | ||
// basic tags: area=no | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
tags: { | ||
"area": "no", | ||
"building": "yes" | ||
}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 3.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].geometry.type).to.equal("LineString"); | ||
}); | ||
}); | ||
describe("options", function () { | ||
@@ -1242,2 +1881,720 @@ // flattened properties output mode | ||
}); | ||
// interesting objects with custom callback | ||
it("uninteresting tags: callback", function () { | ||
var json, result; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [1,2] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
tags: {"tag": "1"}, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
tags: {"tag": "2"}, | ||
lat: 2.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
var result = osmtogeojson.toGeojson(json, {uninterestingTags: function(tags, ignore_tags) { | ||
return tags["tag"] != "1"; | ||
}}); | ||
expect(result.features).to.have.length(2); | ||
expect(result.features[0].geometry.type).to.equal("LineString"); | ||
expect(result.features[1].geometry.type).to.equal("Point"); | ||
expect(result.features[1].properties.id).to.equal(1); | ||
}); | ||
// polygon detection | ||
// see: http://wiki.openstreetmap.org/wiki/Overpass_turbo/Polygon_Features | ||
it("polygon detection", function () { | ||
var json, result; | ||
// custom tagging detection rules | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
tags: {"is_polygon_key": "*"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
tags: {"is_polygon_key_value": "included_value"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "way", | ||
id: 3, | ||
tags: {"is_polygon_key_excluded_value": "*"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "way", | ||
id: 4, | ||
tags: {"is_polygon_key": "no"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "way", | ||
id: 5, | ||
tags: {"is_polygon_key_value": "not_included_value"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "way", | ||
id: 6, | ||
tags: {"is_polygon_key_excluded_value": "excluded_value"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 3.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json, { | ||
polygonFeatures: { | ||
"is_polygon_key": true, | ||
"is_polygon_key_value": { | ||
"included_values": {"included_value": true} | ||
}, | ||
"is_polygon_key_excluded_value": { | ||
"excluded_values": {"excluded_value": true} | ||
} | ||
} | ||
}); | ||
expect(result.features).to.have.length(6); | ||
expect(result.features[0].geometry.type).to.equal("Polygon"); | ||
expect(result.features[1].geometry.type).to.equal("Polygon"); | ||
expect(result.features[2].geometry.type).to.equal("Polygon"); | ||
expect(result.features[3].geometry.type).to.equal("LineString"); | ||
expect(result.features[4].geometry.type).to.equal("LineString"); | ||
expect(result.features[5].geometry.type).to.equal("LineString"); | ||
}); | ||
// polygon detection with custom callback | ||
it("polygon detection: callback", function () { | ||
var json, result; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
tags: {"tag": "1"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
tags: {"tag": "2"}, | ||
nodes: [1,2,3,1] | ||
}, | ||
{ | ||
type: "node", | ||
id: 1, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 2.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 3.0 | ||
} | ||
] | ||
}; | ||
var result = osmtogeojson.toGeojson(json, {polygonFeatures: function(tags) { | ||
return tags["tag"] == "1"; | ||
}}); | ||
expect(result.features).to.have.length(2); | ||
expect(result.features[0].geometry.type).to.equal("Polygon"); | ||
expect(result.features[1].geometry.type).to.equal("LineString"); | ||
}); | ||
}); | ||
describe("tainted data", function () { | ||
// basic tainted geometries | ||
it("tainted geometries", function () { | ||
var json, geojson; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 10, | ||
nodes: [2,3,5] | ||
}, | ||
{ | ||
type: "way", | ||
id: 11, | ||
nodes: [2,3,4,5,2], | ||
tags: {"area":"yes"} | ||
}, | ||
{ | ||
type: "way", | ||
id: 12, | ||
nodes: [2,3,4,2], | ||
}, | ||
{ | ||
type: "relation", | ||
id: 100, | ||
tags: {"type":"multipolygon"}, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 12, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 13, | ||
role: "inner" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 1.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 1.0, | ||
lon: 1.0 | ||
} | ||
] | ||
}; | ||
geojson = { | ||
type: "FeatureCollection", | ||
features: [ | ||
{ | ||
type: "Feature", | ||
id: "way/12", | ||
properties: { | ||
type: "way", | ||
id: 12, | ||
tags: {}, | ||
relations: [ | ||
{ | ||
rel: 100, | ||
role: "outer", | ||
reltags: {"type":"multipolygon"} | ||
} | ||
], | ||
meta: {}, | ||
tainted: true | ||
}, | ||
geometry: { | ||
type: "Polygon", | ||
coordinates: [[ | ||
[0.0,1.0], | ||
[1.0,0.0], | ||
[1.0,1.0], | ||
[0.0,1.0] | ||
]] | ||
} | ||
}, | ||
{ | ||
type: "Feature", | ||
id: "way/11", | ||
properties: { | ||
type: "way", | ||
id: 11, | ||
tags: {"area":"yes"}, | ||
relations: [], | ||
meta: {}, | ||
tainted: true | ||
}, | ||
geometry: { | ||
type: "Polygon", | ||
coordinates: [[ | ||
[0.0,1.0], | ||
[1.0,0.0], | ||
[1.0,1.0], | ||
[0.0,1.0] | ||
]] | ||
} | ||
}, | ||
{ | ||
type: "Feature", | ||
id: "way/10", | ||
properties: { | ||
type: "way", | ||
id: 10, | ||
tags: {}, | ||
relations: [], | ||
meta: {}, | ||
tainted: true | ||
}, | ||
geometry: { | ||
type: "LineString", | ||
coordinates: [ | ||
[0.0,1.0], | ||
[1.0,0.0] | ||
] | ||
} | ||
} | ||
] | ||
}; | ||
var result = osmtogeojson.toGeojson(json); | ||
expect(result).to.eql(geojson); | ||
}); | ||
// ignore missing node coordinates | ||
it("ids_only (missing coordinates or references)", function () { | ||
var json, result; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "node", | ||
id: 1 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
id: 1 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
}); | ||
// tainted way | ||
it("tainted way", function () { | ||
var json; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "way", | ||
id: 1, | ||
nodes: [2,3,4] | ||
}, | ||
{ | ||
type: "node", | ||
id: 2, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 1.0, | ||
lon: 1.0 | ||
} | ||
] | ||
}; | ||
var result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].geometry.coordinates).to.eql([[0.0,0.0],[1.0,1.0]]); | ||
expect(result.features[0].properties.tainted).to.equal(true); | ||
}); | ||
// invalid empty multipolygon | ||
it("empty multipolygon", function () { | ||
var json, result; | ||
}); | ||
// tainted simple multipolygon | ||
it("tainted simple multipolygon", function () { | ||
var json, result; | ||
// missing way | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "inner" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [3,4,5,3] | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 1.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(2); | ||
expect(result.features[0].properties.tainted).to.equal(true); | ||
// missing nodes | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
id: 1, | ||
tags: {"type":"multipolygon"}, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [3,4,5,3] | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
// missing node | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [3,4,5,6,3] | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 1.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(2); | ||
expect(result.features[0].properties.tainted).to.equal(true); | ||
}); | ||
// tainted multipolygon | ||
it("tainted multipolygon", function () { | ||
var json, result; | ||
// missing way | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [4,5,6,4] | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 6, | ||
lat: 1.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].properties.tainted).to.equal(true); | ||
// missing node | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [4,5,6,7,4] | ||
}, | ||
{ | ||
type: "way", | ||
id: 3, | ||
nodes: [4,5,6,4] | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 0.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 6, | ||
lat: 1.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(1); | ||
expect(result.features[0].properties.id).to.equal(1); | ||
expect(result.features[0].properties.tainted).to.equal(true); | ||
}); | ||
// degenerate multipolygon | ||
it("degenerate multipolygon", function () { | ||
// no coordinates | ||
var json, result; | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [4,5,6] | ||
}, | ||
{ | ||
type: "way", | ||
id: 3, | ||
nodes: [6,4] | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
// no outer ring | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "inner" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [3,4,5,3] | ||
}, | ||
{ | ||
type: "node", | ||
id: 3, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 1.0, | ||
lon: 1.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 1.0, | ||
lon: 0.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
// expected behaviour: do not return a degenerate (multi)polygon. | ||
// this could in principle return just the way that is now sort of unused | ||
// but just as with an (untagged) node of a one-node-way we're going to | ||
// assume that those outlines aren't interesting enough. | ||
expect(result.features).to.have.length(0); | ||
// incomplete outer ring | ||
json = { | ||
elements: [ | ||
{ | ||
type: "relation", | ||
tags: {"type": "multipolygon"}, | ||
id: 1, | ||
members: [ | ||
{ | ||
type: "way", | ||
ref: 2, | ||
role: "outer" | ||
}, | ||
{ | ||
type: "way", | ||
ref: 3, | ||
role: "outer" | ||
} | ||
] | ||
}, | ||
{ | ||
type: "way", | ||
id: 2, | ||
nodes: [4,5,6,4] | ||
}, | ||
{ | ||
type: "node", | ||
id: 4, | ||
lat: 0.0, | ||
lon: 0.0 | ||
}, | ||
{ | ||
type: "node", | ||
id: 5, | ||
lat: 1.0, | ||
lon: 1.0 | ||
} | ||
] | ||
}; | ||
result = osmtogeojson.toGeojson(json); | ||
expect(result.features).to.have.length(0); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
101250
2
3235
73