@wemap/geo 0.3.9 → 1.0.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/index.js CHANGED
@@ -6,23 +6,10 @@ import Level from './src/coordinates/Level';
6
6
  import WGS84 from './src/coordinates/WGS84';
7
7
  import WGS84UserPosition from './src/coordinates/WGS84UserPosition';
8
8
 
9
- import Edge from './src/graph/Edge';
10
- import GraphRouter from './src/graph/GraphRouter';
11
- import Itinerary from './src/graph/Itinerary';
12
- import Network from './src/graph/Network';
13
- import Node from './src/graph/Node';
14
- import MapMatching from './src/graph/MapMatching';
15
-
16
9
  export {
17
10
  Attitude,
18
11
  Constants,
19
- Edge,
20
- GraphRouter,
21
- Itinerary,
22
12
  Level,
23
- MapMatching,
24
- Network,
25
- Node,
26
13
  WGS84,
27
14
  WGS84UserPosition
28
15
  };
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "directory": "packages/geo"
13
13
  },
14
14
  "name": "@wemap/geo",
15
- "version": "0.3.9",
15
+ "version": "1.0.0",
16
16
  "bugs": {
17
17
  "url": "https://github.com/wemap/wemap-utils-js/issues"
18
18
  },
@@ -31,5 +31,5 @@
31
31
  "lodash.isnumber": "^3.0.3",
32
32
  "lodash.isstring": "^4.0.1"
33
33
  },
34
- "gitHead": "84a60e64b0968bc45f0f76cc26c08e165dbe6985"
34
+ "gitHead": "2a8dc4304fae3f175819ed1a1561a818e871cf44"
35
35
  }
