map-2d-base 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/README.md +3 -0
- package/dist/assets/map-2d-base.css +1 -0
- package/dist/chunks/asserts-B5CSgOpZ.js +713 -0
- package/dist/chunks/index-CwJi8_r0.js +828 -0
- package/dist/chunks/index-qMK-h7Yi.js +3260 -0
- package/dist/chunks/index-snoDp5kN.js +1216 -0
- package/dist/chunks/math-CtjJ8U9C.js +105 -0
- package/dist/geom.esm.js +4 -0
- package/dist/index.esm.js +22796 -0
- package/dist/style.esm.js +9 -0
- package/dist/utils.esm.js +5 -0
- package/package.json +80 -0
|
@@ -0,0 +1,828 @@
|
|
|
1
|
+
import { a as createEmpty, y as createOrUpdateEmpty, a0 as returnOrUpdate, _ as get, j as getHeight, S as getTransform, Y as createOrUpdateFromFlatCoordinates, g as getCenter, Z as createOrUpdateFromCoordinate, a1 as containsXY } from "./index-snoDp5kN.js";
|
|
2
|
+
import { s as squaredDistance } from "./math-CtjJ8U9C.js";
|
|
3
|
+
import { b as assert, B as BaseObject, p as memoizeOne, i as abstract } from "./asserts-B5CSgOpZ.js";
|
|
4
|
+
new Array(6);
|
|
5
|
+
function create() {
|
|
6
|
+
return [1, 0, 0, 1, 0, 0];
|
|
7
|
+
}
|
|
8
|
+
function setFromArray(transform1, transform2) {
|
|
9
|
+
transform1[0] = transform2[0];
|
|
10
|
+
transform1[1] = transform2[1];
|
|
11
|
+
transform1[2] = transform2[2];
|
|
12
|
+
transform1[3] = transform2[3];
|
|
13
|
+
transform1[4] = transform2[4];
|
|
14
|
+
transform1[5] = transform2[5];
|
|
15
|
+
return transform1;
|
|
16
|
+
}
|
|
17
|
+
function apply(transform, coordinate) {
|
|
18
|
+
const x = coordinate[0];
|
|
19
|
+
const y = coordinate[1];
|
|
20
|
+
coordinate[0] = transform[0] * x + transform[2] * y + transform[4];
|
|
21
|
+
coordinate[1] = transform[1] * x + transform[3] * y + transform[5];
|
|
22
|
+
return coordinate;
|
|
23
|
+
}
|
|
24
|
+
function compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {
|
|
25
|
+
const sin = Math.sin(angle);
|
|
26
|
+
const cos = Math.cos(angle);
|
|
27
|
+
transform[0] = sx * cos;
|
|
28
|
+
transform[1] = sy * sin;
|
|
29
|
+
transform[2] = -sx * sin;
|
|
30
|
+
transform[3] = sy * cos;
|
|
31
|
+
transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;
|
|
32
|
+
transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;
|
|
33
|
+
return transform;
|
|
34
|
+
}
|
|
35
|
+
function makeInverse(target, source) {
|
|
36
|
+
const det = determinant(source);
|
|
37
|
+
assert(det !== 0, "Transformation matrix cannot be inverted");
|
|
38
|
+
const a = source[0];
|
|
39
|
+
const b = source[1];
|
|
40
|
+
const c = source[2];
|
|
41
|
+
const d = source[3];
|
|
42
|
+
const e = source[4];
|
|
43
|
+
const f = source[5];
|
|
44
|
+
target[0] = d / det;
|
|
45
|
+
target[1] = -b / det;
|
|
46
|
+
target[2] = -c / det;
|
|
47
|
+
target[3] = a / det;
|
|
48
|
+
target[4] = (c * f - d * e) / det;
|
|
49
|
+
target[5] = -(a * f - b * e) / det;
|
|
50
|
+
return target;
|
|
51
|
+
}
|
|
52
|
+
function determinant(mat) {
|
|
53
|
+
return mat[0] * mat[3] - mat[1] * mat[2];
|
|
54
|
+
}
|
|
55
|
+
const matrixPrecision = [1e5, 1e5, 1e5, 1e5, 2, 2];
|
|
56
|
+
function toString(mat) {
|
|
57
|
+
const transformString = "matrix(" + mat.join(", ") + ")";
|
|
58
|
+
return transformString;
|
|
59
|
+
}
|
|
60
|
+
function fromString(cssTransform) {
|
|
61
|
+
const values = cssTransform.substring(7, cssTransform.length - 1).split(",");
|
|
62
|
+
return values.map(parseFloat);
|
|
63
|
+
}
|
|
64
|
+
function equivalent(cssTransform1, cssTransform2) {
|
|
65
|
+
const mat1 = fromString(cssTransform1);
|
|
66
|
+
const mat2 = fromString(cssTransform2);
|
|
67
|
+
for (let i = 0; i < 6; ++i) {
|
|
68
|
+
if (Math.round((mat1[i] - mat2[i]) * matrixPrecision[i]) !== 0) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
function transform2D(flatCoordinates, offset, end, stride, transform, dest, destinationStride) {
|
|
75
|
+
dest = dest ? dest : [];
|
|
76
|
+
destinationStride = destinationStride ? destinationStride : 2;
|
|
77
|
+
let i = 0;
|
|
78
|
+
for (let j = offset; j < end; j += stride) {
|
|
79
|
+
const x = flatCoordinates[j];
|
|
80
|
+
const y = flatCoordinates[j + 1];
|
|
81
|
+
dest[i++] = transform[0] * x + transform[2] * y + transform[4];
|
|
82
|
+
dest[i++] = transform[1] * x + transform[3] * y + transform[5];
|
|
83
|
+
for (let k = 2; k < destinationStride; k++) {
|
|
84
|
+
dest[i++] = flatCoordinates[j + k];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (dest && dest.length != i) {
|
|
88
|
+
dest.length = i;
|
|
89
|
+
}
|
|
90
|
+
return dest;
|
|
91
|
+
}
|
|
92
|
+
function rotate(flatCoordinates, offset, end, stride, angle, anchor, dest) {
|
|
93
|
+
dest = dest ? dest : [];
|
|
94
|
+
const cos = Math.cos(angle);
|
|
95
|
+
const sin = Math.sin(angle);
|
|
96
|
+
const anchorX = anchor[0];
|
|
97
|
+
const anchorY = anchor[1];
|
|
98
|
+
let i = 0;
|
|
99
|
+
for (let j = offset; j < end; j += stride) {
|
|
100
|
+
const deltaX = flatCoordinates[j] - anchorX;
|
|
101
|
+
const deltaY = flatCoordinates[j + 1] - anchorY;
|
|
102
|
+
dest[i++] = anchorX + deltaX * cos - deltaY * sin;
|
|
103
|
+
dest[i++] = anchorY + deltaX * sin + deltaY * cos;
|
|
104
|
+
for (let k = j + 2; k < j + stride; ++k) {
|
|
105
|
+
dest[i++] = flatCoordinates[k];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (dest && dest.length != i) {
|
|
109
|
+
dest.length = i;
|
|
110
|
+
}
|
|
111
|
+
return dest;
|
|
112
|
+
}
|
|
113
|
+
function scale(flatCoordinates, offset, end, stride, sx, sy, anchor, dest) {
|
|
114
|
+
dest = dest ? dest : [];
|
|
115
|
+
const anchorX = anchor[0];
|
|
116
|
+
const anchorY = anchor[1];
|
|
117
|
+
let i = 0;
|
|
118
|
+
for (let j = offset; j < end; j += stride) {
|
|
119
|
+
const deltaX = flatCoordinates[j] - anchorX;
|
|
120
|
+
const deltaY = flatCoordinates[j + 1] - anchorY;
|
|
121
|
+
dest[i++] = anchorX + sx * deltaX;
|
|
122
|
+
dest[i++] = anchorY + sy * deltaY;
|
|
123
|
+
for (let k = j + 2; k < j + stride; ++k) {
|
|
124
|
+
dest[i++] = flatCoordinates[k];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (dest && dest.length != i) {
|
|
128
|
+
dest.length = i;
|
|
129
|
+
}
|
|
130
|
+
return dest;
|
|
131
|
+
}
|
|
132
|
+
function translate(flatCoordinates, offset, end, stride, deltaX, deltaY, dest) {
|
|
133
|
+
dest = dest ? dest : [];
|
|
134
|
+
let i = 0;
|
|
135
|
+
for (let j = offset; j < end; j += stride) {
|
|
136
|
+
dest[i++] = flatCoordinates[j] + deltaX;
|
|
137
|
+
dest[i++] = flatCoordinates[j + 1] + deltaY;
|
|
138
|
+
for (let k = j + 2; k < j + stride; ++k) {
|
|
139
|
+
dest[i++] = flatCoordinates[k];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (dest && dest.length != i) {
|
|
143
|
+
dest.length = i;
|
|
144
|
+
}
|
|
145
|
+
return dest;
|
|
146
|
+
}
|
|
147
|
+
const tmpTransform = create();
|
|
148
|
+
const tmpPoint = [NaN, NaN];
|
|
149
|
+
class Geometry extends BaseObject {
|
|
150
|
+
constructor() {
|
|
151
|
+
super();
|
|
152
|
+
this.extent_ = createEmpty();
|
|
153
|
+
this.extentRevision_ = -1;
|
|
154
|
+
this.simplifiedGeometryMaxMinSquaredTolerance = 0;
|
|
155
|
+
this.simplifiedGeometryRevision = 0;
|
|
156
|
+
this.simplifyTransformedInternal = memoizeOne(
|
|
157
|
+
(revision, squaredTolerance, transform) => {
|
|
158
|
+
if (!transform) {
|
|
159
|
+
return this.getSimplifiedGeometry(squaredTolerance);
|
|
160
|
+
}
|
|
161
|
+
const clone = this.clone();
|
|
162
|
+
clone.applyTransform(transform);
|
|
163
|
+
return clone.getSimplifiedGeometry(squaredTolerance);
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get a transformed and simplified version of the geometry.
|
|
169
|
+
* @abstract
|
|
170
|
+
* @param {number} squaredTolerance Squared tolerance.
|
|
171
|
+
* @param {import("../proj.js").TransformFunction} [transform] Optional transform function.
|
|
172
|
+
* @return {Geometry} Simplified geometry.
|
|
173
|
+
*/
|
|
174
|
+
simplifyTransformed(squaredTolerance, transform) {
|
|
175
|
+
return this.simplifyTransformedInternal(
|
|
176
|
+
this.getRevision(),
|
|
177
|
+
squaredTolerance,
|
|
178
|
+
transform
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Make a complete copy of the geometry.
|
|
183
|
+
* @abstract
|
|
184
|
+
* @return {!Geometry} Clone.
|
|
185
|
+
*/
|
|
186
|
+
clone() {
|
|
187
|
+
return abstract();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* @abstract
|
|
191
|
+
* @param {number} x X.
|
|
192
|
+
* @param {number} y Y.
|
|
193
|
+
* @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
|
|
194
|
+
* @param {number} minSquaredDistance Minimum squared distance.
|
|
195
|
+
* @return {number} Minimum squared distance.
|
|
196
|
+
*/
|
|
197
|
+
closestPointXY(x, y, closestPoint, minSquaredDistance) {
|
|
198
|
+
return abstract();
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* @param {number} x X.
|
|
202
|
+
* @param {number} y Y.
|
|
203
|
+
* @return {boolean} Contains (x, y).
|
|
204
|
+
*/
|
|
205
|
+
containsXY(x, y) {
|
|
206
|
+
return this.closestPointXY(x, y, tmpPoint, Number.MIN_VALUE) === 0;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Return the closest point of the geometry to the passed point as
|
|
210
|
+
* {@link module:ol/coordinate~Coordinate coordinate}.
|
|
211
|
+
* @param {import("../coordinate.js").Coordinate} point Point.
|
|
212
|
+
* @param {import("../coordinate.js").Coordinate} [closestPoint] Closest point.
|
|
213
|
+
* @return {import("../coordinate.js").Coordinate} Closest point.
|
|
214
|
+
* @api
|
|
215
|
+
*/
|
|
216
|
+
getClosestPoint(point, closestPoint) {
|
|
217
|
+
closestPoint = closestPoint ? closestPoint : [NaN, NaN];
|
|
218
|
+
this.closestPointXY(point[0], point[1], closestPoint, Infinity);
|
|
219
|
+
return closestPoint;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Returns true if this geometry includes the specified coordinate. If the
|
|
223
|
+
* coordinate is on the boundary of the geometry, returns false.
|
|
224
|
+
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
|
|
225
|
+
* @return {boolean} Contains coordinate.
|
|
226
|
+
* @api
|
|
227
|
+
*/
|
|
228
|
+
intersectsCoordinate(coordinate) {
|
|
229
|
+
return this.containsXY(coordinate[0], coordinate[1]);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* @abstract
|
|
233
|
+
* @param {import("../extent.js").Extent} extent Extent.
|
|
234
|
+
* @protected
|
|
235
|
+
* @return {import("../extent.js").Extent} extent Extent.
|
|
236
|
+
*/
|
|
237
|
+
computeExtent(extent) {
|
|
238
|
+
return abstract();
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Get the extent of the geometry.
|
|
242
|
+
* @param {import("../extent.js").Extent} [extent] Extent.
|
|
243
|
+
* @return {import("../extent.js").Extent} extent Extent.
|
|
244
|
+
* @api
|
|
245
|
+
*/
|
|
246
|
+
getExtent(extent) {
|
|
247
|
+
if (this.extentRevision_ != this.getRevision()) {
|
|
248
|
+
const extent2 = this.computeExtent(this.extent_);
|
|
249
|
+
if (isNaN(extent2[0]) || isNaN(extent2[1])) {
|
|
250
|
+
createOrUpdateEmpty(extent2);
|
|
251
|
+
}
|
|
252
|
+
this.extentRevision_ = this.getRevision();
|
|
253
|
+
}
|
|
254
|
+
return returnOrUpdate(this.extent_, extent);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Rotate the geometry around a given coordinate. This modifies the geometry
|
|
258
|
+
* coordinates in place.
|
|
259
|
+
* @abstract
|
|
260
|
+
* @param {number} angle Rotation angle in radians.
|
|
261
|
+
* @param {import("../coordinate.js").Coordinate} anchor The rotation center.
|
|
262
|
+
* @api
|
|
263
|
+
*/
|
|
264
|
+
rotate(angle, anchor) {
|
|
265
|
+
abstract();
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Scale the geometry (with an optional origin). This modifies the geometry
|
|
269
|
+
* coordinates in place.
|
|
270
|
+
* @abstract
|
|
271
|
+
* @param {number} sx The scaling factor in the x-direction.
|
|
272
|
+
* @param {number} [sy] The scaling factor in the y-direction (defaults to sx).
|
|
273
|
+
* @param {import("../coordinate.js").Coordinate} [anchor] The scale origin (defaults to the center
|
|
274
|
+
* of the geometry extent).
|
|
275
|
+
* @api
|
|
276
|
+
*/
|
|
277
|
+
scale(sx, sy, anchor) {
|
|
278
|
+
abstract();
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Create a simplified version of this geometry. For linestrings, this uses
|
|
282
|
+
* the [Douglas Peucker](https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm)
|
|
283
|
+
* algorithm. For polygons, a quantization-based
|
|
284
|
+
* simplification is used to preserve topology.
|
|
285
|
+
* @param {number} tolerance The tolerance distance for simplification.
|
|
286
|
+
* @return {Geometry} A new, simplified version of the original geometry.
|
|
287
|
+
* @api
|
|
288
|
+
*/
|
|
289
|
+
simplify(tolerance) {
|
|
290
|
+
return this.getSimplifiedGeometry(tolerance * tolerance);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Create a simplified version of this geometry using the Douglas Peucker
|
|
294
|
+
* algorithm.
|
|
295
|
+
* See https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm.
|
|
296
|
+
* @abstract
|
|
297
|
+
* @param {number} squaredTolerance Squared tolerance.
|
|
298
|
+
* @return {Geometry} Simplified geometry.
|
|
299
|
+
*/
|
|
300
|
+
getSimplifiedGeometry(squaredTolerance) {
|
|
301
|
+
return abstract();
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Get the type of this geometry.
|
|
305
|
+
* @abstract
|
|
306
|
+
* @return {Type} Geometry type.
|
|
307
|
+
*/
|
|
308
|
+
getType() {
|
|
309
|
+
return abstract();
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Apply a transform function to the coordinates of the geometry.
|
|
313
|
+
* The geometry is modified in place.
|
|
314
|
+
* If you do not want the geometry modified in place, first `clone()` it and
|
|
315
|
+
* then use this function on the clone.
|
|
316
|
+
* @abstract
|
|
317
|
+
* @param {import("../proj.js").TransformFunction} transformFn Transform function.
|
|
318
|
+
* Called with a flat array of geometry coordinates.
|
|
319
|
+
*/
|
|
320
|
+
applyTransform(transformFn) {
|
|
321
|
+
abstract();
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Test if the geometry and the passed extent intersect.
|
|
325
|
+
* @abstract
|
|
326
|
+
* @param {import("../extent.js").Extent} extent Extent.
|
|
327
|
+
* @return {boolean} `true` if the geometry and the extent intersect.
|
|
328
|
+
*/
|
|
329
|
+
intersectsExtent(extent) {
|
|
330
|
+
return abstract();
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Translate the geometry. This modifies the geometry coordinates in place. If
|
|
334
|
+
* instead you want a new geometry, first `clone()` this geometry.
|
|
335
|
+
* @abstract
|
|
336
|
+
* @param {number} deltaX Delta X.
|
|
337
|
+
* @param {number} deltaY Delta Y.
|
|
338
|
+
* @api
|
|
339
|
+
*/
|
|
340
|
+
translate(deltaX, deltaY) {
|
|
341
|
+
abstract();
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Transform each coordinate of the geometry from one coordinate reference
|
|
345
|
+
* system to another. The geometry is modified in place.
|
|
346
|
+
* For example, a line will be transformed to a line and a circle to a circle.
|
|
347
|
+
* If you do not want the geometry modified in place, first `clone()` it and
|
|
348
|
+
* then use this function on the clone.
|
|
349
|
+
*
|
|
350
|
+
* @param {import("../proj.js").ProjectionLike} source The current projection. Can be a
|
|
351
|
+
* string identifier or a {@link module:ol/proj/Projection~Projection} object.
|
|
352
|
+
* @param {import("../proj.js").ProjectionLike} destination The desired projection. Can be a
|
|
353
|
+
* string identifier or a {@link module:ol/proj/Projection~Projection} object.
|
|
354
|
+
* @return {this} This geometry. Note that original geometry is
|
|
355
|
+
* modified in place.
|
|
356
|
+
* @api
|
|
357
|
+
*/
|
|
358
|
+
transform(source, destination) {
|
|
359
|
+
const sourceProj = get(source);
|
|
360
|
+
const transformFn = sourceProj.getUnits() == "tile-pixels" ? function(inCoordinates, outCoordinates, stride) {
|
|
361
|
+
const pixelExtent = sourceProj.getExtent();
|
|
362
|
+
const projectedExtent = sourceProj.getWorldExtent();
|
|
363
|
+
const scale2 = getHeight(projectedExtent) / getHeight(pixelExtent);
|
|
364
|
+
compose(
|
|
365
|
+
tmpTransform,
|
|
366
|
+
projectedExtent[0],
|
|
367
|
+
projectedExtent[3],
|
|
368
|
+
scale2,
|
|
369
|
+
-scale2,
|
|
370
|
+
0,
|
|
371
|
+
0,
|
|
372
|
+
0
|
|
373
|
+
);
|
|
374
|
+
const transformed = transform2D(
|
|
375
|
+
inCoordinates,
|
|
376
|
+
0,
|
|
377
|
+
inCoordinates.length,
|
|
378
|
+
stride,
|
|
379
|
+
tmpTransform,
|
|
380
|
+
outCoordinates
|
|
381
|
+
);
|
|
382
|
+
const projTransform = getTransform(sourceProj, destination);
|
|
383
|
+
if (projTransform) {
|
|
384
|
+
return projTransform(transformed, transformed, stride);
|
|
385
|
+
}
|
|
386
|
+
return transformed;
|
|
387
|
+
} : getTransform(sourceProj, destination);
|
|
388
|
+
this.applyTransform(transformFn);
|
|
389
|
+
return this;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
class SimpleGeometry extends Geometry {
|
|
393
|
+
constructor() {
|
|
394
|
+
super();
|
|
395
|
+
this.layout = "XY";
|
|
396
|
+
this.stride = 2;
|
|
397
|
+
this.flatCoordinates;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* @param {import("../extent.js").Extent} extent Extent.
|
|
401
|
+
* @protected
|
|
402
|
+
* @return {import("../extent.js").Extent} extent Extent.
|
|
403
|
+
* @override
|
|
404
|
+
*/
|
|
405
|
+
computeExtent(extent) {
|
|
406
|
+
return createOrUpdateFromFlatCoordinates(
|
|
407
|
+
this.flatCoordinates,
|
|
408
|
+
0,
|
|
409
|
+
this.flatCoordinates.length,
|
|
410
|
+
this.stride,
|
|
411
|
+
extent
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* @abstract
|
|
416
|
+
* @return {Array<*> | null} Coordinates.
|
|
417
|
+
*/
|
|
418
|
+
getCoordinates() {
|
|
419
|
+
return abstract();
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Return the first coordinate of the geometry.
|
|
423
|
+
* @return {import("../coordinate.js").Coordinate} First coordinate.
|
|
424
|
+
* @api
|
|
425
|
+
*/
|
|
426
|
+
getFirstCoordinate() {
|
|
427
|
+
return this.flatCoordinates.slice(0, this.stride);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* @return {Array<number>} Flat coordinates.
|
|
431
|
+
*/
|
|
432
|
+
getFlatCoordinates() {
|
|
433
|
+
return this.flatCoordinates;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Return the last coordinate of the geometry.
|
|
437
|
+
* @return {import("../coordinate.js").Coordinate} Last point.
|
|
438
|
+
* @api
|
|
439
|
+
*/
|
|
440
|
+
getLastCoordinate() {
|
|
441
|
+
return this.flatCoordinates.slice(
|
|
442
|
+
this.flatCoordinates.length - this.stride
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Return the {@link import("./Geometry.js").GeometryLayout layout} of the geometry.
|
|
447
|
+
* @return {import("./Geometry.js").GeometryLayout} Layout.
|
|
448
|
+
* @api
|
|
449
|
+
*/
|
|
450
|
+
getLayout() {
|
|
451
|
+
return this.layout;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Create a simplified version of this geometry using the Douglas Peucker algorithm.
|
|
455
|
+
* @param {number} squaredTolerance Squared tolerance.
|
|
456
|
+
* @return {SimpleGeometry} Simplified geometry.
|
|
457
|
+
* @override
|
|
458
|
+
*/
|
|
459
|
+
getSimplifiedGeometry(squaredTolerance) {
|
|
460
|
+
if (this.simplifiedGeometryRevision !== this.getRevision()) {
|
|
461
|
+
this.simplifiedGeometryMaxMinSquaredTolerance = 0;
|
|
462
|
+
this.simplifiedGeometryRevision = this.getRevision();
|
|
463
|
+
}
|
|
464
|
+
if (squaredTolerance < 0 || this.simplifiedGeometryMaxMinSquaredTolerance !== 0 && squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance) {
|
|
465
|
+
return this;
|
|
466
|
+
}
|
|
467
|
+
const simplifiedGeometry = this.getSimplifiedGeometryInternal(squaredTolerance);
|
|
468
|
+
const simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();
|
|
469
|
+
if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {
|
|
470
|
+
return simplifiedGeometry;
|
|
471
|
+
}
|
|
472
|
+
this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;
|
|
473
|
+
return this;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* @param {number} squaredTolerance Squared tolerance.
|
|
477
|
+
* @return {SimpleGeometry} Simplified geometry.
|
|
478
|
+
* @protected
|
|
479
|
+
*/
|
|
480
|
+
getSimplifiedGeometryInternal(squaredTolerance) {
|
|
481
|
+
return this;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* @return {number} Stride.
|
|
485
|
+
*/
|
|
486
|
+
getStride() {
|
|
487
|
+
return this.stride;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* @param {import("./Geometry.js").GeometryLayout} layout Layout.
|
|
491
|
+
* @param {Array<number>} flatCoordinates Flat coordinates.
|
|
492
|
+
*/
|
|
493
|
+
setFlatCoordinates(layout, flatCoordinates) {
|
|
494
|
+
this.stride = getStrideForLayout(layout);
|
|
495
|
+
this.layout = layout;
|
|
496
|
+
this.flatCoordinates = flatCoordinates;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* @abstract
|
|
500
|
+
* @param {!Array<*>} coordinates Coordinates.
|
|
501
|
+
* @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
|
|
502
|
+
*/
|
|
503
|
+
setCoordinates(coordinates, layout) {
|
|
504
|
+
abstract();
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* @param {import("./Geometry.js").GeometryLayout|undefined} layout Layout.
|
|
508
|
+
* @param {Array<*>} coordinates Coordinates.
|
|
509
|
+
* @param {number} nesting Nesting.
|
|
510
|
+
* @protected
|
|
511
|
+
*/
|
|
512
|
+
setLayout(layout, coordinates, nesting) {
|
|
513
|
+
let stride;
|
|
514
|
+
if (layout) {
|
|
515
|
+
stride = getStrideForLayout(layout);
|
|
516
|
+
} else {
|
|
517
|
+
for (let i = 0; i < nesting; ++i) {
|
|
518
|
+
if (coordinates.length === 0) {
|
|
519
|
+
this.layout = "XY";
|
|
520
|
+
this.stride = 2;
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
coordinates = /** @type {Array<unknown>} */
|
|
524
|
+
coordinates[0];
|
|
525
|
+
}
|
|
526
|
+
stride = coordinates.length;
|
|
527
|
+
layout = getLayoutForStride(stride);
|
|
528
|
+
}
|
|
529
|
+
this.layout = layout;
|
|
530
|
+
this.stride = stride;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Apply a transform function to the coordinates of the geometry.
|
|
534
|
+
* The geometry is modified in place.
|
|
535
|
+
* If you do not want the geometry modified in place, first `clone()` it and
|
|
536
|
+
* then use this function on the clone.
|
|
537
|
+
* @param {import("../proj.js").TransformFunction} transformFn Transform function.
|
|
538
|
+
* Called with a flat array of geometry coordinates.
|
|
539
|
+
* @api
|
|
540
|
+
* @override
|
|
541
|
+
*/
|
|
542
|
+
applyTransform(transformFn) {
|
|
543
|
+
if (this.flatCoordinates) {
|
|
544
|
+
transformFn(
|
|
545
|
+
this.flatCoordinates,
|
|
546
|
+
this.flatCoordinates,
|
|
547
|
+
this.layout.startsWith("XYZ") ? 3 : 2,
|
|
548
|
+
this.stride
|
|
549
|
+
);
|
|
550
|
+
this.changed();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Rotate the geometry around a given coordinate. This modifies the geometry
|
|
555
|
+
* coordinates in place.
|
|
556
|
+
* @param {number} angle Rotation angle in counter-clockwise radians.
|
|
557
|
+
* @param {import("../coordinate.js").Coordinate} anchor The rotation center.
|
|
558
|
+
* @api
|
|
559
|
+
* @override
|
|
560
|
+
*/
|
|
561
|
+
rotate(angle, anchor) {
|
|
562
|
+
const flatCoordinates = this.getFlatCoordinates();
|
|
563
|
+
if (flatCoordinates) {
|
|
564
|
+
const stride = this.getStride();
|
|
565
|
+
rotate(
|
|
566
|
+
flatCoordinates,
|
|
567
|
+
0,
|
|
568
|
+
flatCoordinates.length,
|
|
569
|
+
stride,
|
|
570
|
+
angle,
|
|
571
|
+
anchor,
|
|
572
|
+
flatCoordinates
|
|
573
|
+
);
|
|
574
|
+
this.changed();
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Scale the geometry (with an optional origin). This modifies the geometry
|
|
579
|
+
* coordinates in place.
|
|
580
|
+
* @param {number} sx The scaling factor in the x-direction.
|
|
581
|
+
* @param {number} [sy] The scaling factor in the y-direction (defaults to sx).
|
|
582
|
+
* @param {import("../coordinate.js").Coordinate} [anchor] The scale origin (defaults to the center
|
|
583
|
+
* of the geometry extent).
|
|
584
|
+
* @api
|
|
585
|
+
* @override
|
|
586
|
+
*/
|
|
587
|
+
scale(sx, sy, anchor) {
|
|
588
|
+
if (sy === void 0) {
|
|
589
|
+
sy = sx;
|
|
590
|
+
}
|
|
591
|
+
if (!anchor) {
|
|
592
|
+
anchor = getCenter(this.getExtent());
|
|
593
|
+
}
|
|
594
|
+
const flatCoordinates = this.getFlatCoordinates();
|
|
595
|
+
if (flatCoordinates) {
|
|
596
|
+
const stride = this.getStride();
|
|
597
|
+
scale(
|
|
598
|
+
flatCoordinates,
|
|
599
|
+
0,
|
|
600
|
+
flatCoordinates.length,
|
|
601
|
+
stride,
|
|
602
|
+
sx,
|
|
603
|
+
sy,
|
|
604
|
+
anchor,
|
|
605
|
+
flatCoordinates
|
|
606
|
+
);
|
|
607
|
+
this.changed();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Translate the geometry. This modifies the geometry coordinates in place. If
|
|
612
|
+
* instead you want a new geometry, first `clone()` this geometry.
|
|
613
|
+
* @param {number} deltaX Delta X.
|
|
614
|
+
* @param {number} deltaY Delta Y.
|
|
615
|
+
* @api
|
|
616
|
+
* @override
|
|
617
|
+
*/
|
|
618
|
+
translate(deltaX, deltaY) {
|
|
619
|
+
const flatCoordinates = this.getFlatCoordinates();
|
|
620
|
+
if (flatCoordinates) {
|
|
621
|
+
const stride = this.getStride();
|
|
622
|
+
translate(
|
|
623
|
+
flatCoordinates,
|
|
624
|
+
0,
|
|
625
|
+
flatCoordinates.length,
|
|
626
|
+
stride,
|
|
627
|
+
deltaX,
|
|
628
|
+
deltaY,
|
|
629
|
+
flatCoordinates
|
|
630
|
+
);
|
|
631
|
+
this.changed();
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
function getLayoutForStride(stride) {
|
|
636
|
+
let layout;
|
|
637
|
+
if (stride == 2) {
|
|
638
|
+
layout = "XY";
|
|
639
|
+
} else if (stride == 3) {
|
|
640
|
+
layout = "XYZ";
|
|
641
|
+
} else if (stride == 4) {
|
|
642
|
+
layout = "XYZM";
|
|
643
|
+
}
|
|
644
|
+
return (
|
|
645
|
+
/** @type {import("./Geometry.js").GeometryLayout} */
|
|
646
|
+
layout
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
function getStrideForLayout(layout) {
|
|
650
|
+
let stride;
|
|
651
|
+
if (layout == "XY") {
|
|
652
|
+
stride = 2;
|
|
653
|
+
} else if (layout == "XYZ" || layout == "XYM") {
|
|
654
|
+
stride = 3;
|
|
655
|
+
} else if (layout == "XYZM") {
|
|
656
|
+
stride = 4;
|
|
657
|
+
}
|
|
658
|
+
return (
|
|
659
|
+
/** @type {number} */
|
|
660
|
+
stride
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
function transformGeom2D(simpleGeometry, transform, dest) {
|
|
664
|
+
const flatCoordinates = simpleGeometry.getFlatCoordinates();
|
|
665
|
+
if (!flatCoordinates) {
|
|
666
|
+
return null;
|
|
667
|
+
}
|
|
668
|
+
const stride = simpleGeometry.getStride();
|
|
669
|
+
return transform2D(
|
|
670
|
+
flatCoordinates,
|
|
671
|
+
0,
|
|
672
|
+
flatCoordinates.length,
|
|
673
|
+
stride,
|
|
674
|
+
transform,
|
|
675
|
+
dest
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
function deflateCoordinate(flatCoordinates, offset, coordinate, stride) {
|
|
679
|
+
for (let i = 0, ii = coordinate.length; i < ii; ++i) {
|
|
680
|
+
flatCoordinates[offset++] = coordinate[i];
|
|
681
|
+
}
|
|
682
|
+
return offset;
|
|
683
|
+
}
|
|
684
|
+
function deflateCoordinates(flatCoordinates, offset, coordinates, stride) {
|
|
685
|
+
for (let i = 0, ii = coordinates.length; i < ii; ++i) {
|
|
686
|
+
const coordinate = coordinates[i];
|
|
687
|
+
for (let j = 0; j < stride; ++j) {
|
|
688
|
+
flatCoordinates[offset++] = coordinate[j];
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return offset;
|
|
692
|
+
}
|
|
693
|
+
function deflateCoordinatesArray(flatCoordinates, offset, coordinatess, stride, ends) {
|
|
694
|
+
ends = ends ? ends : [];
|
|
695
|
+
let i = 0;
|
|
696
|
+
for (let j = 0, jj = coordinatess.length; j < jj; ++j) {
|
|
697
|
+
const end = deflateCoordinates(
|
|
698
|
+
flatCoordinates,
|
|
699
|
+
offset,
|
|
700
|
+
coordinatess[j],
|
|
701
|
+
stride
|
|
702
|
+
);
|
|
703
|
+
ends[i++] = end;
|
|
704
|
+
offset = end;
|
|
705
|
+
}
|
|
706
|
+
ends.length = i;
|
|
707
|
+
return ends;
|
|
708
|
+
}
|
|
709
|
+
class Point extends SimpleGeometry {
|
|
710
|
+
/**
|
|
711
|
+
* @param {import("../coordinate.js").Coordinate} coordinates Coordinates.
|
|
712
|
+
* @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
|
|
713
|
+
*/
|
|
714
|
+
constructor(coordinates, layout) {
|
|
715
|
+
super();
|
|
716
|
+
this.setCoordinates(coordinates, layout);
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Make a complete copy of the geometry.
|
|
720
|
+
* @return {!Point} Clone.
|
|
721
|
+
* @api
|
|
722
|
+
* @override
|
|
723
|
+
*/
|
|
724
|
+
clone() {
|
|
725
|
+
const point = new Point(this.flatCoordinates.slice(), this.layout);
|
|
726
|
+
point.applyProperties(this);
|
|
727
|
+
return point;
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* @param {number} x X.
|
|
731
|
+
* @param {number} y Y.
|
|
732
|
+
* @param {import("../coordinate.js").Coordinate} closestPoint Closest point.
|
|
733
|
+
* @param {number} minSquaredDistance Minimum squared distance.
|
|
734
|
+
* @return {number} Minimum squared distance.
|
|
735
|
+
* @override
|
|
736
|
+
*/
|
|
737
|
+
closestPointXY(x, y, closestPoint, minSquaredDistance) {
|
|
738
|
+
const flatCoordinates = this.flatCoordinates;
|
|
739
|
+
const squaredDistance$1 = squaredDistance(
|
|
740
|
+
x,
|
|
741
|
+
y,
|
|
742
|
+
flatCoordinates[0],
|
|
743
|
+
flatCoordinates[1]
|
|
744
|
+
);
|
|
745
|
+
if (squaredDistance$1 < minSquaredDistance) {
|
|
746
|
+
const stride = this.stride;
|
|
747
|
+
for (let i = 0; i < stride; ++i) {
|
|
748
|
+
closestPoint[i] = flatCoordinates[i];
|
|
749
|
+
}
|
|
750
|
+
closestPoint.length = stride;
|
|
751
|
+
return squaredDistance$1;
|
|
752
|
+
}
|
|
753
|
+
return minSquaredDistance;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Return the coordinate of the point.
|
|
757
|
+
* @return {import("../coordinate.js").Coordinate} Coordinates.
|
|
758
|
+
* @api
|
|
759
|
+
* @override
|
|
760
|
+
*/
|
|
761
|
+
getCoordinates() {
|
|
762
|
+
return this.flatCoordinates.slice();
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* @param {import("../extent.js").Extent} extent Extent.
|
|
766
|
+
* @protected
|
|
767
|
+
* @return {import("../extent.js").Extent} extent Extent.
|
|
768
|
+
* @override
|
|
769
|
+
*/
|
|
770
|
+
computeExtent(extent) {
|
|
771
|
+
return createOrUpdateFromCoordinate(this.flatCoordinates, extent);
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Get the type of this geometry.
|
|
775
|
+
* @return {import("./Geometry.js").Type} Geometry type.
|
|
776
|
+
* @api
|
|
777
|
+
* @override
|
|
778
|
+
*/
|
|
779
|
+
getType() {
|
|
780
|
+
return "Point";
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Test if the geometry and the passed extent intersect.
|
|
784
|
+
* @param {import("../extent.js").Extent} extent Extent.
|
|
785
|
+
* @return {boolean} `true` if the geometry and the extent intersect.
|
|
786
|
+
* @api
|
|
787
|
+
* @override
|
|
788
|
+
*/
|
|
789
|
+
intersectsExtent(extent) {
|
|
790
|
+
return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* @param {!Array<*>} coordinates Coordinates.
|
|
794
|
+
* @param {import("./Geometry.js").GeometryLayout} [layout] Layout.
|
|
795
|
+
* @api
|
|
796
|
+
* @override
|
|
797
|
+
*/
|
|
798
|
+
setCoordinates(coordinates, layout) {
|
|
799
|
+
this.setLayout(layout, coordinates, 0);
|
|
800
|
+
if (!this.flatCoordinates) {
|
|
801
|
+
this.flatCoordinates = [];
|
|
802
|
+
}
|
|
803
|
+
this.flatCoordinates.length = deflateCoordinate(
|
|
804
|
+
this.flatCoordinates,
|
|
805
|
+
0,
|
|
806
|
+
coordinates,
|
|
807
|
+
this.stride
|
|
808
|
+
);
|
|
809
|
+
this.changed();
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
export {
|
|
813
|
+
Point as P,
|
|
814
|
+
SimpleGeometry as S,
|
|
815
|
+
deflateCoordinatesArray as a,
|
|
816
|
+
create as b,
|
|
817
|
+
compose as c,
|
|
818
|
+
deflateCoordinates as d,
|
|
819
|
+
apply as e,
|
|
820
|
+
fromString as f,
|
|
821
|
+
transformGeom2D as g,
|
|
822
|
+
equivalent as h,
|
|
823
|
+
toString as i,
|
|
824
|
+
makeInverse as m,
|
|
825
|
+
rotate as r,
|
|
826
|
+
setFromArray as s,
|
|
827
|
+
transform2D as t
|
|
828
|
+
};
|