@opengeoweb/warnings 19.6.1-nightly-20260917 → 20.0.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/dist/index.esm.js CHANGED
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useDispatch, useSelector, useStore, shallowEqual } from 'react-redux';
3
3
  import { uiTypes, uiActions, getSingularDrawtoolDrawLayerId, drawingToolSelectors, layerSelectors, uiSelectors, layerActions, drawingToolActions, layerUtils, mapListener, layersListener, drawingToolListener, syncGroupsListener, openlayersListener, syncGroupsReducer, drawingToolReducer, uiReducer, layerReducer, mapReducer, useSetupDialog, PUBLIC_WARNING_DRAW_TOOL_ID, genericSelectors, useUpdateFeatureSyncLayers, genericActions, selectorMemoizationOptions, useRegisterFeatureSyncSource, syncGroupsSelector } from '@opengeoweb/store';
4
4
  import { Polygons, Edit, Delete, ExitDomain, ChevronDown, DrawPolygon, Remove, Options, Waterspouts, Snow, FreezingRain, CoastalEvent, TemperatureLow, TemperatureHigh, Rain, Lightning, Fog, Wind, Thunderstorm, SevereMountainWaves, VulcanicEruption, Haze, FreezingPrecipitation, ModerateAircraftIcing, SevereAircraftIcing, ModerateTurbulence, SevereTurbulence, SandStorm, RadioactiveMaterials, DrawMask, Visibility, Add, breakpoints, DragHandle, Info, ArrowUpCompact, ArrowDownCompact, CalendarToday, Expire, Cube, AlertBadge, ArrowDropDownDown, Extend24h, Copy, Update, Cancel, Success, VisibilityOff, ChevronUp, Close, Clock } from '@opengeoweb/theme';
5
- import { WEBMAP_REACT_NAMESPACE, defaultPolygon, emptyGeoJSON, MapControlButton, isGeoJSONGeometryEmpty, rewindGeometry, removeTransientFeatureProperties, defaultSmoothLine, defaultLineString, defaultFreehandLine, defaultOval, defaultCircle, defaultRotatableBox, defaultSquare, defaultLocation, defaultPoint, defaultSplit, defaultDelete, getDrawModeIdFromSelectionType, getIcon, getGeoJSONPropertyValue, DRAWMODE, currentlySupportedDrawModes, defaultLayers, viewUtils, OpenLayersMapView, MapControls, OpenLayersZoomControl, OpenLayersLayer, OpenLayersFeatureLayer, genericOpenLayersFeatureStyle, DEFAULT_GEOJSON_STYLE_FILL_OPACITY, FEATURE_DRAW_FILL_COLOR, FEATURE_DRAW_SECONDARY_FILL_COLOR, FEATURE_DRAW_STROKE_COLOR } from '@opengeoweb/webmap-react';
5
+ import { WEBMAP_REACT_NAMESPACE, defaultPolygon, emptyGeoJSON, MapControlButton, isGeoJSONGeometryEmpty, rewindGeometry, removeTransientFeatureProperties, defaultSmoothLine, defaultLineString, defaultFreehandLine, defaultOval, defaultCircle, defaultRotatableBox, defaultSquare, defaultLocation, defaultPoint, defaultSplit, defaultDelete, getDrawModeIdFromSelectionType, getIcon, getGeoJSONPropertyValue, FEATURE_DRAW_SECONDARY_STROKE_COLOR, DRAWMODE, currentlySupportedDrawModes, defaultLayers, viewUtils, OpenLayersMapView, MapControls, OpenLayersZoomControl, OpenLayersLayer, OpenLayersFeatureLayer, genericOpenLayersFeatureStyle, DEFAULT_GEOJSON_STYLE_FILL_OPACITY, FEATURE_DRAW_FILL_COLOR, FEATURE_DRAW_SECONDARY_FILL_COLOR, FEATURE_DRAW_STROKE_COLOR } from '@opengeoweb/webmap-react';
6
6
  import { SHARED_NAMESPACE, useConfirmationDialog, dateUtils, sessionStorageProvider, ToggleMenu, calculateStartSize, ToolContainerDraggable, AlertBanner, ConfirmationDialog, CustomIconButton, usePrevious, usePreventBrowserClose, CustomTooltip, Avatar, getInitials, SwitchButton, Filter, CustomToggleButton, FilterChip, TooltipSelect, LastUpdateTime, DateTimePicker, StatusTag, FilterOption, getAxiosErrorMessage, CustomDialog, ConfirmationButtons, ErrorBoundary } from '@opengeoweb/shared';
7
7
  import { createEntityAdapter, createSlice, createSelector, createListenerMiddleware, combineReducers, configureStore } from '@reduxjs/toolkit';
8
8
  import { t } from 'i18next';
@@ -18,12 +18,12 @@ import { List, useListRef } from 'react-window';
18
18
  import { useQueryClient, useMutation, queryOptions, QueryClient, useQuery } from '@tanstack/react-query';
19
19
  import { getHeaders, handleResponse, AirmetPhenomena, SigmetPhenomena, useAuthQuery, useAuthenticationContext, optimisticUpdate, ProductStatus, LevelUnits } from '@opengeoweb/api';
20
20
  import { snackbarListener, snackbarReducer, snackbarActions, snackbarTypes } from '@opengeoweb/snackbar';
21
- import { isEqual, cloneDeep, clamp, concat, groupBy, pick } from 'lodash';
21
+ import { isEqual, cloneDeep, clamp, omit, concat, groupBy, pick } from 'lodash';
22
22
  import { useFormContext, useFieldArray, useForm, FormProvider, useWatch } from 'react-hook-form';
23
- import { isEmpty, createEmpty, extend } from 'ol/extent';
23
+ import { bbox, intersect, featureCollection, union, bboxClip, polygonToLine, lineSplit, along, length, booleanPointInPolygon, area } from '@turf/turf';
24
+ import { intersects, buffer, getWidth, getHeight, isEmpty, createEmpty, extend } from 'ol/extent';
24
25
  import GeoJSON from 'ol/format/GeoJSON';
25
26
  import { ReactSortable } from 'react-sortablejs';
26
- import { intersect, area } from '@turf/turf';
27
27
  import Box$1 from '@mui/material/Box';
28
28
  import Tooltip$1 from '@mui/material/Tooltip';
29
29
  import { useTheme as useTheme$1 } from '@mui/material/styles';
