@wemap/geo 11.7.0 → 11.8.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
@@ -1725,6 +1725,9 @@ class NoRouteFoundError extends Error {
1725
1725
  if (this.end instanceof GeoGraphVertex) {
1726
1726
  return `GeoGraphVertex ${this.end.coords.toString()}`;
1727
1727
  }
1728
+ if (Array.isArray(this.end)) {
1729
+ return this.end.map((p) => p instanceof GeoGraphVertex ? p.coords.toString() : p.toString()).join(",");
1730
+ }
1728
1731
  return this.end.toString();
1729
1732
  }
1730
1733
  get message() {
@@ -1747,7 +1750,7 @@ const _GeoGraphRouter = class _GeoGraphRouter {
1747
1750
  const { acceptEdgeFn, weightEdgeFn, projectionMaxDistance } = options;
1748
1751
  this._mapMatching.maxDistance = projectionMaxDistance;
1749
1752
  const createdVertices = [];
1750
- const retrieveOrCreateNearestVertex = (point) => {
1753
+ const retrieveOrCreateNearestVertex = (point, options2 = _GeoGraphRouter.DEFAULT_OPTIONS) => {
1751
1754
  if (point instanceof GeoGraphVertex) {
1752
1755
  return point;
1753
1756
  }
@@ -1755,7 +1758,7 @@ const _GeoGraphRouter = class _GeoGraphRouter {
1755
1758
  if (closeVertex) {
1756
1759
  return closeVertex;
1757
1760
  }
1758
- const proj = this._mapMatching.getProjection(point, true, false, false, acceptEdgeFn);
1761
+ const proj = this._mapMatching.getProjection(point, true, false, false, options2.acceptEdgeFn);
1759
1762
  if (!proj) {
1760
1763
  let message = `Point ${point.toString()} is too far from the graph > ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
1761
1764
  if (point.level !== null) {
@@ -1806,6 +1809,71 @@ const _GeoGraphRouter = class _GeoGraphRouter {
1806
1809
  }
1807
1810
  return graphItinerary;
1808
1811
  }
1812
+ getShortestPaths(start, ends, options = _GeoGraphRouter.DEFAULT_OPTIONS) {
1813
+ const { acceptEdgeFn, weightEdgeFn, projectionMaxDistance } = options;
1814
+ this._mapMatching.maxDistance = projectionMaxDistance;
1815
+ const createdVertices = [];
1816
+ const retrieveOrCreateNearestVertex = (point, options2 = _GeoGraphRouter.DEFAULT_OPTIONS) => {
1817
+ if (point instanceof GeoGraphVertex) {
1818
+ return point;
1819
+ }
1820
+ const closeVertex = this._graph.getVertexByCoords(point);
1821
+ if (closeVertex) {
1822
+ return closeVertex;
1823
+ }
1824
+ const proj = this._mapMatching.getProjection(point, true, false, false, options2.acceptEdgeFn);
1825
+ if (!proj) {
1826
+ return null;
1827
+ }
1828
+ if (proj.nearestElement instanceof GeoGraphVertex) {
1829
+ return proj.nearestElement;
1830
+ }
1831
+ const vertexCreated = this.createVertexInsideEdge(
1832
+ proj.nearestElement,
1833
+ proj.coords
1834
+ );
1835
+ createdVertices.push(vertexCreated);
1836
+ return vertexCreated;
1837
+ };
1838
+ const removeCreatedVertices = () => {
1839
+ while (createdVertices.length) {
1840
+ this.removeVertexFromPreviouslyCreatedEdge(createdVertices.pop());
1841
+ }
1842
+ };
1843
+ const startVertex = retrieveOrCreateNearestVertex(start);
1844
+ const endsStruct = ends.map((e) => ({
1845
+ input: e,
1846
+ vertex: retrieveOrCreateNearestVertex(e),
1847
+ itinerary: null
1848
+ }));
1849
+ const startCoords = start instanceof GeoGraphVertex ? start.coords : start;
1850
+ if (!startVertex) {
1851
+ let message = `Point ${startCoords.toString()} is too far from the graph > ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
1852
+ if (startCoords.level !== null) {
1853
+ message += ` If it is a multi-level map, please verify if you have a graph at level ${Level.toString(startCoords.level)}.`;
1854
+ }
1855
+ throw new NoRouteFoundError(start, ends, message);
1856
+ }
1857
+ const endsStructFiltered = endsStruct.filter((v) => v.vertex != null);
1858
+ const graphItineraries = this.getShortestPathsBetweenGeoGraphVertices(
1859
+ startVertex,
1860
+ endsStructFiltered.map((v) => v.vertex),
1861
+ weightEdgeFn,
1862
+ acceptEdgeFn
1863
+ );
1864
+ graphItineraries.forEach((itinerary, idx) => {
1865
+ itinerary.start = startCoords;
1866
+ const endStructFiltered = endsStructFiltered[idx];
1867
+ endStructFiltered.itinerary = itinerary;
1868
+ });
1869
+ removeCreatedVertices();
1870
+ endsStructFiltered.forEach((e) => {
1871
+ if (e.itinerary !== null) {
1872
+ e.itinerary.end = e.input instanceof GeoGraphVertex ? e.input.coords : e.input;
1873
+ }
1874
+ });
1875
+ return endsStructFiltered.map((e) => e.itinerary);
1876
+ }
1809
1877
  createVertexInsideEdge(edge, point) {
1810
1878
  const a = edge.vertex1;
1811
1879
  const b = edge.vertex2;
@@ -1893,6 +1961,65 @@ const _GeoGraphRouter = class _GeoGraphRouter {
1893
1961
  }
1894
1962
  return GeoGraphItinerary.fromGraphVertices(start.coords, end.coords, path, edgesWeights);
1895
1963
  }
1964
+ getShortestPathsBetweenGeoGraphVertices(start, ends, weightFn, acceptEdgeFn) {
1965
+ const distanceMap = {}, checking = {}, vertexList = {}, vertices = {}, parentVertices = {};
1966
+ this._graph.vertices.forEach((vertex) => {
1967
+ vertices[vertex.id] = vertex;
1968
+ distanceMap[vertex.id] = Infinity;
1969
+ checking[vertex.id] = null;
1970
+ vertexList[vertex.id] = true;
1971
+ });
1972
+ distanceMap[start.id] = 0;
1973
+ while (Object.keys(vertexList).length > 0) {
1974
+ const keys = Object.keys(vertexList).map(Number);
1975
+ const current = Number(
1976
+ keys.reduce((_checking, vertexId) => {
1977
+ return distanceMap[_checking] > distanceMap[vertexId] ? vertexId : _checking;
1978
+ }, keys[0])
1979
+ );
1980
+ this._graph.edges.filter((edge) => {
1981
+ if (acceptEdgeFn && !acceptEdgeFn(edge) || this.disabledEdges.has(edge)) {
1982
+ return false;
1983
+ }
1984
+ const from = edge.vertex1.id, to = edge.vertex2.id;
1985
+ return from === current || to === current;
1986
+ }).forEach((edge) => {
1987
+ let to, from, reversed = false;
1988
+ if (edge.vertex1.id === current) {
1989
+ to = edge.vertex2.id;
1990
+ from = edge.vertex1.id;
1991
+ } else {
1992
+ to = edge.vertex1.id;
1993
+ from = edge.vertex2.id;
1994
+ reversed = true;
1995
+ }
1996
+ if (edge.isOneway && reversed) {
1997
+ return;
1998
+ }
1999
+ const distance = distanceMap[current] + weightFn(edge);
2000
+ if (distanceMap[to] > distance) {
2001
+ distanceMap[to] = distance;
2002
+ checking[to] = current;
2003
+ parentVertices[to] = from;
2004
+ }
2005
+ });
2006
+ delete vertexList[current];
2007
+ }
2008
+ return ends.map((end) => {
2009
+ const edgesWeights = [];
2010
+ const path = [];
2011
+ let endId = end.id;
2012
+ while (typeof parentVertices[endId] !== "undefined") {
2013
+ path.unshift(vertices[endId]);
2014
+ edgesWeights.unshift(distanceMap[endId] - distanceMap[parentVertices[endId]]);
2015
+ endId = parentVertices[endId];
2016
+ }
2017
+ if (path.length !== 0) {
2018
+ path.unshift(start);
2019
+ }
2020
+ return GeoGraphItinerary.fromGraphVertices(start.coords, end.coords, path, edgesWeights);
2021
+ });
2022
+ }
1896
2023
  };
1897
2024
  __publicField(_GeoGraphRouter, "DEFAULT_OPTIONS", {
1898
2025
  projectionMaxDistance: 50,