osm2geojson-lite 0.8.13 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Makefile CHANGED
@@ -1,2 +1,2 @@
1
1
  osm2geojson-lite.js: lib/index.js package.json
2
- browserify -s osm2geojson lib/index.js | uglifyjs -c -m -o dist/osm2geojson-lite.js
2
+ npx browserify -s osm2geojson lib/index.js | npx uglifyjs -c -m -o dist/osm2geojson-lite.js
package/index.html CHANGED
@@ -75,7 +75,7 @@ this page is based on https://github.com/aaronlidman/osm-and-geojson (c)Aaron Li
75
75
  #osmdata, #geojson {
76
76
  width: 100%;
77
77
  background: white;
78
- border: 1px solid #ccc;
78
+ border: 1px solid #cccccc;
79
79
  height: 320px;
80
80
  overflow: auto;
81
81
  margin-bottom: 20px;
@@ -115,6 +115,10 @@ this page is based on https://github.com/aaronlidman/osm-and-geojson (c)Aaron Li
115
115
  outline: none;
116
116
  }
117
117
 
118
+ textarea:focus {
119
+ box-shadow: 0 0 2px 1px #0c74a97f;
120
+ }
121
+
118
122
  #top {
119
123
  font-size: 22px;
120
124
  text-align: center;
@@ -219,11 +223,11 @@ this page is based on https://github.com/aaronlidman/osm-and-geojson (c)Aaron Li
219
223
  <div id="example">
220
224
  <div id="left">
221
225
  <h3>OSM Data</h3>
222
- <textarea id="osmdata" contenteditable="true"></textarea>
226
+ <textarea class="ta" id="osmdata" contenteditable="true"></textarea>
223
227
  </div>
224
228
  <div id="right">
225
229
  <h3>GeoJSON</h3>
226
- <textarea id="geojson" contenteditable="true"></textarea>
230
+ <textarea class="ta" id="geojson" contenteditable="true"></textarea>
227
231
  </div>
228
232
  <a class="button" href="" id="toGeo">Convert to GeoJSON &rarr;</a>
229
233
  </div>
