@wemap/osm 11.0.0-alpha.15 → 11.0.0-alpha.18

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/dist/index.js CHANGED
@@ -17,11 +17,13 @@ class OsmElement {
17
17
  }
18
18
  }
19
19
  class OsmModel {
20
- constructor(nodes, ways) {
20
+ constructor(nodes, ways, relations) {
21
21
  __publicField(this, "nodes");
22
22
  __publicField(this, "ways");
23
+ __publicField(this, "relations");
23
24
  this.nodes = nodes || [];
24
25
  this.ways = ways || [];
26
+ this.relations = relations || [];
25
27
  }
26
28
  getNodeById(id) {
27
29
  return this.nodes.find((node) => node.id === id) || null;
@@ -35,12 +37,19 @@ class OsmModel {
35
37
  getWayByName(name) {
36
38
  return this.ways.find((way) => way.tags.name === name) || null;
37
39
  }
40
+ getRelationById(id) {
41
+ return this.relations.find((way) => way.id === id) || null;
42
+ }
43
+ getRelationByName(name) {
44
+ return this.relations.find((way) => way.tags.name === name) || null;
45
+ }
38
46
  }
39
47
  class OsmNode extends OsmElement {
40
48
  constructor(id, coords, tags) {
41
49
  super(id, tags);
42
50
  __publicField(this, "coords");
43
51
  __publicField(this, "ways", []);
52
+ __publicField(this, "relations", []);
44
53
  this.coords = coords;
45
54
  }
46
55
  get isElevator() {
@@ -54,6 +63,7 @@ class OsmWay extends OsmElement {
54
63
  constructor(id, tags, level = null) {
55
64
  super(id, tags);
56
65
  __publicField(this, "nodes", []);
66
+ __publicField(this, "relations", []);
57
67
  __publicField(this, "level", null);
58
68
  this.level = level;
59
69
  }
@@ -76,6 +86,31 @@ class OsmWay extends OsmElement {
76
86
  return this.nodes[0] === this.nodes[this.nodes.length - 1];
77
87
  }
78
88
  }
89
+ class OsmRelation extends OsmElement {
90
+ constructor(id, members = [], tags) {
91
+ super(id, tags);
92
+ __publicField(this, "relations", []);
93
+ this.members = members;
94
+ }
95
+ isMultipolygon() {
96
+ return this.tags.type === "multipolygon";
97
+ }
98
+ getGeoJsonPolygon() {
99
+ if (!this.isMultipolygon())
100
+ return null;
101
+ const outer = this.members.find((member) => member.ref instanceof OsmWay && member.role === "outer");
102
+ if (!outer)
103
+ return null;
104
+ const inners = this.members.filter((member) => member.ref instanceof OsmWay && member.role === "inner");
105
+ return {
106
+ type: "Polygon",
107
+ coordinates: [outer, ...inners].map((member) => {
108
+ const way = member.ref;
109
+ return way.nodes.map((node) => [node.coords.lng, node.coords.lat]);
110
+ })
111
+ };
112
+ }
113
+ }
79
114
  class OsmParser {
80
115
  static parseOsmXmlString(osmXmlString) {
81
116
  const model = new OsmModel();
@@ -104,6 +139,16 @@ class OsmParser {
104
139
  model.ways.push(osmWay);
105
140
  break;
106
141
  }
142
+ case "relation": {
143
+ if (isDeleted(node)) {
144
+ buffer = null;
145
+ break;
146
+ }
147
+ const osmRelation = this._parseRelation(node.attributes);
148
+ buffer = osmRelation;
149
+ model.relations.push(osmRelation);
150
+ break;
151
+ }
107
152
  case "tag": {
108
153
  if (!buffer) {
109
154
  return;
@@ -128,6 +173,23 @@ class OsmParser {
128
173
  refNode.ways.push(buffer);
129
174
  break;
130
175
  }
176
+ case "member": {
177
+ if (!buffer || !(buffer instanceof OsmRelation)) {
178
+ return;
179
+ }
180
+ const memberId = Number(node.attributes.ref);
181
+ const memberType = node.attributes.type;
182
+ let refElement = null;
183
+ memberType === "node" && (refElement = model.getNodeById(memberId));
184
+ memberType === "way" && (refElement = model.getWayById(memberId));
185
+ memberType === "relation" && (refElement = model.getRelationById(memberId));
186
+ if (!refElement) {
187
+ throw Error("Member: " + memberId + " in relation " + buffer.id + " not found");
188
+ }
189
+ buffer.members.push({ ref: refElement, role: node.attributes.role });
190
+ refElement.relations.push(buffer);
191
+ break;
192
+ }
131
193
  }
132
194
  });
133
195
  parser.write(osmXmlString);
@@ -148,10 +210,13 @@ class OsmParser {
148
210
  static _parseWay(attr) {
149
211
  return new OsmWay(Number(attr.id));
150
212
  }
213
+ static _parseRelation(attr) {
214
+ return new OsmRelation(Number(attr.id));
215
+ }
151
216
  }
152
- class OsmGraphNode$1 extends geo.GraphNode {
217
+ class OsmGraphNode extends geo.GraphNode {
153
218
  }
154
- class OsmGraphNode extends geo.GraphEdge {
219
+ class OsmGraphEdge extends geo.GraphEdge {
155
220
  }
156
221
  class OsmGraphItinerary extends geo.GraphItinerary {
157
222
  static fromNetworkNodes(start, end, networkNodes, edgesWeights) {
@@ -195,7 +260,7 @@ function createNodesAndEdgesFromElevator(nodes, edges, elevatorNode) {
195
260
  const getOrCreateLevelNode = (level, builtFrom) => {
196
261
  let levelNode = createdNodes.find(({ coords }) => geo.Level.equals(level, coords.level));
197
262
  if (!levelNode) {
198
- levelNode = new OsmGraphNode$1(elevatorNode.coords.clone(), builtFrom);
263
+ levelNode = new OsmGraphNode(elevatorNode.coords.clone(), builtFrom);
199
264
  levelNode.coords.level = level;
200
265
  createdNodes.push(levelNode);
201
266
  nodes.push(levelNode);
@@ -223,7 +288,7 @@ function createNodesAndEdgesFromElevator(nodes, edges, elevatorNode) {
223
288
  }
224
289
  const minLevel = Math.min(createdNode1.coords.level, createdNode2.coords.level);
225
290
  const maxLevel = Math.max(createdNode1.coords.level, createdNode2.coords.level);
226
- const newEdge = new OsmGraphNode(
291
+ const newEdge = new OsmGraphEdge(
227
292
  createdNode1,
228
293
  createdNode2,
229
294
  [minLevel, maxLevel],
@@ -245,7 +310,7 @@ function createNetworkFromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SE
245
310
  const getOrCreateNode = (osmNode) => {
246
311
  let node = nodesCreated[osmNode.id];
247
312
  if (!node) {
248
- node = new OsmGraphNode$1(osmNode.coords, osmNode);
313
+ node = new OsmGraphNode(osmNode.coords, osmNode);
249
314
  nodesCreated[osmNode.id] = node;
250
315
  nodes.push(node);
251
316
  if (osmNode.tags.highway === "elevator") {
@@ -261,7 +326,7 @@ function createNetworkFromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SE
261
326
  let firstNode = getOrCreateNode(way.nodes[0]);
262
327
  for (let i = 1; i < way.nodes.length; i++) {
263
328
  const secondNode = getOrCreateNode(way.nodes[i]);
264
- const edge = new OsmGraphNode(firstNode, secondNode, way.level, way);
329
+ const edge = new OsmGraphEdge(firstNode, secondNode, way.level, way);
265
330
  manageOneWay(edge, way);
266
331
  edges.push(edge);
267
332
  firstNode = secondNode;
@@ -271,7 +336,7 @@ function createNetworkFromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SE
271
336
  createNodesAndEdgesFromElevator(nodes, edges, node);
272
337
  });
273
338
  const networkModel = new OsmNetwork(nodes, edges);
274
- OsmGraphNode$1.generateNodesLevels(networkModel.nodes);
339
+ OsmGraphNode.generateNodesLevels(networkModel.nodes);
275
340
  return networkModel;
276
341
  }
277
342
  const OsmNetworkUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -283,9 +348,9 @@ const OsmNetworkUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
283
348
  createNetworkFromOsmModel
284
349
  }, Symbol.toStringTag, { value: "Module" }));
285
350
  exports.OsmElement = OsmElement;
286
- exports.OsmGraphEdge = OsmGraphNode;
351
+ exports.OsmGraphEdge = OsmGraphEdge;
287
352
  exports.OsmGraphItinerary = OsmGraphItinerary;
288
- exports.OsmGraphNode = OsmGraphNode$1;
353
+ exports.OsmGraphNode = OsmGraphNode;
289
354
  exports.OsmGraphProjection = OsmGraphProjection;
290
355
  exports.OsmGraphRouter = OsmGraphRouter;
291
356
  exports.OsmGraphRouterOptions = OsmGraphRouterOptions;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/OsmElement.ts","../src/OsmModel.ts","../src/OsmNode.ts","../src/OsmWay.ts","../src/OsmParser.ts","../src/graph/OsmGraphNode.ts","../src/graph/OsmGraphEdge.ts","../src/graph/OsmGraphItinerary.ts","../src/graph/OsmNetwork.ts","../src/graph/OsmGraphProjection.ts","../src/graph/OsmGraphRouter.ts","../src/graph/OsmGraphRouterOptions.ts","../src/graph/OsmMapMatching.ts","../src/graph/OsmNetworkUtils.ts"],"sourcesContent":["\nexport type OsmTags = { [key: string]: string };\n\nclass OsmElement {\n\n id: number;\n tags: OsmTags;\n\n constructor(id: number, tags?: OsmTags) {\n this.id = id;\n this.tags = tags || {};\n }\n}\n\nexport default OsmElement;\n","import OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmModel {\n\n nodes: OsmNode[];\n ways: OsmWay[];\n\n constructor(nodes?: OsmNode[], ways?: OsmWay[]) {\n this.nodes = nodes || [];\n this.ways = ways || [];\n }\n\n getNodeById(id: number) {\n return this.nodes.find(node => node.id === id) || null;\n }\n\n getNodeByName(name: string) {\n return this.nodes.find(node => node.tags.name === name) || null;\n }\n\n getWayById(id: number) {\n return this.ways.find(way => way.id === id) || null;\n }\n\n getWayByName(name: string) {\n return this.ways.find(way => way.tags.name === name) || null;\n }\n\n}\n\nexport default OsmModel;\n","import { Coordinates } from '@wemap/geo';\n\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmNode extends OsmElement {\n\n coords : Coordinates;\n ways: OsmWay[] = [];\n\n\n constructor(id: number, coords: Coordinates, tags?: OsmTags) {\n super(id, tags);\n this.coords = coords;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isConveying() {\n return this.isElevator;\n }\n}\n\nexport default OsmNode;\n","import { Level_t } from '@wemap/geo';\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmNode from './OsmNode.js';\n\nclass OsmWay extends OsmElement {\n\n nodes: OsmNode[] = [];\n level: Level_t = null;\n\n constructor(id: number, tags?: OsmTags, level: Level_t = null) {\n super(id, tags);\n this.level = level;\n }\n\n get areStairs() {\n return this.tags.highway === 'steps';\n }\n\n get isConveying() {\n return this.tags.hasOwnProperty('conveying');\n }\n\n get isEscalator() {\n return this.areStairs && this.isConveying;\n }\n\n get isMovingWalkway() {\n return !this.areStairs && this.isConveying;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isArea() {\n // That is not the real definition for OSM\n return this.nodes[0] === this.nodes[this.nodes.length - 1];\n }\n}\n\nexport default OsmWay;\n","/* eslint-disable max-statements */\nimport { SaxesParser } from 'saxes';\n\nimport {\n Level, Coordinates\n} from '@wemap/geo';\n\nimport OsmModel from './OsmModel.js';\nimport OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\n\ntype OsmXmlElement = { action?: 'delete' };\ntype OsmXmlNode = { id: string, lat: string, lon: string } & OsmXmlElement;\ntype OsmXmlWay = { id: string } & OsmXmlElement;\n\nclass OsmParser {\n\n static parseOsmXmlString(osmXmlString: string) {\n\n const model = new OsmModel();\n const parser = new SaxesParser();\n\n let buffer: OsmNode | OsmWay | null;\n\n const isDeleted = (element: { attributes: OsmXmlElement }) =>\n element.attributes.action && element.attributes.action === 'delete';\n\n parser.on('opentag', (node) => {\n\n switch (node.name) {\n case 'node': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmNode = this._parseNode(node.attributes as OsmXmlNode);\n buffer = osmNode;\n model.nodes.push(osmNode);\n break;\n }\n case 'way': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmWay = this._parseWay(node.attributes as OsmXmlWay);\n buffer = osmWay;\n model.ways.push(osmWay);\n break;\n }\n case 'tag': {\n if (!buffer) {\n return;\n }\n const {\n k, v\n } = node.attributes;\n buffer.tags[k] = v;\n break;\n }\n case 'nd': {\n if (!buffer || !(buffer instanceof OsmWay)) {\n return;\n }\n const nodeId = Number(node.attributes.ref);\n const refNode = model.getNodeById(nodeId);\n if (!refNode) {\n throw Error('Node: ' + nodeId + ' in way ' + buffer.id + ' not found');\n }\n\n buffer.nodes.push(refNode);\n refNode.ways.push(buffer);\n break;\n }\n }\n });\n\n parser.write(osmXmlString);\n\n for (let i = 0; i < model.ways.length; i++) {\n const way = model.ways[i];\n if (way.tags.level) {\n way.level = Level.fromString(way.tags.level);\n }\n }\n\n return model;\n }\n\n\n static _parseNode(attr: OsmXmlNode) {\n return new OsmNode(\n Number(attr.id),\n new Coordinates(Number(attr.lat), Number(attr.lon)));\n }\n\n static _parseWay(attr: { id: string }) {\n return new OsmWay(Number(attr.id));\n }\n}\n\nexport default OsmParser;\n","import { GraphNode } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphNode extends GraphNode<OsmNode, OsmNode | OsmWay>{ }","import { GraphEdge } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphNode extends GraphEdge<OsmNode | OsmWay, OsmNode>{ }","import { Coordinates, GraphItinerary, GraphNode } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphItinerary extends GraphItinerary<N, E>{ \n\n static fromNetworkNodes<A = N, B = E>(\n start: Coordinates, end: Coordinates,\n networkNodes: GraphNode<A, B>[], edgesWeights: number[]\n ) {\n return super.fromNetworkNodes(start, end, networkNodes, edgesWeights) as GraphItinerary<A, B>;\n }\n}\n","import { Coordinates, Network } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmNetwork extends Network<N, E>{\n static fromCoordinates<A = N, B = E>(segments: Coordinates[][]) {\n return super.fromCoordinates<N, E>(segments) as Network<A, B>;\n }\n}","import { GraphProjection } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphProjection extends GraphProjection<N, E>{ }\n","import { GraphRouter } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouter extends GraphRouter<N, E>{ }\n","import { GraphRouterOptions } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouterOptions extends GraphRouterOptions<N, E>{ }\n","import { MapMatching } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmMapMatching extends MapMatching<N, E>{ }\n","import { Level } from '@wemap/geo';\nimport OsmGraphNode from './OsmGraphNode';\nimport OsmGraphEdge from './OsmGraphEdge';\nimport OsmModel from '../OsmModel';\nimport OsmNode from '../OsmNode';\nimport OsmWay from '../OsmWay';\nimport OsmNetwork from './OsmNetwork';\n\nexport type N = OsmNode;\nexport type E = OsmNode | OsmWay;\n\nexport const HIGHWAYS_PEDESTRIANS = ['footway', 'steps', 'pedestrian', 'living_street', 'path', 'track', 'sidewalk', 'elevator'];\n\nexport const DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway)\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n};\n\nexport function getNodeByName(network: OsmNetwork, name: string) {\n return network.nodes.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nexport function getEdgeByName(network: OsmNetwork, name: string) {\n return network.edges.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nfunction manageOneWay(edge: OsmGraphEdge, way: OsmWay) {\n\n const { highway, oneway, conveying } = way.tags;\n\n edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n || (conveying && highway && ['forward', 'backward'].includes(conveying)));\n\n if (edge.isOneway && conveying === 'backward') {\n const tmpNode = edge.node1;\n edge.node1 = edge.node2;\n edge.node2 = tmpNode;\n }\n}\n\n\nfunction createNodesAndEdgesFromElevator(\n nodes: OsmGraphNode[],\n edges: OsmGraphEdge[],\n elevatorNode: OsmGraphNode\n) {\n\n const createdNodes: OsmGraphNode[] = [];\n const getOrCreateLevelNode = (level: number | null, builtFrom: N | null) => {\n let levelNode = createdNodes.find(({ coords }) => Level.equals(level, coords.level));\n if (!levelNode) {\n levelNode = new OsmGraphNode(elevatorNode.coords.clone(), builtFrom);\n levelNode.coords.level = level;\n createdNodes.push(levelNode);\n nodes.push(levelNode);\n }\n return levelNode;\n };\n\n // Create nodes from node.edges\n elevatorNode.edges.forEach(edge => {\n if (Level.isRange(edge.level)) {\n throw new Error('Cannot handle this elevator edge due to ambiguity');\n }\n\n const levelNode = getOrCreateLevelNode(edge.level, elevatorNode.builtFrom);\n if (edge.node1 === elevatorNode) {\n edge.node1 = levelNode;\n } else {\n edge.node2 = levelNode;\n }\n levelNode.edges.push(edge);\n });\n\n // Create edges from createdNodes\n for (let i = 0; i < createdNodes.length; i++) {\n for (let j = i + 1; j < createdNodes.length; j++) {\n\n const createdNode1 = createdNodes[i];\n const createdNode2 = createdNodes[j];\n\n if (createdNode1.coords.level === null || createdNode2.coords.level === null) {\n // TODO: not the best approach... but cannot do better with [number, number] range for levels\n continue;\n }\n\n const minLevel = Math.min(createdNode1.coords.level as number, createdNode2.coords.level as number);\n const maxLevel = Math.max(createdNode1.coords.level as number, createdNode2.coords.level as number);\n\n const newEdge = new OsmGraphEdge(\n createdNode1,\n createdNode2,\n [minLevel, maxLevel],\n elevatorNode.builtFrom\n );\n edges.push(newEdge);\n }\n }\n\n // Remove the historical elevator node from the network\n const elevatorNodeIndex = nodes.indexOf(elevatorNode);\n if (elevatorNodeIndex > -1) {\n nodes.splice(elevatorNodeIndex, 1);\n }\n}\n\nexport function createNetworkFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = DEFAULT_WAY_SELECTOR\n) {\n\n const nodes: OsmGraphNode[] = [];\n const edges: OsmGraphEdge[] = [];\n\n const nodesCreated: { [key: number]: OsmGraphNode } = {};\n const elevatorNodes: OsmGraphNode[] = [];\n\n const getOrCreateNode = (osmNode: OsmNode) => {\n let node = nodesCreated[osmNode.id];\n if (!node) {\n node = new OsmGraphNode(osmNode.coords, osmNode);\n nodesCreated[osmNode.id] = node;\n nodes.push(node);\n\n if (osmNode.tags.highway === 'elevator') {\n elevatorNodes.push(node);\n }\n }\n return node;\n };\n\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n let firstNode = getOrCreateNode(way.nodes[0]);\n for (let i = 1; i < way.nodes.length; i++) {\n const secondNode = getOrCreateNode(way.nodes[i]);\n\n const edge = new OsmGraphEdge(firstNode, secondNode, way.level, way);\n manageOneWay(edge, way);\n edges.push(edge);\n firstNode = secondNode;\n }\n\n });\n\n elevatorNodes.forEach(node => {\n // We have to clone this node for each connected edge\n createNodesAndEdgesFromElevator(nodes, edges, node);\n });\n\n const networkModel = new OsmNetwork(nodes, edges);\n\n OsmGraphNode.generateNodesLevels(networkModel.nodes);\n\n return networkModel;\n}\n\n\n// /**\n// * @param {GraphNode} node\n// * @param {object} tags\n// */\n// static _applyNodePropertiesFromTags(node, tags) {\n// node.name = tags.name || null;\n// node.subwayEntrance = tags.railway === 'subway_entrance';\n// if (node.subwayEntrance && tags.ref) {\n// node.subwayEntranceRef = tags.ref;\n// }\n// }\n\n// /**\n// * @param {GraphEdge} edge\n// * @param {object} tags\n// */\n// static _applyEdgePropertiesFromTags(edge, tags) {\n// const { highway, oneway, conveying, name } = tags;\n// edge.name = name || null;\n// edge.isStairs = highway === 'steps';\n// edge.isConveying = 'conveying' in tags;\n// edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n// || (conveying && highway && ['yes', 'forward', 'backward'].includes(conveying)));\n\n// if (conveying === 'backward') {\n// const tmpNode = edge.node1;\n// edge.node1 = edge.node2;\n// edge.node2 = tmpNode;\n// }\n\n// }\n"],"names":["SaxesParser","Level","Coordinates","OsmGraphNode","GraphNode","GraphEdge","GraphItinerary","Network","GraphProjection","GraphRouter","GraphRouterOptions","MapMatching","OsmGraphEdge"],"mappings":";;;;;;;;;;AAGA,MAAM,WAAW;AAAA,EAKb,YAAY,IAAY,MAAgB;AAHxC;AACA;AAGI,SAAK,KAAK;AACL,SAAA,OAAO,QAAQ;EACxB;AACJ;ACTA,MAAM,SAAS;AAAA,EAKX,YAAY,OAAmB,MAAiB;AAHhD;AACA;AAGS,SAAA,QAAQ,SAAS;AACjB,SAAA,OAAO,QAAQ;EACxB;AAAA,EAEA,YAAY,IAAY;AACpB,WAAO,KAAK,MAAM,KAAK,UAAQ,KAAK,OAAO,EAAE,KAAK;AAAA,EACtD;AAAA,EAEA,cAAc,MAAc;AACjB,WAAA,KAAK,MAAM,KAAK,CAAA,SAAQ,KAAK,KAAK,SAAS,IAAI,KAAK;AAAA,EAC/D;AAAA,EAEA,WAAW,IAAY;AACnB,WAAO,KAAK,KAAK,KAAK,SAAO,IAAI,OAAO,EAAE,KAAK;AAAA,EACnD;AAAA,EAEA,aAAa,MAAc;AAChB,WAAA,KAAK,KAAK,KAAK,CAAA,QAAO,IAAI,KAAK,SAAS,IAAI,KAAK;AAAA,EAC5D;AAEJ;ACxBA,MAAM,gBAAgB,WAAW;AAAA,EAM7B,YAAY,IAAY,QAAqB,MAAgB;AACzD,UAAM,IAAI,IAAI;AALlB;AACA,gCAAiB,CAAA;AAKb,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,IAAI,aAAa;AACN,WAAA,KAAK,KAAK,YAAY;AAAA,EACjC;AAAA,EAEA,IAAI,cAAc;AACd,WAAO,KAAK;AAAA,EAChB;AACJ;ACnBA,MAAM,eAAe,WAAW;AAAA,EAK5B,YAAY,IAAY,MAAgB,QAAiB,MAAM;AAC3D,UAAM,IAAI,IAAI;AAJlB,iCAAmB,CAAA;AACnB,iCAAiB;AAIb,SAAK,QAAQ;AAAA,EACjB;AAAA,EAEA,IAAI,YAAY;AACL,WAAA,KAAK,KAAK,YAAY;AAAA,EACjC;AAAA,EAEA,IAAI,cAAc;AACP,WAAA,KAAK,KAAK,eAAe,WAAW;AAAA,EAC/C;AAAA,EAEA,IAAI,cAAc;AACP,WAAA,KAAK,aAAa,KAAK;AAAA,EAClC;AAAA,EAEA,IAAI,kBAAkB;AACX,WAAA,CAAC,KAAK,aAAa,KAAK;AAAA,EACnC;AAAA,EAEA,IAAI,aAAa;AACN,WAAA,KAAK,KAAK,YAAY;AAAA,EACjC;AAAA,EAEA,IAAI,SAAS;AAET,WAAO,KAAK,MAAM,OAAO,KAAK,MAAM,KAAK,MAAM,SAAS;AAAA,EAC5D;AACJ;ACvBA,MAAM,UAAU;AAAA,EAEZ,OAAO,kBAAkB,cAAsB;AAErC,UAAA,QAAQ,IAAI;AACZ,UAAA,SAAS,IAAIA,MAAAA;AAEf,QAAA;AAEE,UAAA,YAAY,CAAC,YACf,QAAQ,WAAW,UAAU,QAAQ,WAAW,WAAW;AAExD,WAAA,GAAG,WAAW,CAAC,SAAS;AAE3B,cAAQ,KAAK,MAAM;AAAA,QACf,KAAK,QAAQ;AACL,cAAA,UAAU,IAAI,GAAG;AACR,qBAAA;AACT;AAAA,UACJ;AACA,gBAAM,UAAU,KAAK,WAAW,KAAK,UAAwB;AACpD,mBAAA;AACH,gBAAA,MAAM,KAAK,OAAO;AACxB;AAAA,QACJ;AAAA,QACA,KAAK,OAAO;AACJ,cAAA,UAAU,IAAI,GAAG;AACR,qBAAA;AACT;AAAA,UACJ;AACA,gBAAM,SAAS,KAAK,UAAU,KAAK,UAAuB;AACjD,mBAAA;AACH,gBAAA,KAAK,KAAK,MAAM;AACtB;AAAA,QACJ;AAAA,QACA,KAAK,OAAO;AACR,cAAI,CAAC,QAAQ;AACT;AAAA,UACJ;AACM,gBAAA;AAAA,YACF;AAAA,YAAG;AAAA,UAAA,IACH,KAAK;AACT,iBAAO,KAAK,KAAK;AACjB;AAAA,QACJ;AAAA,QACA,KAAK,MAAM;AACP,cAAI,CAAC,UAAU,EAAE,kBAAkB,SAAS;AACxC;AAAA,UACJ;AACA,gBAAM,SAAS,OAAO,KAAK,WAAW,GAAG;AACnC,gBAAA,UAAU,MAAM,YAAY,MAAM;AACxC,cAAI,CAAC,SAAS;AACV,kBAAM,MAAM,WAAW,SAAS,aAAa,OAAO,KAAK,YAAY;AAAA,UACzE;AAEO,iBAAA,MAAM,KAAK,OAAO;AACjB,kBAAA,KAAK,KAAK,MAAM;AACxB;AAAA,QACJ;AAAA,MACJ;AAAA,IAAA,CACH;AAED,WAAO,MAAM,YAAY;AAEzB,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK,QAAQ,KAAK;AAClC,YAAA,MAAM,MAAM,KAAK;AACnB,UAAA,IAAI,KAAK,OAAO;AAChB,YAAI,QAAQC,UAAM,WAAW,IAAI,KAAK,KAAK;AAAA,MAC/C;AAAA,IACJ;AAEO,WAAA;AAAA,EACX;AAAA,EAGA,OAAO,WAAW,MAAkB;AAChC,WAAO,IAAI;AAAA,MACP,OAAO,KAAK,EAAE;AAAA,MACd,IAAIC,gBAAY,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,GAAG,CAAC;AAAA,IAAA;AAAA,EAC1D;AAAA,EAEA,OAAO,UAAU,MAAsB;AACnC,WAAO,IAAI,OAAO,OAAO,KAAK,EAAE,CAAC;AAAA,EACrC;AACJ;AC/FA,MAAqBC,uBAAqBC,IAAAA,UAAoC;AAAE;ACAhF,MAAqB,qBAAqBC,IAAAA,UAAoC;AAAE;ACAhF,MAAqB,0BAA0BC,IAAAA,eAAoB;AAAA,EAE/D,OAAO,iBACH,OAAoB,KACpB,cAAiC,cACnC;AACE,WAAO,MAAM,iBAAiB,OAAO,KAAK,cAAc,YAAY;AAAA,EACxE;AACJ;ACRA,MAAqB,mBAAmBC,IAAAA,QAAa;AAAA,EACjD,OAAO,gBAA8B,UAA2B;AACrD,WAAA,MAAM,gBAAsB,QAAQ;AAAA,EAC/C;AACJ;ACJA,MAAqB,2BAA2BC,IAAAA,gBAAqB;AAAE;ACAvE,MAAqB,uBAAuBC,IAAAA,YAAiB;AAAE;ACA/D,MAAqB,8BAA8BC,IAAAA,mBAAwB;AAAE;ACA7E,MAAqB,uBAAuBC,IAAAA,YAAiB;AAAE;ACOlD,MAAA,uBAAuB,CAAC,WAAW,SAAS,cAAc,iBAAiB,QAAQ,SAAS,YAAY,UAAU;AAElH,MAAA,uBAAuB,CAAC,QAAgB;AACjD,SAAO,qBAAqB,SAAS,IAAI,KAAK,OAAO,KAC9C,IAAI,KAAK,YAAY,cACrB,IAAI,KAAK,qBAAqB,cAC9B,IAAI,KAAK,YAAY;AAChC;AAEgB,SAAA,cAAc,SAAqB,MAAc;AACtD,SAAA,QAAQ,MAAM,KAAK,CAAC,EAAE,iBAAgB,uCAAW,KAAK,UAAS,IAAI;AAC9E;AAEgB,SAAA,cAAc,SAAqB,MAAc;AACtD,SAAA,QAAQ,MAAM,KAAK,CAAC,EAAE,iBAAgB,uCAAW,KAAK,UAAS,IAAI;AAC9E;AAEA,SAAS,aAAa,MAAoB,KAAa;AAEnD,QAAM,EAAE,SAAS,QAAQ,UAAA,IAAc,IAAI;AAE3C,OAAK,WAAW,QAAS,WAAW,SAAS,WAAW,UAAU,WAAW,OACrE,aAAa,WAAW,CAAC,WAAW,UAAU,EAAE,SAAS,SAAS,CAAE;AAExE,MAAA,KAAK,YAAY,cAAc,YAAY;AAC3C,UAAM,UAAU,KAAK;AACrB,SAAK,QAAQ,KAAK;AAClB,SAAK,QAAQ;AAAA,EACjB;AACJ;AAGA,SAAS,gCACL,OACA,OACA,cACF;AAEE,QAAM,eAA+B,CAAA;AAC/B,QAAA,uBAAuB,CAAC,OAAsB,cAAwB;AACxE,QAAI,YAAY,aAAa,KAAK,CAAC,EAAE,OAAA,MAAaV,IAAA,MAAM,OAAO,OAAO,OAAO,KAAK,CAAC;AACnF,QAAI,CAAC,WAAW;AACZ,kBAAY,IAAIE,eAAa,aAAa,OAAO,MAAA,GAAS,SAAS;AACnE,gBAAU,OAAO,QAAQ;AACzB,mBAAa,KAAK,SAAS;AAC3B,YAAM,KAAK,SAAS;AAAA,IACxB;AACO,WAAA;AAAA,EAAA;AAIE,eAAA,MAAM,QAAQ,CAAQ,SAAA;AAC/B,QAAIF,UAAM,QAAQ,KAAK,KAAK,GAAG;AACrB,YAAA,IAAI,MAAM,mDAAmD;AAAA,IACvE;AAEA,UAAM,YAAY,qBAAqB,KAAK,OAAO,aAAa,SAAS;AACrE,QAAA,KAAK,UAAU,cAAc;AAC7B,WAAK,QAAQ;AAAA,IAAA,OACV;AACH,WAAK,QAAQ;AAAA,IACjB;AACU,cAAA,MAAM,KAAK,IAAI;AAAA,EAAA,CAC5B;AAGD,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC1C,aAAS,IAAI,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAE9C,YAAM,eAAe,aAAa;AAClC,YAAM,eAAe,aAAa;AAElC,UAAI,aAAa,OAAO,UAAU,QAAQ,aAAa,OAAO,UAAU,MAAM;AAE1E;AAAA,MACJ;AAEM,YAAA,WAAW,KAAK,IAAI,aAAa,OAAO,OAAiB,aAAa,OAAO,KAAe;AAC5F,YAAA,WAAW,KAAK,IAAI,aAAa,OAAO,OAAiB,aAAa,OAAO,KAAe;AAElG,YAAM,UAAU,IAAIW;AAAAA,QAChB;AAAA,QACA;AAAA,QACA,CAAC,UAAU,QAAQ;AAAA,QACnB,aAAa;AAAA,MAAA;AAEjB,YAAM,KAAK,OAAO;AAAA,IACtB;AAAA,EACJ;AAGM,QAAA,oBAAoB,MAAM,QAAQ,YAAY;AACpD,MAAI,oBAAoB,IAAI;AAClB,UAAA,OAAO,mBAAmB,CAAC;AAAA,EACrC;AACJ;AAEgB,SAAA,0BACZ,UACA,qBAAqB,sBACvB;AAEE,QAAM,QAAwB,CAAA;AAC9B,QAAM,QAAwB,CAAA;AAE9B,QAAM,eAAgD,CAAA;AACtD,QAAM,gBAAgC,CAAA;AAEhC,QAAA,kBAAkB,CAAC,YAAqB;AACtC,QAAA,OAAO,aAAa,QAAQ;AAChC,QAAI,CAAC,MAAM;AACP,aAAO,IAAIT,eAAa,QAAQ,QAAQ,OAAO;AAC/C,mBAAa,QAAQ,MAAM;AAC3B,YAAM,KAAK,IAAI;AAEX,UAAA,QAAQ,KAAK,YAAY,YAAY;AACrC,sBAAc,KAAK,IAAI;AAAA,MAC3B;AAAA,IACJ;AACO,WAAA;AAAA,EAAA;AAGF,WAAA,KAAK,QAAQ,CAAO,QAAA;AACrB,QAAA,CAAC,mBAAmB,GAAG,GAAG;AAC1B;AAAA,IACJ;AAEA,QAAI,YAAY,gBAAgB,IAAI,MAAM,EAAE;AAC5C,aAAS,IAAI,GAAG,IAAI,IAAI,MAAM,QAAQ,KAAK;AACvC,YAAM,aAAa,gBAAgB,IAAI,MAAM,EAAE;AAE/C,YAAM,OAAO,IAAIS,aAAa,WAAW,YAAY,IAAI,OAAO,GAAG;AACnE,mBAAa,MAAM,GAAG;AACtB,YAAM,KAAK,IAAI;AACH,kBAAA;AAAA,IAChB;AAAA,EAAA,CAEH;AAED,gBAAc,QAAQ,CAAQ,SAAA;AAEM,oCAAA,OAAO,OAAO,IAAI;AAAA,EAAA,CACrD;AAED,QAAM,eAAe,IAAI,WAAW,OAAO,KAAK;AAEnCT,iBAAA,oBAAoB,aAAa,KAAK;AAE5C,SAAA;AACX;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/OsmElement.ts","../src/OsmModel.ts","../src/OsmNode.ts","../src/OsmWay.ts","../src/OsmRelation.ts","../src/OsmParser.ts","../src/graph/OsmGraphNode.ts","../src/graph/OsmGraphEdge.ts","../src/graph/OsmGraphItinerary.ts","../src/graph/OsmNetwork.ts","../src/graph/OsmGraphProjection.ts","../src/graph/OsmGraphRouter.ts","../src/graph/OsmGraphRouterOptions.ts","../src/graph/OsmMapMatching.ts","../src/graph/OsmNetworkUtils.ts"],"sourcesContent":["\nexport type OsmTags = { [key: string]: string };\n\nclass OsmElement {\n\n id: number;\n tags: OsmTags;\n\n constructor(id: number, tags?: OsmTags) {\n this.id = id;\n this.tags = tags || {};\n }\n}\n\nexport default OsmElement;\n","import OsmNode from './OsmNode.js';\nimport OsmRelation from './OsmRelation.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmModel {\n\n nodes: OsmNode[];\n ways: OsmWay[];\n relations: OsmRelation[];\n\n constructor(nodes?: OsmNode[], ways?: OsmWay[], relations?: OsmRelation[]) {\n this.nodes = nodes || [];\n this.ways = ways || [];\n this.relations = relations || [];\n }\n\n getNodeById(id: number) {\n return this.nodes.find(node => node.id === id) || null;\n }\n\n getNodeByName(name: string) {\n return this.nodes.find(node => node.tags.name === name) || null;\n }\n\n getWayById(id: number) {\n return this.ways.find(way => way.id === id) || null;\n }\n\n getWayByName(name: string) {\n return this.ways.find(way => way.tags.name === name) || null;\n }\n\n getRelationById(id: number) {\n return this.relations.find(way => way.id === id) || null;\n }\n\n getRelationByName(name: string) {\n return this.relations.find(way => way.tags.name === name) || null;\n }\n}\n\nexport default OsmModel;\n","import { Coordinates } from '@wemap/geo';\n\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmRelation from './OsmRelation.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmNode extends OsmElement {\n\n coords : Coordinates;\n ways: OsmWay[] = [];\n relations: OsmRelation[] = [];\n\n constructor(id: number, coords: Coordinates, tags?: OsmTags) {\n super(id, tags);\n this.coords = coords;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isConveying() {\n return this.isElevator;\n }\n}\n\nexport default OsmNode;\n","import { Level_t } from '@wemap/geo';\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmNode from './OsmNode.js';\nimport OsmRelation from './OsmRelation.js';\n\nclass OsmWay extends OsmElement {\n\n nodes: OsmNode[] = [];\n relations: OsmRelation[] = [];\n level: Level_t = null;\n\n constructor(id: number, tags?: OsmTags, level: Level_t = null) {\n super(id, tags);\n this.level = level;\n }\n\n get areStairs() {\n return this.tags.highway === 'steps';\n }\n\n get isConveying() {\n return this.tags.hasOwnProperty('conveying');\n }\n\n get isEscalator() {\n return this.areStairs && this.isConveying;\n }\n\n get isMovingWalkway() {\n return !this.areStairs && this.isConveying;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isArea() {\n // That is not the real definition for OSM\n return this.nodes[0] === this.nodes[this.nodes.length - 1];\n }\n}\n\nexport default OsmWay;\n","import OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\nimport type { Position, Polygon } from 'geojson';\n\nexport type OsmRelationMember = {\n ref: OsmRelation | OsmWay | OsmNode,\n role: string\n}\n\nclass OsmRelation extends OsmElement {\n\n relations: OsmRelation[] = [];\n\n constructor(\n id: number,\n public members: OsmRelationMember[] = [],\n tags?: OsmTags\n ) {\n super(id, tags);\n }\n\n isMultipolygon() {\n return this.tags.type === 'multipolygon';\n }\n\n getGeoJsonPolygon(): Polygon | null {\n if (!this.isMultipolygon()) return null;\n const outer = this.members.find(member => member.ref instanceof OsmWay && member.role === 'outer');\n if (!outer) return null;\n const inners = this.members.filter(member => member.ref instanceof OsmWay && member.role === 'inner');\n return {\n type: \"Polygon\",\n coordinates: [outer, ...inners].map(member => {\n const way = member.ref as OsmWay;\n return way.nodes.map(node => [node.coords.lng, node.coords.lat] as Position);\n })\n }\n }\n}\n\nexport default OsmRelation;\n","/* eslint-disable max-statements */\nimport { SaxesParser } from 'saxes';\n\nimport {\n Level, Coordinates\n} from '@wemap/geo';\n\nimport OsmModel from './OsmModel.js';\nimport OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\nimport OsmRelation from './OsmRelation.js';\n\ntype OsmXmlElement = { action?: 'delete' };\ntype OsmXmlNode = { id: string, lat: string, lon: string } & OsmXmlElement;\ntype OsmXmlWay = { id: string } & OsmXmlElement;\ntype OsmXmlRelation = { id: string } & OsmXmlElement;\n\nclass OsmParser {\n\n static parseOsmXmlString(osmXmlString: string) {\n\n const model = new OsmModel();\n const parser = new SaxesParser();\n\n let buffer: OsmNode | OsmWay | OsmRelation | null;\n\n const isDeleted = (element: { attributes: OsmXmlElement }) =>\n element.attributes.action && element.attributes.action === 'delete';\n\n parser.on('opentag', (node) => {\n\n switch (node.name) {\n case 'node': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmNode = this._parseNode(node.attributes as OsmXmlNode);\n buffer = osmNode;\n model.nodes.push(osmNode);\n break;\n }\n case 'way': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmWay = this._parseWay(node.attributes as OsmXmlWay);\n buffer = osmWay;\n model.ways.push(osmWay);\n break;\n }\n case 'relation': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmRelation = this._parseRelation(node.attributes as OsmXmlRelation);\n buffer = osmRelation;\n model.relations.push(osmRelation);\n break;\n }\n case 'tag': {\n if (!buffer) {\n return;\n }\n const {\n k, v\n } = node.attributes;\n buffer.tags[k] = v;\n break;\n }\n case 'nd': {\n if (!buffer || !(buffer instanceof OsmWay)) {\n return;\n }\n const nodeId = Number(node.attributes.ref);\n const refNode = model.getNodeById(nodeId);\n if (!refNode) {\n throw Error('Node: ' + nodeId + ' in way ' + buffer.id + ' not found');\n }\n\n buffer.nodes.push(refNode);\n refNode.ways.push(buffer);\n break;\n }\n case 'member': {\n if (!buffer || !(buffer instanceof OsmRelation)) {\n return;\n }\n const memberId = Number(node.attributes.ref);\n const memberType = node.attributes.type;\n let refElement: OsmNode | OsmWay | OsmRelation | null = null;\n memberType === 'node' && (refElement = model.getNodeById(memberId));\n memberType === 'way' && (refElement = model.getWayById(memberId));\n memberType === 'relation' && (refElement = model.getRelationById(memberId));\n\n if (!refElement) {\n throw Error('Member: ' + memberId + ' in relation ' + buffer.id + ' not found');\n }\n\n buffer.members.push({ ref: refElement, role: node.attributes.role });\n refElement.relations.push(buffer);\n break;\n }\n }\n });\n\n parser.write(osmXmlString);\n\n for (let i = 0; i < model.ways.length; i++) {\n const way = model.ways[i];\n if (way.tags.level) {\n way.level = Level.fromString(way.tags.level);\n }\n }\n\n return model;\n }\n\n\n static _parseNode(attr: OsmXmlNode) {\n return new OsmNode(\n Number(attr.id),\n new Coordinates(Number(attr.lat), Number(attr.lon)));\n }\n\n static _parseWay(attr: { id: string }) {\n return new OsmWay(Number(attr.id));\n }\n\n static _parseRelation(attr: { id: string }) {\n return new OsmRelation(Number(attr.id));\n }\n}\n\nexport default OsmParser;\n","import { GraphNode } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphNode extends GraphNode<OsmNode, OsmNode | OsmWay>{ }","import { GraphEdge } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphEdge extends GraphEdge<OsmNode | OsmWay, OsmNode>{ }","import { Coordinates, GraphItinerary, GraphNode } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphItinerary extends GraphItinerary<N, E>{ \n\n static fromNetworkNodes<A = N, B = E>(\n start: Coordinates, end: Coordinates,\n networkNodes: GraphNode<A, B>[], edgesWeights: number[]\n ) {\n return super.fromNetworkNodes(start, end, networkNodes, edgesWeights) as GraphItinerary<A, B>;\n }\n}\n","import { Coordinates, Network } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmNetwork extends Network<N, E>{\n static fromCoordinates<A = N, B = E>(segments: Coordinates[][]) {\n return super.fromCoordinates<N, E>(segments) as Network<A, B>;\n }\n}","import { GraphProjection } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphProjection extends GraphProjection<N, E>{ }\n","import { GraphRouter } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouter extends GraphRouter<N, E>{ }\n","import { GraphRouterOptions } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouterOptions extends GraphRouterOptions<N, E>{ }\n","import { MapMatching } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmMapMatching extends MapMatching<N, E>{ }\n","import { Level } from '@wemap/geo';\nimport OsmGraphNode from './OsmGraphNode';\nimport OsmGraphEdge from './OsmGraphEdge';\nimport OsmModel from '../OsmModel';\nimport OsmNode from '../OsmNode';\nimport OsmWay from '../OsmWay';\nimport OsmNetwork from './OsmNetwork';\n\nexport type N = OsmNode;\nexport type E = OsmNode | OsmWay;\n\nexport const HIGHWAYS_PEDESTRIANS = ['footway', 'steps', 'pedestrian', 'living_street', 'path', 'track', 'sidewalk', 'elevator'];\n\nexport const DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway)\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n};\n\nexport function getNodeByName(network: OsmNetwork, name: string) {\n return network.nodes.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nexport function getEdgeByName(network: OsmNetwork, name: string) {\n return network.edges.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nfunction manageOneWay(edge: OsmGraphEdge, way: OsmWay) {\n\n const { highway, oneway, conveying } = way.tags;\n\n edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n || (conveying && highway && ['forward', 'backward'].includes(conveying)));\n\n if (edge.isOneway && conveying === 'backward') {\n const tmpNode = edge.node1;\n edge.node1 = edge.node2;\n edge.node2 = tmpNode;\n }\n}\n\n\nfunction createNodesAndEdgesFromElevator(\n nodes: OsmGraphNode[],\n edges: OsmGraphEdge[],\n elevatorNode: OsmGraphNode\n) {\n\n const createdNodes: OsmGraphNode[] = [];\n const getOrCreateLevelNode = (level: number | null, builtFrom: N | null) => {\n let levelNode = createdNodes.find(({ coords }) => Level.equals(level, coords.level));\n if (!levelNode) {\n levelNode = new OsmGraphNode(elevatorNode.coords.clone(), builtFrom);\n levelNode.coords.level = level;\n createdNodes.push(levelNode);\n nodes.push(levelNode);\n }\n return levelNode;\n };\n\n // Create nodes from node.edges\n elevatorNode.edges.forEach(edge => {\n if (Level.isRange(edge.level)) {\n throw new Error('Cannot handle this elevator edge due to ambiguity');\n }\n\n const levelNode = getOrCreateLevelNode(edge.level, elevatorNode.builtFrom);\n if (edge.node1 === elevatorNode) {\n edge.node1 = levelNode;\n } else {\n edge.node2 = levelNode;\n }\n levelNode.edges.push(edge);\n });\n\n // Create edges from createdNodes\n for (let i = 0; i < createdNodes.length; i++) {\n for (let j = i + 1; j < createdNodes.length; j++) {\n\n const createdNode1 = createdNodes[i];\n const createdNode2 = createdNodes[j];\n\n if (createdNode1.coords.level === null || createdNode2.coords.level === null) {\n // TODO: not the best approach... but cannot do better with [number, number] range for levels\n continue;\n }\n\n const minLevel = Math.min(createdNode1.coords.level as number, createdNode2.coords.level as number);\n const maxLevel = Math.max(createdNode1.coords.level as number, createdNode2.coords.level as number);\n\n const newEdge = new OsmGraphEdge(\n createdNode1,\n createdNode2,\n [minLevel, maxLevel],\n elevatorNode.builtFrom\n );\n edges.push(newEdge);\n }\n }\n\n // Remove the historical elevator node from the network\n const elevatorNodeIndex = nodes.indexOf(elevatorNode);\n if (elevatorNodeIndex > -1) {\n nodes.splice(elevatorNodeIndex, 1);\n }\n}\n\nexport function createNetworkFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = DEFAULT_WAY_SELECTOR\n) {\n\n const nodes: OsmGraphNode[] = [];\n const edges: OsmGraphEdge[] = [];\n\n const nodesCreated: { [key: number]: OsmGraphNode } = {};\n const elevatorNodes: OsmGraphNode[] = [];\n\n const getOrCreateNode = (osmNode: OsmNode) => {\n let node = nodesCreated[osmNode.id];\n if (!node) {\n node = new OsmGraphNode(osmNode.coords, osmNode);\n nodesCreated[osmNode.id] = node;\n nodes.push(node);\n\n if (osmNode.tags.highway === 'elevator') {\n elevatorNodes.push(node);\n }\n }\n return node;\n };\n\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n let firstNode = getOrCreateNode(way.nodes[0]);\n for (let i = 1; i < way.nodes.length; i++) {\n const secondNode = getOrCreateNode(way.nodes[i]);\n\n const edge = new OsmGraphEdge(firstNode, secondNode, way.level, way);\n manageOneWay(edge, way);\n edges.push(edge);\n firstNode = secondNode;\n }\n\n });\n\n elevatorNodes.forEach(node => {\n // We have to clone this node for each connected edge\n createNodesAndEdgesFromElevator(nodes, edges, node);\n });\n\n const networkModel = new OsmNetwork(nodes, edges);\n\n OsmGraphNode.generateNodesLevels(networkModel.nodes);\n\n return networkModel;\n}\n\n\n// /**\n// * @param {GraphNode} node\n// * @param {object} tags\n// */\n// static _applyNodePropertiesFromTags(node, tags) {\n// node.name = tags.name || null;\n// node.subwayEntrance = tags.railway === 'subway_entrance';\n// if (node.subwayEntrance && tags.ref) {\n// node.subwayEntranceRef = tags.ref;\n// }\n// }\n\n// /**\n// * @param {GraphEdge} edge\n// * @param {object} tags\n// */\n// static _applyEdgePropertiesFromTags(edge, tags) {\n// const { highway, oneway, conveying, name } = tags;\n// edge.name = name || null;\n// edge.isStairs = highway === 'steps';\n// edge.isConveying = 'conveying' in tags;\n// edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n// || (conveying && highway && ['yes', 'forward', 'backward'].includes(conveying)));\n\n// if (conveying === 'backward') {\n// const tmpNode = edge.node1;\n// edge.node1 = edge.node2;\n// edge.node2 = tmpNode;\n// }\n\n// }\n"],"names":["SaxesParser","Level","Coordinates","GraphNode","GraphEdge","GraphItinerary","Network","GraphProjection","GraphRouter","GraphRouterOptions","MapMatching"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -15,11 +15,13 @@ class OsmElement {
15
15
  }
16
16
  }
17
17
  class OsmModel {
18
- constructor(nodes, ways) {
18
+ constructor(nodes, ways, relations) {
19
19
  __publicField(this, "nodes");
20
20
  __publicField(this, "ways");
21
+ __publicField(this, "relations");
21
22
  this.nodes = nodes || [];
22
23
  this.ways = ways || [];
24
+ this.relations = relations || [];
23
25
  }
24
26
  getNodeById(id) {
25
27
  return this.nodes.find((node) => node.id === id) || null;
@@ -33,12 +35,19 @@ class OsmModel {
33
35
  getWayByName(name) {
34
36
  return this.ways.find((way) => way.tags.name === name) || null;
35
37
  }
38
+ getRelationById(id) {
39
+ return this.relations.find((way) => way.id === id) || null;
40
+ }
41
+ getRelationByName(name) {
42
+ return this.relations.find((way) => way.tags.name === name) || null;
43
+ }
36
44
  }
37
45
  class OsmNode extends OsmElement {
38
46
  constructor(id, coords, tags) {
39
47
  super(id, tags);
40
48
  __publicField(this, "coords");
41
49
  __publicField(this, "ways", []);
50
+ __publicField(this, "relations", []);
42
51
  this.coords = coords;
43
52
  }
44
53
  get isElevator() {
@@ -52,6 +61,7 @@ class OsmWay extends OsmElement {
52
61
  constructor(id, tags, level = null) {
53
62
  super(id, tags);
54
63
  __publicField(this, "nodes", []);
64
+ __publicField(this, "relations", []);
55
65
  __publicField(this, "level", null);
56
66
  this.level = level;
57
67
  }
@@ -74,6 +84,31 @@ class OsmWay extends OsmElement {
74
84
  return this.nodes[0] === this.nodes[this.nodes.length - 1];
75
85
  }
76
86
  }
87
+ class OsmRelation extends OsmElement {
88
+ constructor(id, members = [], tags) {
89
+ super(id, tags);
90
+ __publicField(this, "relations", []);
91
+ this.members = members;
92
+ }
93
+ isMultipolygon() {
94
+ return this.tags.type === "multipolygon";
95
+ }
96
+ getGeoJsonPolygon() {
97
+ if (!this.isMultipolygon())
98
+ return null;
99
+ const outer = this.members.find((member) => member.ref instanceof OsmWay && member.role === "outer");
100
+ if (!outer)
101
+ return null;
102
+ const inners = this.members.filter((member) => member.ref instanceof OsmWay && member.role === "inner");
103
+ return {
104
+ type: "Polygon",
105
+ coordinates: [outer, ...inners].map((member) => {
106
+ const way = member.ref;
107
+ return way.nodes.map((node) => [node.coords.lng, node.coords.lat]);
108
+ })
109
+ };
110
+ }
111
+ }
77
112
  class OsmParser {
78
113
  static parseOsmXmlString(osmXmlString) {
79
114
  const model = new OsmModel();
@@ -102,6 +137,16 @@ class OsmParser {
102
137
  model.ways.push(osmWay);
103
138
  break;
104
139
  }
140
+ case "relation": {
141
+ if (isDeleted(node)) {
142
+ buffer = null;
143
+ break;
144
+ }
145
+ const osmRelation = this._parseRelation(node.attributes);
146
+ buffer = osmRelation;
147
+ model.relations.push(osmRelation);
148
+ break;
149
+ }
105
150
  case "tag": {
106
151
  if (!buffer) {
107
152
  return;
@@ -126,6 +171,23 @@ class OsmParser {
126
171
  refNode.ways.push(buffer);
127
172
  break;
128
173
  }
174
+ case "member": {
175
+ if (!buffer || !(buffer instanceof OsmRelation)) {
176
+ return;
177
+ }
178
+ const memberId = Number(node.attributes.ref);
179
+ const memberType = node.attributes.type;
180
+ let refElement = null;
181
+ memberType === "node" && (refElement = model.getNodeById(memberId));
182
+ memberType === "way" && (refElement = model.getWayById(memberId));
183
+ memberType === "relation" && (refElement = model.getRelationById(memberId));
184
+ if (!refElement) {
185
+ throw Error("Member: " + memberId + " in relation " + buffer.id + " not found");
186
+ }
187
+ buffer.members.push({ ref: refElement, role: node.attributes.role });
188
+ refElement.relations.push(buffer);
189
+ break;
190
+ }
129
191
  }
130
192
  });
131
193
  parser.write(osmXmlString);
@@ -146,10 +208,13 @@ class OsmParser {
146
208
  static _parseWay(attr) {
147
209
  return new OsmWay(Number(attr.id));
148
210
  }
211
+ static _parseRelation(attr) {
212
+ return new OsmRelation(Number(attr.id));
213
+ }
149
214
  }
150
- class OsmGraphNode$1 extends GraphNode {
215
+ class OsmGraphNode extends GraphNode {
151
216
  }
152
- class OsmGraphNode extends GraphEdge {
217
+ class OsmGraphEdge extends GraphEdge {
153
218
  }
154
219
  class OsmGraphItinerary extends GraphItinerary {
155
220
  static fromNetworkNodes(start, end, networkNodes, edgesWeights) {
@@ -193,7 +258,7 @@ function createNodesAndEdgesFromElevator(nodes, edges, elevatorNode) {
193
258
  const getOrCreateLevelNode = (level, builtFrom) => {
194
259
  let levelNode = createdNodes.find(({ coords }) => Level.equals(level, coords.level));
195
260
  if (!levelNode) {
196
- levelNode = new OsmGraphNode$1(elevatorNode.coords.clone(), builtFrom);
261
+ levelNode = new OsmGraphNode(elevatorNode.coords.clone(), builtFrom);
197
262
  levelNode.coords.level = level;
198
263
  createdNodes.push(levelNode);
199
264
  nodes.push(levelNode);
@@ -221,7 +286,7 @@ function createNodesAndEdgesFromElevator(nodes, edges, elevatorNode) {
221
286
  }
222
287
  const minLevel = Math.min(createdNode1.coords.level, createdNode2.coords.level);
223
288
  const maxLevel = Math.max(createdNode1.coords.level, createdNode2.coords.level);
224
- const newEdge = new OsmGraphNode(
289
+ const newEdge = new OsmGraphEdge(
225
290
  createdNode1,
226
291
  createdNode2,
227
292
  [minLevel, maxLevel],
@@ -243,7 +308,7 @@ function createNetworkFromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SE
243
308
  const getOrCreateNode = (osmNode) => {
244
309
  let node = nodesCreated[osmNode.id];
245
310
  if (!node) {
246
- node = new OsmGraphNode$1(osmNode.coords, osmNode);
311
+ node = new OsmGraphNode(osmNode.coords, osmNode);
247
312
  nodesCreated[osmNode.id] = node;
248
313
  nodes.push(node);
249
314
  if (osmNode.tags.highway === "elevator") {
@@ -259,7 +324,7 @@ function createNetworkFromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SE
259
324
  let firstNode = getOrCreateNode(way.nodes[0]);
260
325
  for (let i = 1; i < way.nodes.length; i++) {
261
326
  const secondNode = getOrCreateNode(way.nodes[i]);
262
- const edge = new OsmGraphNode(firstNode, secondNode, way.level, way);
327
+ const edge = new OsmGraphEdge(firstNode, secondNode, way.level, way);
263
328
  manageOneWay(edge, way);
264
329
  edges.push(edge);
265
330
  firstNode = secondNode;
@@ -269,7 +334,7 @@ function createNetworkFromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SE
269
334
  createNodesAndEdgesFromElevator(nodes, edges, node);
270
335
  });
271
336
  const networkModel = new OsmNetwork(nodes, edges);
272
- OsmGraphNode$1.generateNodesLevels(networkModel.nodes);
337
+ OsmGraphNode.generateNodesLevels(networkModel.nodes);
273
338
  return networkModel;
274
339
  }
275
340
  const OsmNetworkUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -282,9 +347,9 @@ const OsmNetworkUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
282
347
  }, Symbol.toStringTag, { value: "Module" }));
283
348
  export {
284
349
  OsmElement,
285
- OsmGraphNode as OsmGraphEdge,
350
+ OsmGraphEdge,
286
351
  OsmGraphItinerary,
287
- OsmGraphNode$1 as OsmGraphNode,
352
+ OsmGraphNode,
288
353
  OsmGraphProjection,
289
354
  OsmGraphRouter,
290
355
  OsmGraphRouterOptions,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/OsmElement.ts","../src/OsmModel.ts","../src/OsmNode.ts","../src/OsmWay.ts","../src/OsmParser.ts","../src/graph/OsmGraphNode.ts","../src/graph/OsmGraphEdge.ts","../src/graph/OsmGraphItinerary.ts","../src/graph/OsmNetwork.ts","../src/graph/OsmGraphProjection.ts","../src/graph/OsmGraphRouter.ts","../src/graph/OsmGraphRouterOptions.ts","../src/graph/OsmMapMatching.ts","../src/graph/OsmNetworkUtils.ts"],"sourcesContent":["\nexport type OsmTags = { [key: string]: string };\n\nclass OsmElement {\n\n id: number;\n tags: OsmTags;\n\n constructor(id: number, tags?: OsmTags) {\n this.id = id;\n this.tags = tags || {};\n }\n}\n\nexport default OsmElement;\n","import OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmModel {\n\n nodes: OsmNode[];\n ways: OsmWay[];\n\n constructor(nodes?: OsmNode[], ways?: OsmWay[]) {\n this.nodes = nodes || [];\n this.ways = ways || [];\n }\n\n getNodeById(id: number) {\n return this.nodes.find(node => node.id === id) || null;\n }\n\n getNodeByName(name: string) {\n return this.nodes.find(node => node.tags.name === name) || null;\n }\n\n getWayById(id: number) {\n return this.ways.find(way => way.id === id) || null;\n }\n\n getWayByName(name: string) {\n return this.ways.find(way => way.tags.name === name) || null;\n }\n\n}\n\nexport default OsmModel;\n","import { Coordinates } from '@wemap/geo';\n\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmNode extends OsmElement {\n\n coords : Coordinates;\n ways: OsmWay[] = [];\n\n\n constructor(id: number, coords: Coordinates, tags?: OsmTags) {\n super(id, tags);\n this.coords = coords;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isConveying() {\n return this.isElevator;\n }\n}\n\nexport default OsmNode;\n","import { Level_t } from '@wemap/geo';\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmNode from './OsmNode.js';\n\nclass OsmWay extends OsmElement {\n\n nodes: OsmNode[] = [];\n level: Level_t = null;\n\n constructor(id: number, tags?: OsmTags, level: Level_t = null) {\n super(id, tags);\n this.level = level;\n }\n\n get areStairs() {\n return this.tags.highway === 'steps';\n }\n\n get isConveying() {\n return this.tags.hasOwnProperty('conveying');\n }\n\n get isEscalator() {\n return this.areStairs && this.isConveying;\n }\n\n get isMovingWalkway() {\n return !this.areStairs && this.isConveying;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isArea() {\n // That is not the real definition for OSM\n return this.nodes[0] === this.nodes[this.nodes.length - 1];\n }\n}\n\nexport default OsmWay;\n","/* eslint-disable max-statements */\nimport { SaxesParser } from 'saxes';\n\nimport {\n Level, Coordinates\n} from '@wemap/geo';\n\nimport OsmModel from './OsmModel.js';\nimport OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\n\ntype OsmXmlElement = { action?: 'delete' };\ntype OsmXmlNode = { id: string, lat: string, lon: string } & OsmXmlElement;\ntype OsmXmlWay = { id: string } & OsmXmlElement;\n\nclass OsmParser {\n\n static parseOsmXmlString(osmXmlString: string) {\n\n const model = new OsmModel();\n const parser = new SaxesParser();\n\n let buffer: OsmNode | OsmWay | null;\n\n const isDeleted = (element: { attributes: OsmXmlElement }) =>\n element.attributes.action && element.attributes.action === 'delete';\n\n parser.on('opentag', (node) => {\n\n switch (node.name) {\n case 'node': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmNode = this._parseNode(node.attributes as OsmXmlNode);\n buffer = osmNode;\n model.nodes.push(osmNode);\n break;\n }\n case 'way': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmWay = this._parseWay(node.attributes as OsmXmlWay);\n buffer = osmWay;\n model.ways.push(osmWay);\n break;\n }\n case 'tag': {\n if (!buffer) {\n return;\n }\n const {\n k, v\n } = node.attributes;\n buffer.tags[k] = v;\n break;\n }\n case 'nd': {\n if (!buffer || !(buffer instanceof OsmWay)) {\n return;\n }\n const nodeId = Number(node.attributes.ref);\n const refNode = model.getNodeById(nodeId);\n if (!refNode) {\n throw Error('Node: ' + nodeId + ' in way ' + buffer.id + ' not found');\n }\n\n buffer.nodes.push(refNode);\n refNode.ways.push(buffer);\n break;\n }\n }\n });\n\n parser.write(osmXmlString);\n\n for (let i = 0; i < model.ways.length; i++) {\n const way = model.ways[i];\n if (way.tags.level) {\n way.level = Level.fromString(way.tags.level);\n }\n }\n\n return model;\n }\n\n\n static _parseNode(attr: OsmXmlNode) {\n return new OsmNode(\n Number(attr.id),\n new Coordinates(Number(attr.lat), Number(attr.lon)));\n }\n\n static _parseWay(attr: { id: string }) {\n return new OsmWay(Number(attr.id));\n }\n}\n\nexport default OsmParser;\n","import { GraphNode } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphNode extends GraphNode<OsmNode, OsmNode | OsmWay>{ }","import { GraphEdge } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphNode extends GraphEdge<OsmNode | OsmWay, OsmNode>{ }","import { Coordinates, GraphItinerary, GraphNode } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphItinerary extends GraphItinerary<N, E>{ \n\n static fromNetworkNodes<A = N, B = E>(\n start: Coordinates, end: Coordinates,\n networkNodes: GraphNode<A, B>[], edgesWeights: number[]\n ) {\n return super.fromNetworkNodes(start, end, networkNodes, edgesWeights) as GraphItinerary<A, B>;\n }\n}\n","import { Coordinates, Network } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmNetwork extends Network<N, E>{\n static fromCoordinates<A = N, B = E>(segments: Coordinates[][]) {\n return super.fromCoordinates<N, E>(segments) as Network<A, B>;\n }\n}","import { GraphProjection } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphProjection extends GraphProjection<N, E>{ }\n","import { GraphRouter } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouter extends GraphRouter<N, E>{ }\n","import { GraphRouterOptions } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouterOptions extends GraphRouterOptions<N, E>{ }\n","import { MapMatching } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmMapMatching extends MapMatching<N, E>{ }\n","import { Level } from '@wemap/geo';\nimport OsmGraphNode from './OsmGraphNode';\nimport OsmGraphEdge from './OsmGraphEdge';\nimport OsmModel from '../OsmModel';\nimport OsmNode from '../OsmNode';\nimport OsmWay from '../OsmWay';\nimport OsmNetwork from './OsmNetwork';\n\nexport type N = OsmNode;\nexport type E = OsmNode | OsmWay;\n\nexport const HIGHWAYS_PEDESTRIANS = ['footway', 'steps', 'pedestrian', 'living_street', 'path', 'track', 'sidewalk', 'elevator'];\n\nexport const DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway)\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n};\n\nexport function getNodeByName(network: OsmNetwork, name: string) {\n return network.nodes.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nexport function getEdgeByName(network: OsmNetwork, name: string) {\n return network.edges.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nfunction manageOneWay(edge: OsmGraphEdge, way: OsmWay) {\n\n const { highway, oneway, conveying } = way.tags;\n\n edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n || (conveying && highway && ['forward', 'backward'].includes(conveying)));\n\n if (edge.isOneway && conveying === 'backward') {\n const tmpNode = edge.node1;\n edge.node1 = edge.node2;\n edge.node2 = tmpNode;\n }\n}\n\n\nfunction createNodesAndEdgesFromElevator(\n nodes: OsmGraphNode[],\n edges: OsmGraphEdge[],\n elevatorNode: OsmGraphNode\n) {\n\n const createdNodes: OsmGraphNode[] = [];\n const getOrCreateLevelNode = (level: number | null, builtFrom: N | null) => {\n let levelNode = createdNodes.find(({ coords }) => Level.equals(level, coords.level));\n if (!levelNode) {\n levelNode = new OsmGraphNode(elevatorNode.coords.clone(), builtFrom);\n levelNode.coords.level = level;\n createdNodes.push(levelNode);\n nodes.push(levelNode);\n }\n return levelNode;\n };\n\n // Create nodes from node.edges\n elevatorNode.edges.forEach(edge => {\n if (Level.isRange(edge.level)) {\n throw new Error('Cannot handle this elevator edge due to ambiguity');\n }\n\n const levelNode = getOrCreateLevelNode(edge.level, elevatorNode.builtFrom);\n if (edge.node1 === elevatorNode) {\n edge.node1 = levelNode;\n } else {\n edge.node2 = levelNode;\n }\n levelNode.edges.push(edge);\n });\n\n // Create edges from createdNodes\n for (let i = 0; i < createdNodes.length; i++) {\n for (let j = i + 1; j < createdNodes.length; j++) {\n\n const createdNode1 = createdNodes[i];\n const createdNode2 = createdNodes[j];\n\n if (createdNode1.coords.level === null || createdNode2.coords.level === null) {\n // TODO: not the best approach... but cannot do better with [number, number] range for levels\n continue;\n }\n\n const minLevel = Math.min(createdNode1.coords.level as number, createdNode2.coords.level as number);\n const maxLevel = Math.max(createdNode1.coords.level as number, createdNode2.coords.level as number);\n\n const newEdge = new OsmGraphEdge(\n createdNode1,\n createdNode2,\n [minLevel, maxLevel],\n elevatorNode.builtFrom\n );\n edges.push(newEdge);\n }\n }\n\n // Remove the historical elevator node from the network\n const elevatorNodeIndex = nodes.indexOf(elevatorNode);\n if (elevatorNodeIndex > -1) {\n nodes.splice(elevatorNodeIndex, 1);\n }\n}\n\nexport function createNetworkFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = DEFAULT_WAY_SELECTOR\n) {\n\n const nodes: OsmGraphNode[] = [];\n const edges: OsmGraphEdge[] = [];\n\n const nodesCreated: { [key: number]: OsmGraphNode } = {};\n const elevatorNodes: OsmGraphNode[] = [];\n\n const getOrCreateNode = (osmNode: OsmNode) => {\n let node = nodesCreated[osmNode.id];\n if (!node) {\n node = new OsmGraphNode(osmNode.coords, osmNode);\n nodesCreated[osmNode.id] = node;\n nodes.push(node);\n\n if (osmNode.tags.highway === 'elevator') {\n elevatorNodes.push(node);\n }\n }\n return node;\n };\n\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n let firstNode = getOrCreateNode(way.nodes[0]);\n for (let i = 1; i < way.nodes.length; i++) {\n const secondNode = getOrCreateNode(way.nodes[i]);\n\n const edge = new OsmGraphEdge(firstNode, secondNode, way.level, way);\n manageOneWay(edge, way);\n edges.push(edge);\n firstNode = secondNode;\n }\n\n });\n\n elevatorNodes.forEach(node => {\n // We have to clone this node for each connected edge\n createNodesAndEdgesFromElevator(nodes, edges, node);\n });\n\n const networkModel = new OsmNetwork(nodes, edges);\n\n OsmGraphNode.generateNodesLevels(networkModel.nodes);\n\n return networkModel;\n}\n\n\n// /**\n// * @param {GraphNode} node\n// * @param {object} tags\n// */\n// static _applyNodePropertiesFromTags(node, tags) {\n// node.name = tags.name || null;\n// node.subwayEntrance = tags.railway === 'subway_entrance';\n// if (node.subwayEntrance && tags.ref) {\n// node.subwayEntranceRef = tags.ref;\n// }\n// }\n\n// /**\n// * @param {GraphEdge} edge\n// * @param {object} tags\n// */\n// static _applyEdgePropertiesFromTags(edge, tags) {\n// const { highway, oneway, conveying, name } = tags;\n// edge.name = name || null;\n// edge.isStairs = highway === 'steps';\n// edge.isConveying = 'conveying' in tags;\n// edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n// || (conveying && highway && ['yes', 'forward', 'backward'].includes(conveying)));\n\n// if (conveying === 'backward') {\n// const tmpNode = edge.node1;\n// edge.node1 = edge.node2;\n// edge.node2 = tmpNode;\n// }\n\n// }\n"],"names":["OsmGraphNode","OsmGraphEdge"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/OsmElement.ts","../src/OsmModel.ts","../src/OsmNode.ts","../src/OsmWay.ts","../src/OsmRelation.ts","../src/OsmParser.ts","../src/graph/OsmGraphNode.ts","../src/graph/OsmGraphEdge.ts","../src/graph/OsmGraphItinerary.ts","../src/graph/OsmNetwork.ts","../src/graph/OsmGraphProjection.ts","../src/graph/OsmGraphRouter.ts","../src/graph/OsmGraphRouterOptions.ts","../src/graph/OsmMapMatching.ts","../src/graph/OsmNetworkUtils.ts"],"sourcesContent":["\nexport type OsmTags = { [key: string]: string };\n\nclass OsmElement {\n\n id: number;\n tags: OsmTags;\n\n constructor(id: number, tags?: OsmTags) {\n this.id = id;\n this.tags = tags || {};\n }\n}\n\nexport default OsmElement;\n","import OsmNode from './OsmNode.js';\nimport OsmRelation from './OsmRelation.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmModel {\n\n nodes: OsmNode[];\n ways: OsmWay[];\n relations: OsmRelation[];\n\n constructor(nodes?: OsmNode[], ways?: OsmWay[], relations?: OsmRelation[]) {\n this.nodes = nodes || [];\n this.ways = ways || [];\n this.relations = relations || [];\n }\n\n getNodeById(id: number) {\n return this.nodes.find(node => node.id === id) || null;\n }\n\n getNodeByName(name: string) {\n return this.nodes.find(node => node.tags.name === name) || null;\n }\n\n getWayById(id: number) {\n return this.ways.find(way => way.id === id) || null;\n }\n\n getWayByName(name: string) {\n return this.ways.find(way => way.tags.name === name) || null;\n }\n\n getRelationById(id: number) {\n return this.relations.find(way => way.id === id) || null;\n }\n\n getRelationByName(name: string) {\n return this.relations.find(way => way.tags.name === name) || null;\n }\n}\n\nexport default OsmModel;\n","import { Coordinates } from '@wemap/geo';\n\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmRelation from './OsmRelation.js';\nimport OsmWay from './OsmWay.js';\n\nclass OsmNode extends OsmElement {\n\n coords : Coordinates;\n ways: OsmWay[] = [];\n relations: OsmRelation[] = [];\n\n constructor(id: number, coords: Coordinates, tags?: OsmTags) {\n super(id, tags);\n this.coords = coords;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isConveying() {\n return this.isElevator;\n }\n}\n\nexport default OsmNode;\n","import { Level_t } from '@wemap/geo';\nimport OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmNode from './OsmNode.js';\nimport OsmRelation from './OsmRelation.js';\n\nclass OsmWay extends OsmElement {\n\n nodes: OsmNode[] = [];\n relations: OsmRelation[] = [];\n level: Level_t = null;\n\n constructor(id: number, tags?: OsmTags, level: Level_t = null) {\n super(id, tags);\n this.level = level;\n }\n\n get areStairs() {\n return this.tags.highway === 'steps';\n }\n\n get isConveying() {\n return this.tags.hasOwnProperty('conveying');\n }\n\n get isEscalator() {\n return this.areStairs && this.isConveying;\n }\n\n get isMovingWalkway() {\n return !this.areStairs && this.isConveying;\n }\n\n get isElevator() {\n return this.tags.highway === 'elevator';\n }\n\n get isArea() {\n // That is not the real definition for OSM\n return this.nodes[0] === this.nodes[this.nodes.length - 1];\n }\n}\n\nexport default OsmWay;\n","import OsmElement, { OsmTags } from './OsmElement.js';\nimport OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\nimport type { Position, Polygon } from 'geojson';\n\nexport type OsmRelationMember = {\n ref: OsmRelation | OsmWay | OsmNode,\n role: string\n}\n\nclass OsmRelation extends OsmElement {\n\n relations: OsmRelation[] = [];\n\n constructor(\n id: number,\n public members: OsmRelationMember[] = [],\n tags?: OsmTags\n ) {\n super(id, tags);\n }\n\n isMultipolygon() {\n return this.tags.type === 'multipolygon';\n }\n\n getGeoJsonPolygon(): Polygon | null {\n if (!this.isMultipolygon()) return null;\n const outer = this.members.find(member => member.ref instanceof OsmWay && member.role === 'outer');\n if (!outer) return null;\n const inners = this.members.filter(member => member.ref instanceof OsmWay && member.role === 'inner');\n return {\n type: \"Polygon\",\n coordinates: [outer, ...inners].map(member => {\n const way = member.ref as OsmWay;\n return way.nodes.map(node => [node.coords.lng, node.coords.lat] as Position);\n })\n }\n }\n}\n\nexport default OsmRelation;\n","/* eslint-disable max-statements */\nimport { SaxesParser } from 'saxes';\n\nimport {\n Level, Coordinates\n} from '@wemap/geo';\n\nimport OsmModel from './OsmModel.js';\nimport OsmNode from './OsmNode.js';\nimport OsmWay from './OsmWay.js';\nimport OsmRelation from './OsmRelation.js';\n\ntype OsmXmlElement = { action?: 'delete' };\ntype OsmXmlNode = { id: string, lat: string, lon: string } & OsmXmlElement;\ntype OsmXmlWay = { id: string } & OsmXmlElement;\ntype OsmXmlRelation = { id: string } & OsmXmlElement;\n\nclass OsmParser {\n\n static parseOsmXmlString(osmXmlString: string) {\n\n const model = new OsmModel();\n const parser = new SaxesParser();\n\n let buffer: OsmNode | OsmWay | OsmRelation | null;\n\n const isDeleted = (element: { attributes: OsmXmlElement }) =>\n element.attributes.action && element.attributes.action === 'delete';\n\n parser.on('opentag', (node) => {\n\n switch (node.name) {\n case 'node': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmNode = this._parseNode(node.attributes as OsmXmlNode);\n buffer = osmNode;\n model.nodes.push(osmNode);\n break;\n }\n case 'way': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmWay = this._parseWay(node.attributes as OsmXmlWay);\n buffer = osmWay;\n model.ways.push(osmWay);\n break;\n }\n case 'relation': {\n if (isDeleted(node)) {\n buffer = null;\n break;\n }\n const osmRelation = this._parseRelation(node.attributes as OsmXmlRelation);\n buffer = osmRelation;\n model.relations.push(osmRelation);\n break;\n }\n case 'tag': {\n if (!buffer) {\n return;\n }\n const {\n k, v\n } = node.attributes;\n buffer.tags[k] = v;\n break;\n }\n case 'nd': {\n if (!buffer || !(buffer instanceof OsmWay)) {\n return;\n }\n const nodeId = Number(node.attributes.ref);\n const refNode = model.getNodeById(nodeId);\n if (!refNode) {\n throw Error('Node: ' + nodeId + ' in way ' + buffer.id + ' not found');\n }\n\n buffer.nodes.push(refNode);\n refNode.ways.push(buffer);\n break;\n }\n case 'member': {\n if (!buffer || !(buffer instanceof OsmRelation)) {\n return;\n }\n const memberId = Number(node.attributes.ref);\n const memberType = node.attributes.type;\n let refElement: OsmNode | OsmWay | OsmRelation | null = null;\n memberType === 'node' && (refElement = model.getNodeById(memberId));\n memberType === 'way' && (refElement = model.getWayById(memberId));\n memberType === 'relation' && (refElement = model.getRelationById(memberId));\n\n if (!refElement) {\n throw Error('Member: ' + memberId + ' in relation ' + buffer.id + ' not found');\n }\n\n buffer.members.push({ ref: refElement, role: node.attributes.role });\n refElement.relations.push(buffer);\n break;\n }\n }\n });\n\n parser.write(osmXmlString);\n\n for (let i = 0; i < model.ways.length; i++) {\n const way = model.ways[i];\n if (way.tags.level) {\n way.level = Level.fromString(way.tags.level);\n }\n }\n\n return model;\n }\n\n\n static _parseNode(attr: OsmXmlNode) {\n return new OsmNode(\n Number(attr.id),\n new Coordinates(Number(attr.lat), Number(attr.lon)));\n }\n\n static _parseWay(attr: { id: string }) {\n return new OsmWay(Number(attr.id));\n }\n\n static _parseRelation(attr: { id: string }) {\n return new OsmRelation(Number(attr.id));\n }\n}\n\nexport default OsmParser;\n","import { GraphNode } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphNode extends GraphNode<OsmNode, OsmNode | OsmWay>{ }","import { GraphEdge } from \"@wemap/geo\";\nimport OsmNode from \"../OsmNode\";\nimport OsmWay from \"../OsmWay\";\n\nexport default class OsmGraphEdge extends GraphEdge<OsmNode | OsmWay, OsmNode>{ }","import { Coordinates, GraphItinerary, GraphNode } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphItinerary extends GraphItinerary<N, E>{ \n\n static fromNetworkNodes<A = N, B = E>(\n start: Coordinates, end: Coordinates,\n networkNodes: GraphNode<A, B>[], edgesWeights: number[]\n ) {\n return super.fromNetworkNodes(start, end, networkNodes, edgesWeights) as GraphItinerary<A, B>;\n }\n}\n","import { Coordinates, Network } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmNetwork extends Network<N, E>{\n static fromCoordinates<A = N, B = E>(segments: Coordinates[][]) {\n return super.fromCoordinates<N, E>(segments) as Network<A, B>;\n }\n}","import { GraphProjection } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphProjection extends GraphProjection<N, E>{ }\n","import { GraphRouter } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouter extends GraphRouter<N, E>{ }\n","import { GraphRouterOptions } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmGraphRouterOptions extends GraphRouterOptions<N, E>{ }\n","import { MapMatching } from '@wemap/geo';\n\nimport { N, E } from './OsmNetworkUtils.js';\n\nexport default class OsmMapMatching extends MapMatching<N, E>{ }\n","import { Level } from '@wemap/geo';\nimport OsmGraphNode from './OsmGraphNode';\nimport OsmGraphEdge from './OsmGraphEdge';\nimport OsmModel from '../OsmModel';\nimport OsmNode from '../OsmNode';\nimport OsmWay from '../OsmWay';\nimport OsmNetwork from './OsmNetwork';\n\nexport type N = OsmNode;\nexport type E = OsmNode | OsmWay;\n\nexport const HIGHWAYS_PEDESTRIANS = ['footway', 'steps', 'pedestrian', 'living_street', 'path', 'track', 'sidewalk', 'elevator'];\n\nexport const DEFAULT_WAY_SELECTOR = (way: OsmWay) => {\n return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway)\n || way.tags.footway === 'sidewalk'\n || way.tags.public_transport === 'platform'\n || way.tags.railway === 'platform';\n};\n\nexport function getNodeByName(network: OsmNetwork, name: string) {\n return network.nodes.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nexport function getEdgeByName(network: OsmNetwork, name: string) {\n return network.edges.find(({ builtFrom }) => builtFrom?.tags.name === name);\n}\n\nfunction manageOneWay(edge: OsmGraphEdge, way: OsmWay) {\n\n const { highway, oneway, conveying } = way.tags;\n\n edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n || (conveying && highway && ['forward', 'backward'].includes(conveying)));\n\n if (edge.isOneway && conveying === 'backward') {\n const tmpNode = edge.node1;\n edge.node1 = edge.node2;\n edge.node2 = tmpNode;\n }\n}\n\n\nfunction createNodesAndEdgesFromElevator(\n nodes: OsmGraphNode[],\n edges: OsmGraphEdge[],\n elevatorNode: OsmGraphNode\n) {\n\n const createdNodes: OsmGraphNode[] = [];\n const getOrCreateLevelNode = (level: number | null, builtFrom: N | null) => {\n let levelNode = createdNodes.find(({ coords }) => Level.equals(level, coords.level));\n if (!levelNode) {\n levelNode = new OsmGraphNode(elevatorNode.coords.clone(), builtFrom);\n levelNode.coords.level = level;\n createdNodes.push(levelNode);\n nodes.push(levelNode);\n }\n return levelNode;\n };\n\n // Create nodes from node.edges\n elevatorNode.edges.forEach(edge => {\n if (Level.isRange(edge.level)) {\n throw new Error('Cannot handle this elevator edge due to ambiguity');\n }\n\n const levelNode = getOrCreateLevelNode(edge.level, elevatorNode.builtFrom);\n if (edge.node1 === elevatorNode) {\n edge.node1 = levelNode;\n } else {\n edge.node2 = levelNode;\n }\n levelNode.edges.push(edge);\n });\n\n // Create edges from createdNodes\n for (let i = 0; i < createdNodes.length; i++) {\n for (let j = i + 1; j < createdNodes.length; j++) {\n\n const createdNode1 = createdNodes[i];\n const createdNode2 = createdNodes[j];\n\n if (createdNode1.coords.level === null || createdNode2.coords.level === null) {\n // TODO: not the best approach... but cannot do better with [number, number] range for levels\n continue;\n }\n\n const minLevel = Math.min(createdNode1.coords.level as number, createdNode2.coords.level as number);\n const maxLevel = Math.max(createdNode1.coords.level as number, createdNode2.coords.level as number);\n\n const newEdge = new OsmGraphEdge(\n createdNode1,\n createdNode2,\n [minLevel, maxLevel],\n elevatorNode.builtFrom\n );\n edges.push(newEdge);\n }\n }\n\n // Remove the historical elevator node from the network\n const elevatorNodeIndex = nodes.indexOf(elevatorNode);\n if (elevatorNodeIndex > -1) {\n nodes.splice(elevatorNodeIndex, 1);\n }\n}\n\nexport function createNetworkFromOsmModel(\n osmModel: OsmModel,\n waySelectionFilter = DEFAULT_WAY_SELECTOR\n) {\n\n const nodes: OsmGraphNode[] = [];\n const edges: OsmGraphEdge[] = [];\n\n const nodesCreated: { [key: number]: OsmGraphNode } = {};\n const elevatorNodes: OsmGraphNode[] = [];\n\n const getOrCreateNode = (osmNode: OsmNode) => {\n let node = nodesCreated[osmNode.id];\n if (!node) {\n node = new OsmGraphNode(osmNode.coords, osmNode);\n nodesCreated[osmNode.id] = node;\n nodes.push(node);\n\n if (osmNode.tags.highway === 'elevator') {\n elevatorNodes.push(node);\n }\n }\n return node;\n };\n\n osmModel.ways.forEach(way => {\n if (!waySelectionFilter(way)) {\n return;\n }\n\n let firstNode = getOrCreateNode(way.nodes[0]);\n for (let i = 1; i < way.nodes.length; i++) {\n const secondNode = getOrCreateNode(way.nodes[i]);\n\n const edge = new OsmGraphEdge(firstNode, secondNode, way.level, way);\n manageOneWay(edge, way);\n edges.push(edge);\n firstNode = secondNode;\n }\n\n });\n\n elevatorNodes.forEach(node => {\n // We have to clone this node for each connected edge\n createNodesAndEdgesFromElevator(nodes, edges, node);\n });\n\n const networkModel = new OsmNetwork(nodes, edges);\n\n OsmGraphNode.generateNodesLevels(networkModel.nodes);\n\n return networkModel;\n}\n\n\n// /**\n// * @param {GraphNode} node\n// * @param {object} tags\n// */\n// static _applyNodePropertiesFromTags(node, tags) {\n// node.name = tags.name || null;\n// node.subwayEntrance = tags.railway === 'subway_entrance';\n// if (node.subwayEntrance && tags.ref) {\n// node.subwayEntranceRef = tags.ref;\n// }\n// }\n\n// /**\n// * @param {GraphEdge} edge\n// * @param {object} tags\n// */\n// static _applyEdgePropertiesFromTags(edge, tags) {\n// const { highway, oneway, conveying, name } = tags;\n// edge.name = name || null;\n// edge.isStairs = highway === 'steps';\n// edge.isConveying = 'conveying' in tags;\n// edge.isOneway = Boolean((oneway === 'yes' || oneway === 'true' || oneway === '1')\n// || (conveying && highway && ['yes', 'forward', 'backward'].includes(conveying)));\n\n// if (conveying === 'backward') {\n// const tmpNode = edge.node1;\n// edge.node1 = edge.node2;\n// edge.node2 = tmpNode;\n// }\n\n// }\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "directory": "packages/osm"
13
13
  },
14
14
  "name": "@wemap/osm",
15
- "version": "11.0.0-alpha.15",
15
+ "version": "11.0.0-alpha.18",
16
16
  "bugs": {
17
17
  "url": "https://github.com/wemap/wemap-modules-js/issues"
18
18
  },
@@ -29,8 +29,8 @@
29
29
  ],
30
30
  "license": "ISC",
31
31
  "dependencies": {
32
- "@wemap/geo": "^11.0.0-alpha.15",
33
- "@wemap/logger": "^11.0.0-alpha.15",
32
+ "@wemap/geo": "^11.0.0-alpha.16",
33
+ "@wemap/logger": "^11.0.0-alpha.16",
34
34
  "saxes": "^5.0.1"
35
35
  },
36
36
  "exports": {
@@ -39,5 +39,5 @@
39
39
  "require": "./dist/index.js"
40
40
  }
41
41
  },
42
- "gitHead": "375928c186d4d20983d6e0d7cfb52274832e5a10"
42
+ "gitHead": "46bef48dec0bce16030ab353c300db8d0f649bd1"
43
43
  }
package/src/OsmModel.ts CHANGED
@@ -1,14 +1,17 @@
1
1
  import OsmNode from './OsmNode.js';
2
+ import OsmRelation from './OsmRelation.js';
2
3
  import OsmWay from './OsmWay.js';
3
4
 
4
5
  class OsmModel {
5
6
 
6
7
  nodes: OsmNode[];
7
8
  ways: OsmWay[];
9
+ relations: OsmRelation[];
8
10
 
9
- constructor(nodes?: OsmNode[], ways?: OsmWay[]) {
11
+ constructor(nodes?: OsmNode[], ways?: OsmWay[], relations?: OsmRelation[]) {
10
12
  this.nodes = nodes || [];
11
13
  this.ways = ways || [];
14
+ this.relations = relations || [];
12
15
  }
13
16
 
14
17
  getNodeById(id: number) {
@@ -27,6 +30,13 @@ class OsmModel {
27
30
  return this.ways.find(way => way.tags.name === name) || null;
28
31
  }
29
32
 
33
+ getRelationById(id: number) {
34
+ return this.relations.find(way => way.id === id) || null;
35
+ }
36
+
37
+ getRelationByName(name: string) {
38
+ return this.relations.find(way => way.tags.name === name) || null;
39
+ }
30
40
  }
31
41
 
32
42
  export default OsmModel;
package/src/OsmNode.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  import { Coordinates } from '@wemap/geo';
2
2
 
3
3
  import OsmElement, { OsmTags } from './OsmElement.js';
4
+ import OsmRelation from './OsmRelation.js';
4
5
  import OsmWay from './OsmWay.js';
5
6
 
6
7
  class OsmNode extends OsmElement {
7
8
 
8
9
  coords : Coordinates;
9
10
  ways: OsmWay[] = [];
10
-
11
+ relations: OsmRelation[] = [];
11
12
 
12
13
  constructor(id: number, coords: Coordinates, tags?: OsmTags) {
13
14
  super(id, tags);
package/src/OsmParser.ts CHANGED
@@ -8,10 +8,12 @@ import {
8
8
  import OsmModel from './OsmModel.js';
9
9
  import OsmNode from './OsmNode.js';
10
10
  import OsmWay from './OsmWay.js';
11
+ import OsmRelation from './OsmRelation.js';
11
12
 
12
13
  type OsmXmlElement = { action?: 'delete' };
13
14
  type OsmXmlNode = { id: string, lat: string, lon: string } & OsmXmlElement;
14
15
  type OsmXmlWay = { id: string } & OsmXmlElement;
16
+ type OsmXmlRelation = { id: string } & OsmXmlElement;
15
17
 
16
18
  class OsmParser {
17
19
 
@@ -20,7 +22,7 @@ class OsmParser {
20
22
  const model = new OsmModel();
21
23
  const parser = new SaxesParser();
22
24
 
23
- let buffer: OsmNode | OsmWay | null;
25
+ let buffer: OsmNode | OsmWay | OsmRelation | null;
24
26
 
25
27
  const isDeleted = (element: { attributes: OsmXmlElement }) =>
26
28
  element.attributes.action && element.attributes.action === 'delete';
@@ -48,6 +50,16 @@ class OsmParser {
48
50
  model.ways.push(osmWay);
49
51
  break;
50
52
  }
53
+ case 'relation': {
54
+ if (isDeleted(node)) {
55
+ buffer = null;
56
+ break;
57
+ }
58
+ const osmRelation = this._parseRelation(node.attributes as OsmXmlRelation);
59
+ buffer = osmRelation;
60
+ model.relations.push(osmRelation);
61
+ break;
62
+ }
51
63
  case 'tag': {
52
64
  if (!buffer) {
53
65
  return;
@@ -72,6 +84,25 @@ class OsmParser {
72
84
  refNode.ways.push(buffer);
73
85
  break;
74
86
  }
87
+ case 'member': {
88
+ if (!buffer || !(buffer instanceof OsmRelation)) {
89
+ return;
90
+ }
91
+ const memberId = Number(node.attributes.ref);
92
+ const memberType = node.attributes.type;
93
+ let refElement: OsmNode | OsmWay | OsmRelation | null = null;
94
+ memberType === 'node' && (refElement = model.getNodeById(memberId));
95
+ memberType === 'way' && (refElement = model.getWayById(memberId));
96
+ memberType === 'relation' && (refElement = model.getRelationById(memberId));
97
+
98
+ if (!refElement) {
99
+ throw Error('Member: ' + memberId + ' in relation ' + buffer.id + ' not found');
100
+ }
101
+
102
+ buffer.members.push({ ref: refElement, role: node.attributes.role });
103
+ refElement.relations.push(buffer);
104
+ break;
105
+ }
75
106
  }
76
107
  });
77
108
 
@@ -97,6 +128,10 @@ class OsmParser {
97
128
  static _parseWay(attr: { id: string }) {
98
129
  return new OsmWay(Number(attr.id));
99
130
  }
131
+
132
+ static _parseRelation(attr: { id: string }) {
133
+ return new OsmRelation(Number(attr.id));
134
+ }
100
135
  }
101
136
 
102
137
  export default OsmParser;
@@ -0,0 +1,42 @@
1
+ import OsmElement, { OsmTags } from './OsmElement.js';
2
+ import OsmNode from './OsmNode.js';
3
+ import OsmWay from './OsmWay.js';
4
+ import type { Position, Polygon } from 'geojson';
5
+
6
+ export type OsmRelationMember = {
7
+ ref: OsmRelation | OsmWay | OsmNode,
8
+ role: string
9
+ }
10
+
11
+ class OsmRelation extends OsmElement {
12
+
13
+ relations: OsmRelation[] = [];
14
+
15
+ constructor(
16
+ id: number,
17
+ public members: OsmRelationMember[] = [],
18
+ tags?: OsmTags
19
+ ) {
20
+ super(id, tags);
21
+ }
22
+
23
+ isMultipolygon() {
24
+ return this.tags.type === 'multipolygon';
25
+ }
26
+
27
+ getGeoJsonPolygon(): Polygon | null {
28
+ if (!this.isMultipolygon()) return null;
29
+ const outer = this.members.find(member => member.ref instanceof OsmWay && member.role === 'outer');
30
+ if (!outer) return null;
31
+ const inners = this.members.filter(member => member.ref instanceof OsmWay && member.role === 'inner');
32
+ return {
33
+ type: "Polygon",
34
+ coordinates: [outer, ...inners].map(member => {
35
+ const way = member.ref as OsmWay;
36
+ return way.nodes.map(node => [node.coords.lng, node.coords.lat] as Position);
37
+ })
38
+ }
39
+ }
40
+ }
41
+
42
+ export default OsmRelation;
package/src/OsmWay.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import { Level_t } from '@wemap/geo';
2
2
  import OsmElement, { OsmTags } from './OsmElement.js';
3
3
  import OsmNode from './OsmNode.js';
4
+ import OsmRelation from './OsmRelation.js';
4
5
 
5
6
  class OsmWay extends OsmElement {
6
7
 
7
8
  nodes: OsmNode[] = [];
9
+ relations: OsmRelation[] = [];
8
10
  level: Level_t = null;
9
11
 
10
12
  constructor(id: number, tags?: OsmTags, level: Level_t = null) {
@@ -2,4 +2,4 @@ import { GraphEdge } from "@wemap/geo";
2
2
  import OsmNode from "../OsmNode";
3
3
  import OsmWay from "../OsmWay";
4
4
 
5
- export default class OsmGraphNode extends GraphEdge<OsmNode | OsmWay, OsmNode>{ }
5
+ export default class OsmGraphEdge extends GraphEdge<OsmNode | OsmWay, OsmNode>{ }