@@ -418,6 +418,9 @@ var en = {
418
418
  "drawing-tool-form-masks-clear": "Clear",
419
419
  "drawing-tool-form-masks-tooltip": "Select a mask to clip your drawing",
420
420
  "drawing-tool-form-masks-empty": "No masks available. Please contact your administrator.",
421
+ "drawing-tool-form-mask-no-overlap": "The drawing does not overlap with the selected mask",
422
+ "drawing-tool-form-mask-clip-error": "The drawing could not be clipped with the selected mask",
423
+ "drawing-tool-form-mask-saved": "Saved mask",
421
424
  "warning-event-button-add-drawing": "Add a drawing to this event, then choose individual objects for each warning",
422
425
  "warning-event-button-assign-object": "Assign an object from the chosen drawing to this warning",
423
426
  "warning-event-objects-menu-title": "Objects",
@@ -767,6 +770,9 @@ var nl = {
767
770
  "drawing-tool-form-masks-clear": "Wissen",
768
771
  "drawing-tool-form-masks-tooltip": "Selecteer een masker om je tekening bij te snijden",
769
772
  "drawing-tool-form-masks-empty": "Geen maskers beschikbaar. Neem contact op met je beheerder.",
773
+ "drawing-tool-form-mask-no-overlap": "De tekening overlapt niet met het geselecteerde masker",
774
+ "drawing-tool-form-mask-clip-error": "De tekening kon niet worden bijgesneden met het geselecteerde masker",
775
+ "drawing-tool-form-mask-saved": "Opgeslagen masker",
770
776
  "warning-event-button-add-drawing": "Voeg een tekening toe aan dit event. Wijs daarna individuele objecten toe aan elke waarschuwing",
771
777
  "warning-event-button-assign-object": "Wijs een object uit de gekozen tekening toe aan deze waarschuwing",
772
778
  "warning-event-objects-menu-title": "Objecten",
@@ -1068,6 +1074,9 @@ var fi = {
1068
1074
  "drawing-tool-form-masks-clear": "ei käännetty",
1069
1075
  "drawing-tool-form-masks-tooltip": "ei käännetty",
1070
1076
  "drawing-tool-form-masks-empty": "ei käännetty",
1077
+ "drawing-tool-form-mask-no-overlap": "ei käännetty",
1078
+ "drawing-tool-form-mask-clip-error": "ei käännetty",
1079
+ "drawing-tool-form-mask-saved": "ei käännetty",
1071
1080
  "warning-event-button-add-drawing": "ei käännetty",
1072
1081
  "warning-event-button-assign-object": "ei käännetty",
1073
1082
  "warning-event-objects-menu-title": "ei käännetty",
@@ -1367,6 +1376,9 @@ var no = {
1367
1376
  "drawing-tool-form-masks-clear": "ikke oversatt",
1368
1377
  "drawing-tool-form-masks-tooltip": "ikke oversatt",
1369
1378
  "drawing-tool-form-masks-empty": "ikke oversatt",
1379
+ "drawing-tool-form-mask-no-overlap": "ikke oversatt",
1380
+ "drawing-tool-form-mask-clip-error": "ikke oversatt",
1381
+ "drawing-tool-form-mask-saved": "ikke oversatt",
1370
1382
  "warning-event-button-add-drawing": "ikke oversatt",
1371
1383
  "warning-event-button-assign-object": "ikke oversatt",
1372
1384
  "warning-event-objects-menu-title": "Objekter",
@@ -1595,6 +1607,20 @@ function _regeneratorDefine(e, r, n, t) {
1595
1607
  }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2));
1596
1608
  }, _regeneratorDefine(e, r, n, t);
1597
1609
  }
1610
+ function _toPrimitive(t, r) {
1611
+ if ("object" != typeof t || !t) return t;
1612
+ var e = t[Symbol.toPrimitive];
1613
+ if (void 0 !== e) {
1614
+ var i = e.call(t, r);
1615
+ if ("object" != typeof i) return i;
1616
+ throw new TypeError("@@toPrimitive must return a primitive value.");
1617
+ }
1618
+ return (String )(t);
1619
+ }
1620
+ function _toPropertyKey(t) {
1621
+ var i = _toPrimitive(t, "string");
1622
+ return "symbol" == typeof i ? i : i + "";
1623
+ }
1598
1624
  function _unsupportedIterableToArray(r, a) {
1599
1625
  if (r) {
1600
1626
  if ("string" == typeof r) return _arrayLikeToArray(r, a);
@@ -5724,6 +5750,7 @@ var AreaDrawingManagerConnect = function AreaDrawingManagerConnect(_ref2) {
5724
5750
  setSelectedDrawingId(drawingId);
5725
5751
  };
5726
5752
  useEffect(function () {
5753
+ var _drawingDetails$trans, _drawingDetails$trans2;
5727
5754
  if (!selectedDrawingId || !drawingDetails || (drawingDetails == null ? void 0 : drawingDetails.id) !== selectedDrawingId || isFetchingDetails) {
5728
5755
  return;
5729
5756
  }
@@ -5732,7 +5759,7 @@ var AreaDrawingManagerConnect = function AreaDrawingManagerConnect(_ref2) {
5732
5759
  id: selectedDrawingId,
5733
5760
  drawingInstanceId: drawingDialogType
5734
5761
  }));
5735
- openDrawDialog(drawingDetails.geoJSON);
5762
+ openDrawDialog((_drawingDetails$trans = (_drawingDetails$trans2 = drawingDetails.transformation) == null ? void 0 : _drawingDetails$trans2.original) != null ? _drawingDetails$trans : drawingDetails.geoJSON);
5736
5763
  setSelectedDrawingId(undefined);
5737
5764
  // eslint-disable-next-line react-hooks/exhaustive-deps
5738
5765
  }, [selectedDrawingId, drawingDetails, dispatch, isFetchingDetails]);
@@ -6320,6 +6347,7 @@ var DrawingToolFormContentsNoMemo = function DrawingToolFormContentsNoMemo(_ref)
6320
6347
  geoJSONProperties = _ref.geoJSONProperties,
6321
6348
  masks = _ref.masks,
6322
6349
  isLoadingMasks = _ref.isLoadingMasks,
6350
+ maskError = _ref.maskError,
6323
6351
  selectedMaskId = _ref.selectedMaskId,
6324
6352
  onSelectMask = _ref.onSelectMask,
6325
6353
  onHoverMask = _ref.onHoverMask;
@@ -6437,19 +6465,28 @@ var DrawingToolFormContentsNoMemo = function DrawingToolFormContentsNoMemo(_ref)
6437
6465
  }
6438
6466
  }
6439
6467
  })]
