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