@wemap/routers 11.4.0 → 11.5.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/dist/index.js CHANGED
@@ -590,53 +590,98 @@ const _OsmGraph = class extends geo.GeoGraph {
590
590
  return super.getEdgeByName(name);
591
591
  }
592
592
  static fromOsmModel(osmModel, waySelectionFilter = DEFAULT_WAY_SELECTOR) {
593
- const nodes = [];
593
+ const vertices = [];
594
594
  const edges = [];
595
- const nodesCreated = {};
596
- const elevatorNodes = [];
597
- const getOrCreateNode = (osmNode) => {
598
- let node = nodesCreated[osmNode.id];
599
- if (!node) {
600
- node = new geo.GeoGraphVertex(osmNode.coords, { data: osmNode, name: osmNode.tags.name });
601
- nodesCreated[osmNode.id] = node;
602
- nodes.push(node);
603
- if (osmNode.tags.highway === "elevator") {
604
- elevatorNodes.push(node);
595
+ const elevatorVertices = [];
596
+ const getOrCreateVertex = (osmNode, forceLevel = null) => {
597
+ let vertex = vertices.find(
598
+ (vertex2) => vertex2.data.id === osmNode.id && (forceLevel !== null ? geo.Level.intersect(vertex2.coords.level, forceLevel) : true)
599
+ ) || null;
600
+ if (vertex) {
601
+ return vertex;
602
+ }
603
+ const otherVertex = vertices.find((v) => v.data.id === osmNode.id);
604
+ if (otherVertex) {
605
+ if (otherVertex && otherVertex.coords.level !== null) {
606
+ throw new Error(`An error occured because repeat_on as not been set on node ${osmNode.coords} for level ${forceLevel}`);
607
+ }
608
+ otherVertex.coords.level = forceLevel;
609
+ }
610
+ let levelsToGenerate = [null];
611
+ if ("level" in osmNode.tags) {
612
+ levelsToGenerate = [osmNode.coords.level];
613
+ if ("repeat_on" in osmNode.tags) {
614
+ levelsToGenerate.push(...osmNode.tags.repeat_on.split(";").map(geo.Level.fromString));
615
+ }
616
+ } else if (forceLevel !== null) {
617
+ levelsToGenerate = [forceLevel];
618
+ }
619
+ levelsToGenerate.forEach((level) => {
620
+ const newVertex = new geo.GeoGraphVertex(osmNode.coords.clone(), { data: osmNode, name: osmNode.tags.name });
621
+ newVertex.coords.level = level;
622
+ vertices.push(newVertex);
623
+ if (geo.Level.intersect(newVertex.coords.level, forceLevel) || forceLevel === null && "level" in osmNode.tags) {
624
+ vertex = newVertex;
605
625
  }
626
+ });
627
+ if (!vertex) {
628
+ throw new Error(`Unable to parse vertex {id: ${osmNode.id}, coords: ${osmNode.coords.lat}, ${osmNode.coords.lng}}. Please check "level" tag.`);
606
629
  }
607
- return node;
630
+ if (osmNode.tags.highway === "elevator" && vertex) {
631
+ elevatorVertices.push(vertex);
632
+ }
633
+ return vertex;
608
634
  };
609
635
  osmModel.ways.forEach((way) => {
610
636
  if (!waySelectionFilter(way)) {
611
637
  return;
612
638
  }
613
- let firstNode = getOrCreateNode(way.nodes[0]);
614
- for (let i = 1; i < way.nodes.length; i++) {
615
- const secondNode = getOrCreateNode(way.nodes[i]);
616
- const edge = new geo.GeoGraphEdge(
617
- firstNode,
618
- secondNode,
619
- { data: way, name: way.tags.name, level: way.level }
620
- );
621
- _OsmGraph.manageOneWay(edge, way);
622
- edges.push(edge);
623
- firstNode = secondNode;
639
+ let levelsToGenerate = [null];
640
+ if ("level" in way.tags) {
641
+ levelsToGenerate = [way.level];
642
+ if ("repeat_on" in way.tags) {
643
+ levelsToGenerate.push(...way.tags.repeat_on.split(";").map(geo.Level.fromString));
644
+ }
624
645
  }
646
+ levelsToGenerate.forEach((level) => {
647
+ let firstVertex = getOrCreateVertex(way.nodes[0], level);
648
+ for (let i = 1; i < way.nodes.length; i++) {
649
+ const secondVertex = getOrCreateVertex(way.nodes[i], level);
650
+ const edge = new geo.GeoGraphEdge(
651
+ firstVertex,
652
+ secondVertex,
653
+ { data: way, name: way.tags.name, level }
654
+ );
655
+ _OsmGraph.manageOneWay(edge, way);
656
+ edges.push(edge);
657
+ firstVertex = secondVertex;
658
+ }
659
+ });
625
660
  });
626
661
  osmModel.ways.filter((way) => way.isElevator).forEach((way) => {
627
- way.nodes.forEach((node) => {
628
- const connectedWays = node.ways.filter((otherWay) => otherWay != way);
629
- if (connectedWays.length) {
630
- const graphVertex = getOrCreateNode(node);
631
- graphVertex.data.tags.highway = "elevator";
632
- elevatorNodes.push(graphVertex);
633
- }
662
+ const entryVertices = way.nodes.map((node) => vertices.filter((v) => v.data.id === node.id)).flat();
663
+ const elevatorLevel = entryVertices.reduce((acc, v) => geo.Level.union(acc, v.coords.level), null);
664
+ const elevatorCenter = way.nodes.reduce((acc, node) => [acc[0] + node.coords.lat, acc[1] + node.coords.lng], [0, 0]).map((val) => val / way.nodes.length);
665
+ const elevatorCenterCoords = new geo.Coordinates(elevatorCenter[0], elevatorCenter[1], null, elevatorLevel);
666
+ const elevatorCenterVertex = new geo.GeoGraphVertex(elevatorCenterCoords, { data: way, name: way.tags.name });
667
+ vertices.push(elevatorCenterVertex);
668
+ entryVertices.forEach((entryVertex) => {
669
+ const newEdge = new geo.GeoGraphEdge(
670
+ elevatorCenterVertex,
671
+ entryVertex,
672
+ {
673
+ level: geo.Level.intersection(elevatorCenterVertex.coords.level, entryVertex.coords.level),
674
+ data: way
675
+ }
676
+ );
677
+ edges.push(newEdge);
634
678
  });
679
+ elevatorVertices.push(elevatorCenterVertex);
635
680
  });
636
- elevatorNodes.forEach((node) => {
637
- _OsmGraph.createNodesAndEdgesFromElevator(nodes, edges, node);
681
+ elevatorVertices.forEach((node) => {
682
+ _OsmGraph.createNodesAndEdgesFromElevator(vertices, edges, node);
638
683
  });
639
- return new _OsmGraph(nodes, edges, true);
684
+ return new _OsmGraph(vertices, edges, true);
640
685
  }
641
686
  static manageOneWay(edge, way) {
642
687
  const { highway, oneway, conveying } = way.tags;
@@ -647,53 +692,52 @@ const _OsmGraph = class extends geo.GeoGraph {
647
692
  edge.vertex2 = tmpNode;
648
693
  }
649
694
  }
650
- static createNodesAndEdgesFromElevator(nodes, edges, elevatorNode) {
651
- const createdNodes = [];
695
+ static createNodesAndEdgesFromElevator(vertices, edges, elevatorVertex) {
696
+ const createdVertices = [];
652
697
  const getOrCreateLevelVertex = (level) => {
653
- let levelVertex = createdNodes.find(({ coords }) => geo.Level.equals(level, coords.level));
698
+ let levelVertex = createdVertices.find(({ coords }) => geo.Level.equals(level, coords.level));
654
699
  if (!levelVertex) {
655
- levelVertex = new geo.GeoGraphVertex(elevatorNode.coords.clone(), {
656
- data: elevatorNode.data,
657
- name: `${elevatorNode.name} (elevator lvl: ${level})`
700
+ levelVertex = new geo.GeoGraphVertex(elevatorVertex.coords.clone(), {
701
+ data: elevatorVertex.data,
702
+ name: `${elevatorVertex.name} (elevator lvl: ${level})`
658
703
  });
659
704
  levelVertex.coords.level = level;
660
- createdNodes.push(levelVertex);
661
- nodes.push(levelVertex);
705
+ createdVertices.push(levelVertex);
706
+ vertices.push(levelVertex);
662
707
  }
663
708
  return levelVertex;
664
709
  };
665
- elevatorNode.edges.forEach((edge) => {
710
+ elevatorVertex.edges.forEach((edge) => {
666
711
  if (geo.Level.isRange(edge.level)) {
667
- throw new Error("Cannot handle this elevator edge due to ambiguity");
712
+ throw new Error(`Cannot handle this elevator edge due to ambiguity (vertex: ${edge.vertex1.coords})`);
668
713
  }
669
714
  const levelVertex = getOrCreateLevelVertex(edge.level);
670
- if (edge.vertex1 === elevatorNode) {
715
+ if (edge.vertex1 === elevatorVertex) {
671
716
  edge.vertex1 = levelVertex;
672
717
  } else {
673
718
  edge.vertex2 = levelVertex;
674
719
  }
675
- levelVertex.edges.push(edge);
676
720
  });
677
- for (let i = 0; i < createdNodes.length; i++) {
678
- for (let j = i + 1; j < createdNodes.length; j++) {
679
- const createdNode1 = createdNodes[i];
680
- const createdNode2 = createdNodes[j];
681
- if (createdNode1.coords.level === null || createdNode2.coords.level === null) {
721
+ for (let i = 0; i < createdVertices.length; i++) {
722
+ for (let j = i + 1; j < createdVertices.length; j++) {
723
+ const createdVertex1 = createdVertices[i];
724
+ const createdVertex2 = createdVertices[j];
725
+ if (createdVertex1.coords.level === null || createdVertex2.coords.level === null) {
682
726
  continue;
683
727
  }
684
- const minLevel = Math.min(createdNode1.coords.level, createdNode2.coords.level);
685
- const maxLevel = Math.max(createdNode1.coords.level, createdNode2.coords.level);
728
+ const minLevel = Math.min(createdVertex1.coords.level, createdVertex2.coords.level);
729
+ const maxLevel = Math.max(createdVertex1.coords.level, createdVertex2.coords.level);
686
730
  const newEdge = new geo.GeoGraphEdge(
687
- createdNode1,
688
- createdNode2,
689
- { data: elevatorNode.data, name: elevatorNode.name, level: [minLevel, maxLevel] }
731
+ createdVertex1,
732
+ createdVertex2,
733
+ { data: elevatorVertex.data, name: elevatorVertex.name, level: [minLevel, maxLevel] }
690
734
  );
691
735
  edges.push(newEdge);
692
736
  }
693
737
  }
694
- const elevatorNodeIndex = nodes.indexOf(elevatorNode);
738
+ const elevatorNodeIndex = vertices.indexOf(elevatorVertex);
695
739
  if (elevatorNodeIndex > -1) {
696
- nodes.splice(elevatorNodeIndex, 1);
740
+ vertices.splice(elevatorNodeIndex, 1);
697
741
  }
698
742
  }
699
743
  };