@vcmap/core 5.0.0-rc.22 → 5.0.0-rc.24
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/index.d.ts +631 -98
- package/index.js +24 -9
- package/package.json +2 -2
- package/src/category/category.js +1 -1
- package/src/featureProvider/abstractFeatureProvider.js +1 -18
- package/src/featureProvider/wmsFeatureProvider.js +1 -1
- package/src/interaction/eventHandler.js +14 -0
- package/src/layer/cesium/clusterContext.js +12 -0
- package/src/layer/cesium/vectorCesiumImpl.js +2 -2
- package/src/layer/cesium/vectorContext.js +115 -7
- package/src/layer/cesiumTilesetLayer.js +0 -14
- package/src/layer/czmlLayer.js +1 -1
- package/src/layer/dataSourceLayer.js +1 -53
- package/src/layer/featureLayer.js +0 -44
- package/src/layer/featureStoreLayer.js +0 -15
- package/src/layer/layer.js +0 -11
- package/src/layer/vectorHelpers.js +0 -85
- package/src/layer/vectorLayer.js +0 -9
- package/src/layer/vectorProperties.js +150 -8
- package/src/layer/vectorTileLayer.js +0 -9
- package/src/layer/wmsHelpers.js +2 -0
- package/src/map/baseOLMap.js +12 -6
- package/src/map/cesiumMap.js +48 -38
- package/src/map/openlayersMap.js +6 -5
- package/src/map/vcsMap.js +22 -0
- package/src/style/arcStyle.js +316 -0
- package/src/style/arrowStyle.js +269 -0
- package/src/util/editor/createFeatureSession.js +3 -1
- package/src/util/editor/editFeaturesSession.js +315 -0
- package/src/util/editor/editGeometrySession.js +5 -1
- package/src/util/editor/editorHelpers.js +118 -14
- package/src/util/editor/editorSessionHelpers.js +12 -0
- package/src/util/editor/editorSymbols.js +6 -0
- package/src/util/editor/interactions/editFeaturesMouseOverInteraction.js +120 -0
- package/src/util/editor/interactions/editGeometryMouseOverInteraction.js +1 -3
- package/src/util/editor/interactions/ensureHandlerSelectionInteraction.js +48 -0
- package/src/util/editor/interactions/mapInteractionController.js +5 -2
- package/src/util/editor/interactions/selectMultiFeatureInteraction.js +146 -0
- package/src/util/editor/interactions/translateVertexInteraction.js +2 -2
- package/src/util/editor/transformation/create2DHandlers.js +294 -0
- package/src/util/editor/transformation/create3DHandlers.js +575 -0
- package/src/util/editor/transformation/extrudeInteraction.js +91 -0
- package/src/util/editor/transformation/rotateInteraction.js +188 -0
- package/src/util/editor/transformation/scaleInteraction.js +185 -0
- package/src/util/editor/transformation/transformationHandler.js +168 -0
- package/src/util/editor/transformation/transformationTypes.js +83 -0
- package/src/util/editor/transformation/translateInteraction.js +209 -0
- package/src/util/featureconverter/arcToCesium.js +87 -0
- package/src/util/featureconverter/convert.js +7 -1
- package/src/util/featureconverter/extent3D.js +64 -1
- package/src/util/featureconverter/lineStringToCesium.js +103 -2
- package/src/util/featureconverter/pointHelpers.js +341 -0
- package/src/util/featureconverter/pointToCesium.js +27 -76
- package/src/util/geometryHelpers.js +11 -8
- package/src/util/mapCollection.js +25 -0
- package/src/util/math.js +99 -2
- package/tests/unit/helpers/cesiumHelpers.js +17 -5
- package/tests/unit/helpers/helpers.js +13 -0
- package/src/featureProvider/featureProviderHelpers.js +0 -50
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { Feature } from 'ol';
|
|
2
|
+
import { Circle, LineString, Point, Polygon } from 'ol/geom.js';
|
|
3
|
+
import { Fill, Icon, Stroke, Style } from 'ol/style.js';
|
|
4
|
+
import { Color } from '@vcmap/cesium';
|
|
5
|
+
import { unByKey } from 'ol/Observable.js';
|
|
6
|
+
import { handlerSymbol } from '../editorSymbols.js';
|
|
7
|
+
import { AXIS_AND_PLANES, greyedOutColor, is1DAxis, is2DAxis, TransformationMode } from './transformationTypes.js';
|
|
8
|
+
import { mercatorProjection } from '../../projection.js';
|
|
9
|
+
import Vector from '../../../layer/vectorLayer.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {import("ol/coordinate").Coordinate} center
|
|
13
|
+
* @param {AXIS_AND_PLANES} axis
|
|
14
|
+
* @param {import("ol/extent").Extent} extent
|
|
15
|
+
* @returns {Array<import("ol/coordinate").Coordinate>}
|
|
16
|
+
*/
|
|
17
|
+
function createAxisPositions(center, axis, extent) {
|
|
18
|
+
if (axis === AXIS_AND_PLANES.X) {
|
|
19
|
+
return [
|
|
20
|
+
[extent[0], center[1], center[2]],
|
|
21
|
+
[center[0], center[1], center[2]],
|
|
22
|
+
[extent[2], center[1], center[2]],
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return [
|
|
27
|
+
[center[0], extent[1], center[2]],
|
|
28
|
+
[center[0], center[1], center[2]],
|
|
29
|
+
[center[0], extent[3], center[2]],
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Creates a function to add axis to the scratch layer. To cleanup features created by this function, you can call
|
|
35
|
+
* it with AXIS_AND_PLANES.NONE.
|
|
36
|
+
* @param {import("@vcmap/core").VectorLayer} scratchLayer
|
|
37
|
+
* @param {import("ol/extent").Extent} [projectionExtent]
|
|
38
|
+
* @returns {function(AXIS_AND_PLANES, import("ol/coordinate").Coordinate):void}
|
|
39
|
+
*/
|
|
40
|
+
function createShowAxisFeatures(scratchLayer, projectionExtent) {
|
|
41
|
+
let featureIds;
|
|
42
|
+
const extent = projectionExtent ?? mercatorProjection.proj.getExtent();
|
|
43
|
+
|
|
44
|
+
return (axis, center) => {
|
|
45
|
+
if (featureIds) {
|
|
46
|
+
scratchLayer.removeFeaturesById(featureIds);
|
|
47
|
+
featureIds = null;
|
|
48
|
+
}
|
|
49
|
+
if (axis !== AXIS_AND_PLANES.NONE) {
|
|
50
|
+
const features = [];
|
|
51
|
+
if (axis === AXIS_AND_PLANES.X || axis === AXIS_AND_PLANES.XY) {
|
|
52
|
+
const feature = new Feature({
|
|
53
|
+
geometry: new LineString(createAxisPositions(center, AXIS_AND_PLANES.X, extent)),
|
|
54
|
+
});
|
|
55
|
+
feature.setStyle(new Style({
|
|
56
|
+
stroke: new Stroke({ color: Color.RED.withAlpha(0.5).toCssColorString(), width: 1 }),
|
|
57
|
+
}));
|
|
58
|
+
features.push(feature);
|
|
59
|
+
}
|
|
60
|
+
if (axis === AXIS_AND_PLANES.Y || axis === AXIS_AND_PLANES.XY) {
|
|
61
|
+
const feature = new Feature({
|
|
62
|
+
geometry: new LineString(createAxisPositions(center, AXIS_AND_PLANES.Y, extent)),
|
|
63
|
+
});
|
|
64
|
+
feature.setStyle(new Style({
|
|
65
|
+
stroke: new Stroke({ color: Color.GREEN.withAlpha(0.5).toCssColorString(), width: 1 }),
|
|
66
|
+
}));
|
|
67
|
+
features.push(feature);
|
|
68
|
+
}
|
|
69
|
+
features.forEach((f) => {
|
|
70
|
+
const geometry = f.getGeometry();
|
|
71
|
+
geometry[Vector.alreadyTransformedToImage] = true;
|
|
72
|
+
geometry[Vector.doNotTransform] = true;
|
|
73
|
+
});
|
|
74
|
+
featureIds = scratchLayer.addFeatures(features);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {AXIS_AND_PLANES} axis
|
|
81
|
+
* @param {TransformationMode} mode
|
|
82
|
+
* @param {string=} [colorOverride]
|
|
83
|
+
* @returns {Array<import("ol").Feature>}
|
|
84
|
+
*/
|
|
85
|
+
function createLineAxisFeatures(axis, mode, colorOverride) {
|
|
86
|
+
let color;
|
|
87
|
+
let coordinates;
|
|
88
|
+
let rotation = 0;
|
|
89
|
+
|
|
90
|
+
if (axis === AXIS_AND_PLANES.X) {
|
|
91
|
+
color = Color.RED.toCssColorString();
|
|
92
|
+
coordinates = [[0, 0, 0], [1, 0, 0]];
|
|
93
|
+
rotation = Math.PI / 2;
|
|
94
|
+
} else {
|
|
95
|
+
color = Color.GREEN.toCssColorString();
|
|
96
|
+
coordinates = [[0, 0, 0], [0, 1, 0]];
|
|
97
|
+
}
|
|
98
|
+
color = colorOverride ?? color;
|
|
99
|
+
let src;
|
|
100
|
+
if (mode === TransformationMode.TRANSLATE) {
|
|
101
|
+
src = '<svg height="13" width="13" xmlns="http://www.w3.org/2000/svg"><polygon points="0,13 13,13 6,0" style="fill:white;" /></svg>'; // an arrow svg
|
|
102
|
+
} else {
|
|
103
|
+
src = '<svg height="13" width="13" xmlns="http://www.w3.org/2000/svg"><polygon points="0,0 13,0 13,13 0,13" style="fill:white" /></svg>'; // a cube svg
|
|
104
|
+
}
|
|
105
|
+
src = `data:image/svg+xml,${encodeURIComponent(src)}`;
|
|
106
|
+
|
|
107
|
+
const features = [
|
|
108
|
+
new Feature({
|
|
109
|
+
geometry: new Point(coordinates[1].slice()),
|
|
110
|
+
axis,
|
|
111
|
+
}),
|
|
112
|
+
new Feature({
|
|
113
|
+
geometry: new LineString(coordinates),
|
|
114
|
+
axis,
|
|
115
|
+
}),
|
|
116
|
+
];
|
|
117
|
+
features[0].setStyle(new Style({
|
|
118
|
+
image: new Icon({
|
|
119
|
+
src,
|
|
120
|
+
anchor: [0.5, 1],
|
|
121
|
+
color,
|
|
122
|
+
rotation,
|
|
123
|
+
}),
|
|
124
|
+
}));
|
|
125
|
+
features[1].setStyle(new Style({ stroke: new Stroke({ color, width: 4 }) }));
|
|
126
|
+
|
|
127
|
+
return features;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {string=} [colorOverride]
|
|
132
|
+
* @returns {import("ol").Feature<Polygon>}
|
|
133
|
+
*/
|
|
134
|
+
function createPlaneFeature(colorOverride) {
|
|
135
|
+
const feature = new Feature({
|
|
136
|
+
geometry: new Polygon([[
|
|
137
|
+
[0.2, 0.2, 0],
|
|
138
|
+
[0.2, 0.4, 0],
|
|
139
|
+
[0.4, 0.4, 0],
|
|
140
|
+
[0.4, 0.2, 0],
|
|
141
|
+
[0.2, 0.2, 0],
|
|
142
|
+
]]),
|
|
143
|
+
axis: AXIS_AND_PLANES.XY,
|
|
144
|
+
});
|
|
145
|
+
const color = colorOverride ?? Color.BLUE.toCssColorString();
|
|
146
|
+
feature.setStyle(new Style({ fill: new Fill({ color }) }));
|
|
147
|
+
return feature;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Creates a function to add a shadow (greyed out clone of a handler) to the scratch layer. To cleanup features created by this function, you can call
|
|
152
|
+
* it with AXIS_AND_PLANES.NONE.
|
|
153
|
+
* @param {import("@vcmap/core").VectorLayer} scratchLayer
|
|
154
|
+
* @returns {function(AXIS_AND_PLANES, TransformationMode, import("ol/coordinate").Coordinate, number):void}
|
|
155
|
+
*/
|
|
156
|
+
function createShowShadowFeatures(scratchLayer) {
|
|
157
|
+
let featureIds;
|
|
158
|
+
const color = greyedOutColor.toCssColorString();
|
|
159
|
+
|
|
160
|
+
return (axis, mode, center, scale) => {
|
|
161
|
+
if (featureIds) {
|
|
162
|
+
scratchLayer.removeFeaturesById(featureIds);
|
|
163
|
+
featureIds = null;
|
|
164
|
+
}
|
|
165
|
+
if (axis !== AXIS_AND_PLANES.NONE) {
|
|
166
|
+
let features = [];
|
|
167
|
+
if (is1DAxis(axis)) {
|
|
168
|
+
features = createLineAxisFeatures(axis, mode, color);
|
|
169
|
+
} else if (is2DAxis(axis)) {
|
|
170
|
+
features = [createPlaneFeature(color)];
|
|
171
|
+
}
|
|
172
|
+
features.forEach((f) => {
|
|
173
|
+
f.getGeometry().applyTransform((input, output) => {
|
|
174
|
+
const inputLength = input.length;
|
|
175
|
+
for (let i = 0; i < inputLength; i += 3) {
|
|
176
|
+
output[i] = (input[i] * scale) + center[0];
|
|
177
|
+
output[i + 1] = (input[i + 1] * scale) + center[1];
|
|
178
|
+
output[i + 2] = 0;
|
|
179
|
+
}
|
|
180
|
+
return output;
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
featureIds = scratchLayer.addFeatures(features);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* The function will create 2D handlers for the {@see OpenlayerMap} and the {@see ObliqueMap} depending on the provided mode.
|
|
190
|
+
* In most scenarios, handlers must not be created using this function, but using the startEditFeaturesSession or for lower
|
|
191
|
+
* level access the createTransformationHandler instead.
|
|
192
|
+
* @param {import("@vcmap/core").BaseOLMap} map
|
|
193
|
+
* @param {import("@vcmap/core").VectorLayer} scratchLayer
|
|
194
|
+
* @param {TransformationMode} mode
|
|
195
|
+
* @returns {Handlers}
|
|
196
|
+
*/
|
|
197
|
+
export default function create2DHandlers(map, scratchLayer, mode) {
|
|
198
|
+
let center = [0, 0, 0];
|
|
199
|
+
let scale = 1;
|
|
200
|
+
let features = [];
|
|
201
|
+
if (mode === TransformationMode.TRANSLATE || mode === TransformationMode.SCALE) {
|
|
202
|
+
features = [
|
|
203
|
+
...createLineAxisFeatures(AXIS_AND_PLANES.X, mode),
|
|
204
|
+
...createLineAxisFeatures(AXIS_AND_PLANES.Y, mode),
|
|
205
|
+
createPlaneFeature(),
|
|
206
|
+
];
|
|
207
|
+
} else if (mode === TransformationMode.ROTATE) {
|
|
208
|
+
features = [
|
|
209
|
+
new Feature({
|
|
210
|
+
geometry: new Circle([0, 0, 0], 0.5),
|
|
211
|
+
axis: AXIS_AND_PLANES.Z,
|
|
212
|
+
}),
|
|
213
|
+
];
|
|
214
|
+
features[0].setStyle(new Style({ stroke: new Stroke({ color: Color.BLUE.toCssColorString(), width: 2 }) }));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
features.forEach((f) => {
|
|
218
|
+
const geometry = f.getGeometry();
|
|
219
|
+
geometry[Vector.alreadyTransformedToImage] = true;
|
|
220
|
+
geometry[Vector.doNotTransform] = true;
|
|
221
|
+
f[handlerSymbol] = f.get('axis');
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const postRenderListenerKey = map.olMap.on('postrender', () => {
|
|
225
|
+
if (!(center[0] === 0 && center[1] === 0 && center[2] === 0)) {
|
|
226
|
+
const res = map.getCurrentResolution(center) * 60;
|
|
227
|
+
const factor = res / scale;
|
|
228
|
+
if (factor !== 1) {
|
|
229
|
+
features.forEach((f) => {
|
|
230
|
+
f.getGeometry().applyTransform((input, output) => {
|
|
231
|
+
const inputLength = input.length;
|
|
232
|
+
for (let i = 0; i < inputLength; i += 3) {
|
|
233
|
+
output[i] = ((input[i] - center[0]) * factor) + center[0];
|
|
234
|
+
output[i + 1] = ((input[i + 1] - center[1]) * factor) + center[1];
|
|
235
|
+
output[i + 2] = 0;
|
|
236
|
+
}
|
|
237
|
+
return output;
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
scale = res;
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
let showAxis = AXIS_AND_PLANES.NONE;
|
|
247
|
+
const showAxisFeatures = createShowAxisFeatures(scratchLayer);
|
|
248
|
+
const showShadowFeatures = createShowShadowFeatures(scratchLayer);
|
|
249
|
+
|
|
250
|
+
let showing = false;
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
get show() { return showing; },
|
|
254
|
+
set show(show) {
|
|
255
|
+
if (show !== showing) {
|
|
256
|
+
showing = show;
|
|
257
|
+
if (!show) {
|
|
258
|
+
scratchLayer.removeFeaturesById(features.map(f => f.getId()));
|
|
259
|
+
} else {
|
|
260
|
+
scratchLayer.addFeatures(features);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
get showAxis() { return showAxis; },
|
|
265
|
+
set showAxis(axis) {
|
|
266
|
+
showAxis = axis;
|
|
267
|
+
showAxisFeatures(axis, center);
|
|
268
|
+
showShadowFeatures(axis, mode, center, scale);
|
|
269
|
+
},
|
|
270
|
+
greyOutZ: false,
|
|
271
|
+
setCenter(newCenter) {
|
|
272
|
+
const dx = newCenter[0] - center[0];
|
|
273
|
+
const dy = newCenter[1] - center[1];
|
|
274
|
+
features.forEach((f) => {
|
|
275
|
+
f.getGeometry().applyTransform((input, output) => {
|
|
276
|
+
const inputLength = input.length;
|
|
277
|
+
for (let i = 0; i < inputLength; i += 3) {
|
|
278
|
+
output[i] = input[i] + dx;
|
|
279
|
+
output[i + 1] = input[i + 1] + dy;
|
|
280
|
+
output[i + 2] = input[i + 2];
|
|
281
|
+
}
|
|
282
|
+
return output;
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
center = newCenter.slice();
|
|
286
|
+
},
|
|
287
|
+
destroy() {
|
|
288
|
+
unByKey(postRenderListenerKey);
|
|
289
|
+
showAxisFeatures(AXIS_AND_PLANES.NONE, center);
|
|
290
|
+
showShadowFeatures(AXIS_AND_PLANES.NONE, mode, center, scale);
|
|
291
|
+
scratchLayer.removeFeaturesById(features.map(f => f.getId()).filter(id => id));
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}
|