@opengeoweb/webmap-react 15.0.0 → 15.2.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 CHANGED
@@ -2,7 +2,7 @@ import { WMInvalidDateValues, getCorrectWMSDimName, WMImageStore, WMImageStoreLo
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, extend } from 'ol/extent';
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';
@@ -13,16 +13,16 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
13
13
  import { CustomTooltip, CanvasComponent, useWheelStopPropagation, ToolContainerDraggable, CustomIconButton, dateUtils, useMakeSureContainerStaysInsideWindow, Draggable, Resizable } from '@opengeoweb/shared';
14
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, Polygon, LineString } from 'ol/geom';
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, darkTheme, ChevronRight, Clock as Clock$1, Resize } 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';
@@ -11419,7 +11419,7 @@ var getDimensionsList = function getDimensionsList(dimensions) {
11419
11419
  };
11420
11420
 
11421
11421
  var LayerInfoDialog = function LayerInfoDialog(_ref) {
11422
- var _layer$path, _layer$keywords, _layer$styles;
11422
+ var _layer$styles, _layer$styles2, _layer$path, _layer$keywords;
11423
11423
  var onClose = _ref.onClose,
11424
11424
  layer = _ref.layer,
11425
11425
  serviceName = _ref.serviceName,
@@ -11436,12 +11436,18 @@ var LayerInfoDialog = function LayerInfoDialog(_ref) {
11436
11436
  startPosition = _ref$startPosition === void 0 ? {
11437
11437
  top: 150,
11438
11438
  left: 900
11439
- } : _ref$startPosition;
11439
+ } : _ref$startPosition,
11440
+ selectedStyle = _ref.selectedStyle;
11440
11441
  var styles = getLayerStyles(layer);
11441
11442
  var dimensions = getDimensionsList(layer.dimensions);
11442
11443
  var _useWebmapReactTransl = useWebmapReactTranslation(),
11443
11444
  t = _useWebmapReactTransl.t;
11444
11445
  var bbox = getLayerBbox(t, layer);
11446
+ var legendURL = ((_layer$styles = layer.styles) === null || _layer$styles === void 0 || (_layer$styles = _layer$styles.find(function (styleItem) {
11447
+ return styleItem.name === selectedStyle;
11448
+ })) === null || _layer$styles === void 0 ? void 0 : _layer$styles.legendURL) || ((_layer$styles2 = layer.styles) === null || _layer$styles2 === void 0 ? void 0 : _layer$styles2[0].legendURL) ||
11449
+ // show first style if none selected
11450
+ undefined;
11445
11451
  return jsx(ToolContainerDraggable, {
11446
11452
  isOpen: isOpen,
11447
11453
  onClose: onClose,
@@ -11490,7 +11496,7 @@ var LayerInfoDialog = function LayerInfoDialog(_ref) {
11490
11496
  value: ((_layer$keywords = layer.keywords) === null || _layer$keywords === void 0 ? void 0 : _layer$keywords.join(', ')) || '-'
11491
11497
  }), jsx(LayerInfoLegend, {
11492
11498
  dimensions: layer.dimensions,
11493
- legendURL: (_layer$styles = layer.styles) !== null && _layer$styles !== void 0 && _layer$styles.length ? layer.styles[0].legendURL : undefined,
11499
+ legendURL: legendURL,
11494
11500
  name: layer.name,
11495
11501
  title: layer.title
11496
11502
  })]
@@ -12047,12 +12053,13 @@ var addFeatureProperties = function addFeatureProperties(geojson, featurePropert
12047
12053
  * @returns Whether `feature` is empty or not
12048
12054
  */
12049
12055
  var isGeoJSONGeometryEmpty = function isGeoJSONGeometryEmpty(feature) {
12050
- return feature.geometry && (feature.geometry.type === 'Polygon' && feature.geometry.coordinates && feature.geometry.coordinates.length === 1 && feature.geometry.coordinates[0].length === 0 || feature.geometry.type === 'LineString' && feature.geometry.coordinates && feature.geometry.coordinates.length === 0 || feature.geometry.type === 'Point' && feature.geometry.coordinates && feature.geometry.coordinates.length === 0);
12056
+ var _feature$geometry$coo, _feature$geometry$coo2, _feature$geometry$coo3;
12057
+ return feature.geometry && (feature.geometry.type === 'Polygon' && ((_feature$geometry$coo = feature.geometry.coordinates) === null || _feature$geometry$coo === void 0 ? void 0 : _feature$geometry$coo.length) === 1 && feature.geometry.coordinates[0].length === 0 || feature.geometry.type === 'LineString' && ((_feature$geometry$coo2 = feature.geometry.coordinates) === null || _feature$geometry$coo2 === void 0 ? void 0 : _feature$geometry$coo2.length) === 0 || feature.geometry.type === 'Point' && ((_feature$geometry$coo3 = feature.geometry.coordinates) === null || _feature$geometry$coo3 === void 0 ? void 0 : _feature$geometry$coo3.length) === 0);
12051
12058
  };
12052
12059
  var getGeoJSONPropertyValue = function getGeoJSONPropertyValue(property, properties, polygonDrawMode) {
12053
12060
  var defaultProperties = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : defaultGeoJSONStyleProperties;
12054
12061
  // if a shape is set, extract the style from there
12055
- if (properties && properties[property] !== undefined) {
12062
+ if ((properties === null || properties === void 0 ? void 0 : properties[property]) !== undefined) {
12056
12063
  return properties[property];
12057
12064
  }
12058
12065
  // if active polygon tool is preset, retreive style from there
@@ -12107,7 +12114,7 @@ var moveFeature = function moveFeature(currentGeoJSON, newGeoJSON, featureLayerI
12107
12114
  newGeoJSON.features.push(_copyFeature);
12108
12115
  return newGeoJSON.features.length - 1;
12109
12116
  }
12110
- if (geometry.type === 'Point' && currentFeature && currentFeature.geometry.type === 'Point' && currentFeature.geometry.coordinates.length > 0 && reason === NEW_POINT_CREATED) {
12117
+ if (geometry.type === 'Point' && (currentFeature === null || currentFeature === void 0 ? void 0 : currentFeature.geometry.type) === 'Point' && currentFeature.geometry.coordinates.length > 0 && reason === NEW_POINT_CREATED) {
12111
12118
  var _copyFeature2 = _objectSpread2(_objectSpread2({}, currentFeature), selectionType && {
12112
12119
  properties: _objectSpread2(_objectSpread2({}, feature.properties), {}, {
12113
12120
  selectionType: selectionType
@@ -13738,7 +13745,7 @@ var FeatureLayer = function FeatureLayer(_ref) {
13738
13745
  var previousHover = [];
13739
13746
  var pointerMoveFunction = debounce(function (evt) {
13740
13747
  var hoveredFeature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
13741
- if (!layer || layer.getSource() !== source) {
13748
+ if (!layer || (layer === null || layer === void 0 ? void 0 : layer.getSource()) !== source) {
13742
13749
  return false;
13743
13750
  }
13744
13751
  return feature;
@@ -13925,6 +13932,28 @@ var fetchStacCollection = /*#__PURE__*/function () {
13925
13932
  return _ref.apply(this, arguments);
13926
13933
  };
13927
13934
  }();
13935
+ var fetchStacItem = /*#__PURE__*/function () {
13936
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(stacItemUrl) {
13937
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
13938
+ while (1) switch (_context2.prev = _context2.next) {
13939
+ case 0:
13940
+ _context2.next = 2;
13941
+ return fetch(stacItemUrl);
13942
+ case 2:
13943
+ _context2.next = 4;
13944
+ return _context2.sent.json();
13945
+ case 4:
13946
+ return _context2.abrupt("return", _context2.sent);
13947
+ case 5:
13948
+ case "end":
13949
+ return _context2.stop();
13950
+ }
13951
+ }, _callee2);
13952
+ }));
13953
+ return function fetchStacItem(_x2) {
13954
+ return _ref2.apply(this, arguments);
13955
+ };
13956
+ }();
13928
13957
  var fetchStacItems = /*#__PURE__*/function () {
13929
13958
  var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(collectionUrl) {
13930
13959
  var collection;
@@ -15373,15 +15402,38 @@ var ICON_LOCATIONMARKER_MODIFY = createIconStyle(locationPath, {
15373
15402
  anchor: [0.5, 1]
15374
15403
  }
15375
15404
  });
15405
+ // Pre-rendered canvas for the rotate icon so we can create
15406
+ // dynamically rotated instances that follow the box orientation.
15407
+ var ROTATE_ICON_SIZE = [24, 24];
15408
+ var ROTATE_ICON_CANVAS = typeof document !== 'undefined' ? function () {
15409
+ var canvas = document.createElement('canvas');
15410
+ var width = ROTATE_ICON_SIZE[0],
15411
+ height = ROTATE_ICON_SIZE[1];
15412
+ canvas.width = width;
15413
+ canvas.height = height;
15414
+ var ctx = canvas.getContext('2d');
15415
+ if (!ctx) {
15416
+ return undefined;
15417
+ }
15418
+ var path = new Path2D(rotatePath);
15419
+ // Draw a white outline behind the rotate icon for better contrast
15420
+ ctx.lineWidth = 1.5;
15421
+ ctx.strokeStyle = 'rgba(255, 255, 255, 1)';
15422
+ ctx.stroke(path);
15423
+ // Fill the actual rotate icon
15424
+ ctx.fillStyle = '#051039';
15425
+ ctx.fill(path);
15426
+ return canvas;
15427
+ }() : undefined;
15376
15428
  var FEATURE_VERTICES_EDIT_HANDLES = new Style$1({
15377
15429
  image: FEATURE_VERTICE_IMAGE,
15378
15430
  geometry: function geometry(feature) {
15379
15431
  var geom = feature === null || feature === void 0 ? void 0 : feature.getGeometry();
15380
- if (geom && geom.getType() === 'Polygon') {
15432
+ if ((geom === null || geom === void 0 ? void 0 : geom.getType()) === 'Polygon') {
15381
15433
  var coordinates = geom.getCoordinates()[0];
15382
15434
  return new MultiPoint(coordinates);
15383
15435
  }
15384
- if (geom && geom.getType() === 'LineString') {
15436
+ if ((geom === null || geom === void 0 ? void 0 : geom.getType()) === 'LineString') {
15385
15437
  var _coordinates = geom.getCoordinates();
15386
15438
  return new MultiPoint(_coordinates);
15387
15439
  }
@@ -15892,7 +15944,7 @@ var drawPolygonLikeFeatureStyle = function drawPolygonLikeFeatureStyle(feature)
15892
15944
  image: FEATURE_VERTICE_IMAGE,
15893
15945
  geometry: function geometry(feature) {
15894
15946
  var geom = feature === null || feature === void 0 ? void 0 : feature.getGeometry();
15895
- if (geom && geom.getType() === 'LineString') {
15947
+ if ((geom === null || geom === void 0 ? void 0 : geom.getType()) === 'LineString') {
15896
15948
  var coordinates = geom.getCoordinates();
15897
15949
  return new MultiPoint(coordinates);
15898
15950
  }
@@ -15965,49 +16017,294 @@ new Style$1({
15965
16017
  }),
15966
16018
  // Vertices
15967
16019
  FEATURE_VERTICES_EDIT_HANDLES];
15968
- // This function creates a box out of a modified polygon. It detects which corner was moved by comparing
15969
- // vertices between the two geometries. Then it draws a new box based on the moved vertice and the opposing
15970
- // vertice.
16020
+ // 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.
16021
+ // For squares the box scales uniformly around the fixed center.
16022
+ // For rectangles the diagonal opposite corner does not change, the other two corners are recomputed.
16023
+ // The original rotation is preserved.
15971
16024
  var createBoxBasedOnModifiedVertex = function createBoxBasedOnModifiedVertex(modifiedGeometry, originalGeometry) {
15972
- var originalGeometryCoords = originalGeometry.getCoordinates()[0];
15973
- var draggedCornerIndex = modifiedGeometry.getCoordinates()[0].findIndex(function (coords, idx) {
15974
- return originalGeometryCoords[idx][0] !== coords[0] || originalGeometryCoords[idx][1] !== coords[1];
16025
+ var _classified$find, _classified$find2, _classified$find3, _classified$find4;
16026
+ var keepSquare = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
16027
+ var originalRing = originalGeometry.getCoordinates()[0];
16028
+ var modifiedRing = modifiedGeometry.getCoordinates()[0];
16029
+ if (!originalRing || !modifiedRing || originalRing.length < 4) {
16030
+ return originalGeometry;
16031
+ }
16032
+ // Strip closing coordinate if present so we only work with the four corners.
16033
+ var stripClose = function stripClose(ring) {
16034
+ if (ring.length > 4 && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1]) {
16035
+ return ring.slice(0, ring.length - 1);
16036
+ }
16037
+ return ring;
16038
+ };
16039
+ var originalCorners = stripClose(originalRing);
16040
+ var modifiedCorners = stripClose(modifiedRing);
16041
+ if (originalCorners.length < 4 || modifiedCorners.length < 4) {
16042
+ return originalGeometry;
16043
+ }
16044
+ // Detect which corner was dragged by comparing original vs modified
16045
+ var draggedCornerIndex = originalCorners.findIndex(function (orig, idx) {
16046
+ var mod = modifiedCorners[idx];
16047
+ return orig[0] !== mod[0] || orig[1] !== mod[1];
15975
16048
  });
15976
16049
  if (draggedCornerIndex === -1) {
16050
+ // No corner actually changed, keep original
15977
16051
  return originalGeometry;
15978
16052
  }
15979
- var draggedCoords = modifiedGeometry.getCoordinates()[0][draggedCornerIndex];
15980
- var opposingCoords = modifiedGeometry.getCoordinates()[0][(draggedCornerIndex + 2) % 4];
15981
- var box = extend([draggedCoords[0], draggedCoords[1], draggedCoords[0], draggedCoords[1]], [opposingCoords[0], opposingCoords[1], opposingCoords[0], opposingCoords[1]]);
15982
- var boxPolygon = new Polygon([[[box[0], box[1]], [box[2], box[1]], [box[2], box[3]], [box[0], box[3]], [box[0], box[1]]]]);
15983
- return boxPolygon;
15984
- };
15985
- var boxModificationStyle = [new Style$1({
15986
- fill: FEATURE_FILL,
15987
- stroke: FEATURE_STROKE_EDIT,
15988
- geometry: function geometry(feature) {
15989
- var originalGeometry = feature === null || feature === void 0 ? void 0 : feature.get('originalGeometry');
15990
- if (originalGeometry) {
15991
- return createBoxBasedOnModifiedVertex(feature.getGeometry(), originalGeometry);
15992
- }
15993
- return feature.getGeometry();
16053
+ var dragged = modifiedCorners[draggedCornerIndex];
16054
+ // Compute center of the original box
16055
+ var centerX = originalCorners.reduce(function (sum, _ref) {
16056
+ var _ref2 = _slicedToArray(_ref, 1),
16057
+ x = _ref2[0];
16058
+ return sum + x;
16059
+ }, 0) / originalCorners.length;
16060
+ var centerY = originalCorners.reduce(function (sum, _ref3) {
16061
+ var _ref4 = _slicedToArray(_ref3, 2),
16062
+ y = _ref4[1];
16063
+ return sum + y;
16064
+ }, 0) / originalCorners.length;
16065
+ // Derive local axes from the original box so we can preserve its
16066
+ // rotation. Use the edges from corner 0 to its two neighbours.
16067
+ var p0 = originalCorners[0];
16068
+ var p1 = originalCorners[1];
16069
+ var p3 = originalCorners[3];
16070
+ var edgeUx = p1[0] - p0[0];
16071
+ var edgeUy = p1[1] - p0[1];
16072
+ var edgeVx = p3[0] - p0[0];
16073
+ var edgeVy = p3[1] - p0[1];
16074
+ var edgeUlength = Math.hypot(edgeUx, edgeUy);
16075
+ var edgeVlenght = Math.hypot(edgeVx, edgeVy);
16076
+ if (!edgeUlength || !edgeVlenght) {
16077
+ // if either egde has zero length, bail out
16078
+ return originalGeometry;
15994
16079
  }
15995
- }), new Style$1({
15996
- image: FEATURE_VERTICE_IMAGE,
15997
- geometry: function geometry(feature) {
15998
- var originalGeometry = feature === null || feature === void 0 ? void 0 : feature.get('originalGeometry');
15999
- var geom = originalGeometry ? createBoxBasedOnModifiedVertex(feature.getGeometry(), originalGeometry) : feature === null || feature === void 0 ? void 0 : feature.getGeometry();
16000
- if (geom && geom.getType() === 'Polygon') {
16001
- var coordinates = geom.getCoordinates()[0];
16002
- return new MultiPoint(coordinates);
16003
- }
16004
- if (geom && geom.getType() === 'LineString') {
16005
- var _coordinates2 = geom.getCoordinates();
16006
- return new MultiPoint(_coordinates2);
16007
- }
16080
+ var ux = edgeUx / edgeUlength;
16081
+ var uy = edgeUy / edgeUlength;
16082
+ var vx = edgeVx / edgeVlenght;
16083
+ var vy = edgeVy / edgeVlenght;
16084
+ // Remember which corner is which
16085
+ var cornerSigns = [{
16086
+ sx: -1,
16087
+ sy: -1
16088
+ }, {
16089
+ sx: 1,
16090
+ sy: -1
16091
+ }, {
16092
+ sx: 1,
16093
+ sy: 1
16094
+ }, {
16095
+ sx: -1,
16096
+ sy: 1
16097
+ }];
16098
+ var minSize = 1e-6;
16099
+ // Squares keep their center fixed and scale uniformly from the
16100
+ // dragged corner.
16101
+ if (keepSquare) {
16102
+ // Project the dragged corner into the same local coordinate
16103
+ // system to determine the new half-size while keeping the
16104
+ // existing rotation.
16105
+ var drx = dragged[0] - centerX;
16106
+ var dry = dragged[1] - centerY;
16107
+ var dragLocalX = drx * ux + dry * uy;
16108
+ var dragLocalY = drx * vx + dry * vy;
16109
+ var _halfWidth = Math.max(Math.abs(dragLocalX), minSize);
16110
+ var _halfHeight = Math.max(Math.abs(dragLocalY), minSize);
16111
+ var halfSize = Math.max(_halfWidth, _halfHeight);
16112
+ var newCorners = originalCorners.map(function (_, idx) {
16113
+ var _cornerSigns$idx = cornerSigns[idx],
16114
+ sx = _cornerSigns$idx.sx,
16115
+ sy = _cornerSigns$idx.sy;
16116
+ var localX = sx * halfSize;
16117
+ var localY = sy * halfSize;
16118
+ var worldX = centerX + localX * ux + localY * vx;
16119
+ var worldY = centerY + localX * uy + localY * vy;
16120
+ return [worldX, worldY];
16121
+ });
16122
+ newCorners.push(newCorners[0]);
16123
+ return new Polygon([newCorners]);
16124
+ }
16125
+ // Rectangles (non-squares) should resize using the dragged
16126
+ // corner while keeping the diagonal opposite anchored. The two remaining
16127
+ // corners adjust accordingly, and the overall rotation is kept. When the
16128
+ // dragged corner crosses past the center, the rectangle is allowed to
16129
+ // "flip" instead of bouncing back.
16130
+ // Diagonal corner relative to the dragged one in the 4-corner ring
16131
+ var anchorIndex = (draggedCornerIndex + 2) % originalCorners.length;
16132
+ var anchor = originalCorners[anchorIndex];
16133
+ // Vector from anchored corner to dragged corner, in world space
16134
+ var deltaWx = dragged[0] - anchor[0];
16135
+ var deltaWy = dragged[1] - anchor[1];
16136
+ // Express that vector in the local (u, v) frame
16137
+ var deltaLocalX = deltaWx * ux + deltaWy * uy;
16138
+ var deltaLocalY = deltaWx * vx + deltaWy * vy;
16139
+ // Half-sizes in local coordinates. We keep the sign so that when the
16140
+ // dragged corner crosses past the anchor along either axis, the
16141
+ // rectangle flips instead of being clamped.
16142
+ var halfWidth = deltaLocalX / 2;
16143
+ var halfHeight = deltaLocalY / 2;
16144
+ // Center in local coordinates is halfway between anchor (0,0) and
16145
+ // dragged (deltaLocalX, deltaLocalY).
16146
+ var centerLocalX = halfWidth;
16147
+ var centerLocalY = halfHeight;
16148
+ // Convert center back to world coordinates.
16149
+ var centerXNew = anchor[0] + centerLocalX * ux + centerLocalY * vx;
16150
+ var centerYNew = anchor[1] + centerLocalX * uy + centerLocalY * vy;
16151
+ // Rebuild the four corners in local coordinates around the new center.
16152
+ var localCorners = [[-halfWidth, -halfHeight], [halfWidth, -halfHeight], [halfWidth, halfHeight], [-halfWidth, halfHeight]];
16153
+ var newCornersWorld = localCorners.map(function (_ref5) {
16154
+ var _ref6 = _slicedToArray(_ref5, 2),
16155
+ lx = _ref6[0],
16156
+ ly = _ref6[1];
16157
+ var worldX = centerXNew + lx * ux + ly * vx;
16158
+ var worldY = centerYNew + lx * uy + ly * vy;
16159
+ return [worldX, worldY];
16160
+ });
16161
+ // Normalise corner order so index 0..3 always correspond to
16162
+ // bottom-left, bottom-right, top-right, top-left in the box's
16163
+ // local frame. This keeps rotate-handle orientation and
16164
+ // indexing stable even after the rectangle "flips" when a
16165
+ // corner is dragged past the centre.
16166
+ var classified = newCornersWorld.map(function (corner) {
16167
+ var _corner = _slicedToArray(corner, 2),
16168
+ wx = _corner[0],
16169
+ wy = _corner[1];
16170
+ var rx = wx - centerXNew;
16171
+ var ry = wy - centerYNew;
16172
+ var localX = rx * ux + ry * uy;
16173
+ var localY = rx * vx + ry * vy;
16174
+ return {
16175
+ corner: corner,
16176
+ qx: localX >= 0 ? 1 : -1,
16177
+ qy: localY >= 0 ? 1 : -1
16178
+ };
16179
+ });
16180
+ var bl = (_classified$find = classified.find(function (corner) {
16181
+ return corner.qx === -1 && corner.qy === -1;
16182
+ })) === null || _classified$find === void 0 ? void 0 : _classified$find.corner;
16183
+ var br = (_classified$find2 = classified.find(function (corner) {
16184
+ return corner.qx === 1 && corner.qy === -1;
16185
+ })) === null || _classified$find2 === void 0 ? void 0 : _classified$find2.corner;
16186
+ var tr = (_classified$find3 = classified.find(function (corner) {
16187
+ return corner.qx === 1 && corner.qy === 1;
16188
+ })) === null || _classified$find3 === void 0 ? void 0 : _classified$find3.corner;
16189
+ var tl = (_classified$find4 = classified.find(function (corner) {
16190
+ return corner.qx === -1 && corner.qy === 1;
16191
+ })) === null || _classified$find4 === void 0 ? void 0 : _classified$find4.corner;
16192
+ var orderedCorners = bl && br && tr && tl ? [bl, br, tr, tl] : newCornersWorld;
16193
+ // Close the ring
16194
+ orderedCorners.push(orderedCorners[0]);
16195
+ return new Polygon([orderedCorners]);
16196
+ };
16197
+ var getBoxRotateHandlePoints = function getBoxRotateHandlePoints(feature, resolution) {
16198
+ var originalGeometry = feature === null || feature === void 0 ? void 0 : feature.get('originalGeometry');
16199
+ var geom = originalGeometry ? createBoxBasedOnModifiedVertex(feature.getGeometry(), originalGeometry, feature.get('selectionType') === 'square') : feature === null || feature === void 0 ? void 0 : feature.getGeometry();
16200
+ if (!geom || (geom === null || geom === void 0 ? void 0 : geom.getType()) !== 'Polygon') {
16008
16201
  return undefined;
16009
16202
  }
16010
- })];
16203
+ var ring = geom.getCoordinates()[0];
16204
+ if (ring.length < 4) {
16205
+ return undefined;
16206
+ }
16207
+ // First four coordinates are the corners of the box (possibly rotated)
16208
+ var corners = ring.slice(0, 4);
16209
+ // Compute box center as the average of the corners
16210
+ var centerX = corners.reduce(function (sum, _ref7) {
16211
+ var _ref8 = _slicedToArray(_ref7, 1),
16212
+ x = _ref8[0];
16213
+ return sum + x;
16214
+ }, 0) / corners.length;
16215
+ var centerY = corners.reduce(function (sum, _ref9) {
16216
+ var _ref0 = _slicedToArray(_ref9, 2),
16217
+ y = _ref0[1];
16218
+ return sum + y;
16219
+ }, 0) / corners.length;
16220
+ // Place the rotate handle at a nearly constant distance from the
16221
+ // corner in screen space, independent of how large the box is.
16222
+ // We move a fixed number of pixels along the outward diagonal
16223
+ // from each corner.
16224
+ var pixelOffset = 16; // pixels away from the corner
16225
+ var baseOffset = resolution ? pixelOffset * resolution : 0;
16226
+ return corners.map(function (_ref1) {
16227
+ var _ref10 = _slicedToArray(_ref1, 2),
16228
+ x = _ref10[0],
16229
+ y = _ref10[1];
16230
+ var dx = x - centerX;
16231
+ var dy = y - centerY;
16232
+ var distance = Math.hypot(dx, dy);
16233
+ if (!distance || !baseOffset) {
16234
+ return [x, y];
16235
+ }
16236
+ var ux = dx / distance;
16237
+ var uy = dy / distance;
16238
+ return [x + ux * baseOffset, y + uy * baseOffset];
16239
+ });
16240
+ };
16241
+ var boxModificationStyle = function boxModificationStyle(feature, resolution) {
16242
+ var styles = [];
16243
+ var originalGeometry = feature === null || feature === void 0 ? void 0 : feature.get('originalGeometry');
16244
+ var geom = originalGeometry ? createBoxBasedOnModifiedVertex(feature.getGeometry(), originalGeometry, feature.get('selectionType') === 'square') : feature.getGeometry();
16245
+ if (geom) {
16246
+ styles.push(new Style$1({
16247
+ fill: FEATURE_FILL,
16248
+ stroke: FEATURE_STROKE_EDIT,
16249
+ geometry: geom
16250
+ }));
16251
+ }
16252
+ if (geom && (geom.getType() === 'Polygon' || geom.getType() === 'LineString')) {
16253
+ var coordinates = geom.getType() === 'Polygon' ? geom.getCoordinates()[0] : geom.getCoordinates();
16254
+ styles.push(new Style$1({
16255
+ image: FEATURE_VERTICE_IMAGE,
16256
+ geometry: new MultiPoint(coordinates)
16257
+ }));
16258
+ }
16259
+ var handlePoints = getBoxRotateHandlePoints(feature, resolution);
16260
+ var activeIndexRaw = feature.get('activeRotateHandleIndex');
16261
+ var activeIndex = typeof activeIndexRaw === 'number' && activeIndexRaw >= 0 && activeIndexRaw < 4 ? activeIndexRaw : undefined;
16262
+ // While the box is being modified (corner drag), hide the rotate
16263
+ // handle so only sizing handles are visible.
16264
+ var suppressRotateHandle = feature.get('suppressRotateHandle');
16265
+ if (ROTATE_ICON_CANVAS && handlePoints && handlePoints.length >= 4 && activeIndex !== undefined && !suppressRotateHandle) {
16266
+ var _handlePoints = _slicedToArray(handlePoints, 4),
16267
+ h0 = _handlePoints[0],
16268
+ h1 = _handlePoints[1],
16269
+ h2 = _handlePoints[2],
16270
+ h3 = _handlePoints[3];
16271
+ // Base angle: along the edge between first two corner handles.
16272
+ var baseAngle = Math.atan2(h1[1] - h0[1], h1[0] - h0[0]);
16273
+ // Assign per-corner offsets.
16274
+ var handleConfigs = [{
16275
+ point: h0,
16276
+ offset: 0
16277
+ },
16278
+ // bottom-left
16279
+ {
16280
+ point: h1,
16281
+ offset: -Math.PI / 2
16282
+ },
16283
+ // bottom-right
16284
+ {
16285
+ point: h2,
16286
+ offset: Math.PI
16287
+ },
16288
+ // top-right
16289
+ {
16290
+ point: h3,
16291
+ offset: Math.PI / 2
16292
+ } // top-left
16293
+ ];
16294
+ var _handleConfigs$active = handleConfigs[activeIndex],
16295
+ point = _handleConfigs$active.point,
16296
+ offset = _handleConfigs$active.offset;
16297
+ var icon = new Icon$1({
16298
+ img: ROTATE_ICON_CANVAS,
16299
+ rotation: -baseAngle + offset
16300
+ });
16301
+ styles.push(new Style$1({
16302
+ image: icon,
16303
+ geometry: new MultiPoint([point])
16304
+ }));
16305
+ }
16306
+ return styles;
16307
+ };
16011
16308
  var circleFeatureStyle = function circleFeatureStyle(feature, resolution) {
16012
16309
  // use OL default styles to keep circle edge tracking
16013
16310
  var styles = createDefaultStyle(feature, resolution);
@@ -16213,7 +16510,9 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16213
16510
  geojson = _ref.geojson,
16214
16511
  selectedFeatureIndex = _ref.selectedFeatureIndex,
16215
16512
  exitDrawModeCallback = _ref.exitDrawModeCallback,
16216
- updateGeojson = _ref.updateGeojson;
16513
+ updateGeojson = _ref.updateGeojson,
16514
+ onViewOnlyFeatureClick = _ref.onViewOnlyFeatureClick,
16515
+ onNoFeatureClick = _ref.onNoFeatureClick;
16217
16516
  var _React$useContext = React.useContext(MapContext),
16218
16517
  map = _React$useContext.map;
16219
16518
  var projection = useProjection();
@@ -16242,7 +16541,7 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16242
16541
  style: viewOnlyStyle,
16243
16542
  zIndex: 1000000 - 1
16244
16543
  });
16245
- var editFeatureCollection = new Collection([allFeatures[selectedFeatureIndex]]);
16544
+ var editFeatureCollection = new Collection(allFeatures[selectedFeatureIndex] ? [allFeatures[selectedFeatureIndex]] : []);
16246
16545
  var source = new VectorSource({
16247
16546
  features: editFeatureCollection
16248
16547
  });
@@ -16256,6 +16555,26 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16256
16555
  map.addLayer(layer);
16257
16556
  map.addLayer(viewOnlyLayer);
16258
16557
  var interactions = [];
16558
+ var handleSingleClick = (onViewOnlyFeatureClick || onNoFeatureClick) && function (event) {
16559
+ var features = [];
16560
+ map.forEachFeatureAtPixel(event.pixel, function (featureAtPixel, layerAtPixel) {
16561
+ if (layerAtPixel === viewOnlyLayer || layerAtPixel === layer) {
16562
+ features.push(featureAtPixel);
16563
+ }
16564
+ }, {
16565
+ layerFilter: function layerFilter(layerAtPixel) {
16566
+ return layerAtPixel === viewOnlyLayer || layerAtPixel === layer;
16567
+ }
16568
+ });
16569
+ if (features.length) {
16570
+ onViewOnlyFeatureClick === null || onViewOnlyFeatureClick === void 0 || onViewOnlyFeatureClick(features);
16571
+ } else {
16572
+ onNoFeatureClick === null || onNoFeatureClick === void 0 || onNoFeatureClick();
16573
+ }
16574
+ };
16575
+ if (handleSingleClick) {
16576
+ map.on('singleclick', handleSingleClick);
16577
+ }
16259
16578
  var updateFeature = function updateFeature(feature) {
16260
16579
  var _feature$getGeometry;
16261
16580
  // Convert Circle to Polygon for GeoJSON serialization
@@ -16334,6 +16653,62 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16334
16653
  var lastPointerEvent = null;
16335
16654
  var trackPointerMove = function trackPointerMove(event) {
16336
16655
  lastPointerEvent = event;
16656
+ if (onViewOnlyFeatureClick) {
16657
+ var pixel = map.getEventPixel(event);
16658
+ var hasViewOnlyHit = false;
16659
+ map.forEachFeatureAtPixel(pixel, function (_featureAtPixel, layerAtPixel) {
16660
+ if (layerAtPixel === viewOnlyLayer) {
16661
+ hasViewOnlyHit = true;
16662
+ }
16663
+ }, {
16664
+ layerFilter: function layerFilter(layerAtPixel) {
16665
+ return layerAtPixel === viewOnlyLayer;
16666
+ }
16667
+ });
16668
+ map.getViewport().style.cursor = hasViewOnlyHit ? 'pointer' : '';
16669
+ }
16670
+ // Update which rotate handle is "active" so only that
16671
+ // icon is rendered near the mouse when editing boxes/squares.
16672
+ // While rotating, keep the originally clicked handle active.
16673
+ if (isBoxOrSquare && selectedFeatureHasGeometry && !isRotating) {
16674
+ var featureToRotate = editFeatureCollection.item(0);
16675
+ if (!featureToRotate) {
16676
+ return;
16677
+ }
16678
+ var resolution = map.getView().getResolution();
16679
+ var handlePoints = getBoxRotateHandlePoints(featureToRotate, resolution);
16680
+ var prevIndex = featureToRotate.get('activeRotateHandleIndex');
16681
+ var newIndex;
16682
+ if (!handlePoints || !resolution) {
16683
+ newIndex = undefined;
16684
+ } else {
16685
+ var coord = map.getEventCoordinate(event);
16686
+ var threshold = 18 * resolution; // enlarge hover hit area for rotate handle
16687
+ var closestIndex = -1;
16688
+ var closestDist = Infinity;
16689
+ handlePoints.forEach(function (_ref2, idx) {
16690
+ var _ref3 = _slicedToArray(_ref2, 2),
16691
+ hx = _ref3[0],
16692
+ hy = _ref3[1];
16693
+ var dx = coord[0] - hx;
16694
+ var dy = coord[1] - hy;
16695
+ var dist = Math.sqrt(dx * dx + dy * dy);
16696
+ if (dist < closestDist) {
16697
+ closestDist = dist;
16698
+ closestIndex = idx;
16699
+ }
16700
+ });
16701
+ newIndex = closestDist <= threshold ? closestIndex : undefined;
16702
+ }
16703
+ if (prevIndex !== newIndex) {
16704
+ if (newIndex === undefined) {
16705
+ featureToRotate.unset('activeRotateHandleIndex', true);
16706
+ } else {
16707
+ featureToRotate.set('activeRotateHandleIndex', newIndex, true);
16708
+ }
16709
+ layer.changed();
16710
+ }
16711
+ }
16337
16712
  };
16338
16713
  map.getViewport().addEventListener('pointermove', trackPointerMove);
16339
16714
  var deleteVertexOnDeleteKey = function deleteVertexOnDeleteKey(event) {
@@ -16346,12 +16721,13 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16346
16721
  }
16347
16722
  };
16348
16723
  window.addEventListener('keydown', deleteVertexOnDeleteKey);
16349
- var isBoxOrSquare = actualDrawMode === DRAWMODE.BOX || actualDrawMode === DRAWMODE.SQUARE;
16724
+ var isSquare = actualDrawMode === DRAWMODE.SQUARE;
16725
+ var isBoxOrSquare = actualDrawMode === DRAWMODE.BOX || isSquare;
16350
16726
  // Modifying is a combination of Modify and Translate interactions
16351
16727
  var modify = new Modify({
16352
16728
  features: editFeatureCollection,
16353
16729
  insertVertexCondition: !isBoxOrSquare ? always : never,
16354
- style: modifyHandleStyle
16730
+ style: isSquare ? [] : modifyHandleStyle
16355
16731
  });
16356
16732
  if (isBoxOrSquare) {
16357
16733
  // Box is a special case:
@@ -16360,16 +16736,39 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16360
16736
  modify.on('modifystart', function (evt) {
16361
16737
  var _feature$getGeometry2;
16362
16738
  var feature = evt.features.getArray()[0];
16739
+ // Mark that we are modifying the box so rotate handles
16740
+ // can be hidden while dragging.
16741
+ feature.set('suppressRotateHandle', true, true);
16363
16742
  feature.set('originalGeometry', (_feature$getGeometry2 = feature.getGeometry()) === null || _feature$getGeometry2 === void 0 ? void 0 : _feature$getGeometry2.clone(), true);
16743
+ var viewport = map.getViewport();
16744
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16745
+ viewport.style.cursor = 'grabbing';
16746
+ }
16364
16747
  });
16365
16748
  modify.on('modifyend', function (evt) {
16366
16749
  var feature = evt.features.getArray()[0];
16367
- var boxPolygon = createBoxBasedOnModifiedVertex(feature.getGeometry(), feature.get('originalGeometry'));
16750
+ var boxPolygon = createBoxBasedOnModifiedVertex(feature.getGeometry(), feature.get('originalGeometry'), isSquare);
16368
16751
  feature.setGeometry(boxPolygon);
16752
+ // Re-enable rotate handle visibility after modifying.
16753
+ feature.unset('suppressRotateHandle', true);
16754
+ var viewport = map.getViewport();
16755
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16756
+ viewport.style.cursor = '';
16757
+ }
16369
16758
  updateFeature(feature);
16370
16759
  });
16371
16760
  } else {
16761
+ modify.on('modifystart', function () {
16762
+ var viewport = map.getViewport();
16763
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16764
+ viewport.style.cursor = 'grabbing';
16765
+ }
16766
+ });
16372
16767
  modify.on('modifyend', function (evt) {
16768
+ var viewport = map.getViewport();
16769
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16770
+ viewport.style.cursor = '';
16771
+ }
16373
16772
  updateFeature(evt.features.getArray()[0]);
16374
16773
  });
16375
16774
  }
@@ -16379,6 +16778,236 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16379
16778
  translate.on('translateend', function (evt) {
16380
16779
  updateFeature(evt.features.getArray()[0]);
16381
16780
  });
16781
+ // Rotation handling for boxes and squares using the visual rotate handles
16782
+ var isRotating = false;
16783
+ var rotationCenter = null;
16784
+ var rotationStartAngle = 0;
16785
+ var originalRing = null;
16786
+ var disabledDragPans = [];
16787
+ // Track when the user has pressed down near a resize corner so we can
16788
+ // immediately show a grabbing cursor on mousedown (before any movement).
16789
+ var isPointerDownNearCorner = false;
16790
+ var handlePointerDownNearCorner = function handlePointerDownNearCorner(event) {
16791
+ if (!isBoxOrSquare || !selectedFeatureHasGeometry) {
16792
+ return;
16793
+ }
16794
+ var feature = editFeatureCollection.item(0);
16795
+ var geom = feature === null || feature === void 0 ? void 0 : feature.getGeometry();
16796
+ if (!geom || (geom === null || geom === void 0 ? void 0 : geom.getType()) !== 'Polygon') {
16797
+ return;
16798
+ }
16799
+ var polygon = geom;
16800
+ var ring = polygon.getCoordinates()[0];
16801
+ if (!ring || ring.length < 4) {
16802
+ return;
16803
+ }
16804
+ var clickCoord = map.getEventCoordinate(event);
16805
+ var resolution = map.getView().getResolution();
16806
+ if (!resolution) {
16807
+ return;
16808
+ }
16809
+ var threshold = 10 * resolution;
16810
+ var closestDist = Infinity;
16811
+ ring.forEach(function (_ref4) {
16812
+ var _ref5 = _slicedToArray(_ref4, 2),
16813
+ vx = _ref5[0],
16814
+ vy = _ref5[1];
16815
+ var dx = clickCoord[0] - vx;
16816
+ var dy = clickCoord[1] - vy;
16817
+ var dist = Math.sqrt(dx * dx + dy * dy);
16818
+ if (dist < closestDist) {
16819
+ closestDist = dist;
16820
+ }
16821
+ });
16822
+ if (closestDist <= threshold) {
16823
+ var viewport = map.getViewport();
16824
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16825
+ viewport.style.cursor = 'grabbing';
16826
+ }
16827
+ isPointerDownNearCorner = true;
16828
+ }
16829
+ };
16830
+ var handlePointerUpAfterCorner = function handlePointerUpAfterCorner() {
16831
+ if (!isPointerDownNearCorner && !isRotating) {
16832
+ return;
16833
+ }
16834
+ var viewport = map.getViewport();
16835
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16836
+ viewport.style.cursor = '';
16837
+ }
16838
+ isPointerDownNearCorner = false;
16839
+ };
16840
+ var startRotateIfOnHandle = function startRotateIfOnHandle(event) {
16841
+ if (!isBoxOrSquare || !selectedFeatureHasGeometry) {
16842
+ return;
16843
+ }
16844
+ var featureToRotate = editFeatureCollection.item(0);
16845
+ var geom = featureToRotate === null || featureToRotate === void 0 ? void 0 : featureToRotate.getGeometry();
16846
+ if (!geom || (geom === null || geom === void 0 ? void 0 : geom.getType()) !== 'Polygon') {
16847
+ return;
16848
+ }
16849
+ var polygon = geom;
16850
+ var ring = polygon.getCoordinates()[0];
16851
+ if (!ring || ring.length < 4) {
16852
+ return;
16853
+ }
16854
+ // Exclude possible closing coordinate
16855
+ 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;
16856
+ var clickCoord = map.getEventCoordinate(event);
16857
+ var resolution = map.getView().getResolution();
16858
+ if (!resolution) {
16859
+ return;
16860
+ }
16861
+ // Use the same helper for handle locations as the style code,
16862
+ // so visual position and click area are consistent.
16863
+ var handlePoints = getBoxRotateHandlePoints(featureToRotate, resolution);
16864
+ if (!handlePoints) {
16865
+ return;
16866
+ }
16867
+ var threshold = 12 * resolution; // enlarge click hit area for rotate handle
16868
+ // Determine which handle was clicked (nearest within threshold)
16869
+ var closestIndex = -1;
16870
+ var closestDist = Infinity;
16871
+ handlePoints.forEach(function (_ref6, idx) {
16872
+ var _ref7 = _slicedToArray(_ref6, 2),
16873
+ hx = _ref7[0],
16874
+ hy = _ref7[1];
16875
+ var dx = clickCoord[0] - hx;
16876
+ var dy = clickCoord[1] - hy;
16877
+ var dist = Math.sqrt(dx * dx + dy * dy);
16878
+ if (dist < closestDist) {
16879
+ closestDist = dist;
16880
+ closestIndex = idx;
16881
+ }
16882
+ });
16883
+ if (closestIndex === -1 || closestDist > threshold) {
16884
+ return;
16885
+ }
16886
+ // Lock the active rotate handle index so its icon stays visible
16887
+ var handleFeature = editFeatureCollection.item(0);
16888
+ if (handleFeature) {
16889
+ handleFeature.set('activeRotateHandleIndex', closestIndex, true);
16890
+ layer.changed();
16891
+ }
16892
+ isRotating = true;
16893
+ // Temporarily disable map panning while rotating so the
16894
+ // underlying map does not move when dragging the rotate handle.
16895
+ disabledDragPans = [];
16896
+ map.getInteractions().forEach(function (interaction) {
16897
+ if (interaction instanceof DragPan && interaction.getActive()) {
16898
+ disabledDragPans.push(interaction);
16899
+ interaction.setActive(false);
16900
+ }
16901
+ });
16902
+ // Recompute box center from the current polygon
16903
+ var minX = ringWithoutClose[0][0];
16904
+ var maxX = ringWithoutClose[0][0];
16905
+ var minY = ringWithoutClose[0][1];
16906
+ var maxY = ringWithoutClose[0][1];
16907
+ ringWithoutClose.forEach(function (_ref8) {
16908
+ var _ref9 = _slicedToArray(_ref8, 2),
16909
+ x = _ref9[0],
16910
+ y = _ref9[1];
16911
+ if (x < minX) {
16912
+ minX = x;
16913
+ }
16914
+ if (x > maxX) {
16915
+ maxX = x;
16916
+ }
16917
+ if (y < minY) {
16918
+ minY = y;
16919
+ }
16920
+ if (y > maxY) {
16921
+ maxY = y;
16922
+ }
16923
+ });
16924
+ var centerX = (minX + maxX) / 2;
16925
+ var centerY = (minY + maxY) / 2;
16926
+ rotationCenter = [centerX, centerY];
16927
+ rotationStartAngle = Math.atan2(clickCoord[1] - centerY, clickCoord[0] - centerX);
16928
+ originalRing = ring.map(function (_ref0) {
16929
+ var _ref1 = _slicedToArray(_ref0, 2),
16930
+ x = _ref1[0],
16931
+ y = _ref1[1];
16932
+ return [x, y];
16933
+ });
16934
+ // While rotating, show a grabbing cursor on the map viewport
16935
+ var viewport = map.getViewport();
16936
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16937
+ viewport.style.cursor = 'grabbing';
16938
+ }
16939
+ // While rotating, disable modify/translate to avoid conflicts
16940
+ modify.setActive(false);
16941
+ translate.setActive(false);
16942
+ event.preventDefault();
16943
+ };
16944
+ var rotateOnPointerMove = function rotateOnPointerMove(event) {
16945
+ if (!isRotating || !rotationCenter || !originalRing) {
16946
+ return;
16947
+ }
16948
+ var featureToRotate = editFeatureCollection.item(0);
16949
+ var geom = featureToRotate === null || featureToRotate === void 0 ? void 0 : featureToRotate.getGeometry();
16950
+ if (!geom || (geom === null || geom === void 0 ? void 0 : geom.getType()) !== 'Polygon') {
16951
+ return;
16952
+ }
16953
+ var polygon = geom;
16954
+ var _rotationCenter = rotationCenter,
16955
+ _rotationCenter2 = _slicedToArray(_rotationCenter, 2),
16956
+ centerX = _rotationCenter2[0],
16957
+ centerY = _rotationCenter2[1];
16958
+ var coord = map.getEventCoordinate(event);
16959
+ var angle = Math.atan2(coord[1] - centerY, coord[0] - centerX);
16960
+ var delta = angle - rotationStartAngle;
16961
+ var cos = Math.cos(delta);
16962
+ var sin = Math.sin(delta);
16963
+ var rotatedRing = originalRing.map(function (_ref10) {
16964
+ var _ref11 = _slicedToArray(_ref10, 2),
16965
+ x = _ref11[0],
16966
+ y = _ref11[1];
16967
+ var dx = x - centerX;
16968
+ var dy = y - centerY;
16969
+ var newX = centerX + dx * cos - dy * sin;
16970
+ var newY = centerY + dx * sin + dy * cos;
16971
+ return [newX, newY];
16972
+ });
16973
+ if (rotatedRing.length > 0) {
16974
+ // Ensure the ring is closed
16975
+ var _rotatedRing$ = _slicedToArray(rotatedRing[0], 2),
16976
+ firstX = _rotatedRing$[0],
16977
+ firstY = _rotatedRing$[1];
16978
+ rotatedRing[rotatedRing.length - 1] = [firstX, firstY];
16979
+ }
16980
+ polygon.setCoordinates([rotatedRing]);
16981
+ };
16982
+ var endRotate = function endRotate() {
16983
+ if (!isRotating) {
16984
+ return;
16985
+ }
16986
+ isRotating = false;
16987
+ rotationCenter = null;
16988
+ rotationStartAngle = 0;
16989
+ originalRing = null;
16990
+ // Re-enable any drag-pan interactions we disabled when rotation
16991
+ // started so normal map panning works again.
16992
+ disabledDragPans.forEach(function (interaction) {
16993
+ return interaction.setActive(true);
16994
+ });
16995
+ disabledDragPans = [];
16996
+ // Restore the default cursor when rotation stops
16997
+ var viewport = map.getViewport();
16998
+ if (viewport !== null && viewport !== void 0 && viewport.style) {
16999
+ viewport.style.cursor = '';
17000
+ }
17001
+ modify.setActive(true);
17002
+ translate.setActive(true);
17003
+ var featureToRotate = editFeatureCollection.item(0);
17004
+ if (featureToRotate) {
17005
+ updateFeature(featureToRotate);
17006
+ // Clear active handle so hover logic can take over again
17007
+ featureToRotate.unset('activeRotateHandleIndex', true);
17008
+ layer.changed();
17009
+ }
17010
+ };
16382
17011
  var abortOnEsc = function abortOnEsc(evt) {
16383
17012
  if (evt.key === 'Escape') {
16384
17013
  evt.preventDefault();
@@ -16390,7 +17019,7 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16390
17019
  }
16391
17020
  }
16392
17021
  };
16393
- var onlyAllowMoving = actualDrawMode === DRAWMODE.CIRCLE || actualDrawMode === DRAWMODE.OVAL || actualDrawMode === DRAWMODE.FREEHANDLINE || actualDrawMode === DRAWMODE.SQUARE;
17022
+ var onlyAllowMoving = actualDrawMode === DRAWMODE.CIRCLE || actualDrawMode === DRAWMODE.OVAL || actualDrawMode === DRAWMODE.FREEHANDLINE;
16394
17023
  if (selectedFeatureHasGeometry) {
16395
17024
  if (onlyAllowMoving) {
16396
17025
  interactions.push(translate); // Only allow moving
@@ -16403,6 +17032,16 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16403
17032
  interactions.push(new Snap({
16404
17033
  source: viewOnlySource
16405
17034
  }));
17035
+ if (isBoxOrSquare && selectedFeatureHasGeometry) {
17036
+ var viewport = map.getViewport();
17037
+ viewport.addEventListener('pointerdown', startRotateIfOnHandle);
17038
+ viewport.addEventListener('pointermove', rotateOnPointerMove);
17039
+ viewport.addEventListener('pointerup', endRotate);
17040
+ // Ensure the grabbing cursor appears immediately when pressing on a
17041
+ // resize corner, not only after the pointer starts moving.
17042
+ viewport.addEventListener('pointerdown', handlePointerDownNearCorner);
17043
+ viewport.addEventListener('pointerup', handlePointerUpAfterCorner);
17044
+ }
16406
17045
  window.addEventListener('keydown', abortOnEsc);
16407
17046
  interactions.forEach(function (i) {
16408
17047
  return map.addInteraction(i);
@@ -16417,14 +17056,28 @@ var OpenLayersMapDraw = function OpenLayersMapDraw(_ref) {
16417
17056
  map.removeLayer(layer);
16418
17057
  map.removeLayer(viewOnlyLayer);
16419
17058
  map.getViewport().removeEventListener('pointermove', trackPointerMove);
17059
+ if (isBoxOrSquare && selectedFeatureHasGeometry) {
17060
+ var _viewport = map.getViewport();
17061
+ _viewport.removeEventListener('pointerdown', startRotateIfOnHandle);
17062
+ _viewport.removeEventListener('pointermove', rotateOnPointerMove);
17063
+ _viewport.removeEventListener('pointerup', endRotate);
17064
+ _viewport.removeEventListener('pointerdown', handlePointerDownNearCorner);
17065
+ _viewport.removeEventListener('pointerup', handlePointerUpAfterCorner);
17066
+ }
16420
17067
  window.removeEventListener('keydown', deleteVertexOnDeleteKey);
17068
+ if (handleSingleClick) {
17069
+ map.un('singleclick', handleSingleClick);
17070
+ }
17071
+ if (onViewOnlyFeatureClick) {
17072
+ map.getViewport().style.cursor = '';
17073
+ }
16421
17074
  };
16422
- }, [map, isInEditMode, geojson, projection, viewOnlyStyle, selectedFeatureIndex, exitDrawModeCallback, updateGeojson, drawMode]);
17075
+ }, [map, isInEditMode, geojson, projection, viewOnlyStyle, selectedFeatureIndex, exitDrawModeCallback, updateGeojson, drawMode, onViewOnlyFeatureClick, onNoFeatureClick]);
16423
17076
  return null;
16424
17077
  };
16425
17078
 
16426
17079
  var defaultIntersectionStyleProperties = _objectSpread2(_objectSpread2({}, defaultGeoJSONStyleProperties), {}, {
16427
- 'fill-opacity': 0.5
17080
+ 'fill-opacity': 0.1
16428
17081
  });
16429
17082
  var emptyLineString = _objectSpread2(_objectSpread2({}, lineString), {}, {
16430
17083
  properties: defaultGeoJSONStyleProperties
@@ -18474,32 +19127,42 @@ var Clock = function Clock(_ref2) {
18474
19127
  var time = _ref2.time,
18475
19128
  _ref2$isVisible = _ref2.isVisible,
18476
19129
  isClockVisible = _ref2$isVisible === void 0 ? true : _ref2$isVisible,
18477
- onToggleClock = _ref2.onToggleClock;
18478
- var _useWebmapReactTransl = useWebmapReactTranslation(),
18479
- t = _useWebmapReactTransl.t;
18480
- var clockElement = useRef(null);
18481
- var _useState = useState({
19130
+ onToggleClock = _ref2.onToggleClock,
19131
+ _ref2$position = _ref2.position,
19132
+ position = _ref2$position === void 0 ? {
18482
19133
  x: 0,
18483
19134
  y: 0
18484
- }),
18485
- _useState2 = _slicedToArray(_useState, 2),
18486
- position = _useState2[0],
18487
- setPosition = _useState2[1];
18488
- useMakeSureContainerStaysInsideWindow(clockElement, position, setPosition);
18489
- var _useState3 = useState({
19135
+ } : _ref2$position,
19136
+ onSetPosition = _ref2.onSetPosition,
19137
+ _ref2$size = _ref2.size,
19138
+ size = _ref2$size === void 0 ? {
18490
19139
  width: MIN_WIDTH,
18491
19140
  height: MIN_HEIGHT
18492
- }),
19141
+ } : _ref2$size,
19142
+ onSetSize = _ref2.onSetSize;
19143
+ var _useWebmapReactTransl = useWebmapReactTranslation(),
19144
+ t = _useWebmapReactTransl.t;
19145
+ var clockElement = useRef(null);
19146
+ useMakeSureContainerStaysInsideWindow(clockElement, position, onSetPosition);
19147
+ var _useState = useState(FONT_SIZE_WIDTH_RATIO * size.width),
19148
+ _useState2 = _slicedToArray(_useState, 2),
19149
+ resizeFontSize = _useState2[0],
19150
+ setResizeFontSize = _useState2[1];
19151
+ var _useState3 = useState(false),
18493
19152
  _useState4 = _slicedToArray(_useState3, 2),
18494
- size = _useState4[0],
18495
- setSize = _useState4[1];
18496
- var _useState5 = useState(MIN_FONT_SIZE),
18497
- _useState6 = _slicedToArray(_useState5, 2),
18498
- fontSize = _useState6[0],
18499
- setFontSize = _useState6[1];
19153
+ isResizing = _useState4[0],
19154
+ setIsResizing = _useState4[1];
19155
+ // While resizing, use the local font size. Once you finish and the width has been updated, revert back to the size as determined from width
19156
+ var fontSize = isResizing ? resizeFontSize : FONT_SIZE_WIDTH_RATIO * size.width;
18500
19157
  var toggleClock = function toggleClock(isClockVisible) {
18501
19158
  onToggleClock === null || onToggleClock === void 0 || onToggleClock(isClockVisible);
18502
19159
  };
19160
+ var setPosition = function setPosition(position) {
19161
+ onSetPosition === null || onSetPosition === void 0 || onSetPosition(position);
19162
+ };
19163
+ var setSize = function setSize(size) {
19164
+ onSetSize === null || onSetSize === void 0 || onSetSize(size);
19165
+ };
18503
19166
  return jsx(Fragment, {
18504
19167
  children: !isClockVisible ? jsx(CustomIconButton, {
18505
19168
  "aria-label": t('clock-show'),
@@ -18520,7 +19183,10 @@ var Clock = function Clock(_ref2) {
18520
19183
  cancel: ".MuiButtonBase-root",
18521
19184
  nodeRef: clockElement,
18522
19185
  onStop: function onStop(_event, position) {
18523
- setPosition(position);
19186
+ setPosition({
19187
+ x: position.x,
19188
+ y: position.y
19189
+ });
18524
19190
  },
18525
19191
  position: position,
18526
19192
  children: jsx("div", {
@@ -18546,15 +19212,21 @@ var Clock = function Clock(_ref2) {
18546
19212
  lockAspectRatio: true,
18547
19213
  minHeight: MIN_HEIGHT,
18548
19214
  minWidth: MIN_WIDTH + BUTTON_WIDTH,
19215
+ nodeRef: clockElement,
18549
19216
  onResize: function onResize(_event, _direction, _ref, delta) {
18550
19217
  var width = size.width + delta.width;
18551
- var adjustedWidth = width - BUTTON_WIDTH;
18552
- var fontSize = FONT_SIZE_WIDTH_RATIO * adjustedWidth;
18553
- setFontSize(fontSize);
19218
+ var fontSize = FONT_SIZE_WIDTH_RATIO * width;
19219
+ setResizeFontSize(fontSize);
19220
+ },
19221
+ onResizeStart: function onResizeStart() {
19222
+ setIsResizing(true);
19223
+ setResizeFontSize(FONT_SIZE_WIDTH_RATIO * size.width);
18554
19224
  },
18555
19225
  onResizeStop: function onResizeStop(_event, _direction, _ref, delta) {
18556
19226
  var width = size.width + delta.width;
18557
19227
  var height = size.height + delta.height;
19228
+ setIsResizing(false);
19229
+ setResizeFontSize(FONT_SIZE_WIDTH_RATIO * width);
18558
19230
  setSize({
18559
19231
  width: width,
18560
19232
  height: height
@@ -18650,4 +19322,4 @@ var getLayerUpdateInfo = function getLayerUpdateInfo(wmLayer, mapId) {
18650
19322
  return updateObject;
18651
19323
  };
18652
19324
 
18653
- 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, 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 };
19325
+ 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, MIN_HEIGHT, MIN_WIDTH, 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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/webmap-react",
3
- "version": "15.0.0",
3
+ "version": "15.2.0",
4
4
  "description": "GeoWeb react wrapper for webmap",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,9 +8,9 @@
8
8
  "url": "git@gitlab.com:opengeoweb/opengeoweb.git"
9
9
  },
10
10
  "dependencies": {
11
- "@opengeoweb/webmap": "15.0.0",
12
- "@opengeoweb/theme": "15.0.0",
13
- "@opengeoweb/shared": "15.0.0",
11
+ "@opengeoweb/webmap": "15.2.0",
12
+ "@opengeoweb/theme": "15.2.0",
13
+ "@opengeoweb/shared": "15.2.0",
14
14
  "lodash": "^4.17.21",
15
15
  "ol": "^10.4.0",
16
16
  "proj4": "^2.9.2",
@@ -1,6 +1,20 @@
1
1
  import type { FC } from 'react';
2
+ export declare const MIN_WIDTH = 170;
3
+ export declare const MIN_HEIGHT = 32;
4
+ export interface Position {
5
+ x: number;
6
+ y: number;
7
+ }
8
+ export interface Size {
9
+ width: number;
10
+ height: number;
11
+ }
2
12
  export declare const Clock: FC<{
3
13
  time: number;
4
14
  isVisible?: boolean;
5
15
  onToggleClock?: (isVisible: boolean) => void;
16
+ position?: Position | undefined;
17
+ onSetPosition: (position: Position) => void;
18
+ size?: Size | undefined;
19
+ onSetSize: (size: Size) => void;
6
20
  }>;
@@ -11,5 +11,6 @@ export interface LayerInfoDialogProps {
11
11
  source?: Source;
12
12
  dialogHeight?: number;
13
13
  startPosition?: Position;
14
+ selectedStyle?: string;
14
15
  }
15
16
  export declare const LayerInfoDialog: React.FC<LayerInfoDialogProps>;
@@ -3,6 +3,6 @@ export interface LayerInfoLegendProps {
3
3
  title: string;
4
4
  name: string;
5
5
  dimensions: Dimension[];
6
- legendURL: string;
6
+ legendURL?: string;
7
7
  }
8
8
  export declare const LayerInfoLegend: React.FC<LayerInfoLegendProps>;
@@ -43,7 +43,8 @@ export declare const geowebColorToOpenLayersColor: (color: string, opacity?: str
43
43
  export declare const inlineFeatureStyle: (feature: FeatureLike) => Style[];
44
44
  export declare const genericOpenLayersFeatureStyle: StyleFunction;
45
45
  export declare const catmullRomSpline: (points: LineCoordType, numPoints?: number) => Coordinate[];
46
- export declare const createBoxBasedOnModifiedVertex: (modifiedGeometry: Polygon, originalGeometry: Polygon) => Polygon;
46
+ export declare const createBoxBasedOnModifiedVertex: (modifiedGeometry: Polygon, originalGeometry: Polygon, keepSquare?: boolean) => Polygon;
47
+ export declare const getBoxRotateHandlePoints: (feature: FeatureLike, resolution?: number) => Coordinate[] | undefined;
47
48
  export declare const createOval: () => GeometryFunction;
48
49
  export declare const drawStyles: Record<DrawModeValue, StyleLike>;
49
50
  export declare const modifyStyles: Record<DrawModeValue, Style[] | StyleLike>;
@@ -1,3 +1,5 @@
1
+ import type { Feature } from 'ol';
2
+ import type { Geometry } from 'ol/geom';
1
3
  import type { StyleLike } from 'ol/style/Style';
2
4
  import React from 'react';
3
5
  import type { DrawModeExitCallback, DrawModeValue } from './types';
@@ -9,6 +11,8 @@ export interface OpenLayersMapDrawProps {
9
11
  isInEditMode: boolean;
10
12
  selectedFeatureIndex: number;
11
13
  updateGeojson?: (geoJson: GeoJSON.FeatureCollection, text: string) => void;
14
+ onViewOnlyFeatureClick?: (feature: Feature<Geometry>[]) => void;
15
+ onNoFeatureClick?: () => void;
12
16
  }
13
17
  /**
14
18
  * Integrates with OpenLayers Draw and Modify (+Snap) interactions, to implement feature drawing
@@ -0,0 +1,2 @@
1
+ export * from './api';
2
+ export * from './hooks';
@@ -4,4 +4,5 @@ export * from './hooks';
4
4
  export * from './utils';
5
5
  export type * from './types';
6
6
  export * from './edr-layer-api';
7
+ export * from './geotiff-layer-api';
7
8
  export { WEBMAP_REACT_NAMESPACE } from './utils/i18n';