terra-route 0.0.11 → 0.0.12

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.
Files changed (34) hide show
  1. package/README.md +2 -12
  2. package/dist/terra-route.cjs +1 -1
  3. package/dist/terra-route.cjs.map +1 -1
  4. package/dist/terra-route.d.ts +1 -2
  5. package/dist/terra-route.modern.js +1 -1
  6. package/dist/terra-route.modern.js.map +1 -1
  7. package/dist/terra-route.module.js +1 -1
  8. package/dist/terra-route.module.js.map +1 -1
  9. package/dist/terra-route.umd.js +1 -1
  10. package/dist/terra-route.umd.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/terra-route.ts +1 -2
  13. package/src/graph/graph.spec.ts +0 -238
  14. package/src/graph/graph.ts +0 -212
  15. package/src/graph/methods/bounding-box.spec.ts +0 -199
  16. package/src/graph/methods/bounding-box.ts +0 -85
  17. package/src/graph/methods/connected.spec.ts +0 -219
  18. package/src/graph/methods/connected.ts +0 -168
  19. package/src/graph/methods/duplicates.spec.ts +0 -161
  20. package/src/graph/methods/duplicates.ts +0 -117
  21. package/src/graph/methods/leaf.spec.ts +0 -224
  22. package/src/graph/methods/leaf.ts +0 -88
  23. package/src/graph/methods/nodes.spec.ts +0 -317
  24. package/src/graph/methods/nodes.ts +0 -77
  25. package/src/graph/methods/spatial-index/geokdbush.spec.ts +0 -86
  26. package/src/graph/methods/spatial-index/geokdbush.ts +0 -189
  27. package/src/graph/methods/spatial-index/kdbush.spec.ts +0 -67
  28. package/src/graph/methods/spatial-index/kdbush.ts +0 -189
  29. package/src/graph/methods/spatial-index/tinyqueue.spec.ts +0 -51
  30. package/src/graph/methods/spatial-index/tinyqueue.ts +0 -108
  31. package/src/graph/methods/unify.spec.ts +0 -475
  32. package/src/graph/methods/unify.ts +0 -132
  33. package/src/graph/methods/unique.spec.ts +0 -65
  34. package/src/graph/methods/unique.ts +0 -69
