@mapwhit/tilerenderer 1.2.0 → 1.2.2
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/build/min/package.json +1 -1
- package/package.json +5 -5
- package/src/data/bucket/fill_extrusion_bucket.js +34 -39
- package/src/data/bucket/line_bucket.js +40 -48
- package/src/data/bucket/symbol_bucket.js +4 -5
- package/src/data/feature_index.js +10 -3
- package/src/geo/transform.js +13 -13
- package/src/index.js +1 -1
- package/src/source/geojson_wrapper.js +1 -9
- package/src/source/query_features.js +4 -1
- package/src/source/rtl_text_plugin.js +3 -1
- package/src/source/source_cache.js +3 -3
- package/src/source/tile.js +1 -1
- package/src/style/evaluation_parameters.js +5 -4
- package/src/style/query_utils.js +82 -7
- package/src/style/style.js +8 -2
- package/src/style/style_layer/circle_style_layer.js +26 -45
- package/src/style/style_layer/fill_extrusion_style_layer.js +26 -33
- package/src/style/style_layer/heatmap_style_layer.js +21 -7
- package/src/style/style_layer/line_style_layer.js +7 -7
- package/src/style/style_layer.js +3 -3
- package/src/style-spec/feature_filter/index.js +24 -19
- package/src/symbol/anchor.js +1 -1
- package/src/symbol/check_max_angle.js +6 -6
- package/src/symbol/collision_feature.js +9 -15
- package/src/symbol/collision_index.js +33 -27
- package/src/symbol/get_anchors.js +6 -5
- package/src/symbol/projection.js +3 -3
- package/src/symbol/quads.js +1 -1
- package/src/symbol/symbol_layout.js +1 -2
- package/src/ui/camera.js +1 -1
- package/src/ui/map.js +24 -24
- package/src/util/classify_rings.js +2 -4
- package/src/util/vectortile_to_geojson.js +65 -26
- package/build/min/src/shaders/.dir +0 -0
- package/src/symbol/clip_line.js +0 -72
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Point from '@mapbox/point-geometry';
|
|
2
1
|
import { polygonIntersectsPolygon } from '@mapwhit/geometry';
|
|
3
2
|
import * as projection from '../symbol/projection.js';
|
|
4
3
|
import Grid from './grid_index.js';
|
|
@@ -20,10 +19,9 @@ const viewportPadding = 100;
|
|
|
20
19
|
* there's room for a symbol, then insertCollisionBox/Circles actually puts the
|
|
21
20
|
* symbol in the index. The two step process allows paired symbols to be inserted
|
|
22
21
|
* together even if they overlap.
|
|
23
|
-
*
|
|
24
|
-
* @private
|
|
25
22
|
*/
|
|
26
|
-
|
|
23
|
+
|
|
24
|
+
export default class CollisionIndex {
|
|
27
25
|
constructor(
|
|
28
26
|
transform,
|
|
29
27
|
grid = new Grid(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25),
|
|
@@ -116,7 +114,7 @@ class CollisionIndex {
|
|
|
116
114
|
const lineOffsetX = symbol.lineOffsetX * fontSize;
|
|
117
115
|
const lineOffsetY = symbol.lineOffsetY * fontSize;
|
|
118
116
|
|
|
119
|
-
const tileUnitAnchorPoint =
|
|
117
|
+
const tileUnitAnchorPoint = { x: symbol.anchorX, y: symbol.anchorY };
|
|
120
118
|
// projection.project generates NDC coordinates, as opposed to the
|
|
121
119
|
// pixel-based grid coordinates generated by this.projectPoint
|
|
122
120
|
const labelPlaneAnchorPoint = projection.project(tileUnitAnchorPoint, labelPlaneMatrix).point;
|
|
@@ -253,18 +251,28 @@ class CollisionIndex {
|
|
|
253
251
|
return {};
|
|
254
252
|
}
|
|
255
253
|
|
|
256
|
-
const query =
|
|
254
|
+
const query = new Array(viewportQueryGeometry.length);
|
|
257
255
|
let minX = Number.POSITIVE_INFINITY;
|
|
258
256
|
let minY = Number.POSITIVE_INFINITY;
|
|
259
257
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
260
258
|
let maxY = Number.NEGATIVE_INFINITY;
|
|
261
|
-
for (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
259
|
+
for (let i = 0; i < viewportQueryGeometry.length; i++) {
|
|
260
|
+
let { x, y } = viewportQueryGeometry[i];
|
|
261
|
+
x += viewportPadding;
|
|
262
|
+
y += viewportPadding;
|
|
263
|
+
if (x < minX) {
|
|
264
|
+
minX = x;
|
|
265
|
+
}
|
|
266
|
+
if (x > maxX) {
|
|
267
|
+
maxX = x;
|
|
268
|
+
}
|
|
269
|
+
if (y < minY) {
|
|
270
|
+
minY = y;
|
|
271
|
+
}
|
|
272
|
+
if (y > maxY) {
|
|
273
|
+
maxY = y;
|
|
274
|
+
}
|
|
275
|
+
query[i] = { x, y };
|
|
268
276
|
}
|
|
269
277
|
|
|
270
278
|
const features = this.grid.query(minX, minY, maxX, maxY).concat(this.ignoredGrid.query(minX, minY, maxX, maxY));
|
|
@@ -288,10 +296,10 @@ class CollisionIndex {
|
|
|
288
296
|
// distinction doesn't matter as much, and box geometry is easier
|
|
289
297
|
// to work with.
|
|
290
298
|
const bbox = [
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
299
|
+
{ x: feature.x1, y: feature.y1 },
|
|
300
|
+
{ x: feature.x2, y: feature.y1 },
|
|
301
|
+
{ x: feature.x2, y: feature.y2 },
|
|
302
|
+
{ x: feature.x1, y: feature.y2 }
|
|
295
303
|
];
|
|
296
304
|
if (!polygonIntersectsPolygon(query, bbox)) {
|
|
297
305
|
continue;
|
|
@@ -343,19 +351,19 @@ class CollisionIndex {
|
|
|
343
351
|
projectPoint(posMatrix, x, y) {
|
|
344
352
|
const p = [x, y, 0, 1];
|
|
345
353
|
projection.xyTransformMat4(p, p, posMatrix);
|
|
346
|
-
return
|
|
347
|
-
((p[0] / p[3] + 1) / 2) * this.transform.width + viewportPadding,
|
|
348
|
-
((-p[1] / p[3] + 1) / 2) * this.transform.height + viewportPadding
|
|
349
|
-
|
|
354
|
+
return {
|
|
355
|
+
x: ((p[0] / p[3] + 1) / 2) * this.transform.width + viewportPadding,
|
|
356
|
+
y: ((-p[1] / p[3] + 1) / 2) * this.transform.height + viewportPadding
|
|
357
|
+
};
|
|
350
358
|
}
|
|
351
359
|
|
|
352
360
|
projectAndGetPerspectiveRatio(posMatrix, x, y) {
|
|
353
361
|
const p = [x, y, 0, 1];
|
|
354
362
|
projection.xyTransformMat4(p, p, posMatrix);
|
|
355
|
-
const a =
|
|
356
|
-
((p[0] / p[3] + 1) / 2) * this.transform.width + viewportPadding,
|
|
357
|
-
((-p[1] / p[3] + 1) / 2) * this.transform.height + viewportPadding
|
|
358
|
-
|
|
363
|
+
const a = {
|
|
364
|
+
x: ((p[0] / p[3] + 1) / 2) * this.transform.width + viewportPadding,
|
|
365
|
+
y: ((-p[1] / p[3] + 1) / 2) * this.transform.height + viewportPadding
|
|
366
|
+
};
|
|
359
367
|
return {
|
|
360
368
|
point: a,
|
|
361
369
|
// See perspective ratio comment in symbol_sdf.vertex
|
|
@@ -379,5 +387,3 @@ class CollisionIndex {
|
|
|
379
387
|
function markCollisionCircleUsed(collisionCircles, index, used) {
|
|
380
388
|
collisionCircles[index + 4] = used ? 1 : 0;
|
|
381
389
|
}
|
|
382
|
-
|
|
383
|
-
export default CollisionIndex;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { angleTo, dist } from '@mapwhit/point-geometry';
|
|
1
2
|
import Anchor from '../symbol/anchor.js';
|
|
2
3
|
import interpolate from '../util/interpolate.js';
|
|
3
4
|
import checkMaxAngle from './check_max_angle.js';
|
|
@@ -5,7 +6,7 @@ import checkMaxAngle from './check_max_angle.js';
|
|
|
5
6
|
function getLineLength(line) {
|
|
6
7
|
let lineLength = 0;
|
|
7
8
|
for (let k = 0; k < line.length - 1; k++) {
|
|
8
|
-
lineLength += line[k]
|
|
9
|
+
lineLength += dist(line[k], line[k + 1]);
|
|
9
10
|
}
|
|
10
11
|
return lineLength;
|
|
11
12
|
}
|
|
@@ -32,7 +33,7 @@ export function getCenterAnchor(line, maxAngle, shapedText, shapedIcon, glyphSiz
|
|
|
32
33
|
const a = line[i];
|
|
33
34
|
const b = line[i + 1];
|
|
34
35
|
|
|
35
|
-
const segmentDistance =
|
|
36
|
+
const segmentDistance = dist(a, b);
|
|
36
37
|
|
|
37
38
|
if (prevDistance + segmentDistance > centerDistance) {
|
|
38
39
|
// The center is on this segment
|
|
@@ -40,7 +41,7 @@ export function getCenterAnchor(line, maxAngle, shapedText, shapedIcon, glyphSiz
|
|
|
40
41
|
const x = interpolate(a.x, b.x, t);
|
|
41
42
|
const y = interpolate(a.y, b.y, t);
|
|
42
43
|
|
|
43
|
-
const anchor = new Anchor(x, y,
|
|
44
|
+
const anchor = new Anchor(x, y, angleTo(b, a), i);
|
|
44
45
|
anchor._round();
|
|
45
46
|
if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) {
|
|
46
47
|
return anchor;
|
|
@@ -117,8 +118,8 @@ function resample(
|
|
|
117
118
|
const a = line[i];
|
|
118
119
|
const b = line[i + 1];
|
|
119
120
|
|
|
120
|
-
const segmentDist =
|
|
121
|
-
const angle =
|
|
121
|
+
const segmentDist = dist(a, b);
|
|
122
|
+
const angle = angleTo(b, a);
|
|
122
123
|
|
|
123
124
|
while (markedDistance + spacing < distance + segmentDist) {
|
|
124
125
|
markedDistance += spacing;
|
package/src/symbol/projection.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import glMatrix from '@mapbox/gl-matrix';
|
|
2
|
-
import Point from '@
|
|
2
|
+
import { Point } from '@mapwhit/point-geometry';
|
|
3
3
|
import { addDynamicAttributes } from '../data/bucket/symbol_bucket.js';
|
|
4
4
|
import properties from '../style/style_layer/symbol_style_layer_properties.js';
|
|
5
5
|
import { WritingMode } from '../symbol/shaping.js';
|
|
@@ -448,10 +448,10 @@ function projectTruncatedLineSegment(
|
|
|
448
448
|
// point near the plane of the camera. We wouldn't be able to render the label anyway once it crossed the
|
|
449
449
|
// plane of the camera.
|
|
450
450
|
const projectedUnitVertex = project(
|
|
451
|
-
previousTilePoint.
|
|
451
|
+
Point.clone(previousTilePoint)._add(Point.clone(previousTilePoint)._sub(currentTilePoint)._unit()),
|
|
452
452
|
projectionMatrix
|
|
453
453
|
).point;
|
|
454
|
-
const projectedUnitSegment = previousProjectedPoint.
|
|
454
|
+
const projectedUnitSegment = Point.clone(previousProjectedPoint)._sub(projectedUnitVertex);
|
|
455
455
|
|
|
456
456
|
return previousProjectedPoint.add(projectedUnitSegment._mult(minimumLength / projectedUnitSegment.mag()));
|
|
457
457
|
}
|
package/src/symbol/quads.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { findPoleOfInaccessibility } from '@mapwhit/geometry';
|
|
1
|
+
import { clipLine, findPoleOfInaccessibility } from '@mapwhit/geometry';
|
|
2
2
|
import murmur3 from 'murmurhash-js';
|
|
3
3
|
import SymbolBucket from '../data/bucket/symbol_bucket.js';
|
|
4
4
|
import EXTENT from '../data/extent.js';
|
|
@@ -7,7 +7,6 @@ import classifyRings from '../util/classify_rings.js';
|
|
|
7
7
|
import { allowsLetterSpacing, allowsVerticalWritingMode } from '../util/script_detection.js';
|
|
8
8
|
import warn from '../util/warn.js';
|
|
9
9
|
import Anchor from './anchor.js';
|
|
10
|
-
import clipLine from './clip_line.js';
|
|
11
10
|
import CollisionFeature from './collision_feature.js';
|
|
12
11
|
import { getAnchors, getCenterAnchor } from './get_anchors.js';
|
|
13
12
|
import { getGlyphQuads, getIconQuads } from './quads.js';
|
package/src/ui/camera.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Point from '@mapbox/point-geometry';
|
|
2
1
|
import { Event, Evented } from '@mapwhit/events';
|
|
2
|
+
import { Point } from '@mapwhit/point-geometry';
|
|
3
3
|
import LngLat from '../geo/lng_lat.js';
|
|
4
4
|
import LngLatBounds from '../geo/lng_lat_bounds.js';
|
|
5
5
|
import browser from '../util/browser.js';
|
package/src/ui/map.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Point from '@mapbox/point-geometry';
|
|
2
1
|
import { ErrorEvent, Event } from '@mapwhit/events';
|
|
3
2
|
import LngLat from '../geo/lng_lat.js';
|
|
4
3
|
import LngLatBounds from '../geo/lng_lat_bounds.js';
|
|
@@ -287,10 +286,10 @@ class Map extends Camera {
|
|
|
287
286
|
*/
|
|
288
287
|
getBounds() {
|
|
289
288
|
return new LngLatBounds()
|
|
290
|
-
.extend(this.transform.pointLocation(
|
|
291
|
-
.extend(this.transform.pointLocation(
|
|
292
|
-
.extend(this.transform.pointLocation(
|
|
293
|
-
.extend(this.transform.pointLocation(
|
|
289
|
+
.extend(this.transform.pointLocation({ x: 0, y: 0 }))
|
|
290
|
+
.extend(this.transform.pointLocation({ x: this.transform.width, y: 0 }))
|
|
291
|
+
.extend(this.transform.pointLocation({ x: this.transform.width, y: this.transform.height }))
|
|
292
|
+
.extend(this.transform.pointLocation({ x: 0, y: this.transform.height }));
|
|
294
293
|
}
|
|
295
294
|
|
|
296
295
|
/**
|
|
@@ -453,7 +452,7 @@ class Map extends Camera {
|
|
|
453
452
|
* @see [Show polygon information on click](https://www.mapbox.com/mapbox-gl-js/example/polygon-popup-on-click/)
|
|
454
453
|
*/
|
|
455
454
|
unproject(point) {
|
|
456
|
-
return this.transform.pointLocation(
|
|
455
|
+
return this.transform.pointLocation(toPoint(point));
|
|
457
456
|
}
|
|
458
457
|
|
|
459
458
|
/**
|
|
@@ -577,33 +576,26 @@ class Map extends Camera {
|
|
|
577
576
|
}
|
|
578
577
|
|
|
579
578
|
return this.style.queryRenderedFeatures(this._makeQueryGeometry(geometry), options, this.transform) || [];
|
|
580
|
-
|
|
581
|
-
function isPointLike(input) {
|
|
582
|
-
return input instanceof Point || Array.isArray(input);
|
|
583
|
-
}
|
|
584
579
|
}
|
|
585
580
|
|
|
586
|
-
_makeQueryGeometry(
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
581
|
+
_makeQueryGeometry(
|
|
582
|
+
pointOrBox = [
|
|
583
|
+
{ x: 0, y: 0 },
|
|
584
|
+
{ x: this.transform.width, y: this.transform.height }
|
|
585
|
+
]
|
|
586
|
+
) {
|
|
592
587
|
let queryGeometry;
|
|
593
588
|
|
|
594
|
-
if (pointOrBox
|
|
595
|
-
|
|
596
|
-
queryGeometry = [point];
|
|
589
|
+
if (typeof pointOrBox.x === 'number' || typeof pointOrBox[0] === 'number') {
|
|
590
|
+
queryGeometry = [toPoint(pointOrBox)];
|
|
597
591
|
} else {
|
|
598
|
-
const box = [
|
|
599
|
-
queryGeometry = [box[0],
|
|
592
|
+
const box = [toPoint(pointOrBox[0]), toPoint(pointOrBox[1])];
|
|
593
|
+
queryGeometry = [box[0], { x: box[1].x, y: box[0].y }, box[1], { x: box[0].x, y: box[1].y }, box[0]];
|
|
600
594
|
}
|
|
601
595
|
|
|
602
596
|
return {
|
|
603
597
|
viewport: queryGeometry,
|
|
604
|
-
worldCoordinate: queryGeometry.map(p =>
|
|
605
|
-
return this.transform.pointCoordinate(p);
|
|
606
|
-
})
|
|
598
|
+
worldCoordinate: queryGeometry.map(p => this.transform.pointCoordinate(p))
|
|
607
599
|
};
|
|
608
600
|
}
|
|
609
601
|
|
|
@@ -1558,6 +1550,14 @@ function removeNode(node) {
|
|
|
1558
1550
|
}
|
|
1559
1551
|
}
|
|
1560
1552
|
|
|
1553
|
+
function toPoint(p) {
|
|
1554
|
+
return Array.isArray(p) ? { x: p[0], y: p[1] } : p;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
function isPointLike(input) {
|
|
1558
|
+
return Array.isArray(input) || (typeof input.x === 'number' && typeof input.y === 'number');
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
1561
|
/**
|
|
1562
1562
|
* Interface for interactive controls added to the map. This is an
|
|
1563
1563
|
* specification for implementers to model: it is not
|
|
@@ -2,7 +2,7 @@ import { calculateSignedArea } from '@mapwhit/geometry';
|
|
|
2
2
|
import quickselect from 'quickselect';
|
|
3
3
|
|
|
4
4
|
// classifies an array of rings into polygons with outer rings and holes
|
|
5
|
-
export default function classifyRings(rings, maxRings) {
|
|
5
|
+
export default function classifyRings(rings, maxRings = -1) {
|
|
6
6
|
if (rings.length <= 1) {
|
|
7
7
|
return [rings];
|
|
8
8
|
}
|
|
@@ -19,9 +19,7 @@ export default function classifyRings(rings, maxRings) {
|
|
|
19
19
|
|
|
20
20
|
ring.area = Math.abs(area);
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
ccw = area < 0;
|
|
24
|
-
}
|
|
22
|
+
ccw ??= area < 0;
|
|
25
23
|
|
|
26
24
|
if (ccw === area < 0) {
|
|
27
25
|
append(polygon);
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import { VectorTileFeature } from '@mapwhit/vector-tile';
|
|
2
|
+
import classifyRings from './classify_rings.js';
|
|
3
|
+
|
|
4
|
+
export default class GeoJSONFeature {
|
|
5
|
+
#vectorTileFeature;
|
|
6
|
+
#geometry;
|
|
7
|
+
#xyz;
|
|
8
|
+
|
|
2
9
|
constructor(vectorTileFeature, z, x, y) {
|
|
3
10
|
this.type = 'Feature';
|
|
4
11
|
|
|
5
|
-
this
|
|
6
|
-
|
|
7
|
-
vectorTileFeature._x = x;
|
|
8
|
-
vectorTileFeature._y = y;
|
|
12
|
+
this.#vectorTileFeature = vectorTileFeature;
|
|
13
|
+
this.#xyz = { z, x, y };
|
|
9
14
|
|
|
10
15
|
this.properties = vectorTileFeature.properties;
|
|
11
16
|
|
|
@@ -15,32 +20,66 @@ class Feature {
|
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
get geometry() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
this.#geometry ??= toGeoJSONGeometry(this.#vectorTileFeature, this.#xyz);
|
|
24
|
+
return this.#geometry;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const invPi = 360 / Math.PI;
|
|
29
|
+
|
|
30
|
+
function toGeoJSONGeometry(vtf, { x, y, z }) {
|
|
31
|
+
const size = vtf.extent * 2 ** z;
|
|
32
|
+
const scale = 360 / size;
|
|
33
|
+
const x0 = vtf.extent * x;
|
|
34
|
+
const y0 = vtf.extent * y;
|
|
35
|
+
let coords = vtf.loadGeometry();
|
|
36
|
+
let type = VectorTileFeature.types[vtf.type];
|
|
37
|
+
|
|
38
|
+
switch (vtf.type) {
|
|
39
|
+
case 1: {
|
|
40
|
+
const points = new Array(coords.length);
|
|
41
|
+
for (let i = 0; i < coords.length; i++) {
|
|
42
|
+
points[i] = coords[i][0];
|
|
43
|
+
}
|
|
44
|
+
coords = points;
|
|
45
|
+
project(coords);
|
|
46
|
+
break;
|
|
24
47
|
}
|
|
25
|
-
|
|
48
|
+
|
|
49
|
+
case 2:
|
|
50
|
+
for (let i = 0; i < coords.length; i++) {
|
|
51
|
+
project(coords[i]);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
|
|
55
|
+
case 3:
|
|
56
|
+
coords = classifyRings(coords);
|
|
57
|
+
for (let i = 0; i < coords.length; i++) {
|
|
58
|
+
for (let j = 0; j < coords[i].length; j++) {
|
|
59
|
+
project(coords[i][j]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
26
63
|
}
|
|
27
64
|
|
|
28
|
-
|
|
29
|
-
|
|
65
|
+
if (coords.length === 1) {
|
|
66
|
+
coords = coords[0];
|
|
67
|
+
} else {
|
|
68
|
+
type = `Multi${type}`;
|
|
30
69
|
}
|
|
31
70
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
71
|
+
return {
|
|
72
|
+
type,
|
|
73
|
+
coordinates: coords
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function project(line) {
|
|
77
|
+
for (let i = 0; i < line.length; i++) {
|
|
78
|
+
const { x, y } = line[i];
|
|
79
|
+
const lon = (x + x0) * scale - 180;
|
|
80
|
+
const y2 = 180 - (y + y0) * scale;
|
|
81
|
+
const lat = invPi * Math.atan(Math.exp((y2 * Math.PI) / 180)) - 90;
|
|
82
|
+
line[i] = [lon, lat];
|
|
41
83
|
}
|
|
42
|
-
return json;
|
|
43
84
|
}
|
|
44
85
|
}
|
|
45
|
-
|
|
46
|
-
export default Feature;
|
|
File without changes
|
package/src/symbol/clip_line.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import Point from '@mapbox/point-geometry';
|
|
2
|
-
export default clipLine;
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Returns the part of a multiline that intersects with the provided rectangular box.
|
|
6
|
-
*
|
|
7
|
-
* @param lines
|
|
8
|
-
* @param x1 the left edge of the box
|
|
9
|
-
* @param y1 the top edge of the box
|
|
10
|
-
* @param x2 the right edge of the box
|
|
11
|
-
* @param y2 the bottom edge of the box
|
|
12
|
-
* @returns lines
|
|
13
|
-
* @private
|
|
14
|
-
*/
|
|
15
|
-
function clipLine(lines, x1, y1, x2, y2) {
|
|
16
|
-
const clippedLines = [];
|
|
17
|
-
|
|
18
|
-
for (let l = 0; l < lines.length; l++) {
|
|
19
|
-
const line = lines[l];
|
|
20
|
-
let clippedLine;
|
|
21
|
-
|
|
22
|
-
for (let i = 0; i < line.length - 1; i++) {
|
|
23
|
-
let p0 = line[i];
|
|
24
|
-
let p1 = line[i + 1];
|
|
25
|
-
|
|
26
|
-
if (p0.x < x1 && p1.x < x1) {
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (p0.x < x1) {
|
|
30
|
-
p0 = new Point(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round();
|
|
31
|
-
} else if (p1.x < x1) {
|
|
32
|
-
p1 = new Point(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (p0.y < y1 && p1.y < y1) {
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (p0.y < y1) {
|
|
39
|
-
p0 = new Point(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round();
|
|
40
|
-
} else if (p1.y < y1) {
|
|
41
|
-
p1 = new Point(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (p0.x >= x2 && p1.x >= x2) {
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
if (p0.x >= x2) {
|
|
48
|
-
p0 = new Point(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round();
|
|
49
|
-
} else if (p1.x >= x2) {
|
|
50
|
-
p1 = new Point(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (p0.y >= y2 && p1.y >= y2) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (p0.y >= y2) {
|
|
57
|
-
p0 = new Point(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round();
|
|
58
|
-
} else if (p1.y >= y2) {
|
|
59
|
-
p1 = new Point(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (!clippedLine || !p0.equals(clippedLine[clippedLine.length - 1])) {
|
|
63
|
-
clippedLine = [p0];
|
|
64
|
-
clippedLines.push(clippedLine);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
clippedLine.push(p1);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return clippedLines;
|
|
72
|
-
}
|