package/lib/index.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import {FeatureCollection, GeometryObject} from 'geojson';
2
+
3
+ export = osm2geojson;
4
+ export as namespace osm2geojson;
5
+
6
+ declare var osm2geojson: osm2geojson.Default;
7
+
8
+ declare namespace osm2geojson {
9
+ interface Options {
10
+ completeFeature?: boolean;
11
+ allFeatures?: boolean;
12
+ renderTagged?: boolean;
13
+ excludeWay?: boolean;
14
+ suppressWay?: boolean;
15
+ }
16
+
17
+ export interface Default {
18
+ // tslint:disable-next-line:no-any
19
+ (osm: string | {[k: string]: any}, opts?: Options): FeatureCollection<GeometryObject>;
20
+ }
21
+ }
package/lib/index.js CHANGED
@@ -50,8 +50,9 @@ module.exports = (osm, opts) => {
50
50
 
51
51
  case 'relation':
52
52
  let relation = new Relation(elem.id, refElements);
53
- if (elem.bounds) with (elem.bounds)
54
- relation.setBounds([parseFloat(minlon), parseFloat(minlat), parseFloat(maxlon), parseFloat(maxlat)]);
53
+ if (elem.bounds) {
54
+ relation.setBounds([parseFloat(elem.bounds.minlon), parseFloat(elem.bounds.minlat), parseFloat(elem.bounds.maxlon), parseFloat(elem.bounds.maxlat)]);
55
+ }
55
56
  if (elem.tags) relation.addTags(elem.tags);
56
57
  relation.addProps(purgeProps(elem, ['id', 'type', 'tags', 'bounds', 'members']));
57
58
  if (elem.members)
@@ -69,35 +70,31 @@ module.exports = (osm, opts) => {
69
70
  const xmlParser = new XmlParser({progressive: true});
70
71
 
71
72
  xmlParser.on('</osm.node>', node => {
72
- with (node) {
73
- let nd = new Node(id, refElements);
74
- for (let [k, v] of Object.entries(node))
75
- if (!k.startsWith('$') && ['id', 'lon', 'lat'].indexOf(k) < 0)
76
- nd.addProp(k, v);
77
- nd.setLatLng(node);
78
- if (node.$innerNodes)
79
- for (let ind of $innerNodes)
80
- if(ind.$tag === 'tag')
81
- nd.addTag(ind.k, ind.v);
82
- }
73
+ let nd = new Node(node.id, refElements);
74
+ for (let [k, v] of Object.entries(node))
75
+ if (!k.startsWith('$') && ['id', 'lon', 'lat'].indexOf(k) < 0)
76
+ nd.addProp(k, v);
77
+ nd.setLatLng(node);
78
+ if (node.$innerNodes)
79
+ for (let ind of node.$innerNodes)
80
+ if(ind.$tag === 'tag')
81
+ nd.addTag(ind.k, ind.v);
83
82
  });
84
83
 
85
84
  xmlParser.on('</osm.way>', node => {
86
- with (node) {
87
- let way = new Way(id, refElements);
88
- for (let [k, v] of Object.entries(node))
89
- if (!k.startsWith('$') && ['id'].indexOf(k) < 0)
90
- way.addProp(k, v);
91
- if (node.$innerNodes) {
92
- for (let ind of $innerNodes)
93
- if (ind.$tag === 'nd') {
94
- if (ind.lon && ind.lat)
95
- way.addLatLng(ind);
96
- else if (ind.ref)
97
- way.addNodeRef(ind.ref);
98
- } else if (ind.$tag === 'tag')
99
- way.addTag(ind.k, ind.v);
100
- }
85
+ let way = new Way(node.id, refElements);
86
+ for (let [k, v] of Object.entries(node))
87
+ if (!k.startsWith('$') && ['id'].indexOf(k) < 0)
88
+ way.addProp(k, v);
89
+ if (node.$innerNodes) {
90
+ for (let ind of node.$innerNodes)
91
+ if (ind.$tag === 'nd') {
92
+ if (ind.lon && ind.lat)
93
+ way.addLatLng(ind);
94
+ else if (ind.ref)
95
+ way.addNodeRef(ind.ref);
96
+ } else if (ind.$tag === 'tag')
97
+ way.addTag(ind.k, ind.v);
101
98
  }
102
99
  });
103
100
 
@@ -106,42 +103,37 @@ module.exports = (osm, opts) => {
106
103
  });
107
104
 
108
105
  xmlParser.on('</osm.relation.member>', (node, parent) => {
109
- with (node) {
110
- let relation = refElements.get(`relation/${parent.id}`);
111
- let member = {
112
- type: type,
113
- role: node.role? role : '',
114
- ref: ref
115
- };
116
-
117
- if (node.lat && node.lon) {
118
- member.lat = lat, member.lon = lon, member.tags = {};
119
- for (let [k, v] of Object.entries(node))
120
- if (!k.startsWith('$') && ['type', 'lat', 'lon'].indexOf(k) < 0)
121
- member[k] = v;
122
- }
123
-
124
- if (node.$innerNodes) {
125
- let geometry = [];
126
- let nodes = [];
127
- for (let ind of $innerNodes) {
128
- if (ind.lat && ind.lon)
129
- geometry.push(ind);
130
- else
131
- nodes.push(ind.ref);
132
- }
133
- if (geometry.length > 0)
134
- member.geometry = geometry;
135
- else if (nodes.length > 0)
136
- member.nodes = nodes;
106
+ let relation = refElements.get(`relation/${parent.id}`);
107
+ let member = {
108
+ type: node.type,
109
+ role: node.role? node.role : '',
110
+ ref: node.ref
111
+ };
112
+ if (node.lat && node.lon) {
113
+ member.lat = node.lat, member.lon = node.lon, member.tags = {};
114
+ for (let [k, v] of Object.entries(node))
115
+ if (!k.startsWith('$') && ['type', 'lat', 'lon'].indexOf(k) < 0)
116
+ member[k] = v;
117
+ }
118
+ if (node.$innerNodes) {
119
+ let geometry = [];
120
+ let nodes = [];
121
+ for (let ind of node.$innerNodes) {
122
+ if (ind.lat && ind.lon)
123
+ geometry.push(ind);
124
+ else
125
+ nodes.push(ind.ref);
137
126
  }
138
- relation.addMember(member);
127
+ if (geometry.length > 0)
128
+ member.geometry = geometry;
129
+ else if (nodes.length > 0)
130
+ member.nodes = nodes;
139
131
  }
132
+ relation.addMember(member);
140
133
  });
141
134
 
142
135
  xmlParser.on('</osm.relation.bounds>', (node, parent) => {
143
- with (node)
144
- refElements.get(`relation/${parent.id}`).setBounds([parseFloat(minlon), parseFloat(minlat), parseFloat(maxlon), parseFloat(maxlat)]);
136
+ refElements.get(`relation/${parent.id}`).setBounds([parseFloat(node.minlon), parseFloat(node.minlat), parseFloat(node.maxlon), parseFloat(node.maxlat)]);
145
137
  });
146
138
 
147
139
  xmlParser.on('</osm.relation.tag>', (node, parent) => {
package/lib/osmobjs.js CHANGED
@@ -192,7 +192,7 @@ module.exports = (() => {
192
192
  break;
193
193
 
194
194
  case 'way':
195
- if (!member.role) member.role === '';
195
+ if (!member.role) member.role = '';
196
196
  let ways = this[member.role];
197
197
  if (!ways) ways = this[member.role] = [];
198
198
  if (member.geometry) {
package/lib/xmlparser.js CHANGED
@@ -27,7 +27,7 @@ module.exports = (() => {
27
27
  this.evtListeners = {};
28
28
  }
29
29
 
30
- parse(xml, parent?, dir?) {
30
+ parse(xml, parent, dir) {
31
31
  dir = dir? dir + '.' : '';
32
32
  let nodeRegEx = /<([^ >\/]+)(.*?)>/mg, nodeMatch = null, nodes = [];
33
33
  while (nodeMatch = nodeRegEx.exec(xml)) {
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const osm2geojson = require('./lib/index.js');
5
+
6
+ const data = fs.readFileSync("/dev/stdin", "utf-8");
7
+
8
+ const geojson = osm2geojson(data, {});
9
+
10
+ process.stdout.write(JSON.stringify(geojson));
package/package.json CHANGED
@@ -19,6 +19,9 @@
19
19
  "/"
20
20
  ],
21
21
  "author": "tibetty",
22
+ "bin": {
23
+ "osm2geojson-lite": "osm2geojson-lite"
24
+ },
22
25
  "bugs": {
23
26
  "url": "https://github.com/tibetty/osm2geojson-lite/issues"
24
27
  },
@@ -52,10 +55,17 @@
52
55
  "scripts": {
53
56
  "test": "npm run --prefix test test"
54
57
  },
55
- "version": "0.8.13",
58
+ "optionalDependencies": {
59
+ "@types/geojson": "^1.0.6"
60
+ },
61
+ "types": "lib/index.d.ts",
62
+ "version": "0.9.0",
56
63
  "directories": {
57
64
  "lib": "lib",
58
65
  "test": "test"
59
66
  },
60
- "devDependencies": {}
67
+ "devDependencies": {
68
+ "browserify": "^17.0.0",
69
+ "uglify-js": "^3.14.5"
70
+ }
61
71
  }
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const osmobjs_1 = require("./osmobjs");
4
+ const utils_1 = require("./utils");
5
+ const xmlparser_1 = require("./xmlparser");
6
+ exports.default = (osm, opts) => {
7
+ let completeFeature = false;
8
+ let renderTagged = false;
9
+ let excludeWay = true;
10
+ const parseOpts = (os) => {
11
+ if (os) {
12
+ completeFeature = os.completeFeature || os.allFeatures ? true : false;
13
+ renderTagged = os.renderTagged ? true : false;
14
+ const wayOpt = os.suppressWay || os.excludeWay;
15
+ if (wayOpt !== undefined && !wayOpt) {
16
+ excludeWay = false;
17
+ }
18
+ }
19
+ };
20
+ if (opts) {
21
+ parseOpts(opts);
22
+ }
23
+ const detectFormat = (o) => {
24
+ if (o.elements) {
25
+ return 'json';
26
+ }
27
+ if (o.indexOf('<osm') >= 0) {
28
+ return 'xml';
29
+ }
30
+ if (o.trim().startsWith('{')) {
31
+ return 'json-raw';
32
+ }
33
+ return 'invalid';
34
+ };
35
+ let format = detectFormat(osm);
36
+ const refElements = new utils_1.RefElements();
37
+ let featureArray = [];
38
+ const analyzeFeaturesFromJson = (o) => {
39
+ for (const elem of osm.elements) {
40
+ switch (elem.type) {
41
+ case 'node':
42
+ const node = new osmobjs_1.Node(elem.id, refElements);
43
+ if (elem.tags) {
44
+ node.addTags(elem.tags);
45
+ }
46
+ node.addProps(utils_1.purgeProps(elem, ['id', 'type', 'tags', 'lat', 'lon']));
47
+ node.setLatLng(elem);
48
+ break;
49
+ case 'way':
50
+ const way = new osmobjs_1.Way(elem.id, refElements);
51
+ if (elem.tags) {
52
+ way.addTags(elem.tags);
53
+ }
54
+ way.addProps(utils_1.purgeProps(elem, ['id', 'type', 'tags', 'nodes', 'geometry']));
55
+ if (elem.nodes) {
56
+ for (const n of elem.nodes) {
57
+ way.addNodeRef(n);
58
+ }
59
+ }
60
+ else if (elem.geometry) {
61
+ way.setLatLngArray(elem.geometry);
62
+ }
63
+ break;
64
+ case 'relation':
65
+ const relation = new osmobjs_1.Relation(elem.id, refElements);
66
+ if (elem.bounds) {
67
+ relation.setBounds([parseFloat(elem.bounds.minlon), parseFloat(elem.bounds.minlat), parseFloat(elem.bounds.maxlon), parseFloat(elem.bounds.maxlat)]);
68
+ }
69
+ if (elem.tags) {
70
+ relation.addTags(elem.tags);
71
+ }
72
+ relation.addProps(utils_1.purgeProps(elem, ['id', 'type', 'tags', 'bounds', 'members']));
73
+ if (elem.members) {
74
+ for (const member of elem.members) {
75
+ relation.addMember(member);
76
+ }
77
+ }
78
+ default:
79
+ break;
80
+ }
81
+ }
82
+ };
83
+ const analyzeFeaturesFromXml = (o) => {
84
+ const xmlParser = new xmlparser_1.default({ progressive: true });
85
+ xmlParser.on('</osm.node>', (node) => {
86
+ const nd = new osmobjs_1.Node(node.id, refElements);
87
+ for (const [k, v] of Object.entries(node)) {
88
+ if (!k.startsWith('$') && ['id', 'lon', 'lat'].indexOf(k) < 0) {
89
+ nd.addProp(k, v);
90
+ }
91
+ }
92
+ nd.setLatLng(node);
93
+ if (node.$innerNodes) {
94
+ for (const ind of node.$innerNodes) {
95
+ if (ind.$tag === 'tag') {
96
+ nd.addTag(ind.k, ind.v);
97
+ }
98
+ }
99
+ }
100
+ });
101
+ xmlParser.on('</osm.way>', (node) => {
102
+ const way = new osmobjs_1.Way(node.id, refElements);
103
+ for (const [k, v] of Object.entries(node)) {
104
+ if (!k.startsWith('$') && ['id'].indexOf(k) < 0) {
105
+ way.addProp(k, v);
106
+ }
107
+ }
108
+ if (node.$innerNodes) {
109
+ for (const ind of node.$innerNodes) {
110
+ if (ind.$tag === 'nd') {
111
+ if (ind.lon && ind.lat) {
112
+ way.addLatLng(ind);
113
+ }
114
+ else if (ind.ref) {
115
+ way.addNodeRef(ind.ref);
116
+ }
117
+ }
118
+ else if (ind.$tag === 'tag') {
119
+ way.addTag(ind.k, ind.v);
120
+ }
121
+ }
122
+ }
123
+ });
124
+ xmlParser.on('<osm.relation>', (node) => new osmobjs_1.Relation(node.id, refElements));
125
+ xmlParser.on('</osm.relation.member>', (node, parent) => {
126
+ const relation = refElements.get(`relation/${parent.id}`);
127
+ const member = {
128
+ type: node.type,
129
+ role: node.role ? node.role : '',
130
+ ref: node.ref,
131
+ };
132
+ if (node.lat && node.lon) {
133
+ member.lat = node.lat, member.lon = node.lon, member.tags = {};
134
+ for (const [k, v] of Object.entries(node)) {
135
+ if (!k.startsWith('$') && ['type', 'lat', 'lon'].indexOf(k) < 0) {
136
+ member[k] = v;
137
+ }
138
+ }
139
+ }
140
+ if (node.$innerNodes) {
141
+ const geometry = [];
142
+ const nodes = [];
143
+ for (const ind of node.$innerNodes) {
144
+ if (ind.lat && ind.lon) {
145
+ geometry.push(ind);
146
+ }
147
+ else if (ind.ref) {
148
+ nodes.push(ind.ref);
149
+ }
150
+ }
151
+ if (geometry.length > 0) {
152
+ member.geometry = geometry;
153
+ }
154
+ else if (nodes.length > 0) {
155
+ member.nodes = nodes;
156
+ }
157
+ }
158
+ relation.addMember(member);
159
+ });
160
+ xmlParser.on('</osm.relation.bounds>', (node, parent) => {
161
+ refElements.get(`relation/${parent.id}`).setBounds([parseFloat(node.minlon), parseFloat(node.minlat), parseFloat(node.maxlon), parseFloat(node.maxlat)]);
162
+ });
163
+ xmlParser.on('</osm.relation.tag>', (node, parent) => {
164
+ refElements.get(`relation/${parent.id}`).addTag(node.k, node.v);
165
+ });
166
+ xmlParser.parse(o);
167
+ };
168
+ if (format === 'json-raw') {
169
+ osm = JSON.parse(osm);
170
+ if (osm.elements) {
171
+ format = 'json';
172
+ }
173
+ else {
174
+ format = 'invalid';
175
+ }
176
+ }
177
+ if (format === 'json') {
178
+ analyzeFeaturesFromJson(osm);
179
+ }
180
+ else if (format === 'xml') {
181
+ analyzeFeaturesFromXml(osm);
182
+ }
183
+ refElements.bindAll();
184
+ for (const v of refElements.values()) {
185
+ if (v.refCount <= 0 || (v.hasTag && renderTagged && !(v instanceof osmobjs_1.Way && excludeWay))) {
186
+ const features = v.toFeatureArray();
187
+ // return the first geometry of the first relation element
188
+ if (v instanceof osmobjs_1.Relation && !completeFeature && features.length > 0) {
189
+ return features[0].geometry;
190
+ }
191
+ featureArray = featureArray.concat(features);
192
+ }
193
+ }
194
+ return { type: 'FeatureCollection', features: featureArray };
195
+ };