@geogirafe/lib-geoportal 1.1.0-dev.2273129895 → 1.1.0-dev.2273214250

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.
@@ -12,6 +12,7 @@ import { Coordinate } from 'ol/coordinate.js';
12
12
  import { ContextMenu } from '../map/tools/contextmenu.js';
13
13
  import IGirafeContext from '../../tools/context/icontext.js';
14
14
  import { StyleFunction } from 'ol/style/Style.js';
15
+ import Transform from 'ol-ext/interaction/Transform.js';
15
16
  export default class OlDrawing {
16
17
  private readonly map;
17
18
  private readonly toolName;
@@ -28,7 +29,7 @@ export default class OlDrawing {
28
29
  drawingLayer: VectorLayer;
29
30
  lastClosestFeature: Feature | null;
30
31
  translate: Translate | null;
31
- rotateAndScale: Modify | null;
32
+ transform: Transform | null;
32
33
  defaultStyle: StyleFunction | undefined;
33
34
  private readonly updateGeometryInState;
34
35
  private get state();
@@ -39,8 +40,8 @@ export default class OlDrawing {
39
40
  private addSnapInteraction;
40
41
  private addTranslateInteraction;
41
42
  private removeTranslateInteraction;
42
- private addRotateAndScaleInteraction;
43
- private removeRotateAndScaleInteraction;
43
+ private addTransformInteraction;
44
+ private removeTransformInteraction;
44
45
  /**
45
46
  * Adds a context menu to the map with a single entry 'remove vertex'. The menu is configured to open
46
47
  * when the user does an alternate click ( = context event) on or near a vertex of a modifiable feature.
@@ -8,14 +8,13 @@ import VectorSource from 'ol/source/Vector.js';
8
8
  import VectorLayer from 'ol/layer/Vector.js';
9
9
  import GeoJSON from 'ol/format/GeoJSON.js';
10
10
  import { getPointResolution } from 'ol/proj.js';
11
- import { never, primaryAction } from 'ol/events/condition.js';
11
+ import { always, never, primaryAction } from 'ol/events/condition.js';
12
12
  import { ensurePolygonIsProperlyClosed, getAreaOfPolygon, getDistance, getHalfPoint, getLabelStyle, getRadiusDataForCircle } from '../../tools/utils/olutils.js';
13
13
  import { ContextMenu, EntryInteractionType } from '../map/tools/contextmenu.js';
14
14
  import { formatCoordinates } from '../../tools/geometrytools.js';
15
15
  import { v4 as uuidv4 } from 'uuid';
16
16
  import { isAlternateMouseClick, isPrimaryPointerAction } from '../../tools/state/userinteractionevent.js';
17
- import { getCenter, getHeight, getWidth } from 'ol/extent.js';
18
- import CircleStyle from 'ol/style/Circle.js';
17
+ import Transform from 'ol-ext/interaction/Transform.js';
19
18
  function getLineStroke(strokeType, lineWidth) {
20
19
  switch (strokeType) {
21
20
  case 'full':
@@ -48,46 +47,6 @@ function extractVerticesFromGeometry(geometry) {
48
47
  }
49
48
  return new MultiPoint(vertices);
50
49
  }
51
- function calculateCenter(geometry) {
52
- let center, coordinates, minRadius;
53
- if (geometry instanceof Polygon) {
54
- let x = 0;
55
- let y = 0;
56
- let i = 0;
57
- coordinates = geometry.getCoordinates()[0].slice();
58
- for (const coordinate of coordinates) {
59
- x += coordinate[0];
60
- y += coordinate[1];
61
- i++;
62
- }
63
- center = [x / i, y / i];
64
- }
65
- else if (geometry instanceof LineString) {
66
- center = geometry.getCoordinateAt(0.5);
67
- coordinates = geometry.getCoordinates();
68
- }
69
- else {
70
- center = getCenter(geometry.getExtent());
71
- }
72
- let sqDistances;
73
- if (coordinates) {
74
- sqDistances = coordinates.map(function (coordinate) {
75
- const dx = coordinate[0] - center[0];
76
- const dy = coordinate[1] - center[1];
77
- return dx * dx + dy * dy;
78
- });
79
- minRadius = Math.sqrt(Math.max(...sqDistances)) / 3;
80
- }
81
- else {
82
- minRadius = Math.max(getWidth(geometry.getExtent()), getHeight(geometry.getExtent())) / 3;
83
- }
84
- return {
85
- center: center,
86
- coordinates: coordinates,
87
- minRadius: minRadius,
88
- sqDistances: sqDistances
89
- };
90
- }
91
50
  export default class OlDrawing {
92
51
  map;
93
52
  toolName;
@@ -104,7 +63,7 @@ export default class OlDrawing {
104
63
  drawingLayer;
105
64
  lastClosestFeature = null;
106
65
  translate = null;
107
- rotateAndScale = null;
66
+ transform = null;
108
67
  defaultStyle;
109
68
  updateGeometryInState = (olFeature) => {
110
69
  const idx = this.drawingState.features.findIndex((f) => f.id === olFeature.getId());
@@ -205,92 +164,34 @@ export default class OlDrawing {
205
164
  this.translate = null;
206
165
  }
207
166
  }
208
- addRotateAndScaleInteraction() {
209
- this.removeRotateAndScaleInteraction();
210
- const defaultStyle = this.defaultStyle;
211
- const getCoordinates = (feature) => {
212
- const geometry = feature.getGeometry();
213
- if (geometry instanceof Point) {
214
- return geometry.getCoordinates();
215
- }
216
- else if (geometry instanceof LineString) {
217
- return geometry.getCoordinates()[0];
218
- }
219
- else if (geometry instanceof Polygon) {
220
- return geometry.getCoordinates()[0][0];
221
- }
222
- return [];
223
- };
224
- this.rotateAndScale = new Modify({
225
- features: this.modifiableFeatures,
226
- condition: (event) => {
227
- return this.rotateAndScale != null && primaryAction(event);
228
- },
229
- deleteCondition: never,
230
- insertVertexCondition: never,
231
- style: function (feature, resolution) {
232
- feature.get('features').forEach(function (modifyFeature) {
233
- const modifyGeometry = modifyFeature.get('modifyGeometry');
234
- if (modifyGeometry) {
235
- const point = getCoordinates(feature);
236
- let modifyPoint = modifyGeometry.point;
237
- if (!modifyPoint) {
238
- // save the initial geometry and vertex position
239
- modifyPoint = point;
240
- modifyGeometry.point = modifyPoint;
241
- modifyGeometry.geometry0 = modifyGeometry.geometry;
242
- // get anchor and minimum radius of vertices to be used
243
- const result = calculateCenter(modifyGeometry.geometry0);
244
- modifyGeometry.center = result.center;
245
- modifyGeometry.minRadius = result.minRadius;
246
- }
247
- const center = modifyGeometry.center;
248
- const minRadius = modifyGeometry.minRadius;
249
- let dx, dy;
250
- dx = modifyPoint[0] - center[0];
251
- dy = modifyPoint[1] - center[1];
252
- const initialRadius = Math.hypot(dx, dy);
253
- if (initialRadius > minRadius) {
254
- const initialAngle = Math.atan2(dy, dx);
255
- dx = point[0] - center[0];
256
- dy = point[1] - center[1];
257
- const currentRadius = Math.hypot(dx, dy);
258
- if (currentRadius > 0) {
259
- const currentAngle = Math.atan2(dy, dx);
260
- const geometry = modifyGeometry.geometry0.clone();
261
- geometry.scale(currentRadius / initialRadius, undefined, center);
262
- geometry.rotate(currentAngle - initialAngle, center);
263
- modifyGeometry.geometry = geometry;
264
- }
265
- }
266
- }
267
- });
268
- return defaultStyle(feature, resolution);
167
+ addTransformInteraction() {
168
+ this.transform = new Transform({
169
+ enableRotatedTransform: false,
170
+ features: new Collection(this.lastClosestFeature ? [this.lastClosestFeature] : []),
171
+ hitTolerance: this.map.pixelTolerance,
172
+ translateFeature: false,
173
+ scale: true,
174
+ rotate: true,
175
+ keepAspectRatio: always,
176
+ keepRectangle: false,
177
+ translate: false,
178
+ stretch: false,
179
+ pointRadius: function (f) {
180
+ const radius = f.get('radius') || 10;
181
+ return [radius, radius];
269
182
  }
270
183
  });
271
- this.rotateAndScale.on('modifystart', function (event) {
272
- // prettier-ignore
273
- event.features.forEach(function (feature) {
274
- feature.set('modifyGeometry', { geometry: feature.getGeometry().clone() }, true);
275
- });
276
- });
277
- this.rotateAndScale.on('modifyend', (event) => {
278
- // prettier-ignore
279
- event.features.forEach((olFeature) => {
280
- const modifyGeometry = olFeature.get('modifyGeometry');
281
- if (modifyGeometry) {
282
- olFeature.setGeometry(modifyGeometry.geometry);
283
- olFeature.unset('modifyGeometry', true);
284
- this.updateGeometryInState(olFeature);
285
- }
286
- });
287
- });
288
- this.map.olMap.addInteraction(this.rotateAndScale);
184
+ this.map.olMap.addInteraction(this.transform);
185
+ if (this.lastClosestFeature) {
186
+ this.transform.select(this.lastClosestFeature, true);
187
+ this.lastClosestFeature.changed();
188
+ }
289
189
  }
290
- removeRotateAndScaleInteraction() {
291
- if (this.rotateAndScale) {
292
- this.map.olMap.removeInteraction(this.rotateAndScale);
293
- this.rotateAndScale = null;
190
+ removeTransformInteraction() {
191
+ if (this.transform) {
192
+ this.map.olMap.removeInteraction(this.transform);
193
+ this.transform = null;
194
+ this.lastClosestFeature?.changed();
294
195
  }
295
196
  }
296
197
  /**
@@ -334,9 +235,9 @@ export default class OlDrawing {
334
235
  callback: (_evt, _mapCoordinate) => {
335
236
  if (this.lastClosestFeature) {
336
237
  this.removeModifyInteraction();
337
- this.addRotateAndScaleInteraction();
238
+ this.addTransformInteraction();
338
239
  this.map.olMap.on('singleclick', () => {
339
- this.removeRotateAndScaleInteraction();
240
+ this.removeTransformInteraction();
340
241
  this.addModifyInteraction();
341
242
  });
342
243
  }
@@ -790,7 +691,7 @@ export default class OlDrawing {
790
691
  addLabel(getHalfPoint(segment), dFeature.getLengthText(getDistance(segment, this.state.projection)));
791
692
  addLabel(square.getInteriorPoint(), dFeature.getAreaText(getAreaOfPolygon(square, this.state.projection)));
792
693
  }
793
- if (dFeature.selected && this.rotateAndScale == null) {
694
+ if (dFeature.selected && this.transform == null) {
794
695
  const vertexStyle = dFeature.getVertexStyle();
795
696
  // Add a node style to every vertex of the geometry
796
697
  vertexStyle.setGeometry(function (f) {
@@ -801,35 +702,6 @@ export default class OlDrawing {
801
702
  });
802
703
  styles.push(vertexStyle);
803
704
  }
804
- // Draw Point/Circle for Center of Geometry if rotating/scaling
805
- if (this.rotateAndScale != null) {
806
- const result = calculateCenter(geometry);
807
- const center = result.center;
808
- if (center) {
809
- styles.push(new Style({
810
- geometry: new Point(center),
811
- image: new CircleStyle({
812
- radius: 4,
813
- fill: new Fill({
814
- color: '#ff3333'
815
- })
816
- })
817
- }));
818
- const coordinates = result.coordinates;
819
- if (coordinates) {
820
- const minRadius = result.minRadius;
821
- const sqDistances = result.sqDistances;
822
- const rsq = minRadius * minRadius;
823
- const points = coordinates.filter(function (_c, index) {
824
- return sqDistances[index] > rsq;
825
- });
826
- const vertexStyle = dFeature.getVertexStyle();
827
- // Add a node style to every vertex of the geometry
828
- vertexStyle.setGeometry(new MultiPoint(points));
829
- styles.push(vertexStyle);
830
- }
831
- }
832
- }
833
705
  return styles;
834
706
  }
835
707
  removeDrawInteraction() {
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "GeoGirafe PSC",
6
6
  "url": "https://doc.geomapfish.dev"
7
7
  },
8
- "version": "1.1.0-dev.2273129895",
8
+ "version": "1.1.0-dev.2273214250",
9
9
  "type": "module",
10
10
  "engines": {
11
11
  "node": ">=20.19.0"
@@ -36,7 +36,7 @@
36
36
  "buffer": "6.0.3",
37
37
  "d3": "7.9.0",
38
38
  "dompurify": "3.2.6",
39
- "driver.js": "^1.3.6",
39
+ "driver.js": "1.3.6",
40
40
  "error-stack-parser": "2.1.4",
41
41
  "file-saver": "2.0.5",
42
42
  "jsts": "2.12.1",
@@ -56,6 +56,7 @@
56
56
  "@types/geojson": "7946",
57
57
  "cesium": ">1.113",
58
58
  "ol": "8 || 9 || 10",
59
+ "ol-ext": "^4.0.37",
59
60
  "ol-mapbox-style": "12",
60
61
  "olcs": "2",
61
62
  "proj4": "2"
@@ -69,6 +70,7 @@
69
70
  "@types/geojson": "7946.0.16",
70
71
  "@types/jsts": "0.17.24",
71
72
  "@types/lodash-es": "4.17.12",
73
+ "@types/ol-ext": "npm:@siedlerchr/types-ol-ext@3.6.5",
72
74
  "@types/serviceworker": "0.0.147",
73
75
  "@types/tabulator-tables": "6.2.9",
74
76
  "@types/uuid": "10.0.0",
@@ -93,6 +95,7 @@
93
95
  "svgo": "4.0.0",
94
96
  "typescript": "5.8.3",
95
97
  "vite": "7.0.6",
98
+ "vite-bundle-analyzer": "1.3.2",
96
99
  "vite-plugin-html": "3.2.2",
97
100
  "vite-plugin-static-copy": "3.1.1",
98
101
  "vitest": "3.2.4"
@@ -157,6 +160,7 @@
157
160
  "prepare-commit": "npm run pretty && npm run tsc && npm run lint && npm run test && npm run build && npm run build-lib",
158
161
  "generate-dev-certs-win": "buildtools\\generate-dev-certs.cmd",
159
162
  "generate-dev-certs-nix": "bash -C './buildtools/generate-dev-certs.sh'",
160
- "trust-default-dev-certs-win": "buildtools\\trust-dev-certs.cmd"
163
+ "trust-default-dev-certs-win": "buildtools\\trust-dev-certs.cmd",
164
+ "size-analysis": "node buildtools/app-clean.js && cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode analyze"
161
165
  }
162
166
  }
@@ -1 +1 @@
1
- {"version":"1.1.0-dev.2273129895", "build":"2273129895", "date":"20/01/2026"}
1
+ {"version":"1.1.0-dev.2273214250", "build":"2273214250", "date":"20/01/2026"}
@@ -7,6 +7,7 @@ import { HtmlRebuildPlugin } from '@geogirafe/lib-geoportal/buildtools';
7
7
  import { createHtmlPlugin } from 'vite-plugin-html';
8
8
  import { viteStaticCopy } from 'vite-plugin-static-copy';
9
9
  import dns from 'dns';
10
+ import analyzer from 'vite-bundle-analyzer';
10
11
 
11
12
  /**
12
13
  * Custom name resolution for app.localhost:
@@ -43,7 +44,7 @@ const geogirafeSource = 'node_modules/@geogirafe/lib-geoportal';
43
44
  const certsDirectory = 'certs';
44
45
 
45
46
  // https://v2.vitejs.dev/config/
46
- export default defineConfig(({ command }) => {
47
+ export default defineConfig(({ command, mode }) => {
47
48
  return {
48
49
  base: './',
49
50
  server: {
@@ -112,7 +113,6 @@ export default defineConfig(({ command }) => {
112
113
  { src: `${geogirafeSource}/styles/*.css`, dest: 'styles/' },
113
114
  { src: `${geogirafeSource}/assets/*`, dest: '' },
114
115
  { src: `${geogirafeSource}/tools/auth/silentlogincallback.html`, dest: '' },
115
- //{ src: `${geogirafeSource}/api/index.html`, dest: 'api/' },
116
116
  { src: 'node_modules/ol/ol.css', dest: 'lib/ol/' },
117
117
  { src: 'node_modules/tabulator-tables/dist/css/tabulator.min.css', dest: 'lib/tabulator-tables/' },
118
118
  { src: 'node_modules/tippy.js/dist/*.css', dest: 'lib/tippy.js/' },
@@ -123,7 +123,15 @@ export default defineConfig(({ command }) => {
123
123
  HtmlRebuildPlugin(),
124
124
  createHtmlPlugin({
125
125
  minify: true
126
- })
126
+ }),
127
+ mode === 'analyze' &&
128
+ // https://www.npmjs.com/package/vite-bundle-analyzer
129
+ analyzer({
130
+ analyzerMode: 'static',
131
+ openAnalyzer: true,
132
+ defaultSizes: 'brotli', // or "gzip"
133
+ summary: true
134
+ })
127
135
  ],
128
136
  define: {
129
137
  // Define relative base path in cesium for loading assets