@wemap/routers 11.3.3 → 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));
605
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;
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
  };
@@ -1475,8 +1519,8 @@ class OsrmRemoteRouter extends RemoteRouter {
1475
1519
  get rname() {
1476
1520
  return "osrm";
1477
1521
  }
1478
- async getItineraries(endpointUrl, mode, waypoints) {
1479
- const url = this.getURL(endpointUrl, mode, waypoints);
1522
+ async getItineraries(endpointUrl, mode, waypoints, options = {}) {
1523
+ const url = this.getURL(endpointUrl, mode, waypoints, options);
1480
1524
  const res = await fetch(url).catch(() => {
1481
1525
  throw new RemoteRouterServerUnreachable(this.rname, url);
1482
1526
  });
@@ -1488,11 +1532,14 @@ class OsrmRemoteRouter extends RemoteRouter {
1488
1532
  const osrmMode = inputModeCorrespondance$1.get(mode);
1489
1533
  return this.createRouterResponseFromJson(jsonResponse, from, to, osrmMode);
1490
1534
  }
1491
- getURL(endpointUrl, mode, waypoints) {
1492
- const osrmMode = inputModeCorrespondance$1.get(mode);
1535
+ getURL(endpointUrl, mode, waypoints, options = {}) {
1536
+ let osrmMode = inputModeCorrespondance$1.get(mode);
1493
1537
  if (!osrmMode) {
1494
1538
  throw new RoutingModeCorrespondanceNotFound(this.rname, mode);
1495
1539
  }
1540
+ if ("useStairs" in options && !options.useStairs) {
1541
+ osrmMode = "pmr";
1542
+ }
1496
1543
  let url = endpointUrl + "/route/v1/" + osrmMode + "/";
1497
1544
  url += waypoints.map((waypoint) => [waypoint.longitude + "," + waypoint.latitude]).join(";");
1498
1545
  url += "?geometries=geojson&overview=full&steps=true";
@@ -1930,7 +1977,7 @@ class WemapMultiRouter {
1930
1977
  const ioMapsToTest = this.getIoMapsFromOptions(options);
1931
1978
  if (!ioMapsToTest.length) {
1932
1979
  try {
1933
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
1980
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints, options || void 0);
1934
1981
  } catch (e) {
1935
1982
  if (!isRoutingError(e)) {
1936
1983
  throw e;
@@ -1960,7 +2007,7 @@ class WemapMultiRouter {
1960
2007
  let remoteRouterResponse;
1961
2008
  if (!mapWithStart && !mapWithEnd) {
1962
2009
  try {
1963
- return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints);
2010
+ return await RemoteRouterManager$1.getItinerariesWithFallback(remoteRouters2, mode, waypoints, options || void 0);
1964
2011
  } catch (e) {
1965
2012
  if (!isRoutingError(e)) {
1966
2013
  throw e;
@@ -1980,7 +2027,8 @@ class WemapMultiRouter {
1980
2027
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
1981
2028
  remoteRouters2,
1982
2029
  mode,
1983
- [ioMapItinerary.to, end]
2030
+ [ioMapItinerary.to, end],
2031
+ options || void 0
1984
2032
  );
1985
2033
  if (!remoteRouterResponse.itineraries.length) {
1986
2034
  throw new geo.NoRouteFoundError(ioMapItinerary.to, end, remoteRouterResponse.error);
@@ -2009,7 +2057,8 @@ class WemapMultiRouter {
2009
2057
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
2010
2058
  remoteRouters2,
2011
2059
  mode,
2012
- [start, ioMapItinerary.from]
2060
+ [start, ioMapItinerary.from],
2061
+ options || void 0
2013
2062
  );
2014
2063
  if (!remoteRouterResponse.itineraries.length) {
2015
2064
  throw new geo.NoRouteFoundError(start, ioMapItinerary.from, remoteRouterResponse.error);
@@ -2047,7 +2096,8 @@ class WemapMultiRouter {
2047
2096
  remoteRouterResponse = await RemoteRouterManager$1.getItinerariesWithFallback(
2048
2097
  remoteRouters2,
2049
2098
  mode,
2050
- [ioMapItinerary1.to, ioMapItinerary2.from]
2099
+ [ioMapItinerary1.to, ioMapItinerary2.from],
2100
+ options || void 0
2051
2101
  );
2052
2102
  if (!remoteRouterResponse.itineraries.length) {
2053
2103
  throw new geo.NoRouteFoundError(ioMapItinerary1.to, ioMapItinerary2.from, remoteRouterResponse.error);