Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

osmtogeojson

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

osmtogeojson - npm Package Compare versions

Comparing version 1.2.1 to 1.3.0

8

CHANGELOG.md

@@ -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`

50

osmtogeojson.js

@@ -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.

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc