@opengeoweb/webmap-react 14.5.2 → 15.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.esm.js +956 -57
- package/package.json +4 -4
- package/src/lib/components/Clock/Clock.d.ts +6 -0
- package/src/lib/components/Clock/Clock.spec.d.ts +1 -0
- package/src/lib/components/Clock/Clock.stories.d.ts +9 -0
- package/src/lib/components/Clock/ClockContainer.d.ts +13 -0
- package/src/lib/components/Clock/clockContainerUtils.d.ts +1 -0
- package/src/lib/components/Clock/clockContainerUtils.spec.d.ts +1 -0
- package/src/lib/components/Clock/index.d.ts +1 -0
- package/src/lib/components/LayerInfo/LayerInfoDialog.d.ts +1 -0
- package/src/lib/components/LayerInfo/LayerInfoText.d.ts +2 -0
- package/src/lib/components/OpenLayers/OlStyles.d.ts +2 -1
- package/src/lib/components/OpenLayers/OpenLayersMapView.ReferenceTimeModes.stories.d.ts +6 -0
- package/src/lib/components/OpenLayers/types/Timespan.d.ts +2 -0
- package/src/lib/components/index.d.ts +1 -0
- package/src/lib/geotiff-layer-api/index.d.ts +2 -0
- package/src/lib/hooks/useAnimationForLayer.d.ts +2 -2
- package/src/lib/index.d.ts +1 -0
package/index.esm.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { WMInvalidDateValues, getCorrectWMSDimName, WMImageStore, WMImageStoreLoadType, WMJSDimension, webmapUtils, WMLayer, LayerType, legendImageStore, WMImageEventType, getLegendGraphicURLForLayer, WEBMAP_NAMESPACE, WMProj4Defs, privateWebMapUtils, tilesettings } from '@opengeoweb/webmap';
|
|
1
|
+
import { WMInvalidDateValues, getCorrectWMSDimName, WMImageStore, WMImageStoreLoadType, WMJSDimension, webmapUtils, WMLayer, LayerType, legendImageStore, WMImageEventType, getLegendGraphicURLForLayer, WEBMAP_NAMESPACE, WMProj4Defs, privateWebMapUtils, wmDetermineDimensionMode, tilesettings } from '@opengeoweb/webmap';
|
|
2
2
|
export { WEBMAP_NAMESPACE, webmapTranslations } from '@opengeoweb/webmap';
|
|
3
3
|
import React, { createContext, useMemo, useRef, useState, useEffect, useContext, useCallback, useLayoutEffect } from 'react';
|
|
4
4
|
import { memoize, range, without, isEqual, throttle, debounce, cloneDeep } from 'lodash';
|
|
5
|
-
import { equals, containsExtent, getCenter
|
|
5
|
+
import { equals, containsExtent, getCenter } from 'ol/extent';
|
|
6
6
|
import ImageState from 'ol/ImageState';
|
|
7
7
|
import LayerProperty from 'ol/layer/Property';
|
|
8
8
|
import { fromResolutionLike } from 'ol/resolution';
|
|
@@ -10,19 +10,19 @@ import ImageSource, { getRequestExtent } from 'ol/source/Image';
|
|
|
10
10
|
import ImageWrapper, { load } from 'ol/Image';
|
|
11
11
|
import { getImageSrc, getRequestParams, createLoader } from 'ol/source/wms';
|
|
12
12
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
13
|
-
import { CustomTooltip, CanvasComponent, useWheelStopPropagation, ToolContainerDraggable, CustomIconButton, dateUtils } from '@opengeoweb/shared';
|
|
14
|
-
import { Paper, Box, Typography, useTheme, Grid, styled, Slider, TextField, FormControl, InputLabel, Select, MenuItem, Icon as Icon$2, FormLabel, Switch } from '@mui/material';
|
|
13
|
+
import { CustomTooltip, CanvasComponent, useWheelStopPropagation, ToolContainerDraggable, CustomIconButton, dateUtils, useMakeSureContainerStaysInsideWindow, Draggable, Resizable } from '@opengeoweb/shared';
|
|
14
|
+
import { Paper, Box, Typography, useTheme, Grid, styled, Slider, TextField, FormControl, InputLabel, Select, MenuItem, Icon as Icon$2, FormLabel, Switch, ThemeProvider } from '@mui/material';
|
|
15
15
|
import { queryOptions, useQuery } from '@tanstack/react-query';
|
|
16
|
-
import { Point, MultiPoint,
|
|
16
|
+
import { Point, MultiPoint, LineString, Polygon } from 'ol/geom';
|
|
17
17
|
import { Style, Icon as Icon$1, Circle, Stroke, Fill, Text } from 'ol/style';
|
|
18
|
-
import { arrowUpPath, Home, Add, Minus, List, Equalizer, DimensionsElevation, Link, LinkOff, Info, DimensionsOther, DimensionsRefTime, DimensionsTime, locationPath, Location, DrawToolSmoothLine, DrawToolFreehand, DrawToolOval, DrawToolCircle, DrawToolSquare, Delete, DrawToolLineString, DrawToolRectangle, DrawToolPolygon, DrawToolPoint, DrawFIRLand, ArrowUp } from '@opengeoweb/theme';
|
|
18
|
+
import { arrowUpPath, Home, Add, Minus, List, Equalizer, DimensionsElevation, Link, LinkOff, Info, DimensionsOther, DimensionsRefTime, DimensionsTime, locationPath, rotatePath, Location, DrawToolSmoothLine, DrawToolFreehand, DrawToolOval, DrawToolCircle, DrawToolSquare, Delete, DrawToolLineString, DrawToolRectangle, DrawToolPolygon, DrawToolPoint, DrawFIRLand, ArrowUp, darkTheme, ChevronRight, Clock as Clock$1, Resize } from '@opengeoweb/theme';
|
|
19
19
|
import { http, HttpResponse } from 'msw';
|
|
20
20
|
import 'i18next';
|
|
21
21
|
import { useTranslation } from 'react-i18next';
|
|
22
22
|
import Box$1 from '@mui/material/Box';
|
|
23
23
|
import Typography$1 from '@mui/material/Typography';
|
|
24
24
|
import { View, Map, Feature, Collection, Overlay } from 'ol';
|
|
25
|
-
import { defaults, MouseWheelZoom, Draw, Modify, Translate, Snap } from 'ol/interaction';
|
|
25
|
+
import { defaults, MouseWheelZoom, Draw, Modify, Translate, Snap, DragPan } from 'ol/interaction';
|
|
26
26
|
import 'ol/ol.css';
|
|
27
27
|
import { listen, unlistenByKey } from 'ol/events';
|
|
28
28
|
import { unByKey } from 'ol/Observable';
|
|
@@ -60,6 +60,7 @@ var en = {
|
|
|
60
60
|
"webmap-react-title": "Title",
|
|
61
61
|
"webmap-react-name": "Name",
|
|
62
62
|
"webmap-react-service": "Service",
|
|
63
|
+
"webmap-react-service-url": "Service URL",
|
|
63
64
|
"webmap-react-abstract": "Abstract",
|
|
64
65
|
"webmap-react-dimensions": "Dimensions",
|
|
65
66
|
"webmap-react-styles": "Styles",
|
|
@@ -99,7 +100,9 @@ var en = {
|
|
|
99
100
|
"webmap-react-location": "Location",
|
|
100
101
|
"webmap-react-delete": "Delete",
|
|
101
102
|
"webmap-react-legend-no-image": "No legend graphic available",
|
|
102
|
-
"webmap-react-map-measure-help-tooltip": "Click to measure"
|
|
103
|
+
"webmap-react-map-measure-help-tooltip": "Click to measure",
|
|
104
|
+
"clock-show": "Show clock",
|
|
105
|
+
"clock-hide": "Hide clock"
|
|
103
106
|
};
|
|
104
107
|
var fi = {
|
|
105
108
|
"webmap-react-event": "tapahtuma:",
|
|
@@ -113,6 +116,7 @@ var fi = {
|
|
|
113
116
|
"webmap-react-title": "Otsikko",
|
|
114
117
|
"webmap-react-name": "Nimi",
|
|
115
118
|
"webmap-react-service": "Palvelu",
|
|
119
|
+
"webmap-react-service-url": "Palvelun URL",
|
|
116
120
|
"webmap-react-abstract": "Tiivistelmä",
|
|
117
121
|
"webmap-react-dimensions": "Ulottuvuudet",
|
|
118
122
|
"webmap-react-styles": "Tyylit",
|
|
@@ -144,7 +148,9 @@ var fi = {
|
|
|
144
148
|
"webmap-react-polygon": "Monikulmio",
|
|
145
149
|
"webmap-react-box": "Laatikko",
|
|
146
150
|
"webmap-react-linestring": "Viivajono",
|
|
147
|
-
"webmap-react-delete": "Poista"
|
|
151
|
+
"webmap-react-delete": "Poista",
|
|
152
|
+
"clock-show": "Näytä kello",
|
|
153
|
+
"clock-hide": "Piilota kello"
|
|
148
154
|
};
|
|
149
155
|
var no = {
|
|
150
156
|
"webmap-react-event": "hendelse:",
|
|
@@ -158,6 +164,7 @@ var no = {
|
|
|
158
164
|
"webmap-react-title": "Tittel",
|
|
159
165
|
"webmap-react-name": "Navn",
|
|
160
166
|
"webmap-react-service": "Service",
|
|
167
|
+
"webmap-react-service-url": "Service URL",
|
|
161
168
|
"webmap-react-abstract": "Abstrakt",
|
|
162
169
|
"webmap-react-dimensions": "Dimensjoner",
|
|
163
170
|
"webmap-react-styles": "Stiler",
|
|
@@ -189,7 +196,9 @@ var no = {
|
|
|
189
196
|
"webmap-react-polygon": "Polygon",
|
|
190
197
|
"webmap-react-box": "Boks",
|
|
191
198
|
"webmap-react-linestring": "Linje",
|
|
192
|
-
"webmap-react-delete": "Fjerne"
|
|
199
|
+
"webmap-react-delete": "Fjerne",
|
|
200
|
+
"clock-show": "Vis klokke",
|
|
201
|
+
"clock-hide": "Skjul klokke"
|
|
193
202
|
};
|
|
194
203
|
var nl = {
|
|
195
204
|
"webmap-react-event": "event:",
|
|
@@ -203,6 +212,7 @@ var nl = {
|
|
|
203
212
|
"webmap-react-title": "Titel",
|
|
204
213
|
"webmap-react-name": "Naam",
|
|
205
214
|
"webmap-react-service": "Service",
|
|
215
|
+
"webmap-react-service-url": "Service-URL",
|
|
206
216
|
"webmap-react-abstract": "Abstract",
|
|
207
217
|
"webmap-react-dimensions": "Dimensies",
|
|
208
218
|
"webmap-react-styles": "Stijlen",
|
|
@@ -242,7 +252,9 @@ var nl = {
|
|
|
242
252
|
"webmap-react-location": "Locatie",
|
|
243
253
|
"webmap-react-delete": "Verwijder",
|
|
244
254
|
"webmap-react-legend-no-image": "Geen legenda beschikbaar",
|
|
245
|
-
"webmap-react-map-measure-help-tooltip": "Klik om te meten"
|
|
255
|
+
"webmap-react-map-measure-help-tooltip": "Klik om te meten",
|
|
256
|
+
"clock-show": "Klok tonen",
|
|
257
|
+
"clock-hide": "Klok verbergen"
|
|
246
258
|
};
|
|
247
259
|
var webmapReactTranslations = {
|
|
248
260
|
en: en,
|
|
@@ -11225,7 +11237,8 @@ var LayerInfoButton = function LayerInfoButton(_ref) {
|
|
|
11225
11237
|
|
|
11226
11238
|
var textStyle = {
|
|
11227
11239
|
lineHeight: '20px',
|
|
11228
|
-
letterSpacing: '0.25px'
|
|
11240
|
+
letterSpacing: '0.25px',
|
|
11241
|
+
overflowWrap: 'break-word'
|
|
11229
11242
|
};
|
|
11230
11243
|
var textStyleWithMargin = _objectSpread2(_objectSpread2({}, textStyle), {}, {
|
|
11231
11244
|
marginBottom: 1
|
|
@@ -11410,6 +11423,7 @@ var LayerInfoDialog = function LayerInfoDialog(_ref) {
|
|
|
11410
11423
|
var onClose = _ref.onClose,
|
|
11411
11424
|
layer = _ref.layer,
|
|
11412
11425
|
serviceName = _ref.serviceName,
|
|
11426
|
+
serviceUrl = _ref.serviceUrl,
|
|
11413
11427
|
isOpen = _ref.isOpen,
|
|
11414
11428
|
_ref$onMouseDown = _ref.onMouseDown,
|
|
11415
11429
|
onMouseDown = _ref$onMouseDown === void 0 ? function () {} : _ref$onMouseDown,
|
|
@@ -11453,6 +11467,9 @@ var LayerInfoDialog = function LayerInfoDialog(_ref) {
|
|
|
11453
11467
|
}), jsx(LayerInfoText, {
|
|
11454
11468
|
label: t('webmap-react-service'),
|
|
11455
11469
|
value: serviceName
|
|
11470
|
+
}), jsx(LayerInfoText, {
|
|
11471
|
+
label: t('webmap-react-service-url'),
|
|
11472
|
+
value: serviceUrl || '-'
|
|
11456
11473
|
}), jsx(LayerInfoText, {
|
|
11457
11474
|
label: t('webmap-react-abstract'),
|
|
11458
11475
|
value: layer["abstract"] || '-'
|
|
@@ -12546,7 +12563,12 @@ var useQueryGetWMSLayers = function useQueryGetWMSLayers(serviceUrl) {
|
|
|
12546
12563
|
if (!getCapabilitiesJSON) {
|
|
12547
12564
|
setLayers([]);
|
|
12548
12565
|
} else {
|
|
12549
|
-
|
|
12566
|
+
var tree = privateWmsGetLayerTree(getCapabilitiesJSON);
|
|
12567
|
+
if (!tree) {
|
|
12568
|
+
setLayers([]);
|
|
12569
|
+
} else {
|
|
12570
|
+
setLayers(privateWmsFlattenLayerTree(tree));
|
|
12571
|
+
}
|
|
12550
12572
|
}
|
|
12551
12573
|
}, [serviceUrl, getCapabilitiesJSON]);
|
|
12552
12574
|
return layers;
|
|
@@ -12603,17 +12625,26 @@ var useGetWMLayerInstance = function useGetWMLayerInstance(layerFoundation) {
|
|
|
12603
12625
|
setErrorMessage = _React$useState10[1];
|
|
12604
12626
|
var refId = useRef(id || webmapUtils.generateLayerId());
|
|
12605
12627
|
var layerId = refId.current;
|
|
12628
|
+
var _useContext = useContext(TimeContext),
|
|
12629
|
+
refTimeDimensionModes = _useContext.refTimeDimensionModes;
|
|
12606
12630
|
// Check if the layer is already registered
|
|
12607
12631
|
var tmpWMLayer = webmapUtils.getWMLayerById(layerId);
|
|
12608
12632
|
var layerIdChanged = id && id !== (tmpWMLayer === null || tmpWMLayer === void 0 ? void 0 : tmpWMLayer.id);
|
|
12609
12633
|
var layerServiceChanged = (tmpWMLayer === null || tmpWMLayer === void 0 ? void 0 : tmpWMLayer.service) !== serviceUrl;
|
|
12610
12634
|
if (layerServiceChanged || layerIdChanged) {
|
|
12611
12635
|
// Make a new layer if the serviceUrl changes. (But not when the name changes)
|
|
12636
|
+
var refTimeDimensionMode = wmDetermineDimensionMode({
|
|
12637
|
+
name: name,
|
|
12638
|
+
service: serviceUrl,
|
|
12639
|
+
id: layerId,
|
|
12640
|
+
layerType: layerType
|
|
12641
|
+
}, refTimeDimensionModes);
|
|
12612
12642
|
var wmLayer = new WMLayer({
|
|
12613
12643
|
name: name,
|
|
12614
12644
|
service: serviceUrl,
|
|
12615
12645
|
layerType: layerType,
|
|
12616
|
-
id: layerId
|
|
12646
|
+
id: layerId,
|
|
12647
|
+
refTimeDimensionMode: refTimeDimensionMode
|
|
12617
12648
|
});
|
|
12618
12649
|
webmapUtils.registerWMLayer(wmLayer, layerId);
|
|
12619
12650
|
}
|
|
@@ -13417,6 +13448,7 @@ var USEANIMATIONFORLAYER_DEFAULT_MSINHOUR = 3600000;
|
|
|
13417
13448
|
var useAnimationForLayer = function useAnimationForLayer(layerProps, intervalInMs) {
|
|
13418
13449
|
var numStepsTillLatest = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : USEANIMATIONFORLAYER_DEFAULT_NUMSTEPS;
|
|
13419
13450
|
var checkForUpdatesMs = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : USEANIMATIONFORLAYER_DEFAULT_UPDATEINTERVALMS;
|
|
13451
|
+
var refTimeDimensionModes = arguments.length > 4 ? arguments[4] : undefined;
|
|
13420
13452
|
var now = dateUtils.getNowUtc().getTime();
|
|
13421
13453
|
var animationStep = useRef(0);
|
|
13422
13454
|
var _React$useState = React.useState(''),
|
|
@@ -13504,7 +13536,9 @@ var useAnimationForLayer = function useAnimationForLayer(layerProps, intervalInM
|
|
|
13504
13536
|
name: 'time',
|
|
13505
13537
|
currentValue: timeValue
|
|
13506
13538
|
}],
|
|
13507
|
-
timeContext: timeSpan
|
|
13539
|
+
timeContext: _objectSpread2(_objectSpread2({}, timeSpan), {}, {
|
|
13540
|
+
refTimeDimensionModes: refTimeDimensionModes
|
|
13541
|
+
})
|
|
13508
13542
|
};
|
|
13509
13543
|
};
|
|
13510
13544
|
|
|
@@ -13840,12 +13874,14 @@ var TimeAwareEDRLocationLayer = function TimeAwareEDRLocationLayer(_ref) {
|
|
|
13840
13874
|
features: [],
|
|
13841
13875
|
type: 'FeatureCollection'
|
|
13842
13876
|
};
|
|
13877
|
+
// Don't show anything if no parameter is selected
|
|
13878
|
+
var isVisible = visible && parameter.length > 0;
|
|
13843
13879
|
return jsx(OpenLayersFeatureLayer, {
|
|
13844
13880
|
declutter: true,
|
|
13845
13881
|
featureCollection: featureCollection,
|
|
13846
13882
|
opacity: opacity,
|
|
13847
13883
|
style: isFetching ? loadingStyle : style,
|
|
13848
|
-
visible:
|
|
13884
|
+
visible: isVisible,
|
|
13849
13885
|
zIndex: zIndex
|
|
13850
13886
|
});
|
|
13851
13887
|
};
|
|
@@ -13889,6 +13925,28 @@ var fetchStacCollection = /*#__PURE__*/function () {
|
|
|
13889
13925
|
return _ref.apply(this, arguments);
|
|
13890
13926
|
};
|
|
13891
13927
|
}();
|
|
13928
|
+
var fetchStacItem = /*#__PURE__*/function () {
|
|
13929
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(stacItemUrl) {
|
|
13930
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
13931
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
13932
|
+
case 0:
|
|
13933
|
+
_context2.next = 2;
|
|
13934
|
+
return fetch(stacItemUrl);
|
|
13935
|
+
case 2:
|
|
13936
|
+
_context2.next = 4;
|
|
13937
|
+
return _context2.sent.json();
|
|
13938
|
+
case 4:
|
|
13939
|
+
return _context2.abrupt("return", _context2.sent);
|
|
13940
|
+
case 5:
|
|
13941
|
+
case "end":
|
|
13942
|
+
return _context2.stop();
|
|
13943
|
+
}
|
|
13944
|
+
}, _callee2);
|
|
13945
|
+
}));
|
|
13946
|
+
return function fetchStacItem(_x2) {
|
|
13947
|
+
return _ref2.apply(this, arguments);
|
|
13948
|
+
};
|
|
13949
|
+
}();
|
|
13892
13950
|
var fetchStacItems = /*#__PURE__*/function () {
|
|
13893
13951
|
var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(collectionUrl) {
|
|
13894
13952
|
var collection;
|
|
@@ -15337,6 +15395,29 @@ var ICON_LOCATIONMARKER_MODIFY = createIconStyle(locationPath, {
|
|
|
15337
15395
|
anchor: [0.5, 1]
|
|
15338
15396
|
}
|
|
15339
15397
|
});
|
|
15398
|
+
// Pre-rendered canvas for the rotate icon so we can create
|
|
15399
|
+
// dynamically rotated instances that follow the box orientation.
|
|
15400
|
+
var ROTATE_ICON_SIZE = [24, 24];
|
|
15401
|
+
var ROTATE_ICON_CANVAS = typeof document !== 'undefined' ? function () {
|
|
15402
|
+
var canvas = document.createElement('canvas');
|
|
15403
|
+
var width = ROTATE_ICON_SIZE[0],
|
|
15404
|
+
height = ROTATE_ICON_SIZE[1];
|
|
15405
|
+
canvas.width = width;
|
|
15406
|
+
canvas.height = height;
|
|
15407
|
+
var ctx = canvas.getContext('2d');
|
|
15408
|
+
if (!ctx) {
|
|
15409
|
+
return undefined;
|
|
15410
|
+
}
|
|
15411
|
+
var path = new Path2D(rotatePath);
|
|
15412
|
+
// Draw a white outline behind the rotate icon for better contrast
|
|
15413
|
+
ctx.lineWidth = 1.5;
|
|
15414
|
+
ctx.strokeStyle = 'rgba(255, 255, 255, 1)';
|
|
15415
|
+
ctx.stroke(path);
|
|
15416
|
+
// Fill the actual rotate icon
|
|
15417
|
+
ctx.fillStyle = '#051039';
|
|
15418
|
+
ctx.fill(path);
|
|
15419
|
+
return canvas;
|
|
15420
|
+
}() : undefined;
|
|
15340
15421
|
var FEATURE_VERTICES_EDIT_HANDLES = new Style$1({
|
|
15341
15422
|
image: FEATURE_VERTICE_IMAGE,
|
|
15342
15423
|
geometry: function geometry(feature) {
|
|
@@ -15929,49 +16010,294 @@ new Style$1({
|
|
|
15929
16010
|
}),
|
|
15930
16011
|
// Vertices
|
|
15931
16012
|
FEATURE_VERTICES_EDIT_HANDLES];
|
|
15932
|
-
// This function creates a box out of a modified polygon. It detects which corner was moved by comparing
|
|
15933
|
-
//
|
|
15934
|
-
//
|
|
16013
|
+
// This function creates a box out of a modified polygon. It detects which corner was moved by comparing vertices between the two geometries. Then it draws a new box based on the moved vertice and the opposing vertice.
|
|
16014
|
+
// For squares the box scales uniformly around the fixed center.
|
|
16015
|
+
// For rectangles the diagonal opposite corner does not change, the other two corners are recomputed.
|
|
16016
|
+
// The original rotation is preserved.
|
|
15935
16017
|
var createBoxBasedOnModifiedVertex = function createBoxBasedOnModifiedVertex(modifiedGeometry, originalGeometry) {
|
|
15936
|
-
var
|
|
15937
|
-
var
|
|
15938
|
-
|
|
16018
|
+
var _classified$find, _classified$find2, _classified$find3, _classified$find4;
|
|
16019
|
+
var keepSquare = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
16020
|
+
var originalRing = originalGeometry.getCoordinates()[0];
|
|
16021
|
+
var modifiedRing = modifiedGeometry.getCoordinates()[0];
|
|
16022
|
+
if (!originalRing || !modifiedRing || originalRing.length < 4) {
|
|
16023
|
+
return originalGeometry;
|
|
16024
|
+
}
|
|
16025
|
+
// Strip closing coordinate if present so we only work with the four corners.
|
|
16026
|
+
var stripClose = function stripClose(ring) {
|
|
16027
|
+
if (ring.length > 4 && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1]) {
|
|
16028
|
+
return ring.slice(0, ring.length - 1);
|
|
16029
|
+
}
|
|
16030
|
+
return ring;
|
|
16031
|
+
};
|
|
16032
|
+
var originalCorners = stripClose(originalRing);
|
|
16033
|
+
var modifiedCorners = stripClose(modifiedRing);
|
|
16034
|
+
if (originalCorners.length < 4 || modifiedCorners.length < 4) {
|
|
16035
|
+
return originalGeometry;
|
|
16036
|
+
}
|
|
16037
|
+
// Detect which corner was dragged by comparing original vs modified
|
|
16038
|
+
var draggedCornerIndex = originalCorners.findIndex(function (orig, idx) {
|
|
16039
|
+
var mod = modifiedCorners[idx];
|
|
16040
|
+
return orig[0] !== mod[0] || orig[1] !== mod[1];
|
|
15939
16041
|
});
|
|
15940
16042
|
if (draggedCornerIndex === -1) {
|
|
16043
|
+
// No corner actually changed, keep original
|
|
15941
16044
|
return originalGeometry;
|
|
15942
16045
|
}
|
|
15943
|
-
var
|
|
15944
|
-
|
|
15945
|
-
var
|
|
15946
|
-
|
|
15947
|
-
|
|
15948
|
-
|
|
15949
|
-
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
16046
|
+
var dragged = modifiedCorners[draggedCornerIndex];
|
|
16047
|
+
// Compute center of the original box
|
|
16048
|
+
var centerX = originalCorners.reduce(function (sum, _ref) {
|
|
16049
|
+
var _ref2 = _slicedToArray(_ref, 1),
|
|
16050
|
+
x = _ref2[0];
|
|
16051
|
+
return sum + x;
|
|
16052
|
+
}, 0) / originalCorners.length;
|
|
16053
|
+
var centerY = originalCorners.reduce(function (sum, _ref3) {
|
|
16054
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
16055
|
+
y = _ref4[1];
|
|
16056
|
+
return sum + y;
|
|
16057
|
+
}, 0) / originalCorners.length;
|
|
16058
|
+
// Derive local axes from the original box so we can preserve its
|
|
16059
|
+
// rotation. Use the edges from corner 0 to its two neighbours.
|
|
16060
|
+
var p0 = originalCorners[0];
|
|
16061
|
+
var p1 = originalCorners[1];
|
|
16062
|
+
var p3 = originalCorners[3];
|
|
16063
|
+
var edgeUx = p1[0] - p0[0];
|
|
16064
|
+
var edgeUy = p1[1] - p0[1];
|
|
16065
|
+
var edgeVx = p3[0] - p0[0];
|
|
16066
|
+
var edgeVy = p3[1] - p0[1];
|
|
16067
|
+
var edgeUlength = Math.hypot(edgeUx, edgeUy);
|
|
16068
|
+
var edgeVlenght = Math.hypot(edgeVx, edgeVy);
|
|
16069
|
+
if (!edgeUlength || !edgeVlenght) {
|
|
16070
|
+
// if either egde has zero length, bail out
|
|
16071
|
+
return originalGeometry;
|
|
15958
16072
|
}
|
|
15959
|
-
|
|
15960
|
-
|
|
15961
|
-
|
|
15962
|
-
|
|
15963
|
-
|
|
15964
|
-
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
|
-
|
|
15968
|
-
|
|
15969
|
-
|
|
15970
|
-
|
|
15971
|
-
|
|
16073
|
+
var ux = edgeUx / edgeUlength;
|
|
16074
|
+
var uy = edgeUy / edgeUlength;
|
|
16075
|
+
var vx = edgeVx / edgeVlenght;
|
|
16076
|
+
var vy = edgeVy / edgeVlenght;
|
|
16077
|
+
// Remember which corner is which
|
|
16078
|
+
var cornerSigns = [{
|
|
16079
|
+
sx: -1,
|
|
16080
|
+
sy: -1
|
|
16081
|
+
}, {
|
|
16082
|
+
sx: 1,
|
|
16083
|
+
sy: -1
|
|
16084
|
+
}, {
|
|
16085
|
+
sx: 1,
|
|
16086
|
+
sy: 1
|
|
16087
|
+
}, {
|
|
16088
|
+
sx: -1,
|
|
16089
|
+
sy: 1
|
|
16090
|
+
}];
|
|
16091
|
+
var minSize = 1e-6;
|
|
16092
|
+
// Squares keep their center fixed and scale uniformly from the
|
|
16093
|
+
// dragged corner.
|
|
16094
|
+
if (keepSquare) {
|
|
16095
|
+
// Project the dragged corner into the same local coordinate
|
|
16096
|
+
// system to determine the new half-size while keeping the
|
|
16097
|
+
// existing rotation.
|
|
16098
|
+
var drx = dragged[0] - centerX;
|
|
16099
|
+
var dry = dragged[1] - centerY;
|
|
16100
|
+
var dragLocalX = drx * ux + dry * uy;
|
|
16101
|
+
var dragLocalY = drx * vx + dry * vy;
|
|
16102
|
+
var _halfWidth = Math.max(Math.abs(dragLocalX), minSize);
|
|
16103
|
+
var _halfHeight = Math.max(Math.abs(dragLocalY), minSize);
|
|
16104
|
+
var halfSize = Math.max(_halfWidth, _halfHeight);
|
|
16105
|
+
var newCorners = originalCorners.map(function (_, idx) {
|
|
16106
|
+
var _cornerSigns$idx = cornerSigns[idx],
|
|
16107
|
+
sx = _cornerSigns$idx.sx,
|
|
16108
|
+
sy = _cornerSigns$idx.sy;
|
|
16109
|
+
var localX = sx * halfSize;
|
|
16110
|
+
var localY = sy * halfSize;
|
|
16111
|
+
var worldX = centerX + localX * ux + localY * vx;
|
|
16112
|
+
var worldY = centerY + localX * uy + localY * vy;
|
|
16113
|
+
return [worldX, worldY];
|
|
16114
|
+
});
|
|
16115
|
+
newCorners.push(newCorners[0]);
|
|
16116
|
+
return new Polygon([newCorners]);
|
|
16117
|
+
}
|
|
16118
|
+
// Rectangles (non-squares) should resize using the dragged
|
|
16119
|
+
// corner while keeping the diagonal opposite anchored. The two remaining
|
|
16120
|
+
// corners adjust accordingly, and the overall rotation is kept. When the
|
|
16121
|
+
// dragged corner crosses past the center, the rectangle is allowed to
|
|
16122
|
+
// "flip" instead of bouncing back.
|
|
16123
|
+
// Diagonal corner relative to the dragged one in the 4-corner ring
|
|
16124
|
+
var anchorIndex = (draggedCornerIndex + 2) % originalCorners.length;
|
|
16125
|
+
var anchor = originalCorners[anchorIndex];
|
|
16126
|
+
// Vector from anchored corner to dragged corner, in world space
|
|
16127
|
+
var deltaWx = dragged[0] - anchor[0];
|
|
16128
|
+
var deltaWy = dragged[1] - anchor[1];
|
|
16129
|
+
// Express that vector in the local (u, v) frame
|
|
16130
|
+
var deltaLocalX = deltaWx * ux + deltaWy * uy;
|
|
16131
|
+
var deltaLocalY = deltaWx * vx + deltaWy * vy;
|
|
16132
|
+
// Half-sizes in local coordinates. We keep the sign so that when the
|
|
16133
|
+
// dragged corner crosses past the anchor along either axis, the
|
|
16134
|
+
// rectangle flips instead of being clamped.
|
|
16135
|
+
var halfWidth = deltaLocalX / 2;
|
|
16136
|
+
var halfHeight = deltaLocalY / 2;
|
|
16137
|
+
// Center in local coordinates is halfway between anchor (0,0) and
|
|
16138
|
+
// dragged (deltaLocalX, deltaLocalY).
|
|
16139
|
+
var centerLocalX = halfWidth;
|
|
16140
|
+
var centerLocalY = halfHeight;
|
|
16141
|
+
// Convert center back to world coordinates.
|
|
16142
|
+
var centerXNew = anchor[0] + centerLocalX * ux + centerLocalY * vx;
|
|
16143
|
+
var centerYNew = anchor[1] + centerLocalX * uy + centerLocalY * vy;
|
|
16144
|
+
// Rebuild the four corners in local coordinates around the new center.
|
|
16145
|
+
var localCorners = [[-halfWidth, -halfHeight], [halfWidth, -halfHeight], [halfWidth, halfHeight], [-halfWidth, halfHeight]];
|
|
16146
|
+
var newCornersWorld = localCorners.map(function (_ref5) {
|
|
16147
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
16148
|
+
lx = _ref6[0],
|
|
16149
|
+
ly = _ref6[1];
|
|
16150
|
+
var worldX = centerXNew + lx * ux + ly * vx;
|
|
16151
|
+
var worldY = centerYNew + lx * uy + ly * vy;
|
|
16152
|
+
return [worldX, worldY];
|
|
16153
|
+
});
|
|
16154
|
+
// Normalise corner order so index 0..3 always correspond to
|
|
16155
|
+
// bottom-left, bottom-right, top-right, top-left in the box's
|
|
16156
|
+
// local frame. This keeps rotate-handle orientation and
|
|
16157
|
+
// indexing stable even after the rectangle "flips" when a
|
|
16158
|
+
// corner is dragged past the centre.
|
|
16159
|
+
var classified = newCornersWorld.map(function (corner) {
|
|
16160
|
+
var _corner = _slicedToArray(corner, 2),
|
|
16161
|
+
wx = _corner[0],
|
|
16162
|
+
wy = _corner[1];
|
|
16163
|
+
var rx = wx - centerXNew;
|
|
16164
|
+
var ry = wy - centerYNew;
|
|
16165
|
+
var localX = rx * ux + ry * uy;
|
|
16166
|
+
var localY = rx * vx + ry * vy;
|
|
16167
|
+
return {
|
|
16168
|
+
corner: corner,
|
|
16169
|
+
qx: localX >= 0 ? 1 : -1,
|
|
16170
|
+
qy: localY >= 0 ? 1 : -1
|
|
16171
|
+
};
|
|
16172
|
+
});
|
|
16173
|
+
var bl = (_classified$find = classified.find(function (corner) {
|
|
16174
|
+
return corner.qx === -1 && corner.qy === -1;
|
|
16175
|
+
})) === null || _classified$find === void 0 ? void 0 : _classified$find.corner;
|
|
16176
|
+
var br = (_classified$find2 = classified.find(function (corner) {
|
|
16177
|
+
return corner.qx === 1 && corner.qy === -1;
|
|
16178
|
+
})) === null || _classified$find2 === void 0 ? void 0 : _classified$find2.corner;
|
|
16179
|
+
var tr = (_classified$find3 = classified.find(function (corner) {
|
|
16180
|
+
return corner.qx === 1 && corner.qy === 1;
|
|
16181
|
+
})) === null || _classified$find3 === void 0 ? void 0 : _classified$find3.corner;
|
|
16182
|
+
var tl = (_classified$find4 = classified.find(function (corner) {
|
|
16183
|
+
return corner.qx === -1 && corner.qy === 1;
|
|
16184
|
+
})) === null || _classified$find4 === void 0 ? void 0 : _classified$find4.corner;
|
|
16185
|
+
var orderedCorners = bl && br && tr && tl ? [bl, br, tr, tl] : newCornersWorld;
|
|
16186
|
+
// Close the ring
|
|
16187
|
+
orderedCorners.push(orderedCorners[0]);
|
|
16188
|
+
return new Polygon([orderedCorners]);
|
|
16189
|
+
};
|
|
16190
|
+
var getBoxRotateHandlePoints = function getBoxRotateHandlePoints(feature, resolution) {
|
|
16191
|
+
var originalGeometry = feature === null || feature === void 0 ? void 0 : feature.get('originalGeometry');
|
|
16192
|
+
var geom = originalGeometry ? createBoxBasedOnModifiedVertex(feature.getGeometry(), originalGeometry, feature.get('selectionType') === 'square') : feature === null || feature === void 0 ? void 0 : feature.getGeometry();
|
|
16193
|
+
if (!geom || geom.getType() !== 'Polygon') {
|
|
15972
16194
|
return undefined;
|
|
15973
16195
|
}
|
|
15974
|
-
|
|
16196
|
+
var ring = geom.getCoordinates()[0];
|
|
16197
|
+
if (ring.length < 4) {
|
|
16198
|
+
return undefined;
|
|
16199
|
+
}
|
|
16200
|
+
// First four coordinates are the corners of the box (possibly rotated)
|
|
16201
|
+
var corners = ring.slice(0, 4);
|
|
16202
|
+
// Compute box center as the average of the corners
|
|
16203
|
+
var centerX = corners.reduce(function (sum, _ref7) {
|
|
16204
|
+
var _ref8 = _slicedToArray(_ref7, 1),
|
|
16205
|
+
x = _ref8[0];
|
|
16206
|
+
return sum + x;
|
|
16207
|
+
}, 0) / corners.length;
|
|
16208
|
+
var centerY = corners.reduce(function (sum, _ref9) {
|
|
16209
|
+
var _ref0 = _slicedToArray(_ref9, 2),
|
|
16210
|
+
y = _ref0[1];
|
|
16211
|
+
return sum + y;
|
|
16212
|
+
}, 0) / corners.length;
|
|
16213
|
+
// Place the rotate handle at a nearly constant distance from the
|
|
16214
|
+
// corner in screen space, independent of how large the box is.
|
|
16215
|
+
// We move a fixed number of pixels along the outward diagonal
|
|
16216
|
+
// from each corner.
|
|
16217
|
+
var pixelOffset = 16; // pixels away from the corner
|
|
16218
|
+
var baseOffset = resolution ? pixelOffset * resolution : 0;
|
|
16219
|
+
return corners.map(function (_ref1) {
|
|
16220
|
+
var _ref10 = _slicedToArray(_ref1, 2),
|
|
16221
|
+
x = _ref10[0],
|
|
16222
|
+
y = _ref10[1];
|
|
16223
|
+
var dx = x - centerX;
|
|
16224
|
+
var dy = y - centerY;
|
|
16225
|
+
var distance = Math.hypot(dx, dy);
|
|
16226
|
+
if (!distance || !baseOffset) {
|
|
16227
|
+
return [x, y];
|
|
16228
|
+
}
|
|
16229
|
+
var ux = dx / distance;
|
|
16230
|
+
var uy = dy / distance;
|
|
16231
|
+
return [x + ux * baseOffset, y + uy * baseOffset];
|
|
16232
|
+
});
|
|
16233
|
+
};
|
|
16234
|
+
var boxModificationStyle = function boxModificationStyle(feature, resolution) {
|
|
16235
|
+
var styles = [];
|
|
16236
|
+
var originalGeometry = feature === null || feature === void 0 ? void 0 : feature.get('originalGeometry');
|
|
16237
|
+
var geom = originalGeometry ? createBoxBasedOnModifiedVertex(feature.getGeometry(), originalGeometry, feature.get('selectionType') === 'square') : feature.getGeometry();
|
|
16238
|
+
if (geom) {
|
|
16239
|
+
styles.push(new Style$1({
|
|
16240
|
+
fill: FEATURE_FILL,
|
|
16241
|
+
stroke: FEATURE_STROKE_EDIT,
|
|
16242
|
+
geometry: geom
|
|
16243
|
+
}));
|
|
16244
|
+
}
|
|
16245
|
+
if (geom && (geom.getType() === 'Polygon' || geom.getType() === 'LineString')) {
|
|
16246
|
+
var coordinates = geom.getType() === 'Polygon' ? geom.getCoordinates()[0] : geom.getCoordinates();
|
|
16247
|
+
styles.push(new Style$1({
|
|
16248
|
+
image: FEATURE_VERTICE_IMAGE,
|
|
16249
|
+
geometry: new MultiPoint(coordinates)
|
|
16250
|
+
}));
|
|
16251
|
+
}
|
|
16252
|
+
var handlePoints = getBoxRotateHandlePoints(feature, resolution);
|
|
16253
|
+
var activeIndexRaw = feature.get('activeRotateHandleIndex');
|
|
16254
|
+
var activeIndex = typeof activeIndexRaw === 'number' && activeIndexRaw >= 0 && activeIndexRaw < 4 ? activeIndexRaw : undefined;
|
|
16255
|
+
// While the box is being modified (corner drag), hide the rotate
|
|
16256
|
+
// handle so only sizing handles are visible.
|
|
16257
|
+
var suppressRotateHandle = feature.get('suppressRotateHandle');
|
|
16258
|
+
if (ROTATE_ICON_CANVAS && handlePoints && handlePoints.length >= 4 && activeIndex !== undefined && !suppressRotateHandle) {
|
|
16259
|
+
var _handlePoints = _slicedToArray(handlePoints, 4),
|
|
16260
|
+
h0 = _handlePoints[0],
|
|
16261
|
+
h1 = _handlePoints[1],
|
|
16262
|
+
h2 = _handlePoints[2],
|
|
16263
|
+
h3 = _handlePoints[3];
|
|
16264
|
+
// Base angle: along the edge between first two corner handles.
|
|
16265
|
+
var baseAngle = Math.atan2(h1[1] - h0[1], h1[0] - h0[0]);
|
|
16266
|
+
// Assign per-corner offsets.
|
|
16267
|
+
var handleConfigs = [{
|
|
16268
|
+
point: h0,
|
|
16269
|
+
offset: 0
|
|
16270
|
+
},
|
|
16271
|
+
// bottom-left
|
|
16272
|
+
{
|
|
16273
|
+
point: h1,
|
|
16274
|
+
offset: -Math.PI / 2
|
|
16275
|
+
},
|
|
16276
|
+
// bottom-right
|
|
16277
|
+
{
|
|
16278
|
+
point: h2,
|
|
16279
|
+
offset: Math.PI
|
|
16280
|
+
},
|
|
16281
|
+
// top-right
|
|
16282
|
+
{
|
|
16283
|
+
point: h3,
|
|
16284
|
+
offset: Math.PI / 2
|
|
16285
|
+
} // top-left
|
|
16286
|
+
];
|
|
16287
|
+
var _handleConfigs$active = handleConfigs[activeIndex],
|
|
16288
|
+
point = _handleConfigs$active.point,
|
|
16289
|
+
offset = _handleConfigs$active.offset;
|
|
16290
|
+
var icon = new Icon$1({
|
|
16291
|
+
img: ROTATE_ICON_CANVAS,
|
|
16292
|
+
rotation: -baseAngle + offset
|
|
16293
|
+
});
|
|
16294
|
+
styles.push(new Style$1({
|
|
16295
|
+
image: icon,
|
|
16296
|
+
geometry: new MultiPoint([point])
|
|
16297
|
+
}));
|
|
16298
|
+
}
|
|
16299
|
+
return styles;
|
|
16300
|
+
};
|
|
15975
16301
|
var circleFeatureStyle = function circleFeatureStyle(feature, resolution) {
|
|
15976
16302
|
// use OL default styles to keep circle edge tracking
|
|
15977
16303
|
var styles = createDefaultStyle(feature, resolution);
|
|
@@ -16298,6 +16624,48 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16298
16624
|
var lastPointerEvent = null;
|
|
16299
16625
|
var trackPointerMove = function trackPointerMove(event) {
|
|
16300
16626
|
lastPointerEvent = event;
|
|
16627
|
+
// Update which rotate handle is "active" so only that
|
|
16628
|
+
// icon is rendered near the mouse when editing boxes/squares.
|
|
16629
|
+
// While rotating, keep the originally clicked handle active.
|
|
16630
|
+
if (isBoxOrSquare && selectedFeatureHasGeometry && !isRotating) {
|
|
16631
|
+
var featureToRotate = editFeatureCollection.item(0);
|
|
16632
|
+
if (!featureToRotate) {
|
|
16633
|
+
return;
|
|
16634
|
+
}
|
|
16635
|
+
var resolution = map.getView().getResolution();
|
|
16636
|
+
var handlePoints = getBoxRotateHandlePoints(featureToRotate, resolution);
|
|
16637
|
+
var prevIndex = featureToRotate.get('activeRotateHandleIndex');
|
|
16638
|
+
var newIndex;
|
|
16639
|
+
if (!handlePoints || !resolution) {
|
|
16640
|
+
newIndex = undefined;
|
|
16641
|
+
} else {
|
|
16642
|
+
var coord = map.getEventCoordinate(event);
|
|
16643
|
+
var threshold = 18 * resolution; // enlarge hover hit area for rotate handle
|
|
16644
|
+
var closestIndex = -1;
|
|
16645
|
+
var closestDist = Infinity;
|
|
16646
|
+
handlePoints.forEach(function (_ref2, idx) {
|
|
16647
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
16648
|
+
hx = _ref3[0],
|
|
16649
|
+
hy = _ref3[1];
|
|
16650
|
+
var dx = coord[0] - hx;
|
|
16651
|
+
var dy = coord[1] - hy;
|
|
16652
|
+
var dist = Math.sqrt(dx * dx + dy * dy);
|
|
16653
|
+
if (dist < closestDist) {
|
|
16654
|
+
closestDist = dist;
|
|
16655
|
+
closestIndex = idx;
|
|
16656
|
+
}
|
|
16657
|
+
});
|
|
16658
|
+
newIndex = closestDist <= threshold ? closestIndex : undefined;
|
|
16659
|
+
}
|
|
16660
|
+
if (prevIndex !== newIndex) {
|
|
16661
|
+
if (newIndex === undefined) {
|
|
16662
|
+
featureToRotate.unset('activeRotateHandleIndex', true);
|
|
16663
|
+
} else {
|
|
16664
|
+
featureToRotate.set('activeRotateHandleIndex', newIndex, true);
|
|
16665
|
+
}
|
|
16666
|
+
layer.changed();
|
|
16667
|
+
}
|
|
16668
|
+
}
|
|
16301
16669
|
};
|
|
16302
16670
|
map.getViewport().addEventListener('pointermove', trackPointerMove);
|
|
16303
16671
|
var deleteVertexOnDeleteKey = function deleteVertexOnDeleteKey(event) {
|
|
@@ -16310,12 +16678,13 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16310
16678
|
}
|
|
16311
16679
|
};
|
|
16312
16680
|
window.addEventListener('keydown', deleteVertexOnDeleteKey);
|
|
16313
|
-
var
|
|
16681
|
+
var isSquare = actualDrawMode === DRAWMODE.SQUARE;
|
|
16682
|
+
var isBoxOrSquare = actualDrawMode === DRAWMODE.BOX || isSquare;
|
|
16314
16683
|
// Modifying is a combination of Modify and Translate interactions
|
|
16315
16684
|
var modify = new Modify({
|
|
16316
16685
|
features: editFeatureCollection,
|
|
16317
16686
|
insertVertexCondition: !isBoxOrSquare ? always : never,
|
|
16318
|
-
style: modifyHandleStyle
|
|
16687
|
+
style: isSquare ? [] : modifyHandleStyle
|
|
16319
16688
|
});
|
|
16320
16689
|
if (isBoxOrSquare) {
|
|
16321
16690
|
// Box is a special case:
|
|
@@ -16324,16 +16693,39 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16324
16693
|
modify.on('modifystart', function (evt) {
|
|
16325
16694
|
var _feature$getGeometry2;
|
|
16326
16695
|
var feature = evt.features.getArray()[0];
|
|
16696
|
+
// Mark that we are modifying the box so rotate handles
|
|
16697
|
+
// can be hidden while dragging.
|
|
16698
|
+
feature.set('suppressRotateHandle', true, true);
|
|
16327
16699
|
feature.set('originalGeometry', (_feature$getGeometry2 = feature.getGeometry()) === null || _feature$getGeometry2 === void 0 ? void 0 : _feature$getGeometry2.clone(), true);
|
|
16700
|
+
var viewport = map.getViewport();
|
|
16701
|
+
if (viewport && viewport.style) {
|
|
16702
|
+
viewport.style.cursor = 'grabbing';
|
|
16703
|
+
}
|
|
16328
16704
|
});
|
|
16329
16705
|
modify.on('modifyend', function (evt) {
|
|
16330
16706
|
var feature = evt.features.getArray()[0];
|
|
16331
|
-
var boxPolygon = createBoxBasedOnModifiedVertex(feature.getGeometry(), feature.get('originalGeometry'));
|
|
16707
|
+
var boxPolygon = createBoxBasedOnModifiedVertex(feature.getGeometry(), feature.get('originalGeometry'), isSquare);
|
|
16332
16708
|
feature.setGeometry(boxPolygon);
|
|
16709
|
+
// Re-enable rotate handle visibility after modifying.
|
|
16710
|
+
feature.unset('suppressRotateHandle', true);
|
|
16711
|
+
var viewport = map.getViewport();
|
|
16712
|
+
if (viewport && viewport.style) {
|
|
16713
|
+
viewport.style.cursor = '';
|
|
16714
|
+
}
|
|
16333
16715
|
updateFeature(feature);
|
|
16334
16716
|
});
|
|
16335
16717
|
} else {
|
|
16718
|
+
modify.on('modifystart', function () {
|
|
16719
|
+
var viewport = map.getViewport();
|
|
16720
|
+
if (viewport && viewport.style) {
|
|
16721
|
+
viewport.style.cursor = 'grabbing';
|
|
16722
|
+
}
|
|
16723
|
+
});
|
|
16336
16724
|
modify.on('modifyend', function (evt) {
|
|
16725
|
+
var viewport = map.getViewport();
|
|
16726
|
+
if (viewport && viewport.style) {
|
|
16727
|
+
viewport.style.cursor = '';
|
|
16728
|
+
}
|
|
16337
16729
|
updateFeature(evt.features.getArray()[0]);
|
|
16338
16730
|
});
|
|
16339
16731
|
}
|
|
@@ -16343,6 +16735,236 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16343
16735
|
translate.on('translateend', function (evt) {
|
|
16344
16736
|
updateFeature(evt.features.getArray()[0]);
|
|
16345
16737
|
});
|
|
16738
|
+
// Rotation handling for boxes and squares using the visual rotate handles
|
|
16739
|
+
var isRotating = false;
|
|
16740
|
+
var rotationCenter = null;
|
|
16741
|
+
var rotationStartAngle = 0;
|
|
16742
|
+
var originalRing = null;
|
|
16743
|
+
var disabledDragPans = [];
|
|
16744
|
+
// Track when the user has pressed down near a resize corner so we can
|
|
16745
|
+
// immediately show a grabbing cursor on mousedown (before any movement).
|
|
16746
|
+
var isPointerDownNearCorner = false;
|
|
16747
|
+
var handlePointerDownNearCorner = function handlePointerDownNearCorner(event) {
|
|
16748
|
+
if (!isBoxOrSquare || !selectedFeatureHasGeometry) {
|
|
16749
|
+
return;
|
|
16750
|
+
}
|
|
16751
|
+
var feature = editFeatureCollection.item(0);
|
|
16752
|
+
var geom = feature === null || feature === void 0 ? void 0 : feature.getGeometry();
|
|
16753
|
+
if (!geom || geom.getType() !== 'Polygon') {
|
|
16754
|
+
return;
|
|
16755
|
+
}
|
|
16756
|
+
var polygon = geom;
|
|
16757
|
+
var ring = polygon.getCoordinates()[0];
|
|
16758
|
+
if (!ring || ring.length < 4) {
|
|
16759
|
+
return;
|
|
16760
|
+
}
|
|
16761
|
+
var clickCoord = map.getEventCoordinate(event);
|
|
16762
|
+
var resolution = map.getView().getResolution();
|
|
16763
|
+
if (!resolution) {
|
|
16764
|
+
return;
|
|
16765
|
+
}
|
|
16766
|
+
var threshold = 10 * resolution;
|
|
16767
|
+
var closestDist = Infinity;
|
|
16768
|
+
ring.forEach(function (_ref4) {
|
|
16769
|
+
var _ref5 = _slicedToArray(_ref4, 2),
|
|
16770
|
+
vx = _ref5[0],
|
|
16771
|
+
vy = _ref5[1];
|
|
16772
|
+
var dx = clickCoord[0] - vx;
|
|
16773
|
+
var dy = clickCoord[1] - vy;
|
|
16774
|
+
var dist = Math.sqrt(dx * dx + dy * dy);
|
|
16775
|
+
if (dist < closestDist) {
|
|
16776
|
+
closestDist = dist;
|
|
16777
|
+
}
|
|
16778
|
+
});
|
|
16779
|
+
if (closestDist <= threshold) {
|
|
16780
|
+
var viewport = map.getViewport();
|
|
16781
|
+
if (viewport && viewport.style) {
|
|
16782
|
+
viewport.style.cursor = 'grabbing';
|
|
16783
|
+
}
|
|
16784
|
+
isPointerDownNearCorner = true;
|
|
16785
|
+
}
|
|
16786
|
+
};
|
|
16787
|
+
var handlePointerUpAfterCorner = function handlePointerUpAfterCorner() {
|
|
16788
|
+
if (!isPointerDownNearCorner && !isRotating) {
|
|
16789
|
+
return;
|
|
16790
|
+
}
|
|
16791
|
+
var viewport = map.getViewport();
|
|
16792
|
+
if (viewport && viewport.style) {
|
|
16793
|
+
viewport.style.cursor = '';
|
|
16794
|
+
}
|
|
16795
|
+
isPointerDownNearCorner = false;
|
|
16796
|
+
};
|
|
16797
|
+
var startRotateIfOnHandle = function startRotateIfOnHandle(event) {
|
|
16798
|
+
if (!isBoxOrSquare || !selectedFeatureHasGeometry) {
|
|
16799
|
+
return;
|
|
16800
|
+
}
|
|
16801
|
+
var featureToRotate = editFeatureCollection.item(0);
|
|
16802
|
+
var geom = featureToRotate === null || featureToRotate === void 0 ? void 0 : featureToRotate.getGeometry();
|
|
16803
|
+
if (!geom || geom.getType() !== 'Polygon') {
|
|
16804
|
+
return;
|
|
16805
|
+
}
|
|
16806
|
+
var polygon = geom;
|
|
16807
|
+
var ring = polygon.getCoordinates()[0];
|
|
16808
|
+
if (!ring || ring.length < 4) {
|
|
16809
|
+
return;
|
|
16810
|
+
}
|
|
16811
|
+
// Exclude possible closing coordinate
|
|
16812
|
+
var ringWithoutClose = ring.length > 4 && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1] ? ring.slice(0, ring.length - 1) : ring;
|
|
16813
|
+
var clickCoord = map.getEventCoordinate(event);
|
|
16814
|
+
var resolution = map.getView().getResolution();
|
|
16815
|
+
if (!resolution) {
|
|
16816
|
+
return;
|
|
16817
|
+
}
|
|
16818
|
+
// Use the same helper for handle locations as the style code,
|
|
16819
|
+
// so visual position and click area are consistent.
|
|
16820
|
+
var handlePoints = getBoxRotateHandlePoints(featureToRotate, resolution);
|
|
16821
|
+
if (!handlePoints) {
|
|
16822
|
+
return;
|
|
16823
|
+
}
|
|
16824
|
+
var threshold = 12 * resolution; // enlarge click hit area for rotate handle
|
|
16825
|
+
// Determine which handle was clicked (nearest within threshold)
|
|
16826
|
+
var closestIndex = -1;
|
|
16827
|
+
var closestDist = Infinity;
|
|
16828
|
+
handlePoints.forEach(function (_ref6, idx) {
|
|
16829
|
+
var _ref7 = _slicedToArray(_ref6, 2),
|
|
16830
|
+
hx = _ref7[0],
|
|
16831
|
+
hy = _ref7[1];
|
|
16832
|
+
var dx = clickCoord[0] - hx;
|
|
16833
|
+
var dy = clickCoord[1] - hy;
|
|
16834
|
+
var dist = Math.sqrt(dx * dx + dy * dy);
|
|
16835
|
+
if (dist < closestDist) {
|
|
16836
|
+
closestDist = dist;
|
|
16837
|
+
closestIndex = idx;
|
|
16838
|
+
}
|
|
16839
|
+
});
|
|
16840
|
+
if (closestIndex === -1 || closestDist > threshold) {
|
|
16841
|
+
return;
|
|
16842
|
+
}
|
|
16843
|
+
// Lock the active rotate handle index so its icon stays visible
|
|
16844
|
+
var handleFeature = editFeatureCollection.item(0);
|
|
16845
|
+
if (handleFeature) {
|
|
16846
|
+
handleFeature.set('activeRotateHandleIndex', closestIndex, true);
|
|
16847
|
+
layer.changed();
|
|
16848
|
+
}
|
|
16849
|
+
isRotating = true;
|
|
16850
|
+
// Temporarily disable map panning while rotating so the
|
|
16851
|
+
// underlying map does not move when dragging the rotate handle.
|
|
16852
|
+
disabledDragPans = [];
|
|
16853
|
+
map.getInteractions().forEach(function (interaction) {
|
|
16854
|
+
if (interaction instanceof DragPan && interaction.getActive()) {
|
|
16855
|
+
disabledDragPans.push(interaction);
|
|
16856
|
+
interaction.setActive(false);
|
|
16857
|
+
}
|
|
16858
|
+
});
|
|
16859
|
+
// Recompute box center from the current polygon
|
|
16860
|
+
var minX = ringWithoutClose[0][0];
|
|
16861
|
+
var maxX = ringWithoutClose[0][0];
|
|
16862
|
+
var minY = ringWithoutClose[0][1];
|
|
16863
|
+
var maxY = ringWithoutClose[0][1];
|
|
16864
|
+
ringWithoutClose.forEach(function (_ref8) {
|
|
16865
|
+
var _ref9 = _slicedToArray(_ref8, 2),
|
|
16866
|
+
x = _ref9[0],
|
|
16867
|
+
y = _ref9[1];
|
|
16868
|
+
if (x < minX) {
|
|
16869
|
+
minX = x;
|
|
16870
|
+
}
|
|
16871
|
+
if (x > maxX) {
|
|
16872
|
+
maxX = x;
|
|
16873
|
+
}
|
|
16874
|
+
if (y < minY) {
|
|
16875
|
+
minY = y;
|
|
16876
|
+
}
|
|
16877
|
+
if (y > maxY) {
|
|
16878
|
+
maxY = y;
|
|
16879
|
+
}
|
|
16880
|
+
});
|
|
16881
|
+
var centerX = (minX + maxX) / 2;
|
|
16882
|
+
var centerY = (minY + maxY) / 2;
|
|
16883
|
+
rotationCenter = [centerX, centerY];
|
|
16884
|
+
rotationStartAngle = Math.atan2(clickCoord[1] - centerY, clickCoord[0] - centerX);
|
|
16885
|
+
originalRing = ring.map(function (_ref0) {
|
|
16886
|
+
var _ref1 = _slicedToArray(_ref0, 2),
|
|
16887
|
+
x = _ref1[0],
|
|
16888
|
+
y = _ref1[1];
|
|
16889
|
+
return [x, y];
|
|
16890
|
+
});
|
|
16891
|
+
// While rotating, show a grabbing cursor on the map viewport
|
|
16892
|
+
var viewport = map.getViewport();
|
|
16893
|
+
if (viewport && viewport.style) {
|
|
16894
|
+
viewport.style.cursor = 'grabbing';
|
|
16895
|
+
}
|
|
16896
|
+
// While rotating, disable modify/translate to avoid conflicts
|
|
16897
|
+
modify.setActive(false);
|
|
16898
|
+
translate.setActive(false);
|
|
16899
|
+
event.preventDefault();
|
|
16900
|
+
};
|
|
16901
|
+
var rotateOnPointerMove = function rotateOnPointerMove(event) {
|
|
16902
|
+
if (!isRotating || !rotationCenter || !originalRing) {
|
|
16903
|
+
return;
|
|
16904
|
+
}
|
|
16905
|
+
var featureToRotate = editFeatureCollection.item(0);
|
|
16906
|
+
var geom = featureToRotate === null || featureToRotate === void 0 ? void 0 : featureToRotate.getGeometry();
|
|
16907
|
+
if (!geom || geom.getType() !== 'Polygon') {
|
|
16908
|
+
return;
|
|
16909
|
+
}
|
|
16910
|
+
var polygon = geom;
|
|
16911
|
+
var _rotationCenter = rotationCenter,
|
|
16912
|
+
_rotationCenter2 = _slicedToArray(_rotationCenter, 2),
|
|
16913
|
+
centerX = _rotationCenter2[0],
|
|
16914
|
+
centerY = _rotationCenter2[1];
|
|
16915
|
+
var coord = map.getEventCoordinate(event);
|
|
16916
|
+
var angle = Math.atan2(coord[1] - centerY, coord[0] - centerX);
|
|
16917
|
+
var delta = angle - rotationStartAngle;
|
|
16918
|
+
var cos = Math.cos(delta);
|
|
16919
|
+
var sin = Math.sin(delta);
|
|
16920
|
+
var rotatedRing = originalRing.map(function (_ref10) {
|
|
16921
|
+
var _ref11 = _slicedToArray(_ref10, 2),
|
|
16922
|
+
x = _ref11[0],
|
|
16923
|
+
y = _ref11[1];
|
|
16924
|
+
var dx = x - centerX;
|
|
16925
|
+
var dy = y - centerY;
|
|
16926
|
+
var newX = centerX + dx * cos - dy * sin;
|
|
16927
|
+
var newY = centerY + dx * sin + dy * cos;
|
|
16928
|
+
return [newX, newY];
|
|
16929
|
+
});
|
|
16930
|
+
if (rotatedRing.length > 0) {
|
|
16931
|
+
// Ensure the ring is closed
|
|
16932
|
+
var _rotatedRing$ = _slicedToArray(rotatedRing[0], 2),
|
|
16933
|
+
firstX = _rotatedRing$[0],
|
|
16934
|
+
firstY = _rotatedRing$[1];
|
|
16935
|
+
rotatedRing[rotatedRing.length - 1] = [firstX, firstY];
|
|
16936
|
+
}
|
|
16937
|
+
polygon.setCoordinates([rotatedRing]);
|
|
16938
|
+
};
|
|
16939
|
+
var endRotate = function endRotate() {
|
|
16940
|
+
if (!isRotating) {
|
|
16941
|
+
return;
|
|
16942
|
+
}
|
|
16943
|
+
isRotating = false;
|
|
16944
|
+
rotationCenter = null;
|
|
16945
|
+
rotationStartAngle = 0;
|
|
16946
|
+
originalRing = null;
|
|
16947
|
+
// Re-enable any drag-pan interactions we disabled when rotation
|
|
16948
|
+
// started so normal map panning works again.
|
|
16949
|
+
disabledDragPans.forEach(function (interaction) {
|
|
16950
|
+
return interaction.setActive(true);
|
|
16951
|
+
});
|
|
16952
|
+
disabledDragPans = [];
|
|
16953
|
+
// Restore the default cursor when rotation stops
|
|
16954
|
+
var viewport = map.getViewport();
|
|
16955
|
+
if (viewport && viewport.style) {
|
|
16956
|
+
viewport.style.cursor = '';
|
|
16957
|
+
}
|
|
16958
|
+
modify.setActive(true);
|
|
16959
|
+
translate.setActive(true);
|
|
16960
|
+
var featureToRotate = editFeatureCollection.item(0);
|
|
16961
|
+
if (featureToRotate) {
|
|
16962
|
+
updateFeature(featureToRotate);
|
|
16963
|
+
// Clear active handle so hover logic can take over again
|
|
16964
|
+
featureToRotate.unset('activeRotateHandleIndex', true);
|
|
16965
|
+
layer.changed();
|
|
16966
|
+
}
|
|
16967
|
+
};
|
|
16346
16968
|
var abortOnEsc = function abortOnEsc(evt) {
|
|
16347
16969
|
if (evt.key === 'Escape') {
|
|
16348
16970
|
evt.preventDefault();
|
|
@@ -16354,7 +16976,7 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16354
16976
|
}
|
|
16355
16977
|
}
|
|
16356
16978
|
};
|
|
16357
|
-
var onlyAllowMoving = actualDrawMode === DRAWMODE.CIRCLE || actualDrawMode === DRAWMODE.OVAL || actualDrawMode === DRAWMODE.FREEHANDLINE
|
|
16979
|
+
var onlyAllowMoving = actualDrawMode === DRAWMODE.CIRCLE || actualDrawMode === DRAWMODE.OVAL || actualDrawMode === DRAWMODE.FREEHANDLINE;
|
|
16358
16980
|
if (selectedFeatureHasGeometry) {
|
|
16359
16981
|
if (onlyAllowMoving) {
|
|
16360
16982
|
interactions.push(translate); // Only allow moving
|
|
@@ -16367,6 +16989,16 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16367
16989
|
interactions.push(new Snap({
|
|
16368
16990
|
source: viewOnlySource
|
|
16369
16991
|
}));
|
|
16992
|
+
if (isBoxOrSquare && selectedFeatureHasGeometry) {
|
|
16993
|
+
var viewport = map.getViewport();
|
|
16994
|
+
viewport.addEventListener('pointerdown', startRotateIfOnHandle);
|
|
16995
|
+
viewport.addEventListener('pointermove', rotateOnPointerMove);
|
|
16996
|
+
viewport.addEventListener('pointerup', endRotate);
|
|
16997
|
+
// Ensure the grabbing cursor appears immediately when pressing on a
|
|
16998
|
+
// resize corner, not only after the pointer starts moving.
|
|
16999
|
+
viewport.addEventListener('pointerdown', handlePointerDownNearCorner);
|
|
17000
|
+
viewport.addEventListener('pointerup', handlePointerUpAfterCorner);
|
|
17001
|
+
}
|
|
16370
17002
|
window.addEventListener('keydown', abortOnEsc);
|
|
16371
17003
|
interactions.forEach(function (i) {
|
|
16372
17004
|
return map.addInteraction(i);
|
|
@@ -16381,6 +17013,14 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16381
17013
|
map.removeLayer(layer);
|
|
16382
17014
|
map.removeLayer(viewOnlyLayer);
|
|
16383
17015
|
map.getViewport().removeEventListener('pointermove', trackPointerMove);
|
|
17016
|
+
if (isBoxOrSquare && selectedFeatureHasGeometry) {
|
|
17017
|
+
var _viewport = map.getViewport();
|
|
17018
|
+
_viewport.removeEventListener('pointerdown', startRotateIfOnHandle);
|
|
17019
|
+
_viewport.removeEventListener('pointermove', rotateOnPointerMove);
|
|
17020
|
+
_viewport.removeEventListener('pointerup', endRotate);
|
|
17021
|
+
_viewport.removeEventListener('pointerdown', handlePointerDownNearCorner);
|
|
17022
|
+
_viewport.removeEventListener('pointerup', handlePointerUpAfterCorner);
|
|
17023
|
+
}
|
|
16384
17024
|
window.removeEventListener('keydown', deleteVertexOnDeleteKey);
|
|
16385
17025
|
};
|
|
16386
17026
|
}, [map, isInEditMode, geojson, projection, viewOnlyStyle, selectedFeatureIndex, exitDrawModeCallback, updateGeojson, drawMode]);
|
|
@@ -16388,7 +17028,7 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
|
|
|
16388
17028
|
};
|
|
16389
17029
|
|
|
16390
17030
|
var defaultIntersectionStyleProperties = _objectSpread2(_objectSpread2({}, defaultGeoJSONStyleProperties), {}, {
|
|
16391
|
-
'fill-opacity': 0.
|
|
17031
|
+
'fill-opacity': 0.1
|
|
16392
17032
|
});
|
|
16393
17033
|
var emptyLineString = _objectSpread2(_objectSpread2({}, lineString), {}, {
|
|
16394
17034
|
properties: defaultGeoJSONStyleProperties
|
|
@@ -18279,6 +18919,265 @@ var MapMeasure = function MapMeasure(_ref) {
|
|
|
18279
18919
|
return null;
|
|
18280
18920
|
};
|
|
18281
18921
|
|
|
18922
|
+
/* *
|
|
18923
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
18924
|
+
* you may not use this file except in compliance with the License.
|
|
18925
|
+
* You may obtain a copy of the License at
|
|
18926
|
+
*
|
|
18927
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
18928
|
+
*
|
|
18929
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
18930
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18931
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18932
|
+
* See the License for the specific language governing permissions and
|
|
18933
|
+
* limitations under the License.
|
|
18934
|
+
*
|
|
18935
|
+
* Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
|
|
18936
|
+
* Copyright 2024 - Finnish Meteorological Institute (FMI)
|
|
18937
|
+
* Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
|
|
18938
|
+
* */
|
|
18939
|
+
// To be used with translations of days in formatted date
|
|
18940
|
+
// enum DaysOfWeeki18n {
|
|
18941
|
+
// SUNDAY = 'timeslider-sunday',
|
|
18942
|
+
// MONDAY = 'timeslider-monday',
|
|
18943
|
+
// TUESDAY = 'timeslider-tuesday',
|
|
18944
|
+
// WEDNESDAY = 'timeslider-wednesday',
|
|
18945
|
+
// THURSDAY = 'timeslider-thursday',
|
|
18946
|
+
// FRIDAY = 'timeslider-friday',
|
|
18947
|
+
// SATURDAY = 'timeslider-saturday',
|
|
18948
|
+
// }
|
|
18949
|
+
// To be used with translations of months in formatted date
|
|
18950
|
+
// enum MonthsOfTheYeari18n {
|
|
18951
|
+
// JANUARY = 'timeslider-january',
|
|
18952
|
+
// FEBRUARY = 'timeslider-february',
|
|
18953
|
+
// MARCH = 'timeslider-march',
|
|
18954
|
+
// APRIL = 'timeslider-april',
|
|
18955
|
+
// MAY = 'timeslider-may',
|
|
18956
|
+
// JUNE = 'timeslider-june',
|
|
18957
|
+
// JULY = 'timeslider-july',
|
|
18958
|
+
// AUGUST = 'timeslider-august',
|
|
18959
|
+
// SEPTEMBER = 'timeslider-september',
|
|
18960
|
+
// OCTOBER = 'timeslider-october',
|
|
18961
|
+
// NOVEMBER = 'timeslider-november',
|
|
18962
|
+
// DECEMBER = 'timeslider-december',
|
|
18963
|
+
// }
|
|
18964
|
+
var DaysOfWeek;
|
|
18965
|
+
(function (DaysOfWeek) {
|
|
18966
|
+
DaysOfWeek["SUNDAY"] = "Sun";
|
|
18967
|
+
DaysOfWeek["MONDAY"] = "Mon";
|
|
18968
|
+
DaysOfWeek["TUESDAY"] = "Tue";
|
|
18969
|
+
DaysOfWeek["WEDNESDAY"] = "Wed";
|
|
18970
|
+
DaysOfWeek["THURSDAY"] = "Thu";
|
|
18971
|
+
DaysOfWeek["FRIDAY"] = "Fri";
|
|
18972
|
+
DaysOfWeek["SATURDAY"] = "Sat";
|
|
18973
|
+
})(DaysOfWeek || (DaysOfWeek = {}));
|
|
18974
|
+
var MonthsOfTheYear;
|
|
18975
|
+
(function (MonthsOfTheYear) {
|
|
18976
|
+
MonthsOfTheYear["JANUARY"] = "Jan";
|
|
18977
|
+
MonthsOfTheYear["FEBRUARY"] = "Feb";
|
|
18978
|
+
MonthsOfTheYear["MARCH"] = "Mar";
|
|
18979
|
+
MonthsOfTheYear["APRIL"] = "Apr";
|
|
18980
|
+
MonthsOfTheYear["MAY"] = "May";
|
|
18981
|
+
MonthsOfTheYear["JUNE"] = "Jun";
|
|
18982
|
+
MonthsOfTheYear["JULY"] = "Jul";
|
|
18983
|
+
MonthsOfTheYear["AUGUST"] = "Aug";
|
|
18984
|
+
MonthsOfTheYear["SEPTEMBER"] = "Sep";
|
|
18985
|
+
MonthsOfTheYear["OCTOBER"] = "Oct";
|
|
18986
|
+
MonthsOfTheYear["NOVEMBER"] = "Nov";
|
|
18987
|
+
MonthsOfTheYear["DECEMBER"] = "Dec";
|
|
18988
|
+
})(MonthsOfTheYear || (MonthsOfTheYear = {}));
|
|
18989
|
+
var dateToManualFormatString = function dateToManualFormatString(inDate) {
|
|
18990
|
+
if (!inDate) {
|
|
18991
|
+
return 'Date not available';
|
|
18992
|
+
}
|
|
18993
|
+
var EEE = inDate && Object.values(DaysOfWeek)[inDate.getUTCDay()];
|
|
18994
|
+
var dd = "0".concat(inDate === null || inDate === void 0 ? void 0 : inDate.getUTCDate()).slice(-2);
|
|
18995
|
+
var MMM = inDate && Object.values(MonthsOfTheYear)[inDate.getUTCMonth()];
|
|
18996
|
+
var HH = "0".concat(inDate === null || inDate === void 0 ? void 0 : inDate.getUTCHours()).slice(-2);
|
|
18997
|
+
var mm = "0".concat(inDate === null || inDate === void 0 ? void 0 : inDate.getUTCMinutes()).slice(-2);
|
|
18998
|
+
return "".concat(EEE, " ").concat(dd, " ").concat(MMM, " ").concat(HH, ":").concat(mm, " UTC");
|
|
18999
|
+
};
|
|
19000
|
+
|
|
19001
|
+
/**
|
|
19002
|
+
* Format a date to a string
|
|
19003
|
+
*
|
|
19004
|
+
* Expects the following props:
|
|
19005
|
+
* @param {Date} inDate - date to be formatted
|
|
19006
|
+
*
|
|
19007
|
+
*/
|
|
19008
|
+
var ClockContainer = function ClockContainer(_ref) {
|
|
19009
|
+
var fontSize = _ref.fontSize,
|
|
19010
|
+
onButtonClick = _ref.onButtonClick,
|
|
19011
|
+
time = _ref.time;
|
|
19012
|
+
var _useWebmapReactTransl = useWebmapReactTranslation(),
|
|
19013
|
+
t = _useWebmapReactTransl.t;
|
|
19014
|
+
var title = t('clock-hide');
|
|
19015
|
+
var currentDateString = dateToManualFormatString(dateUtils.fromUnix(time));
|
|
19016
|
+
return jsxs(Grid, {
|
|
19017
|
+
container: true,
|
|
19018
|
+
sx: {
|
|
19019
|
+
justifyContent: 'space-evenly',
|
|
19020
|
+
alignItems: 'center',
|
|
19021
|
+
cursor: 'move',
|
|
19022
|
+
height: '100%',
|
|
19023
|
+
width: '100%',
|
|
19024
|
+
backgroundColor: 'geowebColors.timeSlider.playerTimeMarkers.fill',
|
|
19025
|
+
borderRadius: '5px'
|
|
19026
|
+
},
|
|
19027
|
+
wrap: "nowrap",
|
|
19028
|
+
children: [jsx(Grid, {
|
|
19029
|
+
sx: {
|
|
19030
|
+
width: '4px'
|
|
19031
|
+
}
|
|
19032
|
+
}), jsx(CustomTooltip, {
|
|
19033
|
+
title: title,
|
|
19034
|
+
children: jsx(Grid, {
|
|
19035
|
+
sx: {
|
|
19036
|
+
zIndex: 2
|
|
19037
|
+
},
|
|
19038
|
+
children: jsx(ThemeProvider, {
|
|
19039
|
+
theme: darkTheme,
|
|
19040
|
+
children: jsx(CustomIconButton, {
|
|
19041
|
+
"aria-label": title,
|
|
19042
|
+
onClick: onButtonClick,
|
|
19043
|
+
variant: "boxed",
|
|
19044
|
+
children: jsx(ChevronRight, {})
|
|
19045
|
+
})
|
|
19046
|
+
})
|
|
19047
|
+
})
|
|
19048
|
+
}), jsx(Grid, {
|
|
19049
|
+
children: jsx(Typography, {
|
|
19050
|
+
sx: {
|
|
19051
|
+
whiteSpace: 'nowrap',
|
|
19052
|
+
fontSize: fontSize,
|
|
19053
|
+
color: '#fff'
|
|
19054
|
+
},
|
|
19055
|
+
variant: "subtitle2",
|
|
19056
|
+
children: currentDateString
|
|
19057
|
+
})
|
|
19058
|
+
})]
|
|
19059
|
+
});
|
|
19060
|
+
};
|
|
19061
|
+
|
|
19062
|
+
var MIN_WIDTH = 170;
|
|
19063
|
+
var MIN_HEIGHT = 32;
|
|
19064
|
+
var MIN_FONT_SIZE = 14; // bigger font size will cause render delay in LCP
|
|
19065
|
+
var FONT_SIZE_WIDTH_RATIO = MIN_FONT_SIZE / MIN_WIDTH;
|
|
19066
|
+
var BUTTON_WIDTH = 40;
|
|
19067
|
+
var resizeHandlePlacement = {
|
|
19068
|
+
top: false,
|
|
19069
|
+
right: false,
|
|
19070
|
+
bottom: false,
|
|
19071
|
+
left: false,
|
|
19072
|
+
topRight: false,
|
|
19073
|
+
bottomRight: false,
|
|
19074
|
+
bottomLeft: true,
|
|
19075
|
+
topLeft: false
|
|
19076
|
+
};
|
|
19077
|
+
var Clock = function Clock(_ref2) {
|
|
19078
|
+
var time = _ref2.time,
|
|
19079
|
+
_ref2$isVisible = _ref2.isVisible,
|
|
19080
|
+
isClockVisible = _ref2$isVisible === void 0 ? true : _ref2$isVisible,
|
|
19081
|
+
onToggleClock = _ref2.onToggleClock;
|
|
19082
|
+
var _useWebmapReactTransl = useWebmapReactTranslation(),
|
|
19083
|
+
t = _useWebmapReactTransl.t;
|
|
19084
|
+
var clockElement = useRef(null);
|
|
19085
|
+
var _useState = useState({
|
|
19086
|
+
x: 0,
|
|
19087
|
+
y: 0
|
|
19088
|
+
}),
|
|
19089
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
19090
|
+
position = _useState2[0],
|
|
19091
|
+
setPosition = _useState2[1];
|
|
19092
|
+
useMakeSureContainerStaysInsideWindow(clockElement, position, setPosition);
|
|
19093
|
+
var _useState3 = useState({
|
|
19094
|
+
width: MIN_WIDTH,
|
|
19095
|
+
height: MIN_HEIGHT
|
|
19096
|
+
}),
|
|
19097
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
19098
|
+
size = _useState4[0],
|
|
19099
|
+
setSize = _useState4[1];
|
|
19100
|
+
var _useState5 = useState(MIN_FONT_SIZE),
|
|
19101
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
19102
|
+
fontSize = _useState6[0],
|
|
19103
|
+
setFontSize = _useState6[1];
|
|
19104
|
+
var toggleClock = function toggleClock(isClockVisible) {
|
|
19105
|
+
onToggleClock === null || onToggleClock === void 0 || onToggleClock(isClockVisible);
|
|
19106
|
+
};
|
|
19107
|
+
return jsx(Fragment, {
|
|
19108
|
+
children: !isClockVisible ? jsx(CustomIconButton, {
|
|
19109
|
+
"aria-label": t('clock-show'),
|
|
19110
|
+
onClick: function onClick() {
|
|
19111
|
+
toggleClock(true);
|
|
19112
|
+
},
|
|
19113
|
+
sx: {
|
|
19114
|
+
position: 'absolute',
|
|
19115
|
+
top: 16,
|
|
19116
|
+
right: 8,
|
|
19117
|
+
zIndex: 1
|
|
19118
|
+
},
|
|
19119
|
+
tooltipTitle: t('clock-show'),
|
|
19120
|
+
variant: "boxed",
|
|
19121
|
+
children: jsx(Clock$1, {})
|
|
19122
|
+
}) : jsx(Draggable, {
|
|
19123
|
+
bounds: "parent",
|
|
19124
|
+
cancel: ".MuiButtonBase-root",
|
|
19125
|
+
nodeRef: clockElement,
|
|
19126
|
+
onStop: function onStop(_event, position) {
|
|
19127
|
+
setPosition(position);
|
|
19128
|
+
},
|
|
19129
|
+
position: position,
|
|
19130
|
+
children: jsx("div", {
|
|
19131
|
+
ref: function ref(_ref3) {
|
|
19132
|
+
clockElement.current = _ref3;
|
|
19133
|
+
},
|
|
19134
|
+
style: {
|
|
19135
|
+
position: 'absolute',
|
|
19136
|
+
zIndex: 1001,
|
|
19137
|
+
top: '10px',
|
|
19138
|
+
right: '10px'
|
|
19139
|
+
},
|
|
19140
|
+
children: jsx(Resizable, {
|
|
19141
|
+
enable: resizeHandlePlacement,
|
|
19142
|
+
handleComponent: {
|
|
19143
|
+
bottomLeft: jsx(Resize, {
|
|
19144
|
+
isRightAligned: true,
|
|
19145
|
+
style: {
|
|
19146
|
+
fill: '#FFFFFF'
|
|
19147
|
+
}
|
|
19148
|
+
})
|
|
19149
|
+
},
|
|
19150
|
+
lockAspectRatio: true,
|
|
19151
|
+
minHeight: MIN_HEIGHT,
|
|
19152
|
+
minWidth: MIN_WIDTH + BUTTON_WIDTH,
|
|
19153
|
+
onResize: function onResize(_event, _direction, _ref, delta) {
|
|
19154
|
+
var width = size.width + delta.width;
|
|
19155
|
+
var adjustedWidth = width - BUTTON_WIDTH;
|
|
19156
|
+
var fontSize = FONT_SIZE_WIDTH_RATIO * adjustedWidth;
|
|
19157
|
+
setFontSize(fontSize);
|
|
19158
|
+
},
|
|
19159
|
+
onResizeStop: function onResizeStop(_event, _direction, _ref, delta) {
|
|
19160
|
+
var width = size.width + delta.width;
|
|
19161
|
+
var height = size.height + delta.height;
|
|
19162
|
+
setSize({
|
|
19163
|
+
width: width,
|
|
19164
|
+
height: height
|
|
19165
|
+
});
|
|
19166
|
+
},
|
|
19167
|
+
size: size,
|
|
19168
|
+
children: jsx(ClockContainer, {
|
|
19169
|
+
fontSize: fontSize,
|
|
19170
|
+
onButtonClick: function onButtonClick() {
|
|
19171
|
+
toggleClock(false);
|
|
19172
|
+
},
|
|
19173
|
+
time: time
|
|
19174
|
+
})
|
|
19175
|
+
})
|
|
19176
|
+
})
|
|
19177
|
+
})
|
|
19178
|
+
});
|
|
19179
|
+
};
|
|
19180
|
+
|
|
18282
19181
|
/* *
|
|
18283
19182
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
18284
19183
|
* you may not use this file except in compliance with the License.
|
|
@@ -18355,4 +19254,4 @@ var getLayerUpdateInfo = function getLayerUpdateInfo(wmLayer, mapId) {
|
|
|
18355
19254
|
return updateObject;
|
|
18356
19255
|
};
|
|
18357
19256
|
|
|
18358
|
-
export { BaseLayerType, CLASSNAME_MAP_MEASURE_TOOLTIP, ClickOnMapTool, DEFAULT_GEOJSON_STYLE_FILL_OPACITY, DRAWMODE, DefaultBaseLayers, DimensionSelectButton, DimensionSelectDialog, DimensionSelectSlider, EditModeButton as EditModeButtonField, FEATURE_DRAW_FILL_COLOR, FEATURE_DRAW_FILL_COLOR_TRANSPARENT, FEATURE_DRAW_SECONDARY_FILL_COLOR, FEATURE_DRAW_SECONDARY_STROKE_COLOR, FEATURE_DRAW_STROKE_COLOR, FEATURE_FILL, FEATURE_FILL_SELECTED, FEATURE_STROKE, FEATURE_STROKE_EDIT, FEATURE_STROKE_SELECTED, FEATURE_VERTICES_EDIT_HANDLES, FEATURE_VERTICE_HANDLE_IMAGE, FEATURE_VERTICE_IMAGE, FeatureLayer, FeatureLayers, GeoJSONTextField, IntersectionSelect, LayerInfoButton, LayerInfoDialog, LayerInfoLegend, LayerInfoList, LayerInfoText, Legend, LegendButton, LegendDialog, LegendLayout, MapContext, MapControlButton, MapControls, MapDimensionSelect, MapFeatureClass, MapMeasure, MapTime, MapWarningProperties, NEW_FEATURE_CREATED, NEW_LINESTRING_CREATED, NEW_POINT_CREATED, OpenLayersFeatureLayer, OpenLayersGetFeatureInfo, OpenLayersLayer, OpenLayersMapDraw, OpenLayersMapView, OpenLayersZoomControl, SelectField, StoryLayoutGrid, TimeAwareEDRLocationLayer, TimeAwareGeoTIFFLayer, TimeAwareWMTSLayer, TimeContext, TimeawareImageSource, TimeawareImageSourceWMSLayer, WEBMAP_REACT_NAMESPACE, WMSLayer, WMTSLayer, XYZLayer, ZoomControls, addFeatureProperties, addGeoJSONProperties, addSelectionTypeToGeoJSON, basicExampleDrawOptions, basicExampleMultipleShapeDrawOptions, basicExampleMultipleShapeWithValuesDrawOptions, catmullRomSpline, clearImageCacheForAllMaps, colorMaps, createBoxBasedOnModifiedVertex, createIconStyle, createInterSections, createOval, currentlySupportedDrawModes, defaultBox, defaultCircle, defaultDelete, defaultEdrStyles, defaultFreehandLine, defaultGeoJSONStyleProperties, defaultIntersectionStyleProperties, defaultLayers, defaultLineString, defaultLocation, defaultModes, defaultOval, defaultPoint, defaultPolygon, defaultSmoothLine, defaultSquare, defaultTimeFormat, dimensionConfig, drawPolyStoryStyles, drawStyles, emptyGeoJSON, endToolExampleConfig, exampleIntersectionOptions, exampleIntersectionWithShapeOptions, exampleIntersections, exampleIntersectionsMultiDrawTool, fakeEdrLayerApiHandlers, featureMultiPoint, featurePoint, featurePolygon, fillOptions, firSelectionType, formatTime, generateImageFromLegend, genericOpenLayersFeatureStyle, geowebColorToOpenLayersColor, getDimensionIcon, getDimensionLabel, getDimensionValue, getDimensionsList, getDoubleControlToolIcon, getDrawModeIdFromSelectionType, getFeatureCollection, getFeatureExtent, getFeaturePointStyle, getFirTitle, getGeoJSONPropertyValue, getGeoJson, getIcon, getIntersectionToolIcon, getIsInsideAcceptanceTime, getLastEmptyFeatureIndex, getLayerBbox, getLayerStyles, getLayerUpdateInfo, getLegendClass, getProj4, getTimeDimension, getToolIcon, initializeOpenLayersProjections, inlineFeatureStyle, intersectPointGeoJSONS, intersectPolygonGeoJSONS, intersectionFeatureBE, intersectionFeatureNL, isGeoJSONFeatureCreatedByTool, isGeoJSONGeometryEmpty, isPointFeatureCollection, labelOptions, lineString, lineStringCollection, makeFeatureStyleDisc, makeFeatureStyleLoading, makeFeatureStyleMultiParam, makeFeatureStyleMultiParamLoading, makeFeatureStyleWind, makeLegendFromColorMap, makeLegendFromStyleName, makeTimeList, makeView, marksByDimension, measureResultStyle, measureToolStyle, modifyStyles, moveFeature, multiLineStringLabelStyle, multiPolygonLabelStyle, opacityOptions, openLayersGetMapImageStore, precipitationMMLegendColorsWoW, projectorCache, publicLayers, publicServices, rewindGeometry, roundCoordinates, selectPreferredWMSProjection, setMapCenter, setViewFromExtent, setViewFromFeature, simpleBoxGeoJSON, simpleBoxGeoJSONWrongOrder, simpleFlightRouteLineStringGeoJSON, simpleFlightRoutePointsGeoJSON, simpleGeometryCollectionGeoJSON, simpleLineStringGeoJSON, simpleMultiPolygon, simplePointsGeojson, simplePolygonGeoJSON, simpleSmallLineStringGeoJSON, startToolExampleConfig, strokeWidthOptions, styleNameToStyleLike, temperatureLegendColorsCWK, temperatureLegendColorsWoW, textLabelStyle, textStyle, textStyleWithMargin, updateEditModeButtonsWithFir, useAnimationForLayer, useEDRGetCollectionDetails, useEDRGetParameterData, useEDRWMLayer, useGeoJSON, useGetWMLayerInstance, useGetWMSLayerStyleList, useIconStyle, useMapDrawTool, useProjection, useQueryGetWMSGetCapabilities, useQueryGetWMSLayer, useQueryGetWMSLayers, useQueryGetWMSLayersTree, useQueryGetWMSServiceInfo, useQueryWMTSGetCapabilities, useSetIntervalWhenVisible, useViewFromLayer, viewUtils, webmapEDRQueryOptions, webmapReactTranslations };
|
|
19257
|
+
export { BaseLayerType, CLASSNAME_MAP_MEASURE_TOOLTIP, ClickOnMapTool, Clock, DEFAULT_GEOJSON_STYLE_FILL_OPACITY, DRAWMODE, DefaultBaseLayers, DimensionSelectButton, DimensionSelectDialog, DimensionSelectSlider, EditModeButton as EditModeButtonField, FEATURE_DRAW_FILL_COLOR, FEATURE_DRAW_FILL_COLOR_TRANSPARENT, FEATURE_DRAW_SECONDARY_FILL_COLOR, FEATURE_DRAW_SECONDARY_STROKE_COLOR, FEATURE_DRAW_STROKE_COLOR, FEATURE_FILL, FEATURE_FILL_SELECTED, FEATURE_STROKE, FEATURE_STROKE_EDIT, FEATURE_STROKE_SELECTED, FEATURE_VERTICES_EDIT_HANDLES, FEATURE_VERTICE_HANDLE_IMAGE, FEATURE_VERTICE_IMAGE, FeatureLayer, FeatureLayers, GeoJSONTextField, IntersectionSelect, LayerInfoButton, LayerInfoDialog, LayerInfoLegend, LayerInfoList, LayerInfoText, Legend, LegendButton, LegendDialog, LegendLayout, MapContext, MapControlButton, MapControls, MapDimensionSelect, MapFeatureClass, MapMeasure, MapTime, MapWarningProperties, NEW_FEATURE_CREATED, NEW_LINESTRING_CREATED, NEW_POINT_CREATED, OpenLayersFeatureLayer, OpenLayersGetFeatureInfo, OpenLayersLayer, OpenLayersMapDraw, OpenLayersMapView, OpenLayersZoomControl, SelectField, StoryLayoutGrid, TimeAwareEDRLocationLayer, TimeAwareGeoTIFFLayer, TimeAwareWMTSLayer, TimeContext, TimeawareImageSource, TimeawareImageSourceWMSLayer, WEBMAP_REACT_NAMESPACE, WMSLayer, WMTSLayer, XYZLayer, ZoomControls, addFeatureProperties, addGeoJSONProperties, addSelectionTypeToGeoJSON, basicExampleDrawOptions, basicExampleMultipleShapeDrawOptions, basicExampleMultipleShapeWithValuesDrawOptions, catmullRomSpline, clearImageCacheForAllMaps, colorMaps, createBoxBasedOnModifiedVertex, createIconStyle, createInterSections, createOval, currentlySupportedDrawModes, defaultBox, defaultCircle, defaultDelete, defaultEdrStyles, defaultFreehandLine, defaultGeoJSONStyleProperties, defaultIntersectionStyleProperties, defaultLayers, defaultLineString, defaultLocation, defaultModes, defaultOval, defaultPoint, defaultPolygon, defaultSmoothLine, defaultSquare, defaultTimeFormat, dimensionConfig, drawPolyStoryStyles, drawStyles, emptyGeoJSON, endToolExampleConfig, exampleIntersectionOptions, exampleIntersectionWithShapeOptions, exampleIntersections, exampleIntersectionsMultiDrawTool, fakeEdrLayerApiHandlers, featureMultiPoint, featurePoint, featurePolygon, fetchStacCollection, fetchStacItem, fetchStacItems, fillOptions, firSelectionType, formatTime, generateImageFromLegend, genericOpenLayersFeatureStyle, geowebColorToOpenLayersColor, getBoxRotateHandlePoints, getDimensionIcon, getDimensionLabel, getDimensionValue, getDimensionsList, getDoubleControlToolIcon, getDrawModeIdFromSelectionType, getFeatureCollection, getFeatureExtent, getFeaturePointStyle, getFirTitle, getGeoJSONPropertyValue, getGeoJson, getIcon, getIntersectionToolIcon, getIsInsideAcceptanceTime, getLastEmptyFeatureIndex, getLayerBbox, getLayerStyles, getLayerUpdateInfo, getLegendClass, getProj4, getTimeDimension, getToolIcon, initializeOpenLayersProjections, inlineFeatureStyle, intersectPointGeoJSONS, intersectPolygonGeoJSONS, intersectionFeatureBE, intersectionFeatureNL, isGeoJSONFeatureCreatedByTool, isGeoJSONGeometryEmpty, isPointFeatureCollection, labelOptions, lineString, lineStringCollection, makeFeatureStyleDisc, makeFeatureStyleLoading, makeFeatureStyleMultiParam, makeFeatureStyleMultiParamLoading, makeFeatureStyleWind, makeLegendFromColorMap, makeLegendFromStyleName, makeTimeList, makeView, marksByDimension, measureResultStyle, measureToolStyle, modifyStyles, moveFeature, multiLineStringLabelStyle, multiPolygonLabelStyle, opacityOptions, openLayersGetMapImageStore, precipitationMMLegendColorsWoW, projectorCache, publicLayers, publicServices, rewindGeometry, roundCoordinates, selectPreferredWMSProjection, setMapCenter, setViewFromExtent, setViewFromFeature, simpleBoxGeoJSON, simpleBoxGeoJSONWrongOrder, simpleFlightRouteLineStringGeoJSON, simpleFlightRoutePointsGeoJSON, simpleGeometryCollectionGeoJSON, simpleLineStringGeoJSON, simpleMultiPolygon, simplePointsGeojson, simplePolygonGeoJSON, simpleSmallLineStringGeoJSON, startToolExampleConfig, strokeWidthOptions, styleNameToStyleLike, temperatureLegendColorsCWK, temperatureLegendColorsWoW, textLabelStyle, textStyle, textStyleWithMargin, updateEditModeButtonsWithFir, useAnimationForLayer, useEDRGetCollectionDetails, useEDRGetParameterData, useEDRWMLayer, useFetchGeoTIFFBlob, useGeoJSON, useGetWMLayerInstance, useGetWMSLayerStyleList, useIconStyle, useMapDrawTool, useProjection, useQueryGetWMSGetCapabilities, useQueryGetWMSLayer, useQueryGetWMSLayers, useQueryGetWMSLayersTree, useQueryGetWMSServiceInfo, useQueryWMTSGetCapabilities, useSetIntervalWhenVisible, useStacCollection, useStacItems, useViewFromLayer, viewUtils, webmapEDRQueryOptions, webmapReactTranslations };
|