6440
- }), jsx(Grid, {
6468
+ }), jsxs(Grid, {
6441
6469
  container: true,
6442
6470
  sx: {
6443
6471
  marginBottom: 1
6444
6472
  },
6445
- children: jsx(DrawingToolFormMasks, {
6473
+ children: [jsx(DrawingToolFormMasks, {
6446
6474
  isDisabled: isLoading,
6447
6475
  isLoadingMasks: isLoadingMasks,
6448
6476
  masks: masks,
6449
6477
  onHoverMask: onHoverMask,
6450
6478
  onSelectMask: onSelectMask,
6451
6479
  selectedMaskId: selectedMaskId
6452
- })
6480
+ }), maskError ? jsx(FormHelperText, {
6481
+ "data-testid": "drawingToolForm-masks-error",
6482
+ error: true,
6483
+ sx: {
6484
+ marginLeft: 0,
6485
+ width: '100%'
6486
+ },
6487
+ variant: "filled",
6488
+ children: t(maskError)
6489
+ }) : null]
6453
6490
  }), jsx(Grid, {
6454
6491
  container: true,
6455
6492
  size: "grow",
@@ -6598,7 +6635,7 @@ var DrawingToolFormContentsNoMemo = function DrawingToolFormContentsNoMemo(_ref)
6598
6635
  },
6599
6636
  children: jsx(Button, {
6600
6637
  "data-testid": "saveDrawingFormButton",
6601
- disabled: isLoading || hasErrors,
6638
+ disabled: isLoading || hasErrors || !!maskError,
6602
6639
  onClick: onSubmit,
6603
6640
  sx: {
6604
6641
  width: '100%',
@@ -6696,6 +6733,7 @@ var DrawingToolForm = function DrawingToolForm(_ref) {
6696
6733
  masks = _ref$masks === void 0 ? emptyMasks$1 : _ref$masks,
6697
6734
  _ref$isLoadingMasks = _ref.isLoadingMasks,
6698
6735
  isLoadingMasks = _ref$isLoadingMasks === void 0 ? false : _ref$isLoadingMasks,
6736
+ maskError = _ref.maskError,
6699
6737
  selectedMaskId = _ref.selectedMaskId,
6700
6738
  _ref$onSelectMask = _ref.onSelectMask,
6701
6739
  onSelectMask = _ref$onSelectMask === void 0 ? noopSelectMask : _ref$onSelectMask,
@@ -6830,6 +6868,7 @@ var DrawingToolForm = function DrawingToolForm(_ref) {
6830
6868
  isInEditMode: isInEditMode,
6831
6869
  isLoading: isLoading,
6832
6870
  isLoadingMasks: isLoadingMasks,
6871
+ maskError: maskError,
6833
6872
  masks: masks,
6834
6873
  onBlurName: onBlurName,
6835
6874
  onBlurObjectName: onBlurObjectName,
@@ -6865,6 +6904,265 @@ var Wrapper = function Wrapper(props) {
6865
6904
  });
6866
6905
  };
6867
6906
 
6907
+ var CLIPPED_RESULT_FILL_OPACITY = 0.4;
6908
+ var MASKED_FILL_OPACITY_KEY = 'maskedFillOpacity';
6909
+ var getDrawnFeatureIndexes = function getDrawnFeatureIndexes(geoJSON) {
6910
+ return geoJSON.features.reduce(function (indexes, feature, index) {
6911
+ return isGeoJSONGeometryEmpty(feature) ? indexes : [].concat(indexes, [index]);
6912
+ }, []);
6913
+ };
6914
+ var getFeatureIndexesToHideFill = function getFeatureIndexesToHideFill(geoJSON) {
6915
+ return getDrawnFeatureIndexes(geoJSON).filter(function (index) {
6916
+ var _geoJSON$features$ind;
6917
+ return ((_geoJSON$features$ind = geoJSON.features[index].properties) == null ? void 0 : _geoJSON$features$ind['fill-opacity']) !== 0;
6918
+ });
6919
+ };
6920
+ var getFeatureIndexesToRestoreFill = function getFeatureIndexesToRestoreFill(geoJSON) {
6921
+ return geoJSON.features.reduce(function (indexes, feature, index) {
6922
+ var _feature$properties;
6923
+ return ((_feature$properties = feature.properties) == null ? void 0 : _feature$properties[MASKED_FILL_OPACITY_KEY]) !== undefined ? [].concat(indexes, [index]) : indexes;
6924
+ }, []);
6925
+ };
6926
+ var restoreMaskedFillProperties = function restoreMaskedFillProperties(properties) {
6927
+ if ((properties == null ? void 0 : properties[MASKED_FILL_OPACITY_KEY]) === undefined) {
6928
+ return properties;
6929
+ }
6930
+ var fillOpacity = properties[MASKED_FILL_OPACITY_KEY],
6931
+ restProperties = _objectWithoutPropertiesLoose(properties, [MASKED_FILL_OPACITY_KEY].map(_toPropertyKey));
6932
+ return fillOpacity === null ? omit(restProperties, 'fill-opacity') : Object.assign({}, restProperties, {
6933
+ 'fill-opacity': fillOpacity
6934
+ });
6935
+ };
6936
+ var restoreMaskedFill = function restoreMaskedFill(geoJSON) {
6937
+ return Object.assign({}, geoJSON, {
6938
+ features: geoJSON.features.map(function (feature) {
6939
+ return Object.assign({}, feature, {
6940
+ properties: restoreMaskedFillProperties(feature.properties)
6941
+ });
6942
+ })
6943
+ });
6944
+ };
6945
+ var maskPolygonCache = new WeakMap();
6946
+ var maskPartsCache = new WeakMap();
6947
+ var clippedGeometryCache = new WeakMap();
6948
+ var isPolygonFeature = function isPolygonFeature(feature) {
6949
+ var _feature$geometry, _feature$geometry2;
6950
+ return ((_feature$geometry = feature.geometry) == null ? void 0 : _feature$geometry.type) === 'Polygon' || ((_feature$geometry2 = feature.geometry) == null ? void 0 : _feature$geometry2.type) === 'MultiPolygon';
6951
+ };
6952
+ var getMaskPolygon = function getMaskPolygon(mask) {
6953
+ var _polygons$;
6954
+ var cachedMaskPolygon = maskPolygonCache.get(mask);
6955
+ if (cachedMaskPolygon !== undefined) {
6956
+ return cachedMaskPolygon;
6957
+ }
6958
+ var polygons = mask.features.filter(isPolygonFeature);
6959
+ var maskPolygon = polygons.length > 1 ? union(featureCollection(polygons)) : (_polygons$ = polygons[0]) != null ? _polygons$ : null;
6960
+ maskPolygonCache.set(mask, maskPolygon);
6961
+ return maskPolygon;
6962
+ };
6963
+ var getMaskParts = function getMaskParts(mask) {
6964
+ var cachedMaskParts = maskPartsCache.get(mask);
6965
+ if (cachedMaskParts) {
6966
+ return cachedMaskParts;
6967
+ }
6968
+ var maskParts = mask.features.filter(isPolygonFeature).map(function (polygon) {
6969
+ return {
6970
+ polygon: polygon,
6971
+ bbox: bbox(polygon)
6972
+ };
6973
+ });
6974
+ maskPartsCache.set(mask, maskParts);
6975
+ return maskParts;
6976
+ };
6977
+ var padBBox = function padBBox(geometryBBox) {
6978
+ return buffer(geometryBBox, Math.max(getWidth(geometryBBox), getHeight(geometryBBox)) * 0.01 + 1e-6);
6979
+ };
6980
+ var removeEmptyRings = function removeEmptyRings(polygon) {
6981
+ var isRing = function isRing(ring) {
6982
+ return ring.length > 3;
6983
+ };
6984
+ if (polygon.geometry.type === 'Polygon') {
6985
+ return Object.assign({}, polygon, {
6986
+ geometry: Object.assign({}, polygon.geometry, {
6987
+ coordinates: polygon.geometry.coordinates.filter(isRing)
6988
+ })
6989
+ });
6990
+ }
6991
+ return Object.assign({}, polygon, {
6992
+ geometry: Object.assign({}, polygon.geometry, {
6993
+ coordinates: polygon.geometry.coordinates.map(function (rings) {
6994
+ return rings.filter(isRing);
6995
+ }).filter(function (rings) {
6996
+ return rings.length > 0;
6997
+ })
6998
+ })
6999
+ });
7000
+ };
7001
+ var getMaskPolygonInBBox = function getMaskPolygonInBBox(maskPolygon, maskBBox, geometryBBox) {
7002
+ if (!intersects(maskBBox, geometryBBox)) {
7003
+ return null;
7004
+ }
7005
+ var clippedMask = removeEmptyRings(bboxClip(maskPolygon, padBBox(geometryBBox)));
7006
+ return clippedMask.geometry.coordinates.length ? clippedMask : null;
7007
+ };
7008
+ var isPointInMask = function isPointInMask(position, maskPolygon) {
7009
+ return booleanPointInPolygon(position, maskPolygon);
7010
+ };
7011
+ var clipLine = function clipLine(coordinates, maskPolygon, splitterPolygon) {
7012
+ var line = {
7013
+ type: 'Feature',
7014
+ properties: {},
7015
+ geometry: {
7016
+ type: 'LineString',
7017
+ coordinates: coordinates
7018
+ }
7019
+ };
7020
+ var outline = polygonToLine(splitterPolygon);
7021
+ var outlines = outline.type === 'FeatureCollection' ? outline.features : [outline];
7022
+ var segments = outlines.reduce(function (currentSegments, splitter) {
7023
+ return currentSegments.flatMap(function (segment) {
7024
+ var split = lineSplit(segment, splitter);
7025
+ return split.features.length ? split.features : [segment];
7026
+ });
7027
+ }, [line]);
7028
+ return segments.filter(function (segment) {
7029
+ var midpoint = along(segment, length(segment) / 2);
7030
+ return isPointInMask(midpoint.geometry.coordinates, maskPolygon);
7031
+ }).map(function (segment) {
7032
+ return segment.geometry.coordinates;
7033
+ });
7034
+ };
7035
+ var isPointInAnyMaskPart = function isPointInAnyMaskPart(position, mask) {
7036
+ return getMaskParts(mask).some(function (part) {
7037
+ return isPointInMask(position, part.polygon);
7038
+ });
7039
+ };
7040
+ var clipGeometry = function clipGeometry(geometry, mask) {
7041
+ switch (geometry.type) {
7042
+ case 'Polygon':
7043
+ case 'MultiPolygon':
7044
+ {
7045
+ var _union$geometry, _union;
7046
+ var geometryBBox = bbox(geometry);
7047
+ var feature = {
7048
+ type: 'Feature',
7049
+ properties: {},
7050
+ geometry: geometry
7051
+ };
7052
+ var clippedParts = getMaskParts(mask).reduce(function (result, part) {
7053
+ var maskInBBox = getMaskPolygonInBBox(part.polygon, part.bbox, geometryBBox);
7054
+ var clippedPart = maskInBBox && intersect(featureCollection([feature, maskInBBox]));
7055
+ return clippedPart ? [].concat(result, [clippedPart]) : result;
7056
+ }, []);
7057
+ if (clippedParts.length <= 1) {
7058
+ var _clippedParts$0$geome, _clippedParts$;
7059
+ return (_clippedParts$0$geome = (_clippedParts$ = clippedParts[0]) == null ? void 0 : _clippedParts$.geometry) != null ? _clippedParts$0$geome : null;
7060
+ }
7061
+ return (_union$geometry = (_union = union(featureCollection(clippedParts))) == null ? void 0 : _union.geometry) != null ? _union$geometry : null;
7062
+ }
7063
+ case 'LineString':
7064
+ case 'MultiLineString':
7065
+ {
7066
+ var maskPolygon = getMaskPolygon(mask);
7067
+ var maskInBBox = maskPolygon && getMaskPolygonInBBox(maskPolygon, bbox(maskPolygon), bbox(geometry));
7068
+ if (!maskPolygon || !maskInBBox) {
7069
+ return null;
7070
+ }
7071
+ var lines = geometry.type === 'LineString' ? [geometry.coordinates] : geometry.coordinates;
7072
+ var clipped = lines.flatMap(function (line) {
7073
+ return clipLine(line, maskPolygon, maskInBBox);
7074
+ });
7075
+ if (clipped.length === 0) {
7076
+ return null;
7077
+ }
7078
+ return clipped.length === 1 ? {
7079
+ type: 'LineString',
7080
+ coordinates: clipped[0]
7081
+ } : {
7082
+ type: 'MultiLineString',
7083
+ coordinates: clipped
7084
+ };
7085
+ }
7086
+ case 'Point':
7087
+ return isPointInAnyMaskPart(geometry.coordinates, mask) ? geometry : null;
7088
+ case 'MultiPoint':
7089
+ {
7090
+ var points = geometry.coordinates.filter(function (point) {
7091
+ return isPointInAnyMaskPart(point, mask);
7092
+ });
7093
+ return points.length ? {
7094
+ type: 'MultiPoint',
7095
+ coordinates: points
7096
+ } : null;
7097
+ }
7098
+ default:
7099
+ return geometry;
7100
+ }
7101
+ };
7102
+ var getClippedGeometry = function getClippedGeometry(geometry, mask) {
7103
+ var _clippedGeometryCache;
7104
+ var cachedByMask = (_clippedGeometryCache = clippedGeometryCache.get(geometry)) != null ? _clippedGeometryCache : new WeakMap();
7105
+ if (cachedByMask.has(mask)) {
7106
+ return cachedByMask.get(mask);
7107
+ }
7108
+ var clippedGeometry = clipGeometry(geometry, mask);
7109
+ cachedByMask.set(mask, clippedGeometry);
7110
+ clippedGeometryCache.set(geometry, cachedByMask);
7111
+ return clippedGeometry;
7112
+ };
7113
+ var clipGeoJSONWithMask = function clipGeoJSONWithMask(geoJSON, mask) {
7114
+ if (getMaskParts(mask).length === 0) {
7115
+ return Object.assign({}, geoJSON, {
7116
+ features: []
7117
+ });
7118
+ }
7119
+ var features = geoJSON.features.reduce(function (result, feature) {
7120
+ if (!feature.geometry || isGeoJSONGeometryEmpty(feature)) {
7121
+ return result;
7122
+ }
7123
+ var geometry = getClippedGeometry(feature.geometry, mask);
7124
+ return geometry ? [].concat(result, [Object.assign({}, feature, {
7125
+ geometry: geometry
7126
+ })]) : result;
7127
+ }, []);
7128
+ return Object.assign({}, geoJSON, {
7129
+ features: features
7130
+ });
7131
+ };
7132
+ var findMaskForTransformation = function findMaskForTransformation(masks, transformation) {
7133
+ if (!transformation) {
7134
+ return undefined;
7135
+ }
7136
+ var getGeometries = function getGeometries(geoJSON) {
7137
+ return geoJSON.features.map(function (feature) {
7138
+ return feature.geometry;
7139
+ });
7140
+ };
7141
+ var transformationGeometries = getGeometries(transformation.mask);
7142
+ return masks.find(function (mask) {
7143
+ return isEqual(getGeometries(mask.geoJSON), transformationGeometries);
7144
+ });
7145
+ };
7146
+ var buildClippedHighlightGeoJSON = function buildClippedHighlightGeoJSON(clipped) {
7147
+ return Object.assign({}, clipped, {
7148
+ features: clipped.features.map(function (feature, index) {
7149
+ var _feature$id;
7150
+ return Object.assign({}, feature, {
7151
+ id: "mask-result-" + ((_feature$id = feature.id) != null ? _feature$id : index),
7152
+ properties: Object.assign({}, feature.properties, {
7153
+ isReadonly: true,
7154
+ mapFeatureClass: 'default',
7155
+ isSelected: false,
7156
+ fill: '#186DFF',
7157
+ 'fill-opacity': CLIPPED_RESULT_FILL_OPACITY,
7158
+ 'stroke-width': 0,
7159
+ 'stroke-opacity': 0
7160
+ })
7161
+ });
7162
+ })
7163
+ });
7164
+ };
7165
+
6868
7166
  /* *
6869
7167
  * Licensed under the Apache License, Version 2.0 (the "License");
6870
7168
  * you may not use this file except in compliance with the License.
@@ -6882,10 +7180,13 @@ var Wrapper = function Wrapper(props) {
6882
7180
  * Copyright 2026 - Finnish Meteorological Institute (FMI)
6883
7181
  * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
6884
7182
  * */
6885
- var MASK_PREVIEW_FILL_OPACITY = 0.1;
7183
+ var MASK_PREVIEW_FILL_OPACITY = 0;
6886
7184
  var getMaskPreviewLayerId = function getMaskPreviewLayerId(mapId) {
6887
7185
  return "drawing-mask-preview-" + mapId;
6888
7186
  };
7187
+ var getClippedResultLayerId = function getClippedResultLayerId(mapId) {
7188
+ return "drawing-mask-result-" + mapId;
7189
+ };
6889
7190
  var buildMaskPreviewGeoJSON = function buildMaskPreviewGeoJSON(mask) {
6890
7191
  return Object.assign({}, mask.geoJSON, {
6891
7192
  features: mask.geoJSON.features.map(function (feature, index) {
@@ -6896,21 +7197,19 @@ var buildMaskPreviewGeoJSON = function buildMaskPreviewGeoJSON(mask) {
6896
7197
  isReadonly: true,
6897
7198
  mapFeatureClass: 'default',
6898
7199
  isSelected: false,
6899
- fill: '#186DFF',
7200
+ // TODO https://gitlab.com/opengeoweb/opengeoweb/-/work_items/7413: remove this property and make the hover effect based on selectionType
7201
+ selectionType: 'fir',
7202
+ fill: FEATURE_DRAW_SECONDARY_STROKE_COLOR,
6900
7203
  'fill-opacity': MASK_PREVIEW_FILL_OPACITY,
6901
- stroke: '#006CFD',
6902
- 'stroke-width': 2
7204
+ 'stroke-width': 3,
7205
+ stroke: '#F59E0B'
6903
7206
  })
6904
7207
  });
6905
7208
  })
6906
7209
  });
6907
7210
  };
6908
- var useMaskPreviewLayer = function useMaskPreviewLayer(mapId, mask) {
7211
+ var useReadonlyFeatureLayer = function useReadonlyFeatureLayer(mapId, layerId, geojson) {
6909
7212
  var dispatch = useDispatch();
6910
- var layerId = getMaskPreviewLayerId(mapId);
6911
- var geojson = React.useMemo(function () {
6912
- return mask ? buildMaskPreviewGeoJSON(mask) : emptyGeoJSON;
6913
- }, [mask]);
6914
7213
  React.useEffect(function () {
6915
7214
  if (!mapId) {
6916
7215
  return undefined;
@@ -6943,6 +7242,18 @@ var useMaskPreviewLayer = function useMaskPreviewLayer(mapId, mask) {
6943
7242
  }
6944
7243
  }, [dispatch, geojson, layerId, mapId]);
6945
7244
  };
7245
+ var useMaskPreviewLayer = function useMaskPreviewLayer(mapId, mask) {
7246
+ var geojson = React.useMemo(function () {
7247
+ return mask ? buildMaskPreviewGeoJSON(mask) : emptyGeoJSON;
7248
+ }, [mask]);
7249
+ useReadonlyFeatureLayer(mapId, getMaskPreviewLayerId(mapId), geojson);
7250
+ };
7251
+ var useClippedResultLayer = function useClippedResultLayer(mapId, clippedGeoJSON) {
7252
+ var geojson = React.useMemo(function () {
7253
+ return clippedGeoJSON ? buildClippedHighlightGeoJSON(clippedGeoJSON) : emptyGeoJSON;
7254
+ }, [clippedGeoJSON]);
7255
+ useReadonlyFeatureLayer(mapId, getClippedResultLayerId(mapId), geojson);
7256
+ };
6946
7257
 
6947
7258
  /* *
6948
7259
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -7018,27 +7329,129 @@ var useSelectDrawFeature = function useSelectDrawFeature(layerId) {
7018
7329
  };
7019
7330
 
7020
7331
  var emptyMasks = [];
7021
- var useDrawingToolMasks = function useDrawingToolMasks() {
7332
+ var SAVED_MASK_ID = 'saved-mask';
7333
+ var useRestoreSavedMask = function useRestoreSavedMask(drawingId, masks, isLoadingMasks, onRestoreMask) {
7334
+ var _useWarningsTranslati = useWarningsTranslation(),
7335
+ t = _useWarningsTranslati.t;
7336
+ var _useDrawingDetails = useDrawingDetails(drawingId),
7337
+ drawingDetails = _useDrawingDetails.data;
7338
+ var restoredDrawingIdRef = React.useRef(undefined);
7339
+ var _React$useState = React.useState(),
7340
+ unmatchedSavedMask = _React$useState[0],
7341
+ setUnmatchedSavedMask = _React$useState[1];
7342
+ React.useEffect(function () {
7343
+ if (!drawingId || restoredDrawingIdRef.current === drawingId || (drawingDetails == null ? void 0 : drawingDetails.id) !== drawingId || isLoadingMasks) {
7344
+ return;
7345
+ }
7346
+ restoredDrawingIdRef.current = drawingId;
7347
+ var savedMask = findMaskForTransformation(masks, drawingDetails.transformation);
7348
+ if (savedMask) {
7349
+ onRestoreMask(savedMask.id);
7350
+ return;
7351
+ }
7352
+ if (drawingDetails.transformation) {
7353
+ setUnmatchedSavedMask({
7354
+ id: SAVED_MASK_ID,
7355
+ objectName: t('drawing-tool-form-mask-saved'),
7356
+ geoJSON: drawingDetails.transformation.mask,
7357
+ lastUpdatedTime: drawingDetails.lastUpdatedTime,
7358
+ scope: 'user'
7359
+ });
7360
+ onRestoreMask(SAVED_MASK_ID);
7361
+ }
7362
+ }, [drawingDetails, drawingId, isLoadingMasks, masks, onRestoreMask, t]);
7363
+ return unmatchedSavedMask;
7364
+ };
7365
+ var useClippedGeoJSON = function useClippedGeoJSON(mapId, geoJSON, mask) {
7366
+ var result = React.useMemo(function () {
7367
+ if (!mask || !geoJSON) {
7368
+ return {};
7369
+ }
7370
+ try {
7371
+ return {
7372
+ clippedGeoJSON: clipGeoJSONWithMask(geoJSON, mask.geoJSON)
7373
+ };
7374
+ } catch (_unused) {
7375
+ return {
7376
+ hasClipError: true
7377
+ };
7378
+ }
7379
+ }, [geoJSON, mask]);
7380
+ useClippedResultLayer(mapId, result.clippedGeoJSON);
7381
+ return result;
7382
+ };
7383
+ var getMaskError = function getMaskError(_ref, geoJSON) {
7384
+ var clippedGeoJSON = _ref.clippedGeoJSON,
7385
+ hasClipError = _ref.hasClipError;
7386
+ if (hasClipError) {
7387
+ return 'drawing-tool-form-mask-clip-error';
7388
+ }
7389
+ var hasDrawnFeatures = !!geoJSON && getDrawnFeatureIndexes(geoJSON).length > 0;
7390
+ return clippedGeoJSON && hasDrawnFeatures && !clippedGeoJSON.features.length ? 'drawing-tool-form-mask-no-overlap' : undefined;
7391
+ };
7392
+ var useHideFillOutsideMask = function useHideFillOutsideMask(layerId, geoJSON, isMaskSelected) {
7393
+ var dispatch = useDispatch();
7394
+ React.useEffect(function () {
7395
+ if (!layerId || !geoJSON) {
7396
+ return;
7397
+ }
7398
+ if (isMaskSelected) {
7399
+ getFeatureIndexesToHideFill(geoJSON).forEach(function (targetFeatureIndex) {
7400
+ var _geoJSON$features$tar, _geoJSON$features$tar2, _properties;
7401
+ dispatch(layerActions.updateFeatureProperties({
7402
+ layerId: layerId,
7403
+ properties: (_properties = {
7404
+ 'fill-opacity': 0
7405
+ }, _properties[MASKED_FILL_OPACITY_KEY] = (_geoJSON$features$tar = (_geoJSON$features$tar2 = geoJSON.features[targetFeatureIndex].properties) == null ? void 0 : _geoJSON$features$tar2['fill-opacity']) != null ? _geoJSON$features$tar : null, _properties),
7406
+ targetFeatureIndex: targetFeatureIndex,
7407
+ origin: 'DrawingToolFormConnect'
7408
+ }));
7409
+ });
7410
+ return;
7411
+ }
7412
+ getFeatureIndexesToRestoreFill(geoJSON).forEach(function (targetFeatureIndex) {
7413
+ var _geoJSON$features$tar3, _geoJSON$features$tar4, _properties2;
7414
+ dispatch(layerActions.updateFeatureProperties({
7415
+ layerId: layerId,
7416
+ properties: (_properties2 = {
7417
+ 'fill-opacity': (_geoJSON$features$tar3 = (_geoJSON$features$tar4 = geoJSON.features[targetFeatureIndex].properties) == null ? void 0 : _geoJSON$features$tar4[MASKED_FILL_OPACITY_KEY]) != null ? _geoJSON$features$tar3 : undefined
7418
+ }, _properties2[MASKED_FILL_OPACITY_KEY] = undefined, _properties2),
7419
+ targetFeatureIndex: targetFeatureIndex,
7420
+ origin: 'DrawingToolFormConnect'
7421
+ }));
7422
+ });
7423
+ }, [dispatch, geoJSON, isMaskSelected, layerId]);
7424
+ };
7425
+ var useDrawingToolMasks = function useDrawingToolMasks(drawingId, geoJSON) {
7426
+ var _masks$find;
7022
7427
  var dispatch = useDispatch();
7023
7428
  var _useDrawings = useDrawings({
7024
7429
  keywords: 'mask'
7025
7430
  }),
7026
7431
  _useDrawings$data = _useDrawings.data,
7027
- masks = _useDrawings$data === void 0 ? emptyMasks : _useDrawings$data,
7432
+ fetchedMasks = _useDrawings$data === void 0 ? emptyMasks : _useDrawings$data,
7028
7433
  isLoading = _useDrawings.isLoading;
7029
- var _React$useState = React.useState(),
7030
- selectedMaskId = _React$useState[0],
7031
- setSelectedMaskId = _React$useState[1];
7032
7434
  var _React$useState2 = React.useState(),
7033
- hoveredMaskId = _React$useState2[0],
7034
- setHoveredMaskId = _React$useState2[1];
7435
+ selectedMaskId = _React$useState2[0],
7436
+ setSelectedMaskId = _React$useState2[1];
7437
+ var _React$useState3 = React.useState(),
7438
+ hoveredMaskId = _React$useState3[0],
7439
+ setHoveredMaskId = _React$useState3[1];
7035
7440
  var mapId = useSelector(function (store) {
7036
7441
  return uiSelectors.getDialogMapId(store, drawingDialogType);
7037
7442
  });
7038
- var previewMask = masks.find(function (mask) {
7039
- return mask.id === (hoveredMaskId != null ? hoveredMaskId : selectedMaskId);
7443
+ var unmatchedSavedMask = useRestoreSavedMask(drawingId, fetchedMasks, isLoading, setSelectedMaskId);
7444
+ var masks = React.useMemo(function () {
7445
+ return unmatchedSavedMask ? [].concat(fetchedMasks, [unmatchedSavedMask]) : fetchedMasks;
7446
+ }, [fetchedMasks, unmatchedSavedMask]);
7447
+ var selectedMask = masks.find(function (mask) {
7448
+ return mask.id === selectedMaskId;
7040
7449
  });
7450
+ var previewMask = (_masks$find = masks.find(function (mask) {
7451
+ return mask.id === hoveredMaskId;
7452
+ })) != null ? _masks$find : selectedMask;
7041
7453
  useMaskPreviewLayer(mapId, previewMask);
7454
+ var clipResult = useClippedGeoJSON(mapId, geoJSON, selectedMask);
7042
7455
  var onSelectMask = React.useCallback(function (maskId) {
7043
7456
  setSelectedMaskId(maskId);
7044
7457
  dispatch(warningsDrawingsActions.setFormDirty({
@@ -7049,12 +7462,15 @@ var useDrawingToolMasks = function useDrawingToolMasks() {
7049
7462
  return {
7050
7463
  masks: masks,
7051
7464
  isLoading: isLoading,
7465
+ selectedMask: selectedMask,
7052
7466
  selectedMaskId: selectedMaskId,
7467
+ maskError: getMaskError(clipResult, geoJSON),
7053
7468
  onSelectMask: onSelectMask,
7054
7469
  onHoverMask: setHoveredMaskId
7055
7470
  };
7056
7471
  };
7057
7472
  var DrawingToolFormConnect = function DrawingToolFormConnect() {
7473
+ var _drawing$id;
7058
7474
  var dispatch = useDispatch();
7059
7475
  var _useMutateSaveOrUpdat = useMutateSaveOrUpdateDrawing(),
7060
7476
  saveOrUpdateDrawing = _useMutateSaveOrUpdat.mutate,
@@ -7081,29 +7497,65 @@ var DrawingToolFormConnect = function DrawingToolFormConnect() {
7081
7497
  return getWarningFormDirty(store, drawingDialogType);
7082
7498
  });
7083
7499
  usePreventBrowserClose(isFormDirty || isLayerInEditMode);
7084
- var _useDrawingToolMasks = useDrawingToolMasks(),
7500
+ var _useDrawingToolMasks = useDrawingToolMasks((_drawing$id = drawing == null ? void 0 : drawing.id) != null ? _drawing$id : '', layerFeatureGeoJSON),
7085
7501
  masks = _useDrawingToolMasks.masks,
7086
7502
  isLoadingMasks = _useDrawingToolMasks.isLoading,
7503
+ selectedMask = _useDrawingToolMasks.selectedMask,
7087
7504
  selectedMaskId = _useDrawingToolMasks.selectedMaskId,
7505
+ maskError = _useDrawingToolMasks.maskError,
7088
7506
  onSelectMask = _useDrawingToolMasks.onSelectMask,
7089
7507
  onHoverMask = _useDrawingToolMasks.onHoverMask;
7508
+ useHideFillOutsideMask(drawTool == null ? void 0 : drawTool.geoJSONLayerId, layerFeatureGeoJSON, !!selectedMask);
7509
+ var formGeoJSONRef = React.useRef(undefined);
7510
+ var formGeoJSON = React.useMemo(function () {
7511
+ var restoredGeoJSON = layerFeatureGeoJSON && restoreMaskedFill(layerFeatureGeoJSON);
7512
+ if (!isEqual(formGeoJSONRef.current, restoredGeoJSON)) {
7513
+ formGeoJSONRef.current = restoredGeoJSON;
7514
+ }
7515
+ return formGeoJSONRef.current;
7516
+ }, [layerFeatureGeoJSON]);
7517
+ var geoJSONProperties = React.useMemo(function () {
7518
+ return restoreMaskedFillProperties(featureLayerGeoJSONProperties);
7519
+ }, [featureLayerGeoJSONProperties]);
7090
7520
  var onSubmitForm = React.useCallback(function (formValues) {
7521
+ var original = formValues.geoJSON;
7091
7522
  saveOrUpdateDrawing({
7092
7523
  id: drawing == null ? void 0 : drawing.id,
7093
- data: {
7094
- geoJSON: formValues.geoJSON,
7524
+ data: Object.assign({
7525
+ geoJSON: selectedMask ? clipGeoJSONWithMask(original, selectedMask.geoJSON) : original,
7095
7526
  objectName: formValues.objectName,
7096
7527
  scope: 'user'
7097
- }
7528
+ }, selectedMask && {
7529
+ transformation: {
7530
+ mask: selectedMask.geoJSON,
7531
+ original: original
7532
+ }
7533
+ })
7098
7534
  });
7099
- }, [drawing == null ? void 0 : drawing.id, saveOrUpdateDrawing]);
7535
+ }, [drawing == null ? void 0 : drawing.id, saveOrUpdateDrawing, selectedMask]);
7100
7536
  var onChangeGeoJSONProperties = React.useCallback(function (properties) {
7537
+ var layerId = drawTool == null ? void 0 : drawTool.geoJSONLayerId;
7101
7538
  dispatch(layerActions.updateFeatureProperties({
7102
- layerId: drawTool == null ? void 0 : drawTool.geoJSONLayerId,
7539
+ layerId: layerId,
7103
7540
  properties: properties,
7104
7541
  origin: 'DrawingToolFormConnect'
7105
7542
  }));
7106
- }, [dispatch, drawTool == null ? void 0 : drawTool.geoJSONLayerId]);
7543
+ var fillOpacity = properties == null ? void 0 : properties['fill-opacity'];
7544
+ if (!selectedMask || typeof fillOpacity !== 'number') {
7545
+ return;
7546
+ }
7547
+ getDrawnFeatureIndexes(layerFeatureGeoJSON != null ? layerFeatureGeoJSON : emptyGeoJSON).forEach(function (targetFeatureIndex) {
7548
+ var _properties3;
7549
+ dispatch(layerActions.updateFeatureProperties({
7550
+ layerId: layerId,
7551
+ properties: (_properties3 = {
7552
+ 'fill-opacity': 0
7553
+ }, _properties3[MASKED_FILL_OPACITY_KEY] = fillOpacity, _properties3),
7554
+ targetFeatureIndex: targetFeatureIndex,
7555
+ origin: 'DrawingToolFormConnect'
7556
+ }));
7557
+ });
7558
+ }, [dispatch, drawTool == null ? void 0 : drawTool.geoJSONLayerId, layerFeatureGeoJSON, selectedMask]);
7107
7559
  var onChangeObjectName = React.useCallback(function (featureId, objectName) {
7108
7560
  var _layerFeatureGeoJSON$;
7109
7561
  var featureIndex = ((_layerFeatureGeoJSON$ = layerFeatureGeoJSON == null ? void 0 : layerFeatureGeoJSON.features) != null ? _layerFeatureGeoJSON$ : []).findIndex(function (feature) {
@@ -7167,12 +7619,13 @@ var DrawingToolFormConnect = function DrawingToolFormConnect() {
7167
7619
  dialogError: error == null ? void 0 : error.message,
7168
7620
  drawModes: drawTool == null ? void 0 : drawTool.drawModes,
7169
7621
  drawingName: drawing == null ? void 0 : drawing.objectName,
7170
- geoJSON: layerFeatureGeoJSON,
7171
- geoJSONProperties: featureLayerGeoJSONProperties,
7622
+ geoJSON: formGeoJSON,
7623
+ geoJSONProperties: geoJSONProperties,
7172
7624
  id: drawing == null ? void 0 : drawing.id,
7173
7625
  isInEditMode: isLayerInEditMode,
7174
7626
  isLoading: isPending,
7175
7627
  isLoadingMasks: isLoadingMasks,
7628
+ maskError: maskError,
7176
7629
  masks: masks,
7177
7630
  onChangeDrawMode: onChangeDrawMode,
7178
7631
  onChangeName: onChangeName,
@@ -26,6 +26,7 @@ export interface DrawingToolFormComponentProps {
26
26
  geoJSON: FeatureCollection<Geometry, GeoJsonProperties> | undefined;
27
27
  masks?: DrawingListItem[];
28
28
  isLoadingMasks?: boolean;
29
+ maskError?: string;
29
30
  selectedMaskId?: string;
30
31
  onSelectMask?: (maskId?: string) => void;
31
32
  onHoverMask?: (maskId?: string) => void;
@@ -1,2 +1,3 @@
1
1
  import React from 'react';
2
+ export declare const SAVED_MASK_ID = "saved-mask";
2
3
  export declare const DrawingToolFormConnect: React.FC;
@@ -37,6 +37,7 @@ export interface DrawingToolFormContentsProps {
37
37
  geoJSONProperties?: GeoJSON.GeoJsonProperties;
38
38
  masks: DrawingListItem[];
39
39
  isLoadingMasks: boolean;
40
+ maskError?: string;
40
41
  selectedMaskId?: string;
41
42
  onSelectMask: (maskId?: string) => void;
42
43
  onHoverMask: (maskId?: string) => void;
@@ -0,0 +1,15 @@
1
+ import type { Feature, FeatureCollection, MultiPolygon, Polygon } from 'geojson';
2
+ import type { DrawingListItem, DrawingTransformation } from '../../store/warningsDrawings/types';
3
+ type MaskPolygon = Feature<Polygon | MultiPolygon>;
4
+ export declare const CLIPPED_RESULT_FILL_OPACITY = 0.4;
5
+ export declare const MASKED_FILL_OPACITY_KEY = "maskedFillOpacity";
6
+ export declare const getDrawnFeatureIndexes: (geoJSON: FeatureCollection) => number[];
7
+ export declare const getFeatureIndexesToHideFill: (geoJSON: FeatureCollection) => number[];
8
+ export declare const getFeatureIndexesToRestoreFill: (geoJSON: FeatureCollection) => number[];
9
+ export declare const restoreMaskedFillProperties: (properties: GeoJSON.GeoJsonProperties) => GeoJSON.GeoJsonProperties;
10
+ export declare const restoreMaskedFill: (geoJSON: FeatureCollection) => FeatureCollection;
11
+ export declare const getMaskPolygon: (mask: FeatureCollection) => MaskPolygon | null;
12
+ export declare const clipGeoJSONWithMask: (geoJSON: FeatureCollection, mask: FeatureCollection) => FeatureCollection;
13
+ export declare const findMaskForTransformation: (masks: DrawingListItem[], transformation?: DrawingTransformation) => DrawingListItem | undefined;
14
+ export declare const buildClippedHighlightGeoJSON: (clipped: FeatureCollection) => FeatureCollection;
15
+ export {};
@@ -1,5 +1,7 @@
1
1
  import type { DrawingListItem } from '../../store/warningsDrawings/types';
2
- export declare const MASK_PREVIEW_FILL_OPACITY = 0.1;
2
+ export declare const MASK_PREVIEW_FILL_OPACITY = 0;
3
3
  export declare const getMaskPreviewLayerId: (mapId: string) => string;
4
+ export declare const getClippedResultLayerId: (mapId: string) => string;
4
5
  export declare const buildMaskPreviewGeoJSON: (mask: DrawingListItem) => GeoJSON.FeatureCollection;
5
6
  export declare const useMaskPreviewLayer: (mapId: string, mask?: DrawingListItem) => void;
7
+ export declare const useClippedResultLayer: (mapId: string, clippedGeoJSON?: GeoJSON.FeatureCollection) => void;
@@ -12,10 +12,15 @@ export interface BaseDrawingListItem {
12
12
  objectName: string;
13
13
  lastUpdatedTime: string;
14
14
  }
15
+ export interface DrawingTransformation {
16
+ mask: GeoJSON.FeatureCollection;
17
+ original: GeoJSON.FeatureCollection;
18
+ }
15
19
  export interface DrawingListItem extends BaseDrawingListItem {
16
20
  scope: DrawingScope;
17
21
  geoJSON: GeoJSON.FeatureCollection;
18
22
  keywords?: string;
23
+ transformation?: DrawingTransformation;
19
24
  }
20
25
  export interface AreaListItem extends BaseDrawingListItem {
21
26
  scope: DrawingScope;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/warnings",
3
- "version": "19.6.1-nightly-20260917",
3
+ "version": "20.0.0",
4
4
  "description": "GeoWeb warinings library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -20,24 +20,24 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "@opengeoweb/api": "19.6.1-nightly-20260917",
24
- "@opengeoweb/shared": "19.6.1-nightly-20260917",
25
- "@opengeoweb/store": "19.6.1-nightly-20260917",
26
- "@opengeoweb/webmap-react": "19.6.1-nightly-20260917",
23
+ "@opengeoweb/api": "20.0.0",
24
+ "@opengeoweb/shared": "20.0.0",
25
+ "@opengeoweb/store": "20.0.0",
26
+ "@opengeoweb/webmap-react": "20.0.0",
27
27
  "@tanstack/react-query": "^5.85.5",
28
28
  "react-redux": "^9.2.0",
29
- "@opengeoweb/theme": "19.6.1-nightly-20260917",
30
- "@opengeoweb/form-fields": "19.6.1-nightly-20260917",
29
+ "@opengeoweb/theme": "20.0.0",
30
+ "@opengeoweb/form-fields": "20.0.0",
31
31
  "react-hook-form": "^7.50.1",
32
32
  "lodash": "^4.18.1",
33
33
  "@reduxjs/toolkit": "^2.6.1",
34
- "@opengeoweb/snackbar": "19.6.1-nightly-20260917",
34
+ "@opengeoweb/snackbar": "20.0.0",
35
35
  "react-window": "^2.2.6",
36
36
  "axios": "^1.18.0",
37
- "@opengeoweb/core": "19.6.1-nightly-20260917",
38
- "@opengeoweb/webmap": "19.6.1-nightly-20260917",
39
- "@opengeoweb/authentication": "19.6.1-nightly-20260917",
40
- "@opengeoweb/sigmet-airmet": "19.6.1-nightly-20260917",
37
+ "@opengeoweb/core": "20.0.0",
38
+ "@opengeoweb/webmap": "20.0.0",
39
+ "@opengeoweb/authentication": "20.0.0",
40
+ "@opengeoweb/sigmet-airmet": "20.0.0",
41
41
  "react-i18next": "^15.1.1",
42
42
  "i18next": "^25.0.1",
43
43
  "@mui/material": "^9.0.1",