@sakuzu/maplibre-gl-draw 2.1.2 → 2.1.4
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/CHANGELOG.md +55 -0
- package/dist/api/impl/engine.js +6 -0
- package/dist/api/impl/extension-host.js +3 -1
- package/dist/api/impl/input.js +12 -3
- package/dist/dataset/chunk-set.js +2 -3
- package/dist/dataset/dataset.js +6 -4
- package/dist/dataset/retained.js +3 -3
- package/dist/dataset/selection.js +1 -1
- package/dist/dispatcher/input-router.js +5 -3
- package/dist/modes/select/mode.js +8 -0
- package/dist/snapping/service.js +16 -0
- package/dist/view/layer/renderers.d.ts +3 -0
- package/dist/view/layer/renderers.js +6 -1
- package/dist/view/renderers/anchored-outline.d.ts +5 -0
- package/dist/view/renderers/anchored-outline.js +352 -0
- package/dist/view/renderers/batch-manager.js +25 -17
- package/dist/view/renderers/draw-factors.d.ts +11 -1
- package/dist/view/renderers/draw-factors.js +13 -0
- package/dist/view/renderers/line/line-shader.js +6 -1
- package/dist/view/renderers/point/point-instance.d.ts +19 -0
- package/dist/view/renderers/point/point-instance.js +47 -1
- package/dist/view/renderers/polygon/sdf-polygon.js +5 -1
- package/dist/view/shaders/initializer.d.ts +3 -0
- package/dist/view/shaders/initializer.js +8 -2
- package/dist/view/terrain/drape/renderer.js +11 -2
- package/dist/view/ui/selection-ui/renderer.d.ts +2 -1
- package/dist/view/ui/selection-ui/renderer.js +20 -131
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AnchoredOutlineRenderer } from '../renderers/anchored-outline.js';
|
|
1
2
|
import type { FeatureDrawer } from '../renderers/drawer.js';
|
|
2
3
|
import type { SDFLineRenderer } from '../renderers/line/sdf-line.js';
|
|
3
4
|
import type { PointInstanceRenderer } from '../renderers/point/point-instance.js';
|
|
@@ -16,6 +17,8 @@ export interface ShaderInitializerRenderers {
|
|
|
16
17
|
tentativeRenderer: TentativeRenderer | null;
|
|
17
18
|
quadShader: QuadShader | null;
|
|
18
19
|
strokeRenderer: StrokeRenderer | null;
|
|
20
|
+
/** The outlines laid on the screen around an anchor (the frames of points) */
|
|
21
|
+
outlineRenderer: AnchoredOutlineRenderer | null;
|
|
19
22
|
pointShapeRenderer: PointShapeRenderer | null;
|
|
20
23
|
pointInstanceRenderer: PointInstanceRenderer | null;
|
|
21
24
|
sdfLineRenderer: SDFLineRenderer | null;
|
|
@@ -23,7 +23,7 @@ export class ShaderInitializer {
|
|
|
23
23
|
* Makes every renderer ensure its shader
|
|
24
24
|
*/
|
|
25
25
|
ensureShaders(shaderData) {
|
|
26
|
-
const { featureDrawer, tentativeRenderer, quadShader, strokeRenderer, pointShapeRenderer, pointInstanceRenderer, sdfLineRenderer, polygonBatchRenderer, sdfPolygonRenderer, fillShaderManager, } = this.renderers;
|
|
26
|
+
const { featureDrawer, tentativeRenderer, quadShader, strokeRenderer, outlineRenderer, pointShapeRenderer, pointInstanceRenderer, sdfLineRenderer, polygonBatchRenderer, sdfPolygonRenderer, fillShaderManager, } = this.renderers;
|
|
27
27
|
if (featureDrawer) {
|
|
28
28
|
featureDrawer.ensureShader(shaderData);
|
|
29
29
|
}
|
|
@@ -36,6 +36,9 @@ export class ShaderInitializer {
|
|
|
36
36
|
if (strokeRenderer) {
|
|
37
37
|
strokeRenderer.ensureShader(shaderData);
|
|
38
38
|
}
|
|
39
|
+
if (outlineRenderer) {
|
|
40
|
+
outlineRenderer.ensureShader(shaderData);
|
|
41
|
+
}
|
|
39
42
|
if (pointShapeRenderer) {
|
|
40
43
|
pointShapeRenderer.ensureShader(shaderData);
|
|
41
44
|
}
|
|
@@ -80,7 +83,7 @@ export class ShaderInitializer {
|
|
|
80
83
|
* uniforms once per frame and applies them for each slot.
|
|
81
84
|
*/
|
|
82
85
|
applyOffsetUniforms(uniforms) {
|
|
83
|
-
const { featureDrawer, tentativeRenderer, quadShader, strokeRenderer, pointShapeRenderer, pointInstanceRenderer, sdfLineRenderer, polygonBatchRenderer, sdfPolygonRenderer, fillShaderManager, } = this.renderers;
|
|
86
|
+
const { featureDrawer, tentativeRenderer, quadShader, strokeRenderer, outlineRenderer, pointShapeRenderer, pointInstanceRenderer, sdfLineRenderer, polygonBatchRenderer, sdfPolygonRenderer, fillShaderManager, } = this.renderers;
|
|
84
87
|
if (featureDrawer) {
|
|
85
88
|
featureDrawer.setOffsetUniforms(uniforms);
|
|
86
89
|
}
|
|
@@ -93,6 +96,9 @@ export class ShaderInitializer {
|
|
|
93
96
|
if (strokeRenderer) {
|
|
94
97
|
strokeRenderer.setOffsetUniforms(uniforms);
|
|
95
98
|
}
|
|
99
|
+
if (outlineRenderer) {
|
|
100
|
+
outlineRenderer.setOffsetUniforms(uniforms);
|
|
101
|
+
}
|
|
96
102
|
if (pointShapeRenderer) {
|
|
97
103
|
pointShapeRenderer.setOffsetUniforms(uniforms);
|
|
98
104
|
}
|
|
@@ -207,6 +207,15 @@ float dashDistance(vec2 sa, vec2 sb, float start, float len, float dash, float p
|
|
|
207
207
|
return best;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
// The coverage of an outline of a half width at a screen distance from it. Below one
|
|
211
|
+
// pixel of width the outline is drawn one pixel wide and fainter by its width, so the ink
|
|
212
|
+
// per unit of length follows the width and goes to nothing with it (the rule of the
|
|
213
|
+
// vertex path's line and outline shaders)
|
|
214
|
+
float strokeCoverage(float halfWidth, float dist) {
|
|
215
|
+
float ink = clamp(2.0 * halfWidth, 0.0, 1.0);
|
|
216
|
+
return clamp(max(halfWidth, 0.5) + 0.5 - dist, 0.0, 1.0) * ink;
|
|
217
|
+
}
|
|
218
|
+
|
|
210
219
|
// Compose on top (premultiplied alpha)
|
|
211
220
|
vec4 over(vec4 below, vec3 rgb, float a) {
|
|
212
221
|
return vec4(rgb * a + below.rgb * (1.0 - a), a + below.a * (1.0 - a));
|
|
@@ -342,7 +351,7 @@ void main() {
|
|
|
342
351
|
}
|
|
343
352
|
|
|
344
353
|
if (paints && halfWidth > 0.0 && stroke.a > 0.0) {
|
|
345
|
-
float coverage =
|
|
354
|
+
float coverage = strokeCoverage(halfWidth, strokeDist);
|
|
346
355
|
if (coverage > 0.0) acc = over(acc, stroke.rgb, stroke.a * coverage * factors.x);
|
|
347
356
|
}
|
|
348
357
|
|
|
@@ -367,7 +376,7 @@ void main() {
|
|
|
367
376
|
// for features that have no outline (the same as the immediate mode), and
|
|
368
377
|
// it is solid under a dashed outline too
|
|
369
378
|
float selHalf = halfWidth + u_selection_stroke_extra * 0.5;
|
|
370
|
-
selStroke = max(selStroke,
|
|
379
|
+
selStroke = max(selStroke, strokeCoverage(selHalf, minDist) * factors.x);
|
|
371
380
|
}
|
|
372
381
|
}
|
|
373
382
|
|
|
@@ -9,13 +9,14 @@ import type { ProjectionData } from 'maplibre-gl';
|
|
|
9
9
|
import type { SelectionUIConfig } from '../../../shared/config/selection.js';
|
|
10
10
|
import { type CoordinateTransform } from '../../../shared/math/index.js';
|
|
11
11
|
import type { DragState, Feature } from '../../../store/types.js';
|
|
12
|
+
import type { AnchoredOutlineRenderer } from '../../renderers/anchored-outline.js';
|
|
12
13
|
import type { StrokeRenderer } from '../../renderers/stroke.js';
|
|
13
14
|
import { TerrainContext } from '../../terrain/context.js';
|
|
14
15
|
import type { SelectionExtensionRegistry } from './extension-registry.js';
|
|
15
16
|
import type { BoundingBoxCoords } from './types.js';
|
|
16
17
|
export declare class SelectionUIRenderer {
|
|
17
18
|
#private;
|
|
18
|
-
constructor(strokeRenderer: StrokeRenderer, config: SelectionUIConfig, extensions: SelectionExtensionRegistry, terrain?: TerrainContext);
|
|
19
|
+
constructor(strokeRenderer: StrokeRenderer, outlineRenderer: AnchoredOutlineRenderer, config: SelectionUIConfig, extensions: SelectionExtensionRegistry, terrain?: TerrainContext);
|
|
19
20
|
/** Compute the BoundingBox of a feature (also usable from outside) */
|
|
20
21
|
computeFeatureBoundingBox(feature: Feature): BoundingBoxCoords | null;
|
|
21
22
|
/** Compute the combined BoundingBox of several features (also usable from outside) */
|
|
@@ -11,20 +11,18 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
12
12
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
13
13
|
};
|
|
14
|
-
var _SelectionUIRenderer_instances, _SelectionUIRenderer_strokeRenderer, _SelectionUIRenderer_extensions, _SelectionUIRenderer_terrain, _SelectionUIRenderer_config, _SelectionUIRenderer_transform, _SelectionUIRenderer_projectionData, _SelectionUIRenderer_drawRotatingBoundingBox, _SelectionUIRenderer_drawIndividualBoundingBox,
|
|
14
|
+
var _SelectionUIRenderer_instances, _SelectionUIRenderer_strokeRenderer, _SelectionUIRenderer_outlineRenderer, _SelectionUIRenderer_extensions, _SelectionUIRenderer_terrain, _SelectionUIRenderer_config, _SelectionUIRenderer_transform, _SelectionUIRenderer_projectionData, _SelectionUIRenderer_drawRotatingBoundingBox, _SelectionUIRenderer_drawIndividualBoundingBox, _SelectionUIRenderer_drawBoundingBoxWithMargin, _SelectionUIRenderer_drawPointBoundingBox, _SelectionUIRenderer_pointFrame, _SelectionUIRenderer_applyMargin, _SelectionUIRenderer_strokeBoundingBox, _SelectionUIRenderer_strokePath;
|
|
15
15
|
import { applyMarginToBoundingBox, } from '../../../shared/math/index.js';
|
|
16
16
|
import { anchorElevationMeters, isAnchorActive, projectAnchorAt } from '../../terrain/anchor.js';
|
|
17
17
|
import { TerrainContext } from '../../terrain/context.js';
|
|
18
|
+
import { anchorGhostOpacity } from '../../terrain/occlusion.js';
|
|
18
19
|
import { computeBoundingBox, computeCombinedBoundingBox, hasZeroArea, rotateBoundingBox, } from './bounding-box.js';
|
|
19
|
-
/**
|
|
20
|
-
* How far the positions differ that the scale of the screen around a point is measured
|
|
21
|
-
* between, in pixels at the zoom of the frame
|
|
22
|
-
*/
|
|
23
|
-
const POINT_FRAME_PROBE_PX = 4;
|
|
24
20
|
export class SelectionUIRenderer {
|
|
25
|
-
constructor(strokeRenderer, config, extensions, terrain = new TerrainContext()) {
|
|
21
|
+
constructor(strokeRenderer, outlineRenderer, config, extensions, terrain = new TerrainContext()) {
|
|
26
22
|
_SelectionUIRenderer_instances.add(this);
|
|
27
23
|
_SelectionUIRenderer_strokeRenderer.set(this, void 0);
|
|
24
|
+
/** Draws the frames of points, which are figures of the screen */
|
|
25
|
+
_SelectionUIRenderer_outlineRenderer.set(this, void 0);
|
|
28
26
|
/** The Selection UI extension points of the draw instance this renderer belongs to */
|
|
29
27
|
_SelectionUIRenderer_extensions.set(this, void 0);
|
|
30
28
|
/** The terrain state of the draw instance (an inactive one projects with the map) */
|
|
@@ -33,6 +31,7 @@ export class SelectionUIRenderer {
|
|
|
33
31
|
_SelectionUIRenderer_transform.set(this, null);
|
|
34
32
|
_SelectionUIRenderer_projectionData.set(this, null);
|
|
35
33
|
__classPrivateFieldSet(this, _SelectionUIRenderer_strokeRenderer, strokeRenderer, "f");
|
|
34
|
+
__classPrivateFieldSet(this, _SelectionUIRenderer_outlineRenderer, outlineRenderer, "f");
|
|
36
35
|
__classPrivateFieldSet(this, _SelectionUIRenderer_config, config, "f");
|
|
37
36
|
__classPrivateFieldSet(this, _SelectionUIRenderer_extensions, extensions, "f");
|
|
38
37
|
__classPrivateFieldSet(this, _SelectionUIRenderer_terrain, terrain, "f");
|
|
@@ -87,10 +86,10 @@ export class SelectionUIRenderer {
|
|
|
87
86
|
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_drawIndividualBoundingBox).call(this, feature, zoom);
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
|
-
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m",
|
|
89
|
+
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_drawBoundingBoxWithMargin).call(this, features, zoom);
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
|
-
_SelectionUIRenderer_strokeRenderer = new WeakMap(), _SelectionUIRenderer_extensions = new WeakMap(), _SelectionUIRenderer_terrain = new WeakMap(), _SelectionUIRenderer_config = new WeakMap(), _SelectionUIRenderer_transform = new WeakMap(), _SelectionUIRenderer_projectionData = new WeakMap(), _SelectionUIRenderer_instances = new WeakSet(), _SelectionUIRenderer_drawRotatingBoundingBox = function _SelectionUIRenderer_drawRotatingBoundingBox(features, zoom, dragState) {
|
|
92
|
+
_SelectionUIRenderer_strokeRenderer = new WeakMap(), _SelectionUIRenderer_outlineRenderer = new WeakMap(), _SelectionUIRenderer_extensions = new WeakMap(), _SelectionUIRenderer_terrain = new WeakMap(), _SelectionUIRenderer_config = new WeakMap(), _SelectionUIRenderer_transform = new WeakMap(), _SelectionUIRenderer_projectionData = new WeakMap(), _SelectionUIRenderer_instances = new WeakSet(), _SelectionUIRenderer_drawRotatingBoundingBox = function _SelectionUIRenderer_drawRotatingBoundingBox(features, zoom, dragState) {
|
|
94
93
|
// When dragState.operation === 'rotate', rotateInfo always exists
|
|
95
94
|
const rotateInfo = dragState.rotateInfo;
|
|
96
95
|
if (!rotateInfo)
|
|
@@ -115,99 +114,32 @@ _SelectionUIRenderer_strokeRenderer = new WeakMap(), _SelectionUIRenderer_extens
|
|
|
115
114
|
if (!bbox)
|
|
116
115
|
return;
|
|
117
116
|
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_strokeBoundingBox).call(this, __classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_applyMargin).call(this, bbox, zoom), zoom);
|
|
118
|
-
}, _SelectionUIRenderer_drawCombinedBoundingBox = function _SelectionUIRenderer_drawCombinedBoundingBox(features, zoom) {
|
|
119
|
-
if (!__classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f")) {
|
|
120
|
-
// The fallback when there is no transform (without a margin)
|
|
121
|
-
const bbox = computeCombinedBoundingBox(features, __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f"));
|
|
122
|
-
if (bbox)
|
|
123
|
-
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_strokeBoundingBox).call(this, bbox, zoom);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
const margin = __classPrivateFieldGet(this, _SelectionUIRenderer_config, "f").boundingBox.margin;
|
|
127
|
-
const transform = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f");
|
|
128
|
-
let minLng = Number.POSITIVE_INFINITY;
|
|
129
|
-
let maxLng = Number.NEGATIVE_INFINITY;
|
|
130
|
-
let minLat = Number.POSITIVE_INFINITY;
|
|
131
|
-
let maxLat = Number.NEGATIVE_INFINITY;
|
|
132
|
-
for (const feature of features) {
|
|
133
|
-
const bbox = computeBoundingBox(feature, __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f"));
|
|
134
|
-
if (!bbox)
|
|
135
|
-
continue;
|
|
136
|
-
// A single-coordinate feature (such as Point) is computed from the extent of the
|
|
137
|
-
// point frame + the margin, as its own frame is (#pointFrame). The coordinate used is
|
|
138
|
-
// the center of the bbox (features other than Point can be zero-area too, e.g. a
|
|
139
|
-
// MultiPoint with a single point, so coordinates must not be treated as a Coordinate)
|
|
140
|
-
if (hasZeroArea(bbox)) {
|
|
141
|
-
const frame = __classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_pointFrame).call(this, feature, bbox.center, zoom);
|
|
142
|
-
for (const [lng, lat] of frame?.coords ?? []) {
|
|
143
|
-
minLng = Math.min(minLng, lng);
|
|
144
|
-
maxLng = Math.max(maxLng, lng);
|
|
145
|
-
minLat = Math.min(minLat, lat);
|
|
146
|
-
maxLat = Math.max(maxLat, lat);
|
|
147
|
-
}
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
const marginedBbox = applyMarginToBoundingBox(bbox, margin, transform, zoom);
|
|
151
|
-
const corners = [
|
|
152
|
-
marginedBbox.topLeft,
|
|
153
|
-
marginedBbox.topRight,
|
|
154
|
-
marginedBbox.bottomRight,
|
|
155
|
-
marginedBbox.bottomLeft,
|
|
156
|
-
];
|
|
157
|
-
for (const corner of corners) {
|
|
158
|
-
minLng = Math.min(minLng, corner[0]);
|
|
159
|
-
maxLng = Math.max(maxLng, corner[0]);
|
|
160
|
-
minLat = Math.min(minLat, corner[1]);
|
|
161
|
-
maxLat = Math.max(maxLat, corner[1]);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
if (!Number.isFinite(minLng))
|
|
165
|
-
return;
|
|
166
|
-
const coords = [
|
|
167
|
-
[minLng, maxLat],
|
|
168
|
-
[maxLng, maxLat],
|
|
169
|
-
[maxLng, minLat],
|
|
170
|
-
[minLng, minLat],
|
|
171
|
-
[minLng, maxLat],
|
|
172
|
-
];
|
|
173
|
-
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_strokePath).call(this, coords, zoom);
|
|
174
117
|
}, _SelectionUIRenderer_drawBoundingBoxWithMargin = function _SelectionUIRenderer_drawBoundingBoxWithMargin(features, zoom) {
|
|
175
118
|
const bbox = computeCombinedBoundingBox(features, __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f"));
|
|
176
119
|
if (!bbox)
|
|
177
120
|
return;
|
|
178
121
|
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_strokeBoundingBox).call(this, __classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_applyMargin).call(this, bbox, zoom), zoom);
|
|
179
122
|
}, _SelectionUIRenderer_drawPointBoundingBox = function _SelectionUIRenderer_drawPointBoundingBox(feature, coord, zoom) {
|
|
180
|
-
const frame = __classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_pointFrame).call(this, feature, coord
|
|
181
|
-
|
|
123
|
+
const frame = __classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_pointFrame).call(this, feature, coord);
|
|
124
|
+
const projectionData = __classPrivateFieldGet(this, _SelectionUIRenderer_projectionData, "f");
|
|
125
|
+
if (!frame || !projectionData)
|
|
182
126
|
return;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
});
|
|
187
|
-
}, _SelectionUIRenderer_pointFrame = function _SelectionUIRenderer_pointFrame(feature, coord, zoom) {
|
|
127
|
+
const { x, y } = frame.center;
|
|
128
|
+
__classPrivateFieldGet(this, _SelectionUIRenderer_outlineRenderer, "f").draw([coord[0], coord[1]], frame.elevationMeters, frame.corners.map((corner) => ({ x: corner.x - x, y: corner.y - y })), __classPrivateFieldGet(this, _SelectionUIRenderer_config, "f").boundingBox.stroke, anchorGhostOpacity(__classPrivateFieldGet(this, _SelectionUIRenderer_terrain, "f"), coord[0], coord[1]), zoom, projectionData);
|
|
129
|
+
}, _SelectionUIRenderer_pointFrame = function _SelectionUIRenderer_pointFrame(feature, coord) {
|
|
188
130
|
const transform = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f");
|
|
189
131
|
if (!transform)
|
|
190
132
|
return null;
|
|
191
133
|
const terrain = __classPrivateFieldGet(this, _SelectionUIRenderer_terrain, "f");
|
|
192
134
|
const elevationMeters = anchorElevationMeters(terrain, coord[0], coord[1]);
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
135
|
+
const center = isAnchorActive(terrain)
|
|
136
|
+
? projectAnchorAt(terrain, coord[0], coord[1], elevationMeters)
|
|
137
|
+
: transform.project(coord);
|
|
196
138
|
if (!center)
|
|
197
139
|
return null;
|
|
198
140
|
const margin = __classPrivateFieldGet(this, _SelectionUIRenderer_config, "f").boundingBox.margin;
|
|
199
141
|
const corners = __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f").resolvePointFrameCorners(feature, center, margin);
|
|
200
|
-
|
|
201
|
-
const coords = corners.map((corner) => {
|
|
202
|
-
const position = toPosition?.(corner);
|
|
203
|
-
if (position)
|
|
204
|
-
return position;
|
|
205
|
-
// No terrain, or the plane seen edge on: the corner is cast onto the map
|
|
206
|
-
const at = transform.unproject(corner);
|
|
207
|
-
return [at.lng, at.lat];
|
|
208
|
-
});
|
|
209
|
-
coords.push(coords[0]);
|
|
210
|
-
return { coords, elevationMeters };
|
|
142
|
+
return { anchor: coord, elevationMeters, center, corners };
|
|
211
143
|
}, _SelectionUIRenderer_applyMargin = function _SelectionUIRenderer_applyMargin(bbox, zoom) {
|
|
212
144
|
if (!__classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f"))
|
|
213
145
|
return bbox;
|
|
@@ -219,49 +151,6 @@ _SelectionUIRenderer_strokeRenderer = new WeakMap(), _SelectionUIRenderer_extens
|
|
|
219
151
|
}, _SelectionUIRenderer_strokeBoundingBox = function _SelectionUIRenderer_strokeBoundingBox(bbox, zoom) {
|
|
220
152
|
const corners = [bbox.topLeft, bbox.topRight, bbox.bottomRight, bbox.bottomLeft];
|
|
221
153
|
__classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_strokePath).call(this, [...corners, bbox.topLeft], zoom);
|
|
222
|
-
}, _SelectionUIRenderer_strokePath = function _SelectionUIRenderer_strokePath(coords, zoom
|
|
223
|
-
__classPrivateFieldGet(this, _SelectionUIRenderer_strokeRenderer, "f").draw(coords, __classPrivateFieldGet(this, _SelectionUIRenderer_config, "f").boundingBox.stroke, {
|
|
224
|
-
widthUnit: 'pixels',
|
|
225
|
-
closed: true,
|
|
226
|
-
followTerrain: placement.followTerrain,
|
|
227
|
-
...(placement.elevationMeters !== undefined && {
|
|
228
|
-
elevationMeters: placement.elevationMeters,
|
|
229
|
-
}),
|
|
230
|
-
}, zoom, __classPrivateFieldGet(this, _SelectionUIRenderer_projectionData, "f") ?? undefined);
|
|
154
|
+
}, _SelectionUIRenderer_strokePath = function _SelectionUIRenderer_strokePath(coords, zoom) {
|
|
155
|
+
__classPrivateFieldGet(this, _SelectionUIRenderer_strokeRenderer, "f").draw(coords, __classPrivateFieldGet(this, _SelectionUIRenderer_config, "f").boundingBox.stroke, { widthUnit: 'pixels', closed: true, followTerrain: true }, zoom, __classPrivateFieldGet(this, _SelectionUIRenderer_projectionData, "f") ?? undefined);
|
|
231
156
|
};
|
|
232
|
-
/**
|
|
233
|
-
* The inverse of a projection around a point, to the first order: a point of the screen near
|
|
234
|
-
* `center` to the position whose projection it is
|
|
235
|
-
*
|
|
236
|
-
* The scale of the screen along the longitude and the latitude is measured by projecting
|
|
237
|
-
* positions a few pixels to either side of `coord`.
|
|
238
|
-
*
|
|
239
|
-
* @returns null when the projection is degenerate there (seen edge on, or a probe behind the
|
|
240
|
-
* camera)
|
|
241
|
-
*/
|
|
242
|
-
function screenToPlane(project, coord, center, zoom) {
|
|
243
|
-
const [lng, lat] = coord;
|
|
244
|
-
// Degrees of longitude per pixel at the zoom on a 512 px world, a few pixels' worth
|
|
245
|
-
const step = (360 / (512 * 2 ** zoom)) * POINT_FRAME_PROBE_PX;
|
|
246
|
-
const latStep = Math.min(step, Math.max(1e-9, (89.9 - Math.abs(lat)) / 2));
|
|
247
|
-
const east = project([lng + step, lat]);
|
|
248
|
-
const west = project([lng - step, lat]);
|
|
249
|
-
const north = project([lng, lat + latStep]);
|
|
250
|
-
const south = project([lng, lat - latStep]);
|
|
251
|
-
if (!east || !west || !north || !south)
|
|
252
|
-
return null;
|
|
253
|
-
// The screen per degree of longitude (a, c) and of latitude (b, d)
|
|
254
|
-
const a = (east.x - west.x) / (2 * step);
|
|
255
|
-
const c = (east.y - west.y) / (2 * step);
|
|
256
|
-
const b = (north.x - south.x) / (2 * latStep);
|
|
257
|
-
const d = (north.y - south.y) / (2 * latStep);
|
|
258
|
-
const det = a * d - b * c;
|
|
259
|
-
const scale = Math.max(Math.abs(a), Math.abs(b), Math.abs(c), Math.abs(d));
|
|
260
|
-
if (!Number.isFinite(det) || Math.abs(det) <= 1e-12 * scale * scale)
|
|
261
|
-
return null;
|
|
262
|
-
return (point) => {
|
|
263
|
-
const dx = point.x - center.x;
|
|
264
|
-
const dy = point.y - center.y;
|
|
265
|
-
return [lng + (d * dx - b * dy) / det, lat + (a * dy - c * dx) / det];
|
|
266
|
-
};
|
|
267
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sakuzu/maplibre-gl-draw",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "WebGL2 drawing and editing engine for MapLibre GL JS: points, lines, and polygons rendered in a custom layer, with selection, hit testing, and geometry utilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"maplibre",
|