@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 +129 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/graph/GeoGraphRouter.ts +233 -7
- package/src/graph/NoRouteFoundError.ts +4 -5
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,
|