@@ -1,317 +0,0 @@
1
- import { FeatureCollection, LineString } from 'geojson';
2
- import { graphGetNodesAsPoints, graphGetNodeAndEdgeCount } from './nodes';
3
- import { createFeatureCollection, createLineStringFeature } from '../../test-utils/create';
4
-
5
- describe('graphGetNodeAndEdgeCount', () => {
6
- describe('for an empty feature collection', () => {
7
- it('returns 0 nodes and edges', () => {
8
- const input: FeatureCollection<LineString> = createFeatureCollection([]);
9
- const output = graphGetNodeAndEdgeCount(input);
10
-
11
- expect(output).toEqual({
12
- nodeCount: 0,
13
- edgeCount: 0
14
- });
15
- });
16
- });
17
-
18
- describe('for feature collection with 1 linestring', () => {
19
- it('returns 1', () => {
20
- const input: FeatureCollection<LineString> = createFeatureCollection([
21
- createLineStringFeature([[0, 0], [1, 1]])
22
- ]);
23
- const output = graphGetNodeAndEdgeCount(input);
24
-
25
- expect(output).toEqual({
26
- nodeCount: 2,
27
- edgeCount: 1
28
- });
29
- });
30
- });
31
-
32
- describe('for feature collection with 2 linestring', () => {
33
- it('returns 3 nodes and 2 edges if line is connected', () => {
34
- const input: FeatureCollection<LineString> = createFeatureCollection([
35
- createLineStringFeature([[0, 0], [1, 1]]),
36
- createLineStringFeature([[1, 1], [2, 2]]),
37
-
38
- ]);
39
- const output = graphGetNodeAndEdgeCount(input);
40
-
41
- expect(output).toEqual({
42
- nodeCount: 3,
43
- edgeCount: 2
44
- });
45
- });
46
-
47
- it('returns 4 nodes and 2 if unconnected', () => {
48
- const input: FeatureCollection<LineString> = createFeatureCollection([
49
- createLineStringFeature([[0, 0], [1, 1]]),
50
- createLineStringFeature([[10, 10], [11, 11]]),
51
-
52
- ]);
53
- const output = graphGetNodeAndEdgeCount(input);
54
-
55
- expect(output).toEqual({
56
- nodeCount: 4,
57
- edgeCount: 2
58
- });
59
- });
60
- });
61
-
62
- describe('for feature collection with 3 linestring', () => {
63
- it('returns 1 if connected', () => {
64
- const input: FeatureCollection<LineString> = createFeatureCollection([
65
- createLineStringFeature([[0, 0], [1, 1]]),
66
- createLineStringFeature([[1, 1], [2, 2]]),
67
- createLineStringFeature([[2, 2], [3, 3]]),
68
-
69
- ]);
70
- const output = graphGetNodeAndEdgeCount(input);
71
-
72
- expect(output).toEqual({
73
- nodeCount: 4,
74
- edgeCount: 3
75
- });
76
- });
77
-
78
- it('returns 3 if unconnected', () => {
79
- const input: FeatureCollection<LineString> = createFeatureCollection([
80
- createLineStringFeature([[0, 0], [1, 1]]),
81
- createLineStringFeature([[10, 10], [11, 11]]),
82
- createLineStringFeature([[20, 20], [21, 21]]),
83
- ]);
84
- const output = graphGetNodeAndEdgeCount(input);
85
-
86
- expect(output).toEqual({
87
- nodeCount: 6,
88
- edgeCount: 3
89
- });
90
- });
91
- });
92
-
93
-
94
- describe('for feature collection with multiple linestring', () => {
95
- it('returns 1 when all lines share the same coordinate', () => {
96
- const input = createFeatureCollection([
97
- createLineStringFeature([[0, 0], [1, 1]]),
98
- createLineStringFeature([[1, 1], [2, 2]]),
99
- createLineStringFeature([[1, 1], [3, 3]]),
100
- createLineStringFeature([[4, 4], [1, 1]]),
101
- ]);
102
- const output = graphGetNodeAndEdgeCount(input);
103
-
104
- expect(output).toEqual({
105
- nodeCount: 5,
106
- edgeCount: 4
107
- });
108
- });
109
-
110
- it('returns 2 when two disconnected groups exist', () => {
111
- const input = createFeatureCollection([
112
- createLineStringFeature([[0, 0], [1, 1]]),
113
- createLineStringFeature([[1, 1], [2, 2]]),
114
- createLineStringFeature([[10, 10], [11, 11]]),
115
- createLineStringFeature([[11, 11], [12, 12]]),
116
- ]);
117
- const output = graphGetNodeAndEdgeCount(input);
118
-
119
- expect(output).toEqual({
120
- nodeCount: 6,
121
- edgeCount: 4
122
- });
123
- });
124
-
125
-
126
- it('returns 1 for a loop of connected lines', () => {
127
- const input = createFeatureCollection([
128
- createLineStringFeature([[0, 0], [1, 0]]),
129
- createLineStringFeature([[1, 0], [1, 1]]),
130
- createLineStringFeature([[1, 1], [0, 1]]),
131
- createLineStringFeature([[0, 1], [0, 0]]),
132
- ]);
133
- const output = graphGetNodeAndEdgeCount(input);
134
-
135
- expect(output).toEqual({
136
- nodeCount: 4,
137
- edgeCount: 4
138
- });
139
- });
140
- });
141
- });
142
-
143
- describe('graphGetNodesAsPoints', () => {
144
- it('returns an empty array for an empty feature collection', () => {
145
- const input: FeatureCollection<LineString> = createFeatureCollection([]);
146
- const output = graphGetNodesAsPoints(input);
147
-
148
- expect(output).toEqual([]);
149
- });
150
-
151
- it('returns points for a single linestring', () => {
152
- const input: FeatureCollection<LineString> = createFeatureCollection([
153
- createLineStringFeature([[0, 0], [1, 1]])
154
- ]);
155
- const output = graphGetNodesAsPoints(input);
156
-
157
- expect(output).toEqual([
158
- {
159
- type: 'Feature',
160
- geometry: {
161
- type: 'Point',
162
- coordinates: [0, 0]
163
- },
164
- properties: {}
165
- },
166
- {
167
- type: 'Feature',
168
- geometry: {
169
- type: 'Point',
170
- coordinates: [1, 1]
171
- },
172
- properties: {}
173
- }
174
- ]);
175
- });
176
-
177
- it('returns points for multiple linestrings with unique coordinates', () => {
178
- const input: FeatureCollection<LineString> = createFeatureCollection([
179
- createLineStringFeature([[0, 0], [1, 1]]),
180
- createLineStringFeature([[1, 1], [2, 2]]),
181
- createLineStringFeature([[3, 3], [4, 4]])
182
- ]);
183
- const output = graphGetNodesAsPoints(input);
184
-
185
- expect(output).toEqual([
186
- {
187
- type: 'Feature',
188
- geometry: {
189
- type: 'Point',
190
- coordinates: [0, 0]
191
- },
192
- properties: {}
193
- },
194
- {
195
- type: 'Feature',
196
- geometry: {
197
- type: 'Point',
198
- coordinates: [1, 1]
199
- },
200
- properties: {}
201
- },
202
- {
203
- type: 'Feature',
204
- geometry: {
205
- type: 'Point',
206
- coordinates: [2, 2]
207
- },
208
- properties: {}
209
- },
210
- {
211
- type: 'Feature',
212
- geometry: {
213
- type: 'Point',
214
- coordinates: [3, 3]
215
- },
216
- properties: {}
217
- },
218
- {
219
- type: 'Feature',
220
- geometry: {
221
- type: 'Point',
222
- coordinates: [4, 4]
223
- },
224
- properties: {}
225
- }
226
- ]);
227
- });
228
-
229
- it('returns points for multiple linestrings with shared coordinates', () => {
230
- const input: FeatureCollection<LineString> = createFeatureCollection([
231
- createLineStringFeature([[0, 0], [1, 1]]),
232
- createLineStringFeature([[1, 1], [2, 2]]),
233
- createLineStringFeature([[1, 1], [3, 3]])
234
- ]);
235
- const output = graphGetNodesAsPoints(input);
236
-
237
- expect(output).toEqual([
238
- {
239
- type: 'Feature',
240
- geometry: {
241
- type: 'Point',
242
- coordinates: [0, 0]
243
- },
244
- properties: {}
245
- },
246
- {
247
- type: 'Feature',
248
- geometry: {
249
- type: 'Point',
250
- coordinates: [1, 1]
251
- },
252
- properties: {}
253
- },
254
- {
255
- type: 'Feature',
256
- geometry: {
257
- type: 'Point',
258
- coordinates: [2, 2]
259
- },
260
- properties: {}
261
- },
262
- {
263
- type: 'Feature',
264
- geometry: {
265
- type: 'Point',
266
- coordinates: [3, 3]
267
- },
268
- properties: {}
269
- }
270
- ]);
271
- });
272
-
273
- it('returns points for a loop of connected lines', () => {
274
- const input: FeatureCollection<LineString> = createFeatureCollection([
275
- createLineStringFeature([[0, 0], [1, 0]]),
276
- createLineStringFeature([[1, 0], [1, 1]]),
277
- createLineStringFeature([[1, 1], [0, 1]]),
278
- createLineStringFeature([[0, 1], [0, 0]]),
279
- ]);
280
- const output = graphGetNodesAsPoints(input);
281
-
282
- expect(output).toEqual([
283
- {
284
- type: 'Feature',
285
- geometry: {
286
- type: 'Point',
287
- coordinates: [0, 0]
288
- },
289
- properties: {}
290
- },
291
- {
292
- type: 'Feature',
293
- geometry: {
294
- type: 'Point',
295
- coordinates: [1, 0]
296
- },
297
- properties: {}
298
- },
299
- {
300
- type: 'Feature',
301
- geometry: {
302
- type: 'Point',
303
- coordinates: [1, 1]
304
- },
305
- properties: {}
306
- },
307
- {
308
- type: 'Feature',
309
- geometry: {
310
- type: 'Point',
311
- coordinates: [0, 1]
312
- },
313
- properties: {}
314
- }
315
- ]);
316
- });
317
- })
@@ -1,77 +0,0 @@
1
- import { Feature, FeatureCollection, LineString, Point, Position } from 'geojson'
2
-
3
- /**
4
- * Counts the unique nodes and edges in a GeoJSON FeatureCollection of LineString features.
5
- * @param featureCollection - A GeoJSON FeatureCollection containing LineString features
6
- * @returns An object containing the count of unique nodes and edges
7
- */
8
- export function graphGetNodeAndEdgeCount(
9
- featureCollection: FeatureCollection<LineString>
10
- ): { nodeCount: number; edgeCount: number } {
11
- const nodeSet = new Set<string>()
12
- const edgeSet = new Set<string>()
13
-
14
- for (const feature of featureCollection.features) {
15
- const coordinates = feature.geometry.coordinates
16
-
17
- for (const coordinate of coordinates) {
18
- nodeSet.add(JSON.stringify(coordinate))
19
- }
20
-
21
- for (let i = 0; i < coordinates.length - 1; i++) {
22
- const coordinateOne = coordinates[i]
23
- const coordinateTwo = coordinates[i + 1]
24
-
25
- const edge = normalizeEdge(coordinateOne, coordinateTwo)
26
- edgeSet.add(edge)
27
- }
28
- }
29
-
30
- return {
31
- nodeCount: nodeSet.size,
32
- edgeCount: edgeSet.size,
33
- }
34
- }
35
-
36
- function normalizeEdge(coordinateOne: Position, coordinateTwo: Position): string {
37
- const stringOne = JSON.stringify(coordinateOne)
38
- const stringTwo = JSON.stringify(coordinateTwo)
39
-
40
- if (stringOne < stringTwo) {
41
- return `${stringOne}|${stringTwo}`
42
- }
43
-
44
- return `${stringTwo}|${stringOne}`
45
- }
46
-
47
-
48
- /**
49
- * Converts a FeatureCollection of LineString features into a FeatureCollection of Point features,
50
- * where each unique coordinate in the LineStrings becomes a Point.
51
- * @param lines - A GeoJSON FeatureCollection containing LineString features
52
- * @returns A FeatureCollection of Point features representing unique nodes
53
- */
54
- export function graphGetNodesAsPoints(lines: FeatureCollection<LineString>): Feature<Point>[] {
55
- const seen = new Set<string>();
56
- const points: Feature<Point>[] = [];
57
-
58
- for (const feature of lines.features) {
59
- for (const coord of feature.geometry.coordinates) {
60
- const key = coord.join(',');
61
-
62
- if (!seen.has(key)) {
63
- seen.add(key);
64
- points.push({
65
- type: 'Feature',
66
- geometry: {
67
- type: 'Point',
68
- coordinates: coord
69
- },
70
- properties: {}
71
- });
72
- }
73
- }
74
- }
75
-
76
- return points;
77
- }
@@ -1,86 +0,0 @@
1
- import { KDBush } from './kdbush';
2
- import { around, distance } from './geokdbush';
3
-
4
- describe('geokdbush', () => {
5
- const points = [
6
- [0, 0], [1, 1], [2, 2], [3, 3],
7
- [1, 0], [0, 1], [3, 2], [2, 3]
8
- ];
9
- const index = new KDBush(points.length);
10
- for (const p of points) {
11
- index.add(p[0], p[1]);
12
- }
13
- index.finish();
14
-
15
- it('should return points within a given radius', () => {
16
- const d = distance(0, 0, 1, 1);
17
- const result = around(index, 0, 0, Infinity, d + 1);
18
- const resultPoints = result.map(i => points[i]);
19
- expect(resultPoints).toEqual(expect.arrayContaining([
20
- [0, 0], [1, 1], [1, 0], [0, 1]
21
- ]));
22
- expect(resultPoints.length).toBe(4);
23
- });
24
-
25
- it('defaults to maxResults and maxDistance being Infinity', () => {
26
- const result = around(index, 0, 0);
27
- expect(result.length).toBe(points.length);
28
- const resultPoints = result.map(i => points[i]);
29
- expect(resultPoints).toEqual(expect.arrayContaining(points));
30
- });
31
-
32
- it('should return an empty array if no points are within the radius', () => {
33
- const result = around(index, 10, 10, Infinity, 1);
34
- expect(result).toEqual([]);
35
- });
36
-
37
- it('should handle maxResults correctly', () => {
38
- const result = around(index, 0, 0, 2);
39
- expect(result.length).toBe(2);
40
- });
41
-
42
- it('should also export a distance function', () => {
43
- expect(distance(0, 0, 1, 1)).toBeCloseTo(157.2493, 2);
44
- });
45
-
46
- describe('with a larger number of points', () => {
47
- const largePoints: [number, number][] = [];
48
- for (let i = 0; i < 1000; i++) {
49
- // Points around London
50
- largePoints.push([
51
- -0.1278 + (Math.random() - 0.5) * 2,
52
- 51.5074 + (Math.random() - 0.5) * 2
53
- ]);
54
- }
55
- const index = new KDBush(largePoints.length, 16);
56
- for (const p of largePoints) {
57
- index.add(p[0], p[1]);
58
- }
59
- index.finish();
60
-
61
- it('should find points around a location', () => {
62
- const results = around(index, -0.1278, 51.5074, 10);
63
- expect(results.length).toBe(10);
64
- results.forEach(i => {
65
- const p = largePoints[i];
66
- expect(distance(p[0], p[1], -0.1278, 51.5074)).toBeLessThan(200); // 200km, rough check
67
- });
68
- });
69
-
70
- it('should find points within a radius', () => {
71
- const results = around(index, -0.1278, 51.5074, Infinity, 10); // 10km radius
72
- expect(results.length).toBeGreaterThan(0);
73
- results.forEach(i => {
74
- const p = largePoints[i];
75
- expect(distance(p[0], p[1], -0.1278, 51.5074)).toBeLessThanOrEqual(10);
76
- });
77
- });
78
- });
79
-
80
- it('should work with maxResults being undefined', () => {
81
- const result = around(index, 0, 0, undefined);
82
- expect(result.length).toBe(points.length);
83
- });
84
-
85
-
86
- });
@@ -1,189 +0,0 @@
1
- // Adapted from https://github.com/mourner/geokdbush
2
-
3
- // ISC License
4
-
5
- // Copyright (c) 2017, Vladimir Agafonkin
6
-
7
- // Permission to use, copy, modify, and/or distribute this software for any purpose
8
- // with or without fee is hereby granted, provided that the above copyright notice
9
- // and this permission notice appear in all copies.
10
-
11
- // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
- // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
13
- // FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
- // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
15
- // OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16
- // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
17
- // THIS SOFTWARE.
18
-
19
- import { KDBush } from './kdbush';
20
- import TinyQueue from './tinyqueue';
21
-
22
- const earthRadius = 6371;
23
- const rad = Math.PI / 180;
24
-
25
-
26
- // Distance is in kilometers
27
- export function around(index: KDBush, lng: number, lat: number, maxResults = Infinity, maxDistanceKm = Infinity) {
28
- let maxHaverSinDist = 1;
29
- const result = [];
30
-
31
- if (maxResults === undefined) {
32
- maxResults = Infinity;
33
- }
34
-
35
- if (maxDistanceKm !== undefined) {
36
- maxHaverSinDist = haverSin(maxDistanceKm / earthRadius);
37
- }
38
-
39
- // a distance-sorted priority queue that will contain both points and kd-tree nodes
40
- const q = new TinyQueue([], compareDist);
41
-
42
- // an object that represents the top kd-tree node (the whole Earth)
43
- let node = {
44
- left: 0, // left index in the kd-tree array
45
- right: index.ids.length - 1, // right index
46
- axis: 0, // 0 for longitude axis and 1 for latitude axis
47
- dist: 0, // will hold the lower bound of children's distances to the query point
48
- minLng: -180, // bounding box of the node
49
- minLat: -90,
50
- maxLng: 180,
51
- maxLat: 90
52
- };
53
-
54
- const cosLat = Math.cos(lat * rad);
55
-
56
- while (node) {
57
- const right = node.right;
58
- const left = node.left;
59
-
60
- if (right - left <= index.nodeSize) { // leaf node
61
-
62
- // add all points of the leaf node to the queue
63
- for (let i = left; i <= right; i++) {
64
- const id = index.ids[i];
65
-
66
- const dist = haverSinDist(lng, lat, index.coords[2 * i], index.coords[2 * i + 1], cosLat);
67
- q.push({ id, dist });
68
- }
69
-
70
- } else { // not a leaf node (has child nodes)
71
-
72
- const m = (left + right) >> 1; // middle index
73
- const midLng = index.coords[2 * m];
74
- const midLat = index.coords[2 * m + 1];
75
-
76
- // add middle point to the queue
77
- const id = index.ids[m];
78
- const dist = haverSinDist(lng, lat, midLng, midLat, cosLat);
79
- q.push({ id, dist });
80
-
81
-
82
- const nextAxis = (node.axis + 1) % 2;
83
-
84
- // first half of the node
85
- const leftNode = {
86
- left,
87
- right: m - 1,
88
- axis: nextAxis,
89
- minLng: node.minLng,
90
- minLat: node.minLat,
91
- maxLng: node.axis === 0 ? midLng : node.maxLng,
92
- maxLat: node.axis === 1 ? midLat : node.maxLat,
93
- dist: 0
94
- };
95
- // second half of the node
96
- const rightNode = {
97
- left: m + 1,
98
- right,
99
- axis: nextAxis,
100
- minLng: node.axis === 0 ? midLng : node.minLng,
101
- minLat: node.axis === 1 ? midLat : node.minLat,
102
- maxLng: node.maxLng,
103
- maxLat: node.maxLat,
104
- dist: 0
105
- };
106
-
107
- leftNode.dist = boxDist(lng, lat, cosLat, leftNode);
108
- rightNode.dist = boxDist(lng, lat, cosLat, rightNode);
109
-
110
- // add child nodes to the queue
111
- q.push(leftNode);
112
- q.push(rightNode);
113
- }
114
-
115
- // fetch closest points from the queue; they're guaranteed to be closer
116
- // than all remaining points (both individual and those in kd-tree nodes),
117
- // since each node's distance is a lower bound of distances to its children
118
- while (q.length && q.peek().id != null) {
119
- const candidate = q.pop()!;
120
- if (candidate.dist > maxHaverSinDist) return result;
121
- result.push(candidate.id);
122
- if (result.length === maxResults) return result;
123
- }
124
-
125
- // the next closest kd-tree node
126
- node = q.pop();
127
- }
128
-
129
- return result;
130
- }
131
-
132
- // lower bound for distance from a location to points inside a bounding box
133
- function boxDist(lng: number, lat: number, cosLat: number, node: any) {
134
- const minLng = node.minLng;
135
- const maxLng = node.maxLng;
136
- const minLat = node.minLat;
137
- const maxLat = node.maxLat;
138
-
139
- // query point is between minimum and maximum longitudes
140
- if (lng >= minLng && lng <= maxLng) {
141
- if (lat < minLat) return haverSin((lat - minLat) * rad);
142
- if (lat > maxLat) return haverSin((lat - maxLat) * rad);
143
- return 0;
144
- }
145
-
146
- // query point is west or east of the bounding box;
147
- // calculate the extremum for great circle distance from query point to the closest longitude;
148
- const haverSinDLng = Math.min(haverSin((lng - minLng) * rad), haverSin((lng - maxLng) * rad));
149
- const extremumLat = vertexLat(lat, haverSinDLng);
150
-
151
- // if extremum is inside the box, return the distance to it
152
- if (extremumLat > minLat && extremumLat < maxLat) {
153
- return haverSinDistPartial(haverSinDLng, cosLat, lat, extremumLat);
154
- }
155
- // otherwise return the distan e to one of the bbox corners (whichever is closest)
156
- return Math.min(
157
- haverSinDistPartial(haverSinDLng, cosLat, lat, minLat),
158
- haverSinDistPartial(haverSinDLng, cosLat, lat, maxLat)
159
- );
160
- }
161
-
162
- function compareDist(a: any, b: any) {
163
- return a.dist - b.dist;
164
- }
165
-
166
- function haverSin(theta: number) {
167
- const s = Math.sin(theta / 2);
168
- return s * s;
169
- }
170
-
171
- function haverSinDistPartial(haverSinDLng: number, cosLat1: number, lat1: number, lat2: number) {
172
- return cosLat1 * Math.cos(lat2 * rad) * haverSinDLng + haverSin((lat1 - lat2) * rad);
173
- }
174
-
175
- function haverSinDist(lng1: number, lat1: number, lng2: number, lat2: number, cosLat1: number) {
176
- const haverSinDLng = haverSin((lng1 - lng2) * rad);
177
- return haverSinDistPartial(haverSinDLng, cosLat1, lat1, lat2);
178
- }
179
-
180
- export function distance(lng1: number, lat1: number, lng2: number, lat2: number) {
181
- const h = haverSinDist(lng1, lat1, lng2, lat2, Math.cos(lat1 * rad));
182
- return 2 * earthRadius * Math.asin(Math.sqrt(h));
183
- }
184
-
185
- function vertexLat(lat: number, haverSinDLng: number) {
186
- const cosDLng = 1 - 2 * haverSinDLng;
187
- if (cosDLng <= 0) return lat > 0 ? 90 : -90;
188
- return Math.atan(Math.tan(lat * rad) / cosDLng) / rad;
189
- }