qwc2 2025.10.24 → 2025.10.25
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/components/FeatureAttributesWindow.js +3 -2
- package/components/NumericInputWindow.js +30 -22
- package/components/map/layers/MVTLayer.js +3 -0
- package/components/map/layers/VectorLayer.js +66 -65
- package/components/map3d/drawtool/EditTool3D.js +1 -1
- package/components/style/NumericInputWindow.css +19 -4
- package/components/widgets/TextInput.js +4 -2
- package/package.json +1 -1
- package/plugins/HeightProfile.js +3 -1
- package/plugins/Redlining.js +7 -1
- package/plugins/map/RedliningSupport.js +279 -219
- package/reducers/redlining.js +5 -3
- package/scripts/updateTranslations.js +1 -1
- package/static/translations/bg-BG.json +3 -3
- package/static/translations/ca-ES.json +3 -3
- package/static/translations/cs-CZ.json +3 -3
- package/static/translations/de-CH.json +3 -3
- package/static/translations/de-DE.json +3 -3
- package/static/translations/en-US.json +3 -3
- package/static/translations/es-ES.json +3 -3
- package/static/translations/fi-FI.json +3 -3
- package/static/translations/fr-FR.json +3 -3
- package/static/translations/hu-HU.json +3 -3
- package/static/translations/it-IT.json +3 -3
- package/static/translations/ja-JP.json +3 -3
- package/static/translations/nl-NL.json +3 -3
- package/static/translations/no-NO.json +3 -3
- package/static/translations/pl-PL.json +3 -3
- package/static/translations/pt-BR.json +3 -3
- package/static/translations/pt-PT.json +3 -3
- package/static/translations/ro-RO.json +3 -3
- package/static/translations/ru-RU.json +3 -3
- package/static/translations/sv-SE.json +3 -3
- package/static/translations/tr-TR.json +3 -3
- package/static/translations/tsconfig.json +3 -3
- package/static/translations/uk-UA.json +3 -3
- package/utils/EditingInterface.js +15 -4
- package/utils/LayerUtils.js +16 -6
|
@@ -31,6 +31,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
31
31
|
import React from 'react';
|
|
32
32
|
import { connect } from 'react-redux';
|
|
33
33
|
import FileSaver from 'file-saver';
|
|
34
|
+
import isEmpty from 'lodash.isempty';
|
|
34
35
|
import Mousetrap from 'mousetrap';
|
|
35
36
|
import ol from 'openlayers';
|
|
36
37
|
import PropTypes from 'prop-types';
|
|
@@ -140,16 +141,16 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
140
141
|
});
|
|
141
142
|
_defineProperty(_this, "updateCurrentFeature", function (feature) {
|
|
142
143
|
var deletedKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
143
|
-
if (_this.
|
|
144
|
+
if (_this.selectedFeatures.length === 1 && _this.props.redlining.selectedFeature) {
|
|
144
145
|
if (feature.circleParams) {
|
|
145
146
|
var circleParams = feature.circleParams;
|
|
146
|
-
_this.
|
|
147
|
+
_this.selectedFeatures[0].setGeometry(new ol.geom.Circle(circleParams.center, circleParams.radius));
|
|
147
148
|
} else {
|
|
148
|
-
_this.
|
|
149
|
+
_this.selectedFeatures[0].getGeometry().setCoordinates(feature.geometry.coordinates);
|
|
149
150
|
}
|
|
150
|
-
_this.
|
|
151
|
+
_this.selectedFeatures[0].setProperties(feature.properties, true);
|
|
151
152
|
deletedKeys.forEach(function (key) {
|
|
152
|
-
_this.
|
|
153
|
+
_this.selectedFeatures[0].unset(key);
|
|
153
154
|
});
|
|
154
155
|
_this.props.changeRedliningState({
|
|
155
156
|
selectedFeature: feature,
|
|
@@ -174,16 +175,47 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
174
175
|
var isText = feature.get("shape") === "Text";
|
|
175
176
|
return _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, isText ? "textOutlineColor" : "borderColor", styleOptions.strokeColor), "strokeDash", styleOptions.strokeDash), "size", (styleOptions.strokeWidth - 1) * 2), isText ? "textFillColor" : "fillColor", styleOptions.fillColor), "text", label), "headmarker", styleOptions.headmarker), "tailmarker", styleOptions.tailmarker);
|
|
176
177
|
});
|
|
177
|
-
_defineProperty(_this, "updateFeatureStyle", function (
|
|
178
|
-
|
|
178
|
+
_defineProperty(_this, "updateFeatureStyle", function (feature) {
|
|
179
|
+
_this.blockOnChange = true;
|
|
180
|
+
var styleProps = _this.props.redlining.style;
|
|
181
|
+
var isText = feature.get("shape") === "Text";
|
|
179
182
|
var styleName = isText ? "text" : "default";
|
|
180
183
|
var opts = _this.styleOptions(styleProps, isText);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
184
|
+
if (!feature.get('measurements')) {
|
|
185
|
+
feature.set('label', styleProps.text);
|
|
186
|
+
}
|
|
187
|
+
feature.set('styleName', styleName);
|
|
188
|
+
feature.set('styleOptions', opts);
|
|
185
189
|
_this.blockOnChange = false;
|
|
186
190
|
});
|
|
191
|
+
_defineProperty(_this, "toggleFeatureMeasurements", function (feature) {
|
|
192
|
+
if (_this.props.redlining.measurements) {
|
|
193
|
+
var settings = {
|
|
194
|
+
displayCrs: _this.props.displayCrs,
|
|
195
|
+
lenUnit: _this.props.redlining.lenUnit,
|
|
196
|
+
areaUnit: _this.props.redlining.areaUnit
|
|
197
|
+
};
|
|
198
|
+
MeasureUtils.updateFeatureMeasurements(feature, feature.get('shape'), _this.props.mapCrs, settings);
|
|
199
|
+
} else {
|
|
200
|
+
feature.set('measurements', undefined);
|
|
201
|
+
feature.set('segment_labels', undefined);
|
|
202
|
+
feature.set('label', '');
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
_defineProperty(_this, "updateMeasurements", function (ev) {
|
|
206
|
+
if (_this.blockOnChange) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
var feature = ev.target;
|
|
210
|
+
if (feature.get('measurements')) {
|
|
211
|
+
var settings = {
|
|
212
|
+
displayCrs: _this.props.displayCrs,
|
|
213
|
+
lenUnit: _this.props.redlining.lenUnit,
|
|
214
|
+
areaUnit: _this.props.redlining.areaUnit
|
|
215
|
+
};
|
|
216
|
+
MeasureUtils.updateFeatureMeasurements(feature, feature.get('shape'), _this.props.mapCrs, settings);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
187
219
|
_defineProperty(_this, "styleFunction", function (feature) {
|
|
188
220
|
var styleOptions = feature.get("styleOptions");
|
|
189
221
|
var styleName = feature.get("styleName");
|
|
@@ -199,86 +231,11 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
199
231
|
}
|
|
200
232
|
return styles;
|
|
201
233
|
});
|
|
202
|
-
_defineProperty(_this, "
|
|
203
|
-
var
|
|
204
|
-
_this
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if (circleParams) {
|
|
208
|
-
_this.currentFeature.setGeometry(new ol.geom.Circle(circleParams.center, circleParams.radius));
|
|
209
|
-
}
|
|
210
|
-
var measurements = _this.currentFeature.get('measurements');
|
|
211
|
-
var featureObj = _this.currentFeatureObject();
|
|
212
|
-
var newRedliningState = {
|
|
213
|
-
style: _this.styleProps(_this.currentFeature),
|
|
214
|
-
measurements: !!_this.currentFeature.get('measurements'),
|
|
215
|
-
selectedFeature: featureObj,
|
|
216
|
-
geomType: (_featureObj$shape = featureObj === null || featureObj === void 0 ? void 0 : featureObj.shape) !== null && _featureObj$shape !== void 0 ? _featureObj$shape : _this.props.redlining.geomType
|
|
217
|
-
};
|
|
218
|
-
if (measurements) {
|
|
219
|
-
newRedliningState.lenUnit = measurements.lenUnit;
|
|
220
|
-
newRedliningState.areaUnit = measurements.areaUnit;
|
|
221
|
-
}
|
|
222
|
-
_this.props.changeRedliningState(newRedliningState);
|
|
223
|
-
_this.currentFeature.on('change', _this.updateMeasurements);
|
|
224
|
-
});
|
|
225
|
-
_defineProperty(_this, "addDrawInteraction", function () {
|
|
226
|
-
var geomTypeConfig = GeomTypeConfig[_this.props.redlining.geomType];
|
|
227
|
-
if (!geomTypeConfig) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
var isFreeHand = _this.props.redlining.freehand;
|
|
231
|
-
var drawInteraction = geomTypeConfig.drawInteraction({
|
|
232
|
-
stopClick: true,
|
|
233
|
-
condition: function condition(event) {
|
|
234
|
-
return event.originalEvent.buttons === 1;
|
|
235
|
-
},
|
|
236
|
-
style: function style() {
|
|
237
|
-
return _this.picking ? [] : FeatureStyles.sketchInteraction();
|
|
238
|
-
},
|
|
239
|
-
freehand: isFreeHand
|
|
240
|
-
});
|
|
241
|
-
drawInteraction.on('drawstart', function (evt) {
|
|
242
|
-
if (_this.picking && _this.props.redlining.drawMultiple === false) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
_this.leaveTemporaryEditMode();
|
|
246
|
-
_this.currentFeature = evt.feature;
|
|
247
|
-
_this.currentFeature.setId(uuidv4());
|
|
248
|
-
_this.currentFeature.set('shape', _this.props.redlining.geomType);
|
|
249
|
-
_this.currentFeature.setStyle(_this.styleFunction);
|
|
250
|
-
_this.updateFeatureStyle(_this.props.redlining.style);
|
|
251
|
-
_this.currentFeature.on('change', _this.updateMeasurements);
|
|
252
|
-
}, _this);
|
|
253
|
-
drawInteraction.on('drawend', function () {
|
|
254
|
-
var featureId = _this.currentFeature.getId();
|
|
255
|
-
_this.commitCurrentFeature(_this.props.redlining, true);
|
|
256
|
-
_this.enterTemporaryEditMode(featureId, _this.props.redlining.layer, geomTypeConfig.editTool);
|
|
257
|
-
}, _this);
|
|
258
|
-
_this.props.map.addInteraction(drawInteraction);
|
|
259
|
-
_this.interactions.push(drawInteraction);
|
|
260
|
-
_this.setState({
|
|
261
|
-
showRecordLocation: geomTypeConfig.showRecordLocation
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
_defineProperty(_this, "updateMeasurements", function () {
|
|
265
|
-
if (_this.blockOnChange || !_this.currentFeature) {
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
var feature = _this.currentFeature;
|
|
269
|
-
var hadMeasurements = !!feature.get('measurements');
|
|
270
|
-
if (_this.props.redlining.measurements) {
|
|
271
|
-
var settings = {
|
|
272
|
-
displayCrs: _this.props.displayCrs,
|
|
273
|
-
lenUnit: _this.props.redlining.lenUnit,
|
|
274
|
-
areaUnit: _this.props.redlining.areaUnit
|
|
275
|
-
};
|
|
276
|
-
MeasureUtils.updateFeatureMeasurements(feature, feature.get('shape'), _this.props.mapCrs, settings);
|
|
277
|
-
} else if (hadMeasurements) {
|
|
278
|
-
feature.set('measurements', undefined);
|
|
279
|
-
feature.set('segment_labels', undefined);
|
|
280
|
-
feature.set('label', '');
|
|
281
|
-
}
|
|
234
|
+
_defineProperty(_this, "searchRedliningLayer", function (layerId) {
|
|
235
|
+
var _this$props$map$getLa;
|
|
236
|
+
return (_this$props$map$getLa = _this.props.map.getLayers().getArray().find(function (l) {
|
|
237
|
+
return l.get('id') === layerId;
|
|
238
|
+
})) !== null && _this$props$map$getLa !== void 0 ? _this$props$map$getLa : null;
|
|
282
239
|
});
|
|
283
240
|
_defineProperty(_this, "waitForFeatureAndLayer", function (layerId, featureId, callback) {
|
|
284
241
|
var redliningLayer = _this.searchRedliningLayer(layerId);
|
|
@@ -311,22 +268,59 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
311
268
|
callback(redliningLayer, null);
|
|
312
269
|
}
|
|
313
270
|
});
|
|
271
|
+
_defineProperty(_this, "addDrawInteraction", function () {
|
|
272
|
+
var geomTypeConfig = GeomTypeConfig[_this.props.redlining.geomType];
|
|
273
|
+
if (!geomTypeConfig) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
var isFreeHand = _this.props.redlining.freehand;
|
|
277
|
+
var drawInteraction = geomTypeConfig.drawInteraction({
|
|
278
|
+
stopClick: true,
|
|
279
|
+
condition: function condition(event) {
|
|
280
|
+
return event.originalEvent.buttons === 1;
|
|
281
|
+
},
|
|
282
|
+
style: function style() {
|
|
283
|
+
return _this.picking ? [] : FeatureStyles.sketchInteraction();
|
|
284
|
+
},
|
|
285
|
+
freehand: isFreeHand
|
|
286
|
+
});
|
|
287
|
+
drawInteraction.on('drawstart', function (ev) {
|
|
288
|
+
if (_this.picking && _this.props.redlining.drawMultiple === false) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
_this.leaveTemporaryEditMode();
|
|
292
|
+
ev.feature.setId(uuidv4());
|
|
293
|
+
ev.feature.set('shape', _this.props.redlining.geomType);
|
|
294
|
+
_this.updateFeatureStyle(ev.feature);
|
|
295
|
+
_this.toggleFeatureMeasurements(ev.feature);
|
|
296
|
+
_this.selectFeatures([ev.feature]);
|
|
297
|
+
}, _this);
|
|
298
|
+
drawInteraction.on('drawend', function (ev) {
|
|
299
|
+
_this.commitFeatures([ev.feature], _this.props.redlining, true);
|
|
300
|
+
_this.enterTemporaryEditMode(ev.feature.getId(), _this.props.redlining.layer, geomTypeConfig.editTool);
|
|
301
|
+
}, _this);
|
|
302
|
+
_this.props.map.addInteraction(drawInteraction);
|
|
303
|
+
_this.interactions.push(drawInteraction);
|
|
304
|
+
_this.setState({
|
|
305
|
+
showRecordLocation: geomTypeConfig.showRecordLocation
|
|
306
|
+
});
|
|
307
|
+
});
|
|
314
308
|
_defineProperty(_this, "enterTemporaryEditMode", function (featureId, layerId, editTool) {
|
|
315
309
|
_this.waitForFeatureAndLayer(layerId, featureId, function (redliningLayer, feature) {
|
|
316
310
|
if (!feature) {
|
|
317
311
|
return;
|
|
318
312
|
}
|
|
319
|
-
_this.
|
|
313
|
+
_this.selectFeatures([feature]);
|
|
320
314
|
if (editTool === 'Transform') {
|
|
321
|
-
_this.setupTransformInteraction(
|
|
315
|
+
_this.setupTransformInteraction(redliningLayer, _this.selectedFeatures);
|
|
322
316
|
} else {
|
|
323
|
-
_this.setupModifyInteraction(
|
|
317
|
+
_this.setupModifyInteraction(_this.selectedFeatures);
|
|
324
318
|
}
|
|
325
319
|
_this.picking = true;
|
|
326
320
|
});
|
|
327
321
|
});
|
|
328
322
|
_defineProperty(_this, "leaveTemporaryEditMode", function () {
|
|
329
|
-
_this.
|
|
323
|
+
_this.commitFeatures(_this.selectedFeatures, _this.props.redlining);
|
|
330
324
|
if (_this.picking) {
|
|
331
325
|
// Remove modify interactions
|
|
332
326
|
_this.props.map.removeInteraction(_this.interactions.pop());
|
|
@@ -344,10 +338,10 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
344
338
|
});
|
|
345
339
|
var currentEditInteraction = null;
|
|
346
340
|
selectInteraction.on('select', function (evt) {
|
|
347
|
-
if (evt.selected.length === 1 && evt.selected[0]
|
|
341
|
+
if (evt.selected.length === 1 && _this.selectedFeatures.includes(evt.selected[0])) {
|
|
348
342
|
return;
|
|
349
343
|
}
|
|
350
|
-
_this.
|
|
344
|
+
_this.commitFeatures(_this.selectedFeatures, _this.props.redlining);
|
|
351
345
|
if (currentEditInteraction) {
|
|
352
346
|
_this.props.map.removeInteraction(currentEditInteraction);
|
|
353
347
|
_this.interactions = _this.interactions.filter(function (i) {
|
|
@@ -356,14 +350,14 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
356
350
|
currentEditInteraction = null;
|
|
357
351
|
}
|
|
358
352
|
if (evt.selected.length === 1) {
|
|
359
|
-
_this.
|
|
360
|
-
var geomTypeConfig = GeomTypeConfig[
|
|
353
|
+
_this.selectFeatures(evt.selected);
|
|
354
|
+
var geomTypeConfig = GeomTypeConfig[evt.selected[0].get('shape')];
|
|
361
355
|
if (geomTypeConfig && geomTypeConfig.editTool === 'Transform') {
|
|
362
|
-
currentEditInteraction = _this.setupTransformInteraction([
|
|
356
|
+
currentEditInteraction = _this.setupTransformInteraction(redliningLayer, [evt.selected[0]]);
|
|
363
357
|
currentEditInteraction.on('select', function (ev) {
|
|
364
358
|
// Clear selection when selecting a different feature, and let the parent select interaction deal with the new feature
|
|
365
|
-
if (_this.
|
|
366
|
-
_this.
|
|
359
|
+
if (!isEmpty(_this.selectedFeatures) && !_this.selectedFeatures.includes(ev.feature)) {
|
|
360
|
+
_this.commitFeatures(_this.selectedFeatures, _this.props.redlining);
|
|
367
361
|
currentEditInteraction.setSelection(new ol.Collection());
|
|
368
362
|
}
|
|
369
363
|
});
|
|
@@ -384,26 +378,22 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
384
378
|
if (!redliningLayer) {
|
|
385
379
|
return;
|
|
386
380
|
}
|
|
387
|
-
var transformInteraction = _this.setupTransformInteraction();
|
|
381
|
+
var transformInteraction = _this.setupTransformInteraction(redliningLayer, [], true);
|
|
388
382
|
transformInteraction.on('select', function (evt) {
|
|
389
|
-
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
_this.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
383
|
+
var added = evt.features.getArray().filter(function (x) {
|
|
384
|
+
return !_this.selectedFeatures.includes(x);
|
|
385
|
+
});
|
|
386
|
+
var removed = _this.selectedFeatures.filter(function (x) {
|
|
387
|
+
return !evt.features.getArray().includes(x);
|
|
388
|
+
});
|
|
389
|
+
_this.selectFeatures(added);
|
|
390
|
+
_this.commitFeatures(removed, _this.props.redlining);
|
|
396
391
|
});
|
|
397
392
|
_this.picking = true;
|
|
398
393
|
});
|
|
399
|
-
_defineProperty(_this, "addPickDrawInteraction", function () {
|
|
400
|
-
_this.waitForFeatureAndLayer(_this.props.redlining.layer, null, function () {
|
|
401
|
-
return _this.addPickInteraction();
|
|
402
|
-
});
|
|
403
|
-
});
|
|
404
394
|
_defineProperty(_this, "maybeEnterTemporaryDrawMode", function (ev) {
|
|
405
395
|
var redliningLayer = _this.searchRedliningLayer(_this.props.redlining.layer);
|
|
406
|
-
if (_this.
|
|
396
|
+
if (_this.selectedFeatures.length || !_this.props.redlining.drawMultiple && redliningLayer.getSource().getFeatures().length > 0) {
|
|
407
397
|
return;
|
|
408
398
|
}
|
|
409
399
|
var featureHit = false;
|
|
@@ -433,16 +423,15 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
433
423
|
freehand: isFreeHand
|
|
434
424
|
});
|
|
435
425
|
drawInteraction.on('drawstart', function (evt) {
|
|
436
|
-
|
|
437
|
-
_this.
|
|
438
|
-
_this.
|
|
439
|
-
_this.
|
|
440
|
-
_this.
|
|
441
|
-
_this.currentFeature.on('change', _this.updateMeasurements);
|
|
426
|
+
evt.feature.setId(uuidv4());
|
|
427
|
+
evt.feature.set('shape', _this.props.redlining.geomType);
|
|
428
|
+
_this.updateFeatureStyle(evt.feature);
|
|
429
|
+
_this.toggleFeatureMeasurements(ev.feature);
|
|
430
|
+
_this.selectFeatures([evt.feature]);
|
|
442
431
|
}, _this);
|
|
443
432
|
drawInteraction.on('drawend', function () {
|
|
444
433
|
// Draw end
|
|
445
|
-
_this.
|
|
434
|
+
_this.commitFeatures(_this.selectFeatures, _this.props.redlining, true);
|
|
446
435
|
_this.reset(_this.props.redlining);
|
|
447
436
|
// Ughh... Apparently we need to wait 250ms for the 'singleclick' event processing to finish to avoid pick interactions picking up the current event
|
|
448
437
|
setTimeout(function () {
|
|
@@ -478,18 +467,38 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
478
467
|
_this.interactions.push(modifyInteraction);
|
|
479
468
|
return modifyInteraction;
|
|
480
469
|
});
|
|
481
|
-
_defineProperty(_this, "setupTransformInteraction", function () {
|
|
482
|
-
var selectedFeatures = arguments.length >
|
|
470
|
+
_defineProperty(_this, "setupTransformInteraction", function (redliningLayer) {
|
|
471
|
+
var selectedFeatures = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
472
|
+
var multi = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
483
473
|
var transformInteraction = new ol.interaction.Transform({
|
|
484
474
|
stretch: false,
|
|
475
|
+
addCondition: multi ? function (ev) {
|
|
476
|
+
return ev.originalEvent.ctrlKey;
|
|
477
|
+
} : null,
|
|
485
478
|
keepAspectRatio: function keepAspectRatio(ev) {
|
|
486
|
-
return _this.
|
|
487
|
-
|
|
479
|
+
return _this.selectedFeatures.find(function (f) {
|
|
480
|
+
return GeomTypeConfig[f.get('shape')].regular;
|
|
481
|
+
}) || ol.events.condition.shiftKeyOnly(ev);
|
|
482
|
+
},
|
|
483
|
+
layers: [redliningLayer],
|
|
484
|
+
translateFeature: true
|
|
488
485
|
});
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
486
|
+
// Hacky workaround translateFeature interfering with ctrl-click to deselect selected features
|
|
487
|
+
var origHandleDownEvent = transformInteraction.handleDownEvent;
|
|
488
|
+
transformInteraction.handleDownEvent = function (evt) {
|
|
489
|
+
if (evt.originalEvent.ctrlKey) {
|
|
490
|
+
transformInteraction.set('translateFeature', false);
|
|
492
491
|
}
|
|
492
|
+
var ret = origHandleDownEvent.call(transformInteraction, evt);
|
|
493
|
+
transformInteraction.set('translateFeature', true);
|
|
494
|
+
return ret;
|
|
495
|
+
};
|
|
496
|
+
transformInteraction.on('rotating', function (ev) {
|
|
497
|
+
ev.features.forEach(function (feature) {
|
|
498
|
+
if (feature.get('shape') === 'Text') {
|
|
499
|
+
feature.set('rotation', -ev.angle);
|
|
500
|
+
}
|
|
501
|
+
});
|
|
493
502
|
});
|
|
494
503
|
transformInteraction.on('rotateend', _this.updateSelectedFeature);
|
|
495
504
|
transformInteraction.on('translateend', _this.updateSelectedFeature);
|
|
@@ -500,11 +509,19 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
500
509
|
return transformInteraction;
|
|
501
510
|
});
|
|
502
511
|
_defineProperty(_this, "updateSelectedFeature", function () {
|
|
503
|
-
var _featureObj$
|
|
504
|
-
var featureObj =
|
|
512
|
+
var _featureObj$shape, _featureObj;
|
|
513
|
+
var featureObj = null;
|
|
514
|
+
if (_this.selectedFeatures.length === 1) {
|
|
515
|
+
featureObj = _this.serializeFeature(_this.selectedFeatures[0]);
|
|
516
|
+
} else if (_this.selectedFeatures.length > 1) {
|
|
517
|
+
featureObj = {
|
|
518
|
+
type: "FeatureCollection",
|
|
519
|
+
features: []
|
|
520
|
+
};
|
|
521
|
+
}
|
|
505
522
|
_this.props.changeRedliningState({
|
|
506
523
|
selectedFeature: featureObj,
|
|
507
|
-
geomType: (_featureObj$
|
|
524
|
+
geomType: (_featureObj$shape = (_featureObj = featureObj) === null || _featureObj === void 0 ? void 0 : _featureObj.shape) !== null && _featureObj$shape !== void 0 ? _featureObj$shape : _this.props.redlining.geomType
|
|
508
525
|
});
|
|
509
526
|
});
|
|
510
527
|
_defineProperty(_this, "triggerDelete", function () {
|
|
@@ -512,61 +529,96 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
512
529
|
action: "Delete"
|
|
513
530
|
});
|
|
514
531
|
});
|
|
515
|
-
_defineProperty(_this, "
|
|
516
|
-
if (_this.
|
|
517
|
-
_this.props.removeLayerFeatures(_this.props.redlining.layer,
|
|
518
|
-
|
|
532
|
+
_defineProperty(_this, "deleteCurrentFeatures", function () {
|
|
533
|
+
if (_this.selectedFeatures.length) {
|
|
534
|
+
_this.props.removeLayerFeatures(_this.props.redlining.layer, _this.selectedFeatures.map(function (f) {
|
|
535
|
+
return f.getId();
|
|
536
|
+
}), true);
|
|
537
|
+
_this.selectedFeatures = [];
|
|
519
538
|
}
|
|
520
539
|
});
|
|
521
|
-
_defineProperty(_this, "
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
540
|
+
_defineProperty(_this, "updateRedliningState", function (firstSelection) {
|
|
541
|
+
if (_this.selectedFeatures.length > 0) {
|
|
542
|
+
var features = _this.selectedFeatures;
|
|
543
|
+
var featureObj = features.length === 1 ? _this.serializeFeature(features[0]) : {
|
|
544
|
+
type: "FeatureCollection",
|
|
545
|
+
features: []
|
|
546
|
+
};
|
|
547
|
+
var newRedliningState = {
|
|
548
|
+
selectedFeature: featureObj
|
|
549
|
+
};
|
|
550
|
+
if (firstSelection || _this.selectedFeatures.length === 1) {
|
|
551
|
+
var _featureObj$shape2;
|
|
552
|
+
newRedliningState.style = _this.styleProps(features[0]);
|
|
553
|
+
newRedliningState.measurements = !!features[0].get('measurements');
|
|
554
|
+
newRedliningState.geomType = (_featureObj$shape2 = featureObj === null || featureObj === void 0 ? void 0 : featureObj.shape) !== null && _featureObj$shape2 !== void 0 ? _featureObj$shape2 : _this.props.redlining.geomType;
|
|
555
|
+
var measurements = features[0].get('measurements');
|
|
556
|
+
if (measurements) {
|
|
557
|
+
newRedliningState.lenUnit = measurements.lenUnit;
|
|
558
|
+
newRedliningState.areaUnit = measurements.areaUnit;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
_this.props.changeRedliningState(newRedliningState);
|
|
562
|
+
} else {
|
|
563
|
+
_this.props.changeRedliningState({
|
|
564
|
+
selectedFeature: null
|
|
565
|
+
});
|
|
527
566
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
567
|
+
});
|
|
568
|
+
_defineProperty(_this, "selectFeatures", function (features) {
|
|
569
|
+
var firstSelection = isEmpty(_this.selectedFeatures);
|
|
570
|
+
features.forEach(function (feature) {
|
|
571
|
+
feature.setStyle(_this.styleFunction);
|
|
572
|
+
feature.on('change', _this.updateMeasurements);
|
|
573
|
+
_this.selectedFeatures.push(feature);
|
|
574
|
+
});
|
|
575
|
+
_this.updateRedliningState(firstSelection);
|
|
576
|
+
});
|
|
577
|
+
_defineProperty(_this, "commitFeatures", function (features, redliningProps) {
|
|
578
|
+
var newFeature = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
579
|
+
var featureObjects = features.map(function (feature) {
|
|
580
|
+
var _featureObj$geometry;
|
|
581
|
+
var styleName = feature.get("shape") === "Text" ? "text" : "default";
|
|
582
|
+
var style = FeatureStyles[styleName](feature, feature.get('styleOptions'));
|
|
583
|
+
feature.setStyle(style);
|
|
584
|
+
feature.un('change', _this.updateMeasurements);
|
|
585
|
+
_this.selectedFeatures = _this.selectedFeatures.filter(function (f) {
|
|
586
|
+
return f !== feature;
|
|
587
|
+
});
|
|
588
|
+
var featureObj = _this.serializeFeature(feature);
|
|
589
|
+
// Don't commit empty/invalid features
|
|
590
|
+
if (featureObj.shape === "Text" && !featureObj.properties.label || featureObj.shape === "Circle" && featureObj.circleParams.radius === 0 || ((_featureObj$geometry = featureObj.geometry) === null || _featureObj$geometry === void 0 ? void 0 : _featureObj$geometry.type) === "Polygon" && feature.getGeometry().getArea() === 0) {
|
|
591
|
+
if (!newFeature) {
|
|
592
|
+
_this.props.removeLayerFeatures(redliningProps.layer, [featureObj.id]);
|
|
593
|
+
}
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
if (featureObj.shape === "Circle") {
|
|
597
|
+
var _featureObj$circlePar = featureObj.circleParams,
|
|
598
|
+
center = _featureObj$circlePar.center,
|
|
599
|
+
radius = _featureObj$circlePar.radius;
|
|
600
|
+
var deg2rad = Math.PI / 180;
|
|
601
|
+
featureObj.geometry.type = "Polygon";
|
|
602
|
+
featureObj.geometry.coordinates = [Array.apply(null, Array(91)).map(function (item, index) {
|
|
603
|
+
return [center[0] + radius * Math.cos(4 * index * deg2rad), center[1] + radius * Math.sin(4 * index * deg2rad)];
|
|
604
|
+
})];
|
|
532
605
|
}
|
|
533
|
-
|
|
606
|
+
if (featureObj.geometry.type === "LineString" || featureObj.geometry.type === "Polygon") {
|
|
607
|
+
featureObj.geometry.coordinates = VectorLayerUtils.removeDuplicateNodes(featureObj.geometry.coordinates);
|
|
608
|
+
}
|
|
609
|
+
return featureObj;
|
|
610
|
+
}).filter(Boolean);
|
|
611
|
+
if (isEmpty(featureObjects)) {
|
|
534
612
|
return null;
|
|
535
613
|
}
|
|
536
|
-
if (feature.shape === "Circle") {
|
|
537
|
-
var _feature$circleParams = feature.circleParams,
|
|
538
|
-
center = _feature$circleParams.center,
|
|
539
|
-
radius = _feature$circleParams.radius;
|
|
540
|
-
var deg2rad = Math.PI / 180;
|
|
541
|
-
feature.geometry.type = "Polygon";
|
|
542
|
-
feature.geometry.coordinates = [Array.apply(null, Array(91)).map(function (item, index) {
|
|
543
|
-
return [center[0] + radius * Math.cos(4 * index * deg2rad), center[1] + radius * Math.sin(4 * index * deg2rad)];
|
|
544
|
-
})];
|
|
545
|
-
}
|
|
546
|
-
if (feature.geometry.type === "LineString" || feature.geometry.type === "Polygon") {
|
|
547
|
-
feature.geometry.coordinates = VectorLayerUtils.removeDuplicateNodes(feature.geometry.coordinates);
|
|
548
|
-
}
|
|
549
614
|
var layer = {
|
|
550
615
|
id: redliningProps.layer,
|
|
551
616
|
title: redliningProps.layerTitle,
|
|
552
617
|
role: LayerRole.USERLAYER
|
|
553
618
|
};
|
|
554
|
-
_this.props.addLayerFeatures(layer,
|
|
555
|
-
_this.
|
|
556
|
-
return
|
|
557
|
-
});
|
|
558
|
-
_defineProperty(_this, "resetSelectedFeature", function () {
|
|
559
|
-
if (_this.currentFeature) {
|
|
560
|
-
// Reset selection style
|
|
561
|
-
var styleName = _this.currentFeature.get("shape") === "Text" ? "text" : "default";
|
|
562
|
-
var style = FeatureStyles[styleName](_this.currentFeature, _this.currentFeature.get('styleOptions'));
|
|
563
|
-
_this.currentFeature.setStyle(style);
|
|
564
|
-
_this.currentFeature.un('change', _this.updateMeasurements);
|
|
565
|
-
_this.currentFeature = null;
|
|
566
|
-
_this.props.changeRedliningState({
|
|
567
|
-
selectedFeature: null
|
|
568
|
-
});
|
|
569
|
-
}
|
|
619
|
+
_this.props.addLayerFeatures(layer, featureObjects);
|
|
620
|
+
_this.updateRedliningState();
|
|
621
|
+
return featureObjects;
|
|
570
622
|
});
|
|
571
623
|
_defineProperty(_this, "reset", function (redliningProps) {
|
|
572
624
|
_this.setState({
|
|
@@ -576,50 +628,47 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
576
628
|
_this.props.map.removeInteraction(_this.interactions.shift());
|
|
577
629
|
}
|
|
578
630
|
if (_this.picking) {
|
|
579
|
-
_this.
|
|
631
|
+
_this.commitFeatures(_this.selectedFeatures, redliningProps, false);
|
|
580
632
|
} else {
|
|
581
|
-
_this.
|
|
633
|
+
_this.selectedFeatures.forEach(function (feature) {
|
|
634
|
+
var styleName = feature.get("shape") === "Text" ? "text" : "default";
|
|
635
|
+
var style = FeatureStyles[styleName](feature, feature.get('styleOptions'));
|
|
636
|
+
feature.setStyle(style);
|
|
637
|
+
feature.un('change', _this.updateMeasurements);
|
|
638
|
+
});
|
|
639
|
+
_this.selectedFeatures = [];
|
|
582
640
|
}
|
|
583
641
|
_this.props.map.un('click', _this.maybeEnterTemporaryDrawMode);
|
|
584
642
|
_this.picking = false;
|
|
585
643
|
});
|
|
586
|
-
_defineProperty(_this, "
|
|
587
|
-
var _this$props$map$getLa;
|
|
588
|
-
return (_this$props$map$getLa = _this.props.map.getLayers().getArray().find(function (l) {
|
|
589
|
-
return l.get('id') === layerId;
|
|
590
|
-
})) !== null && _this$props$map$getLa !== void 0 ? _this$props$map$getLa : null;
|
|
591
|
-
});
|
|
592
|
-
_defineProperty(_this, "currentFeatureObject", function () {
|
|
593
|
-
if (!_this.currentFeature) {
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
644
|
+
_defineProperty(_this, "serializeFeature", function (feature) {
|
|
596
645
|
var format = new ol.format.GeoJSON();
|
|
597
|
-
var
|
|
598
|
-
if (
|
|
599
|
-
|
|
600
|
-
center:
|
|
601
|
-
radius:
|
|
646
|
+
var featureObject = format.writeFeatureObject(feature);
|
|
647
|
+
if (feature.get("shape") === "Circle") {
|
|
648
|
+
featureObject.circleParams = {
|
|
649
|
+
center: feature.getGeometry().getCenter(),
|
|
650
|
+
radius: feature.getGeometry().getRadius()
|
|
602
651
|
};
|
|
603
652
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
653
|
+
featureObject.styleName = feature.get('styleName');
|
|
654
|
+
featureObject.styleOptions = feature.get('styleOptions');
|
|
655
|
+
featureObject.shape = feature.get('shape');
|
|
656
|
+
featureObject.measurements = feature.get('measurements');
|
|
657
|
+
featureObject.crs = _this.props.mapCrs;
|
|
609
658
|
// Don't pollute GeoJSON object properties with internal props
|
|
610
|
-
delete
|
|
611
|
-
delete
|
|
612
|
-
delete
|
|
613
|
-
delete
|
|
614
|
-
delete
|
|
659
|
+
delete featureObject.properties.styleName;
|
|
660
|
+
delete featureObject.properties.styleOptions;
|
|
661
|
+
delete featureObject.properties.shape;
|
|
662
|
+
delete featureObject.properties.measurements;
|
|
663
|
+
delete featureObject.properties.circleParams;
|
|
615
664
|
// Don't store empty label prop
|
|
616
|
-
if (
|
|
617
|
-
delete
|
|
665
|
+
if (featureObject.properties.label === "") {
|
|
666
|
+
delete featureObject.properties.label;
|
|
618
667
|
}
|
|
619
|
-
return
|
|
668
|
+
return featureObject;
|
|
620
669
|
});
|
|
621
670
|
_defineProperty(_this, "export", function () {
|
|
622
|
-
var
|
|
671
|
+
var committedFeatures = _this.commitFeatures(_this.selectedFeatures, _this.props.redlining);
|
|
623
672
|
var layer = _this.props.layers.find(function (l) {
|
|
624
673
|
return l.id === _this.props.redlining.layer;
|
|
625
674
|
});
|
|
@@ -630,7 +679,10 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
630
679
|
var geojson = JSON.stringify({
|
|
631
680
|
type: "FeatureCollection",
|
|
632
681
|
features: layer.features.map(function (feature) {
|
|
633
|
-
var
|
|
682
|
+
var _committedFeatures$fi;
|
|
683
|
+
var newFeature = _objectSpread({}, (_committedFeatures$fi = committedFeatures.find(function (f) {
|
|
684
|
+
return f.id === feature.id;
|
|
685
|
+
})) !== null && _committedFeatures$fi !== void 0 ? _committedFeatures$fi : feature);
|
|
634
686
|
newFeature.geometry = VectorLayerUtils.reprojectGeometry(feature.geometry, feature.crs || _this.props.mapCrs, 'EPSG:4326');
|
|
635
687
|
delete newFeature.crs;
|
|
636
688
|
return newFeature;
|
|
@@ -663,7 +715,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
663
715
|
});
|
|
664
716
|
_this.interactions = [];
|
|
665
717
|
_this.picking = false;
|
|
666
|
-
_this.
|
|
718
|
+
_this.selectedFeatures = [];
|
|
667
719
|
_this.blockOnChange = false;
|
|
668
720
|
_this.selectedTextStyle = function (feature, opts) {
|
|
669
721
|
return new ol.style.Style({
|
|
@@ -704,6 +756,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
704
756
|
return _createClass(RedliningSupport, [{
|
|
705
757
|
key: "componentDidUpdate",
|
|
706
758
|
value: function componentDidUpdate(prevProps) {
|
|
759
|
+
var _this2 = this;
|
|
707
760
|
// Bind keyboard shortcuts to delete features
|
|
708
761
|
if (this.props.redlining.action && !prevProps.redlining.action) {
|
|
709
762
|
Mousetrap.bind('del', this.triggerDelete);
|
|
@@ -714,7 +767,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
714
767
|
}
|
|
715
768
|
// Handle delete action immediately and reset the redlining state to the previous action
|
|
716
769
|
if (this.props.redlining.action === 'Delete') {
|
|
717
|
-
this.
|
|
770
|
+
this.deleteCurrentFeatures();
|
|
718
771
|
this.props.changeRedliningState(_objectSpread(_objectSpread({}, prevProps.redlining), {}, {
|
|
719
772
|
selectedFeature: null
|
|
720
773
|
}));
|
|
@@ -725,6 +778,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
725
778
|
this.props.changeRedliningState(_objectSpread(_objectSpread({}, prevProps.redlining), {}, {
|
|
726
779
|
selectedFeature: null
|
|
727
780
|
}));
|
|
781
|
+
return;
|
|
728
782
|
}
|
|
729
783
|
var recreateInteraction = this.props.redlining.action !== prevProps.redlining.action || this.props.redlining.layer !== prevProps.redlining.layer || ['Draw', 'PickDraw'].includes(this.props.redlining.action) && this.props.redlining.geomType !== prevProps.redlining.geomType || this.props.redlining.freehand !== prevProps.redlining.freehand || this.props.redlining.drawMultiple !== prevProps.redlining.drawMultiple;
|
|
730
784
|
if (recreateInteraction) {
|
|
@@ -737,31 +791,37 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
737
791
|
} else if (this.props.redlining.action === 'Pick' || this.props.redlining.action === 'Buffer') {
|
|
738
792
|
this.addPickInteraction();
|
|
739
793
|
} else if (this.props.redlining.action === 'PickDraw') {
|
|
740
|
-
this.
|
|
794
|
+
this.waitForFeatureAndLayer(this.props.redlining.layer, null, function () {
|
|
795
|
+
return _this2.addPickInteraction();
|
|
796
|
+
});
|
|
741
797
|
}
|
|
742
798
|
}
|
|
743
|
-
if (this.
|
|
799
|
+
if (this.selectedFeatures) {
|
|
744
800
|
// Update feature style
|
|
745
801
|
if (this.props.redlining.style !== prevProps.redlining.style) {
|
|
746
|
-
this.
|
|
802
|
+
this.selectedFeatures.forEach(this.updateFeatureStyle);
|
|
747
803
|
}
|
|
748
804
|
// Update current feature measurements
|
|
749
|
-
if (this.props.
|
|
750
|
-
this.
|
|
805
|
+
if (this.props.redlining.measurements !== prevProps.redlining.measurements) {
|
|
806
|
+
this.selectedFeatures.forEach(this.toggleFeatureMeasurements);
|
|
807
|
+
} else if (this.props.map.displayCrs !== prevProps.map.displayCrs || this.props.redlining.lenUnit !== prevProps.redlining.lenUnit || this.props.redlining.areaUnit !== prevProps.redlining.areaUnit) {
|
|
808
|
+
this.selectedFeatures.forEach(function (feature) {
|
|
809
|
+
return feature.changed();
|
|
810
|
+
});
|
|
751
811
|
}
|
|
752
812
|
}
|
|
753
813
|
}
|
|
754
814
|
}, {
|
|
755
815
|
key: "render",
|
|
756
816
|
value: function render() {
|
|
757
|
-
var
|
|
817
|
+
var _this3 = this;
|
|
758
818
|
var widgets = [];
|
|
759
819
|
if (this.props.redlining.extraAction === "NumericInput") {
|
|
760
820
|
widgets.push(/*#__PURE__*/React.createElement(NumericInputWindow, {
|
|
761
821
|
feature: this.props.redlining.selectedFeature,
|
|
762
822
|
key: "NumericInputWindow",
|
|
763
823
|
onClose: function onClose() {
|
|
764
|
-
return
|
|
824
|
+
return _this3.props.changeRedliningState({
|
|
765
825
|
extraAction: null
|
|
766
826
|
});
|
|
767
827
|
},
|
|
@@ -773,7 +833,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
773
833
|
key: "FeatureAttributesWindow",
|
|
774
834
|
layerid: this.props.redlining.layer,
|
|
775
835
|
onClose: function onClose() {
|
|
776
|
-
return
|
|
836
|
+
return _this3.props.changeRedliningState({
|
|
777
837
|
extraAction: null
|
|
778
838
|
});
|
|
779
839
|
},
|