@konfirm/geojson 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/.editorconfig +16 -0
- package/.github/workflows/release.yml +21 -0
- package/.github/workflows/tests.yml +56 -0
- package/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +260 -0
- package/dist/Domain/Constants.d.ts +5 -0
- package/dist/Domain/GeoJSON/Concept/Altitude.d.ts +3 -0
- package/dist/Domain/GeoJSON/Concept/BoundingBox.d.ts +6 -0
- package/dist/Domain/GeoJSON/Concept/ExteriorRing.d.ts +4 -0
- package/dist/Domain/GeoJSON/Concept/GeoJSONObject.d.ts +11 -0
- package/dist/Domain/GeoJSON/Concept/InteriorRing.d.ts +4 -0
- package/dist/Domain/GeoJSON/Concept/Latitude.d.ts +3 -0
- package/dist/Domain/GeoJSON/Concept/LinearRing.d.ts +4 -0
- package/dist/Domain/GeoJSON/Concept/Longitude.d.ts +3 -0
- package/dist/Domain/GeoJSON/Concept/Position.d.ts +7 -0
- package/dist/Domain/GeoJSON/Feature.d.ts +12 -0
- package/dist/Domain/GeoJSON/FeatureCollection.d.ts +8 -0
- package/dist/Domain/GeoJSON/GeoJSON.d.ts +7 -0
- package/dist/Domain/GeoJSON/Geometry/LineString.d.ts +11 -0
- package/dist/Domain/GeoJSON/Geometry/MultiLineString.d.ts +7 -0
- package/dist/Domain/GeoJSON/Geometry/MultiPoint.d.ts +8 -0
- package/dist/Domain/GeoJSON/Geometry/MultiPolygon.d.ts +7 -0
- package/dist/Domain/GeoJSON/Geometry/Point.d.ts +11 -0
- package/dist/Domain/GeoJSON/Geometry/Polygon.d.ts +11 -0
- package/dist/Domain/GeoJSON/Geometry.d.ts +9 -0
- package/dist/Domain/GeoJSON/GeometryCollection.d.ts +8 -0
- package/dist/Domain/GeoJSON/GeometryObject.d.ts +12 -0
- package/dist/Domain/Guards/Number.d.ts +3 -0
- package/dist/Domain/Guards/Tuple.d.ts +3 -0
- package/dist/Domain/Iterator/IterablePair.d.ts +32 -0
- package/dist/Domain/Iterator/SimpleGeometry.d.ts +90 -0
- package/dist/Domain/Utility/Calculate.d.ts +9 -0
- package/dist/Domain/Utility/Distance.d.ts +3 -0
- package/dist/Domain/Utility/Intersect.d.ts +2 -0
- package/dist/Domain/Utility/Segments.d.ts +2 -0
- package/dist/Domain/Utility/Winding.d.ts +3 -0
- package/dist/geojson.cjs.js +655 -0
- package/dist/geojson.cjs.min.js +1 -0
- package/dist/geojson.d.ts +198 -0
- package/dist/geojson.es.js +627 -0
- package/dist/geojson.es.min.js +1 -0
- package/dist/geojson.js +660 -0
- package/dist/geojson.min.js +1 -0
- package/dist/main.d.ts +15 -0
- package/package.json +63 -0
- package/rollup.config.mjs +43 -0
- package/source/Domain/Constants.ts +5 -0
- package/source/Domain/GeoJSON/Concept/Altitude.ts +9 -0
- package/source/Domain/GeoJSON/Concept/BoundingBox.ts +31 -0
- package/source/Domain/GeoJSON/Concept/ExteriorRing.ts +12 -0
- package/source/Domain/GeoJSON/Concept/GeoJSONObject.ts +23 -0
- package/source/Domain/GeoJSON/Concept/InteriorRing.ts +12 -0
- package/source/Domain/GeoJSON/Concept/Latitude.ts +7 -0
- package/source/Domain/GeoJSON/Concept/LinearRing.ts +14 -0
- package/source/Domain/GeoJSON/Concept/Longitude.ts +7 -0
- package/source/Domain/GeoJSON/Concept/Position.ts +18 -0
- package/source/Domain/GeoJSON/Feature.ts +24 -0
- package/source/Domain/GeoJSON/FeatureCollection.ts +16 -0
- package/source/Domain/GeoJSON/GeoJSON.ts +9 -0
- package/source/Domain/GeoJSON/Geometry/LineString.ts +12 -0
- package/source/Domain/GeoJSON/Geometry/MultiLineString.ts +9 -0
- package/source/Domain/GeoJSON/Geometry/MultiPoint.ts +10 -0
- package/source/Domain/GeoJSON/Geometry/MultiPolygon.ts +9 -0
- package/source/Domain/GeoJSON/Geometry/Point.ts +12 -0
- package/source/Domain/GeoJSON/Geometry/Polygon.ts +20 -0
- package/source/Domain/GeoJSON/Geometry.ts +11 -0
- package/source/Domain/GeoJSON/GeometryCollection.ts +23 -0
- package/source/Domain/GeoJSON/GeometryObject.ts +20 -0
- package/source/Domain/Guards/Number.ts +13 -0
- package/source/Domain/Guards/Tuple.ts +6 -0
- package/source/Domain/Guards/Utility.ts +1 -0
- package/source/Domain/Iterator/IterablePair.ts +47 -0
- package/source/Domain/Iterator/SimpleGeometry.ts +137 -0
- package/source/Domain/Utility/Calculate.ts +143 -0
- package/source/Domain/Utility/Distance.ts +56 -0
- package/source/Domain/Utility/Intersect.ts +42 -0
- package/source/Domain/Utility/Numeric.ts +8 -0
- package/source/Domain/Utility/Segments.ts +5 -0
- package/source/Domain/Utility/Winding.ts +19 -0
- package/source/main.ts +20 -0
- package/test/Domain/GeoJSON/Concept/Altitude.ts +58 -0
- package/test/Domain/GeoJSON/Concept/BoundingBox.ts +77 -0
- package/test/Domain/GeoJSON/Concept/ExteriorRing.ts +65 -0
- package/test/Domain/GeoJSON/Concept/GeoJSONObject.ts +56 -0
- package/test/Domain/GeoJSON/Concept/InteriorRing.ts +65 -0
- package/test/Domain/GeoJSON/Concept/Latitude.ts +56 -0
- package/test/Domain/GeoJSON/Concept/LinearRing.ts +63 -0
- package/test/Domain/GeoJSON/Concept/Longitude.ts +56 -0
- package/test/Domain/GeoJSON/Concept/Position.ts +56 -0
- package/test/Domain/GeoJSON/Feature.ts +9 -0
- package/test/Domain/GeoJSON/FeatureCollection.ts +9 -0
- package/test/Domain/GeoJSON/GeoJSON.ts +21 -0
- package/test/Domain/GeoJSON/Geometry/LineString.ts +11 -0
- package/test/Domain/GeoJSON/Geometry/MultiLineString.ts +11 -0
- package/test/Domain/GeoJSON/Geometry/MultiPoint.ts +11 -0
- package/test/Domain/GeoJSON/Geometry/MultiPolygon.ts +11 -0
- package/test/Domain/GeoJSON/Geometry/Point.ts +11 -0
- package/test/Domain/GeoJSON/Geometry/Polygon.ts +11 -0
- package/test/Domain/GeoJSON/Geometry.ts +9 -0
- package/test/Domain/GeoJSON/GeometryCollection.ts +9 -0
- package/test/Domain/GeoJSON/GeometryObject.ts +4 -0
- package/test/Domain/Guards/Number.ts +49 -0
- package/test/Domain/Guards/Tuple.ts +27 -0
- package/test/Domain/Iterator/IterablePair.ts +203 -0
- package/test/Domain/Iterator/SimpleGeometry.ts +195 -0
- package/test/Domain/Utility/Calculate.ts +178 -0
- package/test/Domain/Utility/Distance.ts +19 -0
- package/test/Domain/Utility/Intersect.ts +54 -0
- package/test/Domain/Utility/Numeric.ts +30 -0
- package/test/Domain/Utility/Winding.ts +52 -0
- package/test/README.ts +123 -0
- package/test/data/Distance.ts +51 -0
- package/test/data/HolySee.ts +74 -0
- package/test/data/Intersect.ts +300 -0
- package/test/data/Italy.ts +2883 -0
- package/test/data/SanMarino.ts +83 -0
- package/test/data/Shapes.ts +107 -0
- package/test/helper/geometry.ts +76 -0
- package/test/helper/malform.ts +82 -0
- package/test/main.ts +4 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import * as Export from '../../../source/Domain/Iterator/IterablePair';
|
|
3
|
+
import { SimpleGeometryIterator } from '../../../source/Domain/Iterator/SimpleGeometry';
|
|
4
|
+
import { Point } from '../../../source/Domain/GeoJSON/Geometry/Point';
|
|
5
|
+
import { MultiPoint } from '../../../source/Domain/GeoJSON/Geometry/MultiPoint';
|
|
6
|
+
import { LineString } from '../../../source/Domain/GeoJSON/Geometry/LineString';
|
|
7
|
+
import { MultiLineString } from '../../../source/Domain/GeoJSON/Geometry/MultiLineString';
|
|
8
|
+
import { Polygon } from '../../../source/Domain/GeoJSON/Geometry/Polygon';
|
|
9
|
+
import { MultiPolygon } from '../../../source/Domain/GeoJSON/Geometry/MultiPolygon';
|
|
10
|
+
import { GeometryCollection } from '../../../source/Domain/GeoJSON/GeometryCollection';
|
|
11
|
+
import { Feature } from '../../../source/Domain/GeoJSON/Feature';
|
|
12
|
+
import { FeatureCollection } from '../../../source/Domain/GeoJSON/FeatureCollection';
|
|
13
|
+
import { explain, exported } from '../../helper/geometry';
|
|
14
|
+
|
|
15
|
+
const point: Point = { type: 'Point', coordinates: [0, 0] };
|
|
16
|
+
const multipoint: MultiPoint = { type: 'MultiPoint', coordinates: [[1, 1], [2, 2]] };
|
|
17
|
+
const linestring: LineString = { type: 'LineString', coordinates: [[3, 3], [4, 4]] };
|
|
18
|
+
const multilinestring: MultiLineString = { type: 'MultiLineString', coordinates: [[[5, 5], [6, 6]], [[7, 7], [8, 8]], [[9, 9], [10, 10]]] };
|
|
19
|
+
const polygon: Polygon = { type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] };
|
|
20
|
+
const multipolygon: MultiPolygon = { type: 'MultiPolygon', coordinates: [[[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]], [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]]] };
|
|
21
|
+
const geometrycollection: GeometryCollection = { type: 'GeometryCollection', geometries: [point, multipoint] };
|
|
22
|
+
const feature: Feature = { type: 'Feature', properties: null, geometry: linestring };
|
|
23
|
+
const featurecollection: FeatureCollection = {
|
|
24
|
+
type: 'FeatureCollection', features: [
|
|
25
|
+
{ type: 'Feature', properties: null, geometry: multilinestring },
|
|
26
|
+
{ type: 'Feature', properties: null, geometry: polygon },
|
|
27
|
+
{ type: 'Feature', properties: null, geometry: multipolygon },
|
|
28
|
+
]
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
exported('Domain/Iterator/IterablePair', Export, 'IterablePairIterator');
|
|
32
|
+
|
|
33
|
+
const { IterablePairIterator } = Export;
|
|
34
|
+
|
|
35
|
+
test('Domain/Iterator/IterablePair - implements Symbol.iterator', (t) => {
|
|
36
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(point), new SimpleGeometryIterator(multipoint));
|
|
37
|
+
|
|
38
|
+
t.ok(Symbol.iterator in iterator, 'SimpleGeometryIterator implements Symbol.iterator');
|
|
39
|
+
|
|
40
|
+
t.end();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('Domain/Iterator/IterablePair - Point with MultiPoint', (t) => {
|
|
44
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(point), new SimpleGeometryIterator(multipoint));
|
|
45
|
+
const expanded = [...iterator];
|
|
46
|
+
const expected = [
|
|
47
|
+
[point, { type: 'Point', coordinates: [1, 1] }],
|
|
48
|
+
[point, { type: 'Point', coordinates: [2, 2] }],
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} combinations`);
|
|
52
|
+
|
|
53
|
+
let index = 0;
|
|
54
|
+
for (const combo of iterator) {
|
|
55
|
+
const expect = expected[index++];
|
|
56
|
+
|
|
57
|
+
t.deepEqual(combo, expect, `combination is ${explain(expect[0])} with ${explain(expect[1])}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
t.end();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('Domain/Iterator/IterablePair - MultiPoint with LineString', (t) => {
|
|
64
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(multipoint), new SimpleGeometryIterator(linestring));
|
|
65
|
+
const expanded = [...iterator];
|
|
66
|
+
const expected = [
|
|
67
|
+
[{ type: 'Point', coordinates: [1, 1] }, linestring],
|
|
68
|
+
[{ type: 'Point', coordinates: [2, 2] }, linestring],
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} combinations`);
|
|
72
|
+
|
|
73
|
+
let index = 0;
|
|
74
|
+
for (const combo of iterator) {
|
|
75
|
+
const expect = expected[index++];
|
|
76
|
+
|
|
77
|
+
t.deepEqual(combo, expect, `combination is ${explain(expect[0])} with ${explain(expect[1])}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
t.end();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('Domain/Iterator/IterablePair - MultiPoint with MultiLineString', (t) => {
|
|
84
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(multipoint), new SimpleGeometryIterator(multilinestring));
|
|
85
|
+
const expanded = [...iterator];
|
|
86
|
+
const expected = [
|
|
87
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'LineString', coordinates: [[5, 5], [6, 6]] }],
|
|
88
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'LineString', coordinates: [[7, 7], [8, 8]] }],
|
|
89
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'LineString', coordinates: [[9, 9], [10, 10]] }],
|
|
90
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'LineString', coordinates: [[5, 5], [6, 6]] }],
|
|
91
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'LineString', coordinates: [[7, 7], [8, 8]] }],
|
|
92
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'LineString', coordinates: [[9, 9], [10, 10]] }],
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} combinations`);
|
|
96
|
+
|
|
97
|
+
let index = 0;
|
|
98
|
+
for (const combo of iterator) {
|
|
99
|
+
const expect = expected[index++];
|
|
100
|
+
|
|
101
|
+
t.deepEqual(combo, expect, `combination is ${explain(expect[0])} with ${explain(expect[1])}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
t.end();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('Domain/Iterator/IterablePair - MultiLineString with Polygon', (t) => {
|
|
108
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(multilinestring), new SimpleGeometryIterator(polygon));
|
|
109
|
+
const expanded = [...iterator];
|
|
110
|
+
const expected = [
|
|
111
|
+
[{ type: 'LineString', coordinates: [[5, 5], [6, 6]] }, polygon],
|
|
112
|
+
[{ type: 'LineString', coordinates: [[7, 7], [8, 8]] }, polygon],
|
|
113
|
+
[{ type: 'LineString', coordinates: [[9, 9], [10, 10]] }, polygon],
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} combinations`);
|
|
117
|
+
|
|
118
|
+
let index = 0;
|
|
119
|
+
for (const combo of iterator) {
|
|
120
|
+
const expect = expected[index++];
|
|
121
|
+
|
|
122
|
+
t.deepEqual(combo, expect, `combination is ${explain(expect[0])} with ${explain(expect[1])}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
t.end();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('Domain/Iterator/IterablePair - Polygon with MultiPolygon', (t) => {
|
|
129
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(polygon), new SimpleGeometryIterator(multipolygon));
|
|
130
|
+
const expanded = [...iterator];
|
|
131
|
+
const expected = [
|
|
132
|
+
[polygon, { type: 'Polygon', coordinates: [[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]] }],
|
|
133
|
+
[polygon, { type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] }],
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} combinations`);
|
|
137
|
+
|
|
138
|
+
let index = 0;
|
|
139
|
+
for (const combo of iterator) {
|
|
140
|
+
const expect = expected[index++];
|
|
141
|
+
|
|
142
|
+
t.deepEqual(combo, expect, `combination is ${explain(expect[0])} with ${explain(expect[1])}`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
t.end();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('Domain/Iterator/IterablePair - Polygon with Feature', (t) => {
|
|
149
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(polygon), new SimpleGeometryIterator(feature));
|
|
150
|
+
const expanded = [...iterator];
|
|
151
|
+
const expected = [
|
|
152
|
+
[polygon, linestring],
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} combinations`);
|
|
156
|
+
|
|
157
|
+
let index = 0;
|
|
158
|
+
for (const combo of iterator) {
|
|
159
|
+
const expect = expected[index++];
|
|
160
|
+
|
|
161
|
+
t.deepEqual(combo, expect, `combination is ${explain(expect[0])} with ${explain(expect[1])}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
t.end();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('Domain/Iterator/IterablePair - GeometryCollection with FeatureCollection', (t) => {
|
|
168
|
+
const iterator = new IterablePairIterator(new SimpleGeometryIterator(geometrycollection), new SimpleGeometryIterator(featurecollection));
|
|
169
|
+
const expanded = [...iterator];
|
|
170
|
+
const expected = [
|
|
171
|
+
[point, { type: 'LineString', coordinates: [[5, 5], [6, 6]] }],
|
|
172
|
+
[point, { type: 'LineString', coordinates: [[7, 7], [8, 8]] }],
|
|
173
|
+
[point, { type: 'LineString', coordinates: [[9, 9], [10, 10]] }],
|
|
174
|
+
[point, polygon],
|
|
175
|
+
[point, { type: 'Polygon', coordinates: [[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]] }],
|
|
176
|
+
[point, { type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] }],
|
|
177
|
+
|
|
178
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'LineString', coordinates: [[5, 5], [6, 6]] }],
|
|
179
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'LineString', coordinates: [[7, 7], [8, 8]] }],
|
|
180
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'LineString', coordinates: [[9, 9], [10, 10]] }],
|
|
181
|
+
[{ type: 'Point', coordinates: [1, 1] }, polygon],
|
|
182
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'Polygon', coordinates: [[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]] }],
|
|
183
|
+
[{ type: 'Point', coordinates: [1, 1] }, { type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] }],
|
|
184
|
+
|
|
185
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'LineString', coordinates: [[5, 5], [6, 6]] }],
|
|
186
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'LineString', coordinates: [[7, 7], [8, 8]] }],
|
|
187
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'LineString', coordinates: [[9, 9], [10, 10]] }],
|
|
188
|
+
[{ type: 'Point', coordinates: [2, 2] }, polygon],
|
|
189
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'Polygon', coordinates: [[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]] }],
|
|
190
|
+
[{ type: 'Point', coordinates: [2, 2] }, { type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] }],
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} combinations`);
|
|
194
|
+
|
|
195
|
+
let index = 0;
|
|
196
|
+
for (const combo of iterator) {
|
|
197
|
+
const expect = expected[index++];
|
|
198
|
+
|
|
199
|
+
t.deepEqual(combo, expect, `combination is ${explain(expect[0])} with ${explain(expect[1])}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
t.end();
|
|
203
|
+
});
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import * as Export from '../../../source/Domain/Iterator/SimpleGeometry';
|
|
3
|
+
import { Point } from '../../../source/Domain/GeoJSON/Geometry/Point';
|
|
4
|
+
import { MultiPoint } from '../../../source/Domain/GeoJSON/Geometry/MultiPoint';
|
|
5
|
+
import { LineString } from '../../../source/Domain/GeoJSON/Geometry/LineString';
|
|
6
|
+
import { MultiLineString } from '../../../source/Domain/GeoJSON/Geometry/MultiLineString';
|
|
7
|
+
import { Polygon } from '../../../source/Domain/GeoJSON/Geometry/Polygon';
|
|
8
|
+
import { MultiPolygon } from '../../../source/Domain/GeoJSON/Geometry/MultiPolygon';
|
|
9
|
+
import { GeometryCollection } from '../../../source/Domain/GeoJSON/GeometryCollection';
|
|
10
|
+
import { Feature } from '../../../source/Domain/GeoJSON/Feature';
|
|
11
|
+
import { FeatureCollection } from '../../../source/Domain/GeoJSON/FeatureCollection';
|
|
12
|
+
import { explain, exported } from '../../helper/geometry';
|
|
13
|
+
|
|
14
|
+
const point: Point = { type: 'Point', coordinates: [0, 0] };
|
|
15
|
+
const multipoint: MultiPoint = { type: 'MultiPoint', coordinates: [[1, 1], [2, 2]] };
|
|
16
|
+
const linestring: LineString = { type: 'LineString', coordinates: [[3, 3], [4, 4]] };
|
|
17
|
+
const multilinestring: MultiLineString = { type: 'MultiLineString', coordinates: [[[5, 5], [6, 6]], [[7, 7], [8, 8]], [[9, 9], [10, 10]]] };
|
|
18
|
+
const polygon: Polygon = { type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] };
|
|
19
|
+
const multipolygon: MultiPolygon = { type: 'MultiPolygon', coordinates: [[[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]], [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]]] };
|
|
20
|
+
const geometrycollection: GeometryCollection = { type: 'GeometryCollection', geometries: [point, multipoint] };
|
|
21
|
+
const feature: Feature = { type: 'Feature', properties: null, geometry: linestring };
|
|
22
|
+
const featurecollection: FeatureCollection = {
|
|
23
|
+
type: 'FeatureCollection', features: [
|
|
24
|
+
{ type: 'Feature', properties: null, geometry: multilinestring },
|
|
25
|
+
{ type: 'Feature', properties: null, geometry: polygon },
|
|
26
|
+
{ type: 'Feature', properties: null, geometry: multipolygon },
|
|
27
|
+
]
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
exported('Domain/Utility/SimpleGeometryIterator', Export, 'SimpleGeometryIterator');
|
|
31
|
+
|
|
32
|
+
const { SimpleGeometryIterator } = Export;
|
|
33
|
+
|
|
34
|
+
test('Domain/Utility/SimpleGeometryIterator - implements Symbol.iterator', (t) => {
|
|
35
|
+
const iterator = new SimpleGeometryIterator(point);
|
|
36
|
+
|
|
37
|
+
t.ok(Symbol.iterator in iterator, 'SimpleGeometryIterator implements Symbol.iterator');
|
|
38
|
+
|
|
39
|
+
t.end();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('Domain/Utility/SimpleGeometryIterator - Point with MultiPoint', (t) => {
|
|
43
|
+
const iterator = new SimpleGeometryIterator(point, multipoint);
|
|
44
|
+
const expanded = [...iterator];
|
|
45
|
+
const expected = [
|
|
46
|
+
point,
|
|
47
|
+
{ type: 'Point', coordinates: [1, 1] },
|
|
48
|
+
{ type: 'Point', coordinates: [2, 2] },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} SimpleGeometry values`);
|
|
52
|
+
|
|
53
|
+
let index = 0;
|
|
54
|
+
for (const combo of iterator) {
|
|
55
|
+
const expect = expected[index++];
|
|
56
|
+
|
|
57
|
+
t.deepEqual(combo, expect, `${explain(combo)} is ${explain(expect)}}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
t.end();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('Domain/Utility/SimpleGeometryIterator - MultiPoint with LineString', (t) => {
|
|
64
|
+
const iterator = new SimpleGeometryIterator(multipoint, linestring);
|
|
65
|
+
const expanded = [...iterator];
|
|
66
|
+
const expected = [
|
|
67
|
+
{ type: 'Point', coordinates: [1, 1] },
|
|
68
|
+
{ type: 'Point', coordinates: [2, 2] },
|
|
69
|
+
linestring,
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} SimpleGeometry values`);
|
|
73
|
+
|
|
74
|
+
let index = 0;
|
|
75
|
+
for (const combo of iterator) {
|
|
76
|
+
const expect = expected[index++];
|
|
77
|
+
|
|
78
|
+
t.deepEqual(combo, expect, `${explain(combo)} is ${explain(expect)}}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
t.end();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('Domain/Utility/SimpleGeometryIterator - MultiPoint with MultiLineString', (t) => {
|
|
85
|
+
const iterator = new SimpleGeometryIterator(multipoint, multilinestring);
|
|
86
|
+
const expanded = [...iterator];
|
|
87
|
+
const expected = [
|
|
88
|
+
{ type: 'Point', coordinates: [1, 1] },
|
|
89
|
+
{ type: 'Point', coordinates: [2, 2] },
|
|
90
|
+
{ type: 'LineString', coordinates: [[5, 5], [6, 6]] },
|
|
91
|
+
{ type: 'LineString', coordinates: [[7, 7], [8, 8]] },
|
|
92
|
+
{ type: 'LineString', coordinates: [[9, 9], [10, 10]] },
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} SimpleGeometry values`);
|
|
96
|
+
|
|
97
|
+
let index = 0;
|
|
98
|
+
for (const combo of iterator) {
|
|
99
|
+
const expect = expected[index++];
|
|
100
|
+
|
|
101
|
+
t.deepEqual(combo, expect, `${explain(combo)} is ${explain(expect)}}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
t.end();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('Domain/Utility/SimpleGeometryIterator - MultiLineString with Polygon', (t) => {
|
|
108
|
+
const iterator = new SimpleGeometryIterator(multilinestring, polygon);
|
|
109
|
+
const expanded = [...iterator];
|
|
110
|
+
const expected = [
|
|
111
|
+
{ type: 'LineString', coordinates: [[5, 5], [6, 6]] },
|
|
112
|
+
{ type: 'LineString', coordinates: [[7, 7], [8, 8]] },
|
|
113
|
+
{ type: 'LineString', coordinates: [[9, 9], [10, 10]] },
|
|
114
|
+
polygon,
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} SimpleGeometry values`);
|
|
118
|
+
|
|
119
|
+
let index = 0;
|
|
120
|
+
for (const combo of iterator) {
|
|
121
|
+
const expect = expected[index++];
|
|
122
|
+
|
|
123
|
+
t.deepEqual(combo, expect, `${explain(combo)} is ${explain(expect)}}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
t.end();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('Domain/Utility/SimpleGeometryIterator - Polygon with MultiPolygon', (t) => {
|
|
130
|
+
const iterator = new SimpleGeometryIterator(polygon, multipolygon);
|
|
131
|
+
const expanded = [...iterator];
|
|
132
|
+
const expected = [
|
|
133
|
+
polygon,
|
|
134
|
+
{ type: 'Polygon', coordinates: [[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]] },
|
|
135
|
+
{ type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] },
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} SimpleGeometry values`);
|
|
139
|
+
|
|
140
|
+
let index = 0;
|
|
141
|
+
for (const combo of iterator) {
|
|
142
|
+
const expect = expected[index++];
|
|
143
|
+
|
|
144
|
+
t.deepEqual(combo, expect, `${explain(combo)} is ${explain(expect)}}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
t.end();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('Domain/Utility/SimpleGeometryIterator - Polygon with Feature', (t) => {
|
|
151
|
+
const iterator = new SimpleGeometryIterator(polygon, feature);
|
|
152
|
+
const expanded = [...iterator];
|
|
153
|
+
const expected = [
|
|
154
|
+
polygon,
|
|
155
|
+
linestring,
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} SimpleGeometry values`);
|
|
159
|
+
|
|
160
|
+
let index = 0;
|
|
161
|
+
for (const combo of iterator) {
|
|
162
|
+
const expect = expected[index++];
|
|
163
|
+
|
|
164
|
+
t.deepEqual(combo, expect, `${explain(combo)} is ${explain(expect)}}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
t.end();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('Domain/Utility/SimpleGeometryIterator - GeometryCollection with FeatureCollection', (t) => {
|
|
171
|
+
const iterator = new SimpleGeometryIterator(geometrycollection, featurecollection);
|
|
172
|
+
const expanded = [...iterator];
|
|
173
|
+
const expected = [
|
|
174
|
+
point,
|
|
175
|
+
{ type: 'Point', coordinates: [1, 1] },
|
|
176
|
+
{ type: 'Point', coordinates: [2, 2] },
|
|
177
|
+
{ type: 'LineString', coordinates: [[5, 5], [6, 6]] },
|
|
178
|
+
{ type: 'LineString', coordinates: [[7, 7], [8, 8]] },
|
|
179
|
+
{ type: 'LineString', coordinates: [[9, 9], [10, 10]] },
|
|
180
|
+
polygon,
|
|
181
|
+
{ type: 'Polygon', coordinates: [[[4, 4], [4, 5], [5, 5], [5, 4], [4, 4]]] },
|
|
182
|
+
{ type: 'Polygon', coordinates: [[[0, 0], [0, 3], [3, 3], [3, 0], [0, 0]], [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]]] },
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
t.equal(expanded.length, expected.length, `has ${expected.length} SimpleGeometry values`);
|
|
186
|
+
|
|
187
|
+
let index = 0;
|
|
188
|
+
for (const combo of iterator) {
|
|
189
|
+
const expect = expected[index++];
|
|
190
|
+
|
|
191
|
+
t.deepEqual(combo, expect, `${explain(combo)} is ${explain(expect)}}`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
t.end();
|
|
195
|
+
});
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import { each } from 'template-literal-each';
|
|
3
|
+
import * as Export from '../../../source/Domain/Utility/Calculate';
|
|
4
|
+
import { explain, exported } from '../../helper/geometry';
|
|
5
|
+
|
|
6
|
+
exported('Domain/Utility/Calculate', Export, 'getClosestPointOnLineByPoint', 'getDistanceOfPointToPoint', 'getDistanceOfPointToLine', 'getDistanceOfLineToLine', 'isLinesCrossing', 'isPointOnLine', 'isPointInRing');
|
|
7
|
+
|
|
8
|
+
test('Domain/Utility/Calculate - getDistanceOfPointToPoint', (t) => {
|
|
9
|
+
const { getDistanceOfPointToPoint } = Export;
|
|
10
|
+
|
|
11
|
+
each`
|
|
12
|
+
a | b | cartesian | haversine | vincenty
|
|
13
|
+
------------------------------------------|-------------------------------------------|------------------------|------------------------------|----------
|
|
14
|
+
${[0, 0]} | ${[1, 0]} | 111195.07973436874 | 111195.07973436874 | 111319.49079322325
|
|
15
|
+
${[0, 0]} | ${[0, 1]} | 111195.07973436874 | 111195.07973436874 | 110574.38855795695
|
|
16
|
+
${[0, 0]} | ${[1, 1]} | 157253.589829502 | 157249.5977681334 | 156899.56829129544
|
|
17
|
+
${[0, 0]} | ${[2, 1]} | 248639.75704955778 | 248629.6571521291 | 248575.56516788687
|
|
18
|
+
${[0, 0]} | ${[1, 2]} | 248639.75704955778 | 248629.6571521291 | 247576.47264770948
|
|
19
|
+
${[0, 0]} | ${[2, 2]} | 314507.179659004 | 314475.23806026357 | 313775.70942909684
|
|
20
|
+
${[9, 9]} | ${[1, 9]} | 889560.63787495 | 878591.1714926899 | 879646.2426697082
|
|
21
|
+
${[5.911760330200195, 51.97496770044958]} | ${[5.900301933288574, 51.97938231105512]} | 1365.4087816000642 | 925.6976780365701 | 927.9989469343577
|
|
22
|
+
${[4.8422, 45.7597]} | ${[2.3508, 48.8567]} | 441970.48063825216 | 392217.2577987035 | 392431.52894877724
|
|
23
|
+
${[-180, -90]} | ${[180, 90]} | 44755156.2689204 | 20015114.352186374 | 20003931.4586233
|
|
24
|
+
${[-180, 90]} | ${[180, -90]} | 44755156.2689204 | 20015114.352186374 | 20003931.4586233
|
|
25
|
+
${[-180, 0]} | ${[180, 0]} | 40030228.70437275 | 1.5604470998469443e-9 | 20003931.4586233
|
|
26
|
+
`(({ a, b, ...calc }: any) => {
|
|
27
|
+
Object.keys(calc).forEach((key) => {
|
|
28
|
+
const value = Number(calc[key]);
|
|
29
|
+
t.equal(getDistanceOfPointToPoint(a, b, key as any), value, `${key} distance from ${explain(a)} to ${explain(b)} is ${value}`);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
t.equal(getDistanceOfPointToPoint([0, 0], [0, 0], () => Math.PI), Math.PI, 'Allows for custom function');
|
|
34
|
+
t.throws(() => getDistanceOfPointToPoint([0, 0], [1, 1], <any>'unknown'), /Not a PointToPoint calculation function unknown/);
|
|
35
|
+
|
|
36
|
+
t.end();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('Domain/Utility/Calculate - getDistanceOfPointToLine', (t) => {
|
|
40
|
+
const { getDistanceOfPointToLine } = Export;
|
|
41
|
+
const line = [[5.911760330200195, 51.97496770044958], [5.900301933288574, 51.97938231105512]];
|
|
42
|
+
|
|
43
|
+
each`
|
|
44
|
+
point | line | cartesian | haversine | vincenty
|
|
45
|
+
-------------------------------------------|---------------------|-----------------------|-----------------------|----------
|
|
46
|
+
${[1, 1]} | ${[[0, 0], [3, 3]]} | 0 | 0 | 0
|
|
47
|
+
${[2, 1]} | ${[[0, 0], [3, 3]]} | 78626.794914751 | 78617.31500879859 | 78442.46603900737
|
|
48
|
+
${[1, 2]} | ${[[0, 0], [3, 3]]} | 78626.794914751 | 78608.33580070207 | 78433.68568647826
|
|
49
|
+
${[5, 2]} | ${[[0, 0], [9, 0]]} | 222390.1594687375 | 222390.1594687375 | 221149.45337244959
|
|
50
|
+
${[5, 2]} | ${[[0, 0], [0, 9]]} | 555975.3986718437 | 555636.4985775814 | 556260.4424545396
|
|
51
|
+
${[1, 1]} | ${[[0, 0], [9, 0]]} | 111195.07973436874 | 111195.07973436874 | 110574.38855795695
|
|
52
|
+
${[3, 1]} | ${[[0, 0], [9, 0]]} | 111195.07973436874 | 111195.07973436874 | 110574.38855795695
|
|
53
|
+
${[5, 1]} | ${[[0, 0], [9, 0]]} | 111195.07973436874 | 111195.07973436874 | 110574.38855795695
|
|
54
|
+
${[7, 1]} | ${[[0, 0], [9, 0]]} | 111195.07973436874 | 111195.07973436874 | 110574.38855795695
|
|
55
|
+
${[5.909668207168579, 51.979065108032444]} | ${line} | 341.51430750144857 | 327.53158580286527 | 327.7879564857677
|
|
56
|
+
`(({ point, line, ...calc }: any) => {
|
|
57
|
+
Object.keys(calc).forEach((key) => {
|
|
58
|
+
const value = Number(calc[key]);
|
|
59
|
+
t.equal(getDistanceOfPointToLine(point, line, key as any), value, `${key} distance from ${explain(point)} to ${explain(line)} is ${value}`);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
t.equal(getDistanceOfPointToLine([0, 0], [[0, 0], [1, 1]], () => Math.PI), Math.PI, 'Allows for custom function');
|
|
64
|
+
t.throws(() => getDistanceOfPointToLine([0, 0], [[0, 0], [1, 1]], <any>'unknown'), /Not a PointToPoint calculation function unknown/);
|
|
65
|
+
|
|
66
|
+
t.end();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('Domain/Utility/Calculate - getDistanceOfLineToLine', (t) => {
|
|
70
|
+
const { getDistanceOfLineToLine } = Export;
|
|
71
|
+
|
|
72
|
+
each`
|
|
73
|
+
a | b | cartesian | haversine | vincenty
|
|
74
|
+
---------------------|----------------------|--------------------|--------------------|----------
|
|
75
|
+
${[[1, 1], [2, 2]]} | ${[[0, 0], [3, 3]]} | 0 | 0 | 0
|
|
76
|
+
${[[1, 1], [20, 2]]} | ${[[0, 0], [30, 2]]} | 73965.86679042356 | 73965.72628462575 | 73555.60559277069
|
|
77
|
+
${[[2, 2], [4, 2]]} | ${[[1, 1], [5, 1]]} | 111195.07973436874 | 111195.07973436874 | 110575.06481449273
|
|
78
|
+
${[[2, 2], [4, 2]]} | ${[[1, 1], [1, 5]]} | 111195.07973436874 | 111127.34097821356 | 111252.1298001606
|
|
79
|
+
${[[2, 2], [4, 2]]} | ${[[1, 1], [5, 5]]} | 0 | 0 | 0
|
|
80
|
+
${[[0, 0], [2, 0]]} | ${[[1, 1], [1, 3]]} | 111195.07973436874 | 111195.07973436874 | 110574.38855795695
|
|
81
|
+
${[[0, 0], [0, 5]]} | ${[[3, 3], [9, 3]]} | 333585.23920310626 | 333127.967966738 | 333503.7471426487
|
|
82
|
+
`(({ a, b, ...calc }: any) => {
|
|
83
|
+
Object.keys(calc).forEach((key) => {
|
|
84
|
+
const value = Number(calc[key]);
|
|
85
|
+
t.equal(getDistanceOfLineToLine(a, b, key as any), value, `${key} distance from ${explain(a)} to ${explain(b)} is ${value}`);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
t.equal(getDistanceOfLineToLine([[0, 0], [1, 1]], [[0, 0], [1, 1]], () => Math.PI), Math.PI, 'Allows for custom function');
|
|
90
|
+
t.throws(() => getDistanceOfLineToLine([[0, 0], [0, 1]], [[1, 0], [1, 1]], <any>'unknown'), /Not a PointToPoint calculation function unknown/);
|
|
91
|
+
|
|
92
|
+
t.end();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('Domain/Utility/Calculate - getClosestPointOnLineByPoint', (t) => {
|
|
96
|
+
const { getClosestPointOnLineByPoint } = Export;
|
|
97
|
+
|
|
98
|
+
each`
|
|
99
|
+
point | line | closest
|
|
100
|
+
-------------------------------------------|-------------------------------------------------------------------------------------|---------
|
|
101
|
+
${[1, 1]} | ${[[0, 0], [3, 3]]} | ${[1, 1]}
|
|
102
|
+
${[2, 1]} | ${[[0, 0], [3, 3]]} | ${[1.5, 1.5]}
|
|
103
|
+
${[1, 2]} | ${[[0, 0], [3, 3]]} | ${[1.5, 1.5]}
|
|
104
|
+
${[5, 2]} | ${[[0, 0], [9, 0]]} | ${[5, 0]}
|
|
105
|
+
${[5, 2]} | ${[[0, 0], [0, 9]]} | ${[0, 2]}
|
|
106
|
+
${[5.909668207168579, 51.979065108032444]} | ${[[5.911760330200195, 51.97496770044958], [5.900301933288574, 51.97938231105512]]} | ${[5.9085640303798, 51.97619914837327]}
|
|
107
|
+
`(({ point, line, closest }: any) => {
|
|
108
|
+
t.deepEqual(getClosestPointOnLineByPoint(point, line), closest, `${explain(point)} to ${explain(line)} is ${closest}`);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
t.end();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('Domain/Utility/Calculate - isLinesCrossing', (t) => {
|
|
115
|
+
const { isLinesCrossing } = Export;
|
|
116
|
+
|
|
117
|
+
each`
|
|
118
|
+
a | b | crosses
|
|
119
|
+
-----------------------|------------------------|----------
|
|
120
|
+
${[[0, 0], [2, 2]]} | ${[[0, 1], [2, 1]]} | yes
|
|
121
|
+
${[[0, 1], [9, 2]]} | ${[[0, 2], [9, 1]]} | yes
|
|
122
|
+
${[[0, 1], [9, 2]]} | ${[[0, 2], [9, 3]]} | no
|
|
123
|
+
${[[0, 1], [1000, 2]]} | ${[[0, 2], [1000, 3]]} | no
|
|
124
|
+
`(({ a, b, crosses }: any) => {
|
|
125
|
+
const crossed = crosses === 'yes';
|
|
126
|
+
const message = crossed ? 'crosses' : 'does not cross';
|
|
127
|
+
t.equal(isLinesCrossing(a, b), crossed, `${explain(a)} ${message} ${explain(b)}`);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
t.end();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('Domain/Utility/Calculate - isPointOnLine', (t) => {
|
|
134
|
+
const { isPointOnLine } = Export;
|
|
135
|
+
|
|
136
|
+
each`
|
|
137
|
+
point | line | match
|
|
138
|
+
-------------------------------------------|-------------------------------------------------------------------------------------|----------
|
|
139
|
+
${[1, 1]} | ${[[0, 0], [3, 3]]} | yes
|
|
140
|
+
${[2, 1]} | ${[[0, 0], [3, 3]]} | no
|
|
141
|
+
${[1, 2]} | ${[[0, 0], [3, 3]]} | no
|
|
142
|
+
${[5, 2]} | ${[[0, 0], [9, 0]]} | no
|
|
143
|
+
${[5, 2]} | ${[[0, 0], [0, 9]]} | no
|
|
144
|
+
${[5.909668207168579, 51.979065108032444]} | ${[[5.911760330200195, 51.97496770044958], [5.900301933288574, 51.97938231105512]]} | no
|
|
145
|
+
${[5.906031131744385, 51.97717500575235]} | ${[[5.911760330200195, 51.97496770044958], [5.900301933288574, 51.97938231105512]]} | yes
|
|
146
|
+
`(({ point, line, match }: any) => {
|
|
147
|
+
const output = match === 'yes';
|
|
148
|
+
const message = output ? 'is on line' : 'is not on line';
|
|
149
|
+
|
|
150
|
+
t.equal(isPointOnLine(point, line), output, `${explain(point)} ${message} ${explain(line)}`);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
t.end();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('Domain/Utility/Calculate - isPointInRing', (t) => {
|
|
157
|
+
const { isPointInRing } = Export;
|
|
158
|
+
|
|
159
|
+
each`
|
|
160
|
+
point | ring | match
|
|
161
|
+
-------------|---------------------------------------------|----------
|
|
162
|
+
${[0, 0]} | ${[[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]} | yes
|
|
163
|
+
${[2, 2]} | ${[[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]} | yes
|
|
164
|
+
${[1, 1]} | ${[[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]} | yes
|
|
165
|
+
${[3, 1]} | ${[[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]} | no
|
|
166
|
+
${[1, 3]} | ${[[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]} | no
|
|
167
|
+
${[0, 0]} | ${[[1, 0], [0, 1], [1, 2], [2, 1], [1, 0]]} | no
|
|
168
|
+
${[2, 2]} | ${[[1, 0], [0, 1], [1, 2], [2, 1], [1, 0]]} | no
|
|
169
|
+
${[1, 1]} | ${[[1, 0], [0, 1], [1, 2], [2, 1], [1, 0]]} | yes
|
|
170
|
+
`(({ point, ring, match }: any) => {
|
|
171
|
+
const output = match === 'yes';
|
|
172
|
+
const message = output ? 'is inside' : 'is not inside';
|
|
173
|
+
|
|
174
|
+
t.equal(isPointInRing(point, ring), output, `${explain(point)} ${message} ${explain(ring)}`);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
t.end();
|
|
178
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import * as Export from '../../../source/Domain/Utility/Distance';
|
|
3
|
+
import { explain, exported } from '../../helper/geometry';
|
|
4
|
+
import { shapes } from '../../data/Distance';
|
|
5
|
+
|
|
6
|
+
exported('Domain/Utility/Distance', Export, 'distance');
|
|
7
|
+
|
|
8
|
+
const { distance } = Export;
|
|
9
|
+
|
|
10
|
+
test(`Domain/Utility/Distance - distance`, (t) => {
|
|
11
|
+
shapes
|
|
12
|
+
.forEach(({ a, b, cartesian, haversine, vincenty }) => {
|
|
13
|
+
t.equal(distance(a, b), cartesian, `default calculation: ${explain(a)} to ${explain(b)} is ${cartesian}`);
|
|
14
|
+
t.equal(distance(a, b, 'cartesian'), cartesian, `'cartesian' calculation: ${explain(a)} to ${explain(b)} is ${cartesian}`);
|
|
15
|
+
t.equal(distance(a, b, 'haversine'), haversine, `'haversine' calculation: ${explain(a)} to ${explain(b)} is ${haversine}`);
|
|
16
|
+
t.equal(distance(a, b, 'vincenty'), vincenty, `'vincenty' calculation: ${explain(a)} to ${explain(b)} is ${vincenty}`);
|
|
17
|
+
});
|
|
18
|
+
t.end();
|
|
19
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import test from 'tape';
|
|
2
|
+
import * as Export from '../../../source/Domain/Utility/Intersect';
|
|
3
|
+
import { explain, exported } from '../../helper/geometry';
|
|
4
|
+
import { shapes } from '../../data/Intersect';
|
|
5
|
+
|
|
6
|
+
exported('Domain/Utility/Intersect', Export, 'intersect');
|
|
7
|
+
|
|
8
|
+
const { intersect } = Export;
|
|
9
|
+
|
|
10
|
+
const types = ['Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon', 'GeometryCollection', 'Feature', 'FeatureCollection'];
|
|
11
|
+
const combo = types.reduce((carry, a) => carry.concat(types.map((b) => [a, b])), [])
|
|
12
|
+
|
|
13
|
+
combo.forEach(([ta, tb]) => {
|
|
14
|
+
const tests = shapes
|
|
15
|
+
.reduce((carry, { a, b, intersect }) => {
|
|
16
|
+
if (a.type === ta && b.type === tb) {
|
|
17
|
+
return carry.concat({ a, b, intersect });
|
|
18
|
+
}
|
|
19
|
+
if (a.type === tb && b.type === ta) {
|
|
20
|
+
return carry.concat({ a: b, b: a, intersect });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return carry;
|
|
24
|
+
}, []);
|
|
25
|
+
const hits = tests.filter(({ intersect }) => intersect);
|
|
26
|
+
const miss = tests.filter(({ intersect }) => !intersect);
|
|
27
|
+
|
|
28
|
+
test(`Domain/Utility/Intersect - intersect ${ta} with ${tb}`, (t) => {
|
|
29
|
+
hits.forEach(({ a, b }) => {
|
|
30
|
+
t.ok(intersect(a, b), `${explain(a)} intersects with ${explain(b)}`)
|
|
31
|
+
});
|
|
32
|
+
miss.forEach(({ a, b }) => {
|
|
33
|
+
t.notOk(intersect(a, b), `${explain(a)} does not intersect with ${explain(b)}`)
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
t.end();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('Domain/Utility/Intersect - intersect Point with empty LineString', (t) => {
|
|
41
|
+
t.notOk(intersect({ type: 'Point', coordinates: [1, 1] }, { type: 'LineString', coordinates: [[0, 0], [0, 0]] }));
|
|
42
|
+
|
|
43
|
+
t.end();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test(`Domain/Utility/Intersect - intersect invalid GeoJSON types`, (t) => {
|
|
47
|
+
shapes
|
|
48
|
+
.filter(({ a, b }: any) => a.type === 'Impossible' || b.type === 'Impossible')
|
|
49
|
+
.forEach(({ a, b }: any) => {
|
|
50
|
+
t.notOk(intersect(a, b), `${explain(a)} does not intersect with ${explain(b)}`)
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
t.end();
|
|
54
|
+
});
|