package/src/graph/Edge.js DELETED
@@ -1,73 +0,0 @@
1
- import Node from './Node';
2
-
3
- /**
4
- * An Edge is a segment composed of two Node
5
- * An edge is mostly issued from an OsmWay (data attribute), but this is not
6
- * always the case. For example, edges created by mapmatching.
7
- */
8
- class Edge {
9
-
10
- constructor(node1, node2, data, level) {
11
-
12
- if (!(node1 instanceof Node)) {
13
- throw new TypeError('node1 is not an instance of Node');
14
- }
15
-
16
- if (!(node2 instanceof Node)) {
17
- throw new TypeError('node2 is not an instance of Node');
18
- }
19
-
20
- this.node1 = node1;
21
- this.node2 = node2;
22
- this.data = data;
23
- this.level = level;
24
-
25
- this.node1.edges.push(this);
26
- this.node2.edges.push(this);
27
-
28
- this.computedSizeAndBearing = false;
29
- }
30
-
31
- /**
32
- * Get edge bearing from node1 to node2
33
- */
34
- get bearing() {
35
- if (!this.computedSizeAndBearing) {
36
- this.computeSizeAndBearing();
37
- }
38
- return this._bearing;
39
- }
40
-
41
- /**
42
- * get edge length
43
- */
44
- get length() {
45
- if (!this.computedSizeAndBearing) {
46
- this.computeSizeAndBearing();
47
- }
48
- return this._length;
49
- }
50
-
51
- computeSizeAndBearing() {
52
- this._length = this.node1.distanceTo(this.node2);
53
- this._bearing = this.node1.bearingTo(this.node2);
54
- this.computedSizedAndBearing = true;
55
- }
56
-
57
- equalsTo(other) {
58
-
59
- if (!(other instanceof Edge)) {
60
- return false;
61
- }
62
-
63
- return other.node1.equalsTo(this.node1) && other.node2.equalsTo(this.node2);
64
- }
65
-
66
- clone(node1, node2) {
67
- const edge = new Edge(node1, node2, this.data);
68
- edge.level = this.level;
69
- return edge;
70
- }
71
- }
72
-
73
- export default Edge;
@@ -1,238 +0,0 @@
1
- /* eslint-disable max-statements */
2
- /* eslint-disable complexity */
3
-
4
- import { WGS84 } from '@wemap/geo';
5
-
6
- import Edge from './Edge';
7
- import Itinerary from './Itinerary';
8
- import Node from './Node';
9
- import MapMatching from './MapMatching';
10
-
11
- class GraphRouter {
12
-
13
- constructor(network) {
14
- this.network = network;
15
- this.mapMatching = new MapMatching(network);
16
- this.mapMatching.maxDistance = 50;
17
- }
18
-
19
- getShortestPath(_start, _end, acceptEdgeFn = () => true) {
20
- let start;
21
- let startNodeCreated;
22
-
23
- if (_start instanceof Node) {
24
- start = _start;
25
- } else if (_start instanceof WGS84) {
26
- const node = this.network.getNodeByCoords(_start);
27
- if (node) {
28
- start = node;
29
- } else {
30
- const proj = this.mapMatching.getProjection(_start, true, false, false, acceptEdgeFn);
31
- if (proj && proj.nearestElement instanceof Node) {
32
- start = proj.nearestElement;
33
- } else if (proj && proj.nearestElement instanceof Edge) {
34
- startNodeCreated = this.createNodeInsideEdge(
35
- proj.nearestElement,
36
- proj.projection
37
- );
38
- start = startNodeCreated;
39
- }
40
- }
41
- }
42
-
43
- if (!start) {
44
- throw new Error('Cannot provide path because no starting point has been found');
45
- }
46
-
47
- let end;
48
- let endNodeCreated;
49
-
50
- if (_end instanceof Node) {
51
- end = _end;
52
- } else if (_end instanceof WGS84) {
53
- const node = this.network.getNodeByCoords(_end);
54
- if (node) {
55
- end = node;
56
- } else {
57
- const proj = this.mapMatching.getProjection(_end, true, false, false, acceptEdgeFn);
58
- if (proj && proj.nearestElement instanceof Node) {
59
- end = proj.nearestElement;
60
- } else if (proj && proj.nearestElement instanceof Edge) {
61
- endNodeCreated = this.createNodeInsideEdge(
62
- proj.nearestElement,
63
- proj.projection
64
- );
65
- end = endNodeCreated;
66
- }
67
- }
68
- }
69
-
70
- if (!end) {
71
- if (startNodeCreated) {
72
- this.removeNodeFromPreviouslyCreatedEdge(startNodeCreated);
73
- }
74
- throw new Error('Cannot provide path because no end point has been found');
75
- }
76
-
77
- const path = this.getShortestPathInternal(start, end, acceptEdgeFn);
78
-
79
- let route;
80
- if (path && path.length !== 0) {
81
- route = Itinerary.fromNetworkNodes(path, _start, _end);
82
- }
83
-
84
- if (endNodeCreated) {
85
- this.removeNodeFromPreviouslyCreatedEdge(endNodeCreated);
86
- }
87
-
88
- if (startNodeCreated) {
89
- this.removeNodeFromPreviouslyCreatedEdge(startNodeCreated);
90
- }
91
-
92
- return route;
93
- }
94
-
95
- createNodeInsideEdge(edge, point) {
96
- const a = edge.node1;
97
- const b = edge.node2;
98
-
99
- const m = new Node(point);
100
- m.coords.level = edge.level;
101
-
102
- const u = new Edge(a, m);
103
- u.level = edge.level;
104
- u.data = edge.data;
105
-
106
- const v = new Edge(b, m);
107
- v.level = edge.level;
108
- v.data = edge.data;
109
-
110
- a.edges = a.edges.filter(_edge => _edge !== edge);
111
- b.edges = b.edges.filter(_edge => _edge !== edge);
112
-
113
- this.network.nodes.push(m);
114
- this.network.edges.push(u, v);
115
-
116
- this.network.edges = this.network.edges.filter(
117
- _edge => _edge !== edge
118
- );
119
-
120
- return m;
121
- }
122
-
123
- removeNodeFromPreviouslyCreatedEdge(_node) {
124
- const u = _node.edges[0];
125
- const v = _node.edges[1];
126
-
127
- u.node1.edges = u.node1.edges.filter(edge => edge !== u);
128
- v.node1.edges = v.node1.edges.filter(edge => edge !== v);
129
-
130
- const oldEdge = new Edge(u.node1, v.node1);
131
- oldEdge.data = u.data;
132
- oldEdge.level = u.level;
133
- this.network.edges.push(oldEdge);
134
-
135
- this.network.nodes = this.network.nodes.filter(node => node !== _node);
136
- this.network.edges = this.network.edges.filter(
137
- edge => edge !== u && edge !== v
138
- );
139
- }
140
-
141
- getShortestPathInternal(start, end, acceptEdgeFn) {
142
- const distanceMap = {},
143
- checking = {},
144
- vertexList = {},
145
- vertexNodes = {},
146
- parentVertices = {},
147
- path = [];
148
- let vertexId = 1;
149
-
150
- // Initially, we assume each vertex is unreachable
151
- this.network.nodes.forEach(vertex => {
152
-
153
- // Generate Unique Router Id
154
- vertex.uniqueRouterId = vertexId;
155
- vertexNodes[vertexId] = vertex;
156
-
157
- distanceMap[vertexId] = Infinity;
158
- checking[vertexId] = null;
159
- vertexList[vertexId] = true;
160
-
161
- vertexId++;
162
- });
163
-
164
- // The cost from the starting vertex to the starting vertex is 0
165
- distanceMap[start.uniqueRouterId] = 0;
166
-
167
- // check each vertex
168
- while (Object.keys(vertexList).length > 0) {
169
- const current = Number(
170
- Object.keys(vertexList).reduce((_checking, vertex) => {
171
- return distanceMap[_checking] > distanceMap[vertex]
172
- ? vertex
173
- : _checking;
174
- }, Object.keys(vertexList)[0])
175
- );
176
-
177
- // all the vertices accessible from current vertex
178
- this.network.edges
179
- .filter(edge => {
180
-
181
- if (!acceptEdgeFn(edge)) {
182
- return false;
183
- }
184
-
185
- const from = edge.node1.uniqueRouterId,
186
- to = edge.node2.uniqueRouterId;
187
- // are these vertices joined?
188
- return from === current || to === current;
189
- })
190
- // for each vertex we can reach
191
- .forEach(edge => {
192
- let to, from;
193
- // determine the direction of travel
194
- if (edge.node1.uniqueRouterId === current) {
195
- to = edge.node2.uniqueRouterId;
196
- from = edge.node1.uniqueRouterId;
197
- } else {
198
- to = edge.node1.uniqueRouterId;
199
- from = edge.node2.uniqueRouterId;
200
- }
201
- // distance is how far we travelled to reach the
202
- // current vertex, plus cost of travel the next(to)
203
- const distance = distanceMap[current] + edge.length;
204
-
205
- // if we have found a cheaper path
206
- // update the hash of costs
207
- // and record which vertex we came from
208
- if (distanceMap[to] > distance) {
209
- distanceMap[to] = distance;
210
- checking[to] = current;
211
- parentVertices[to] = from;
212
- }
213
- });
214
-
215
- // remove vertex so we don't revisit it
216
- delete vertexList[current];
217
- }
218
-
219
- // now we have the most efficient paths for all vertices
220
- // build the path for the user specified vertex(end)
221
- let endId = end.uniqueRouterId;
222
- while (parentVertices[endId]) {
223
- path.unshift(vertexNodes[endId]);
224
- endId = parentVertices[endId];
225
- }
226
- if (path.length !== 0) {
227
- path.unshift(start);
228
- }
229
-
230
- // Remove Unique Router Id
231
- this.network.nodes.forEach(vertex => {
232
- delete vertex.uniqueRouterId;
233
- });
234
-
235
- return path;
236
- }
237
- }
238
- export default GraphRouter;
@@ -1,72 +0,0 @@
1
- import { expect } from 'chai';
2
-
3
- import GraphRouter from './GraphRouter';
4
-
5
- import {
6
- network, nodes, itineraryStart, itineraryEnd
7
- } from '../../tests/CommonTest';
8
-
9
- describe('GraphRouter', () => {
10
-
11
-
12
- const router = new GraphRouter(network);
13
- let itinerary;
14
-
15
-
16
- it('network did not change', () => {
17
- const nodesBefore = network.nodes.slice(0);
18
- const edgesBefore = network.edges.slice(0);
19
-
20
- itinerary = router.getShortestPath(itineraryStart, itineraryEnd);
21
-
22
- const isEdgeInArray = (edgeArray, edge) => edgeArray.find(_edge =>
23
- edge.node1 === _edge.node1
24
- && edge.node2 === _edge.node2
25
- && edge.level === _edge.level
26
- && edge.data === _edge.data
27
- );
28
- const areEdgeArrayEquals = (edgeArray1, edgeArray2) => {
29
- if (edgeArray1.length !== edgeArray2.length) {
30
- return false;
31
- }
32
- for (let j = 0; j < edgeArray1.length; j++) {
33
- if (!isEdgeInArray(edgeArray2, edgeArray1[j])) {
34
- return false;
35
- }
36
- }
37
- for (let j = 0; j < edgeArray2.length; j++) {
38
- if (!isEdgeInArray(edgeArray1, edgeArray2[j])) {
39
- return false;
40
- }
41
- }
42
- return true;
43
- };
44
-
45
- expect(network.nodes.length).equals(nodesBefore.length);
46
- for (let i = 0; i < nodesBefore.length; i++) {
47
- const node = network.nodes[i];
48
- const nodeBefore = nodesBefore[i];
49
- expect(nodeBefore).equals(node);
50
- expect(areEdgeArrayEquals(node.edges, nodeBefore.edges)).true;
51
- }
52
-
53
- expect(areEdgeArrayEquals(network.edges, edgesBefore)).true;
54
- });
55
-
56
- it('router returns shortest path', () => {
57
-
58
- expect(itinerary.nodes.length).equal(11);
59
-
60
- for (let i = 1; i <= 10; i++) {
61
- expect(itinerary.nodes[i]).equal(nodes[i + 6]);
62
- }
63
-
64
- });
65
-
66
- it('no route found', () => {
67
- const itineraryWithoutStairs = router.getShortestPath(itineraryStart, itineraryEnd,
68
- edge => !edge.data || !edge.data.hasOwnProperty('stairs') || !edge.data.stairs
69
- );
70
- expect(itineraryWithoutStairs).is.undefined;
71
- });
72
- });