@edugis-org/webmapx 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +149 -0
  2. package/dist-lib/WMTS-DCN4zX0-.js +1169 -0
  3. package/dist-lib/alert-GeHlqlN8.js +310 -0
  4. package/dist-lib/assets/epsg-lookup.worker-J7TVnHDq.js +1 -0
  5. package/dist-lib/assets/shapefile.worker-kQfZj6G2.js +4 -0
  6. package/dist-lib/attribution-format-B4f05_u0.js +62 -0
  7. package/dist-lib/button-DFdGkRPQ.js +741 -0
  8. package/dist-lib/cesium-adapter-BHXNytkU.js +1488 -0
  9. package/dist-lib/checkbox-QoR4S8tV.js +284 -0
  10. package/dist-lib/chunk-HEgqtunE.js +20 -0
  11. package/dist-lib/chunk.36O46B5H-B6ZL7Sm1.js +77 -0
  12. package/dist-lib/chunk.3RPBFEDE-BFO1fHVm.js +138 -0
  13. package/dist-lib/chunk.5JY5FUCG-DTXsslmx.js +1090 -0
  14. package/dist-lib/chunk.6CTB5ZDJ-DjZrBd6Y.js +99 -0
  15. package/dist-lib/chunk.AJ3ENQ5C-Ci7Gm2b6.js +175 -0
  16. package/dist-lib/chunk.LD4M4QGE-CiCfhE8r.js +8 -0
  17. package/dist-lib/chunk.NYIIDP5N-BikXIStD.js +99 -0
  18. package/dist-lib/chunk.RWUUFNUL-DFztA4uV.js +43 -0
  19. package/dist-lib/chunk.SI4ACBFK-CLb9VfMG.js +61 -0
  20. package/dist-lib/chunk.YHLNUJ7P-D-kanrCf.js +503 -0
  21. package/dist-lib/core-CMAlSR68.js +22 -0
  22. package/dist-lib/decorate-CWgUV1hU.js +1139 -0
  23. package/dist-lib/decorators-B35AgiCU.js +351 -0
  24. package/dist-lib/deferred-query-service-BJDcngw6.js +386 -0
  25. package/dist-lib/dist-Dm6b7XCs.js +12318 -0
  26. package/dist-lib/dist-Ha9LQCut.js +244 -0
  27. package/dist-lib/dist-c1PlDAd1.js +2359 -0
  28. package/dist-lib/dist-kKlmcBXq.js +50 -0
  29. package/dist-lib/divider-CPm675yY.js +41 -0
  30. package/dist-lib/dropped-config-C_GyVa8o.js +17 -0
  31. package/dist-lib/dropped-layer-builder-DAaYgUPk.js +396 -0
  32. package/dist-lib/epsg-definitions-BZLZWa8Q.js +668 -0
  33. package/dist-lib/esm-CTuscnN5.js +46 -0
  34. package/dist-lib/file-sniff-Dhxj3KTF.js +251 -0
  35. package/dist-lib/geo-calculations-DbFJAUoI.js +30 -0
  36. package/dist-lib/icon-CEOgWlro.js +9 -0
  37. package/dist-lib/icon-button-Da_nBTy3.js +408 -0
  38. package/dist-lib/input-CeGntPlT.js +590 -0
  39. package/dist-lib/layer-discovery-afWzu5hY.js +2825 -0
  40. package/dist-lib/leaflet-adapter-D9djjrKv.js +1227 -0
  41. package/dist-lib/lib-CdHVicAE.js +4074 -0
  42. package/dist-lib/map-layer-registry-2cmkiRDK.js +62 -0
  43. package/dist-lib/maplibre-adapter-TFc3e0G9.js +1190 -0
  44. package/dist-lib/maplibre-expression-evaluator-DCWUcpwf.js +7233 -0
  45. package/dist-lib/marker-utils-DztWXeop.js +12 -0
  46. package/dist-lib/ol-tilegrid-9VtyxaLG.js +64 -0
  47. package/dist-lib/openlayers-adapter-DVW1KCRv.js +13307 -0
  48. package/dist-lib/option-CBxl1mZP.js +1106 -0
  49. package/dist-lib/papaparse.min-B7v3c0D7.js +501 -0
  50. package/dist-lib/rbush-C8k41T4z.js +254 -0
  51. package/dist-lib/shapefile-SawVY6xg.js +207 -0
  52. package/dist-lib/spinner-DysxdNG9.js +6 -0
  53. package/dist-lib/src-CL94RDe3.js +111 -0
  54. package/dist-lib/throttle-BeneRNYK.js +16 -0
  55. package/dist-lib/toast-Cm28o9U6.js +15 -0
  56. package/dist-lib/togeojson.es-DAgiTBvg.js +579 -0
  57. package/dist-lib/tooltip-Cucn1SiD.js +197 -0
  58. package/dist-lib/webmapx-3d-tool-D4CTD2gB.js +176 -0
  59. package/dist-lib/webmapx-base-tool-Dm9NAWLD.js +75 -0
  60. package/dist-lib/webmapx-config-edit-tool-DCTyxqTk.js +389 -0
  61. package/dist-lib/webmapx-coordinates-tool-jeWohup9.js +648 -0
  62. package/dist-lib/webmapx-core-bundle-BDImi1RE.js +8203 -0
  63. package/dist-lib/webmapx-draw-tool-DooAV8cF.js +4336 -0
  64. package/dist-lib/webmapx-geolocation-tool-Rw3-Iad1.js +788 -0
  65. package/dist-lib/webmapx-import-layer-tool-DRYviHd5.js +250 -0
  66. package/dist-lib/webmapx-info-tool-BJA157cy.js +412 -0
  67. package/dist-lib/webmapx-language-osmvector-M5y_lwOg.js +489 -0
  68. package/dist-lib/webmapx-measure-tool-BXhMJFC6.js +590 -0
  69. package/dist-lib/webmapx-modal-tool-eF6Naluv.js +84 -0
  70. package/dist-lib/webmapx-plugin-tool-D2Hghf9n.js +45 -0
  71. package/dist-lib/webmapx-print-tool-ob1bOsR5.js +348 -0
  72. package/dist-lib/webmapx-search-tool-Cv8BrYvY.js +437 -0
  73. package/dist-lib/webmapx-settings-DDEJ8aoV.js +479 -0
  74. package/dist-lib/webmapx-truearea-tool-CMB4Orm-.js +615 -0
  75. package/dist-lib/webmapx-view-mode-tool-CUpLNjOj.js +106 -0
  76. package/dist-lib/webmapx.css +2 -0
  77. package/dist-lib/webmapx.js +1321 -0
  78. package/dist-lib/wms-feature-info-C0RVMEQC.js +145 -0
  79. package/dist-lib/wms-url-builder-DIJLQ1v2.js +54 -0
  80. package/dist-lib/zip.js-DVhmtjxZ.js +3615 -0
  81. package/package.json +107 -0
  82. package/public/data/country-epsg-codes.json +297 -0
  83. package/public/data/world-countries-simplified.topojson +1 -0
  84. package/src/locales/en/core.json +20 -0
@@ -0,0 +1,615 @@
1
+ import { r as e, t } from "./decorate-CWgUV1hU.js";
2
+ import { i as n, o as r } from "./decorators-B35AgiCU.js";
3
+ import { t as i } from "./esm-CTuscnN5.js";
4
+ import { t as a } from "./webmapx-modal-tool-eF6Naluv.js";
5
+ import { css as o, html as s } from "lit";
6
+ //#region node_modules/@turf/bearing/node_modules/@turf/helpers/dist/esm/index.js
7
+ var c = 6371008.8;
8
+ c * 100, c * 100, 360 / (2 * Math.PI), c * 3.28084, c * 39.37, c / 1e3, c / 1e3, c / 1609.344, c * 1e3, c * 1e3, c / 1852, c * 1.0936;
9
+ function l(e) {
10
+ return e % (2 * Math.PI) * 180 / Math.PI;
11
+ }
12
+ function u(e) {
13
+ return e % 360 * Math.PI / 180;
14
+ }
15
+ //#endregion
16
+ //#region node_modules/@turf/bearing/node_modules/@turf/invariant/dist/esm/index.js
17
+ function d(e) {
18
+ if (!e) throw Error("coord is required");
19
+ if (!Array.isArray(e)) {
20
+ if (e.type === "Feature" && e.geometry !== null && e.geometry.type === "Point") return [...e.geometry.coordinates];
21
+ if (e.type === "Point") return [...e.coordinates];
22
+ }
23
+ if (Array.isArray(e) && e.length >= 2 && !Array.isArray(e[0]) && !Array.isArray(e[1])) return [...e];
24
+ throw Error("coord must be GeoJSON Point or an Array of numbers");
25
+ }
26
+ //#endregion
27
+ //#region node_modules/@turf/bearing/dist/esm/index.js
28
+ function f(e, t, n = {}) {
29
+ if (n.final === !0) return p(e, t);
30
+ let r = d(e), i = d(t), a = u(r[0]), o = u(i[0]), s = u(r[1]), c = u(i[1]), f = Math.sin(o - a) * Math.cos(c), m = Math.cos(s) * Math.sin(c) - Math.sin(s) * Math.cos(c) * Math.cos(o - a);
31
+ return l(Math.atan2(f, m));
32
+ }
33
+ function p(e, t) {
34
+ let n = f(t, e);
35
+ return n = (n + 180) % 360, n;
36
+ }
37
+ var m = f, h = 6371008.8, g = {
38
+ centimeters: h * 100,
39
+ centimetres: h * 100,
40
+ degrees: 360 / (2 * Math.PI),
41
+ feet: h * 3.28084,
42
+ inches: h * 39.37,
43
+ kilometers: h / 1e3,
44
+ kilometres: h / 1e3,
45
+ meters: h,
46
+ metres: h,
47
+ miles: h / 1609.344,
48
+ millimeters: h * 1e3,
49
+ millimetres: h * 1e3,
50
+ nauticalmiles: h / 1852,
51
+ radians: 1,
52
+ yards: h * 1.0936
53
+ };
54
+ function _(e, t, n = {}) {
55
+ let r = { type: "Feature" };
56
+ return (n.id === 0 || n.id) && (r.id = n.id), n.bbox && (r.bbox = n.bbox), r.properties = t || {}, r.geometry = e, r;
57
+ }
58
+ function v(e, t, n = {}) {
59
+ if (!e) throw Error("coordinates is required");
60
+ if (!Array.isArray(e)) throw Error("coordinates must be an Array");
61
+ if (e.length < 2) throw Error("coordinates must be at least 2 numbers long");
62
+ if (!S(e[0]) || !S(e[1])) throw Error("coordinates must contain numbers");
63
+ return _({
64
+ type: "Point",
65
+ coordinates: e
66
+ }, t, n);
67
+ }
68
+ function y(e, t = "kilometers") {
69
+ let n = g[t];
70
+ if (!n) throw Error(t + " units is invalid");
71
+ return e / n;
72
+ }
73
+ function b(e) {
74
+ return e % (2 * Math.PI) * 180 / Math.PI;
75
+ }
76
+ function x(e) {
77
+ return e % 360 * Math.PI / 180;
78
+ }
79
+ function S(e) {
80
+ return !isNaN(e) && e !== null && !Array.isArray(e);
81
+ }
82
+ //#endregion
83
+ //#region node_modules/@turf/destination/node_modules/@turf/invariant/dist/esm/index.js
84
+ function C(e) {
85
+ if (!e) throw Error("coord is required");
86
+ if (!Array.isArray(e)) {
87
+ if (e.type === "Feature" && e.geometry !== null && e.geometry.type === "Point") return [...e.geometry.coordinates];
88
+ if (e.type === "Point") return [...e.coordinates];
89
+ }
90
+ if (Array.isArray(e) && e.length >= 2 && !Array.isArray(e[0]) && !Array.isArray(e[1])) return [...e];
91
+ throw Error("coord must be GeoJSON Point or an Array of numbers");
92
+ }
93
+ //#endregion
94
+ //#region node_modules/@turf/destination/dist/esm/index.js
95
+ function w(e, t, n, r = {}) {
96
+ let i = C(e), a = x(i[0]), o = x(i[1]), s = x(n), c = y(t, r.units), l = Math.asin(Math.sin(o) * Math.cos(c) + Math.cos(o) * Math.sin(c) * Math.cos(s)), u = b(a + Math.atan2(Math.sin(s) * Math.sin(c) * Math.cos(o), Math.cos(c) - Math.sin(o) * Math.sin(l))), d = b(l);
97
+ return i[2] === void 0 ? v([u, d], r.properties) : v([
98
+ u,
99
+ d,
100
+ i[2]
101
+ ], r.properties);
102
+ }
103
+ var T = w, E = [
104
+ "#e63946",
105
+ "#2a9d8f",
106
+ "#e9c46a",
107
+ "#457b9d",
108
+ "#f4a261",
109
+ "#6a4c93",
110
+ "#06d6a0",
111
+ "#ff6b6b"
112
+ ], D = "truearea", O = `${D}:data`, k = "truearea-ghost", A = `${k}:data`;
113
+ function j(e) {
114
+ let t = [];
115
+ if (e.type === "Polygon" ? t = e.coordinates[0] : e.type === "MultiPolygon" ? t = e.coordinates.flat(2) : e.type === "LineString" ? t = e.coordinates : e.type === "MultiLineString" ? t = e.coordinates.flat() : e.type === "Point" && (t = [e.coordinates]), t.length === 0) return [0, 0];
116
+ let n = t.reduce((e, t) => [e[0] + t[0], e[1] + t[1]], [0, 0]);
117
+ return [n[0] / t.length, n[1] / t.length];
118
+ }
119
+ function M(e, t) {
120
+ let n = !1;
121
+ for (let r = 0, i = t.length - 1; r < t.length; i = r++) {
122
+ let a = t[r][0], o = t[r][1], s = t[i][0], c = t[i][1];
123
+ o > e[1] != c > e[1] && e[0] < (s - a) * (e[1] - o) / (c - o) + a && (n = !n);
124
+ }
125
+ return n;
126
+ }
127
+ function N(e, t) {
128
+ return t.type === "Polygon" ? M(e, t.coordinates[0]) && !t.coordinates.slice(1).some((t) => M(e, t)) : t.type === "MultiPolygon" ? t.coordinates.some((t) => M(e, t[0]) && !t.slice(1).some((t) => M(e, t))) : !1;
129
+ }
130
+ function P(e, t) {
131
+ if (t.type === "Polygon") return j(t);
132
+ if (t.type === "MultiPolygon") {
133
+ let n = t.coordinates.find((t) => M(e, t[0]) && !t.slice(1).some((t) => M(e, t)));
134
+ if (n) {
135
+ let e = n[0], t = e.reduce((e, t) => [e[0] + t[0], e[1] + t[1]], [0, 0]);
136
+ return [t[0] / e.length, t[1] / e.length];
137
+ }
138
+ }
139
+ return j(t);
140
+ }
141
+ function F(e, t, n) {
142
+ let r = {
143
+ type: "Feature",
144
+ geometry: {
145
+ type: "Point",
146
+ coordinates: n
147
+ },
148
+ properties: {}
149
+ }, a = (e) => {
150
+ let n = {
151
+ type: "Feature",
152
+ geometry: {
153
+ type: "Point",
154
+ coordinates: e
155
+ },
156
+ properties: {}
157
+ }, a = m(r, n);
158
+ return T(r, i(r, n, { units: "kilometers" }), a + t, { units: "kilometers" }).geometry.coordinates;
159
+ }, o = (e) => e.map(a);
160
+ return e.type === "Polygon" ? {
161
+ type: "Polygon",
162
+ coordinates: e.coordinates.map(o)
163
+ } : e.type === "MultiPolygon" ? {
164
+ type: "MultiPolygon",
165
+ coordinates: e.coordinates.map((e) => e.map(o))
166
+ } : e;
167
+ }
168
+ function I(e, t, n, r) {
169
+ let i = r + t, a = Math.PI / 180, o = (e) => {
170
+ let t = Math.cos(e[1] * a), o = e[1] + n, s = Math.cos(o * a), c = s > 1e-6 ? t / s : 1;
171
+ return [i + (e[0] - r) * c, o];
172
+ }, s = (e) => e.map(o);
173
+ return e.type === "Polygon" ? {
174
+ type: "Polygon",
175
+ coordinates: e.coordinates.map(s)
176
+ } : e.type === "MultiPolygon" ? {
177
+ type: "MultiPolygon",
178
+ coordinates: e.coordinates.map((e) => e.map(s))
179
+ } : e;
180
+ }
181
+ function L(e, t) {
182
+ let n = {
183
+ type: "Feature",
184
+ geometry: {
185
+ type: "Point",
186
+ coordinates: t
187
+ },
188
+ properties: {}
189
+ }, r = (e) => e.map((e) => ({
190
+ bearing: m(n, {
191
+ type: "Feature",
192
+ geometry: {
193
+ type: "Point",
194
+ coordinates: e
195
+ },
196
+ properties: {}
197
+ }),
198
+ distance: i(n, {
199
+ type: "Feature",
200
+ geometry: {
201
+ type: "Point",
202
+ coordinates: e
203
+ },
204
+ properties: {}
205
+ }, { units: "kilometers" })
206
+ }));
207
+ return e.type === "Polygon" ? e.coordinates.map(r) : e.type === "MultiPolygon" ? e.coordinates.flat().map(r) : [];
208
+ }
209
+ function R(e, t, n) {
210
+ let r = {
211
+ type: "Feature",
212
+ geometry: {
213
+ type: "Point",
214
+ coordinates: t
215
+ },
216
+ properties: {}
217
+ }, i = 0, a = () => (n[i++] ?? []).map(({ bearing: e, distance: t }) => T(r, t, e, { units: "kilometers" }).geometry.coordinates);
218
+ return e.type === "Polygon" ? {
219
+ type: "Polygon",
220
+ coordinates: e.coordinates.map(() => a())
221
+ } : e.type === "MultiPolygon" ? {
222
+ type: "MultiPolygon",
223
+ coordinates: e.coordinates.map((e) => e.map(() => a()))
224
+ } : e;
225
+ }
226
+ var z = class extends a {
227
+ constructor(...e) {
228
+ super(...e), this.toolId = "truearea", this.mapElement = null, this.availableLayers = [], this.selectedLayerId = "", this.copies = [], this.dragging = !1, this.lastTouchedCopyId = null, this.rotationDeg = 0, this.geodesic = !0, this.copyMeta = /* @__PURE__ */ new Map(), this.features = [], this.colorIdx = 0, this.unsubEvents = [], this.dragState = null;
229
+ }
230
+ onActivate() {
231
+ this.adapter && this.adapter.setTouchCaptureEnabled(!1), this.bindEvents();
232
+ }
233
+ onDeactivate() {
234
+ this.cleanupEvents(), this.adapter && (this.adapter.setPanEnabled(!0), this.adapter.setTouchCaptureEnabled(!0)), this.dragState = null, this.dragging = !1, this.clearGhost(), this.copies.length === 0 && this.cleanupLayers();
235
+ }
236
+ static {
237
+ this.styles = o`
238
+ :host { display: none; padding: var(--webmapx-tool-padding, 0); font-size: 0.875rem; min-width: 200px; }
239
+ :host([active]) { display: block; }
240
+ label { display: block; font-weight: 600; margin-bottom: 0.25rem; }
241
+ select { width: 100%; margin-bottom: 0.75rem; padding: 0.25rem; box-sizing: border-box; }
242
+ .hint { color: var(--sl-color-neutral-500, #888); font-style: italic; margin-bottom: 0.5rem; font-size: 0.8rem; }
243
+ .copy-item { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.5rem; }
244
+ .copy-swatch { width: 14px; height: 14px; border-radius: 3px; flex-shrink: 0; }
245
+ .copy-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
246
+ .copy-remove { cursor: pointer; color: var(--sl-color-danger-600, #c00); border: none; background: none; padding: 0 2px; font-size: 0.9rem; }
247
+ .clear-btn { width: 100%; padding: 0.3rem; cursor: pointer; }
248
+ .no-copies { color: var(--sl-color-neutral-500, #888); font-style: italic; font-size: 0.8rem; margin-bottom: 0.5rem; margin-top: 0.25rem; }
249
+ .dragging-hint { color: var(--sl-color-primary-600, #3b82f6); font-size: 0.8rem; margin-bottom: 0.4rem; }
250
+ .method-row { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.5rem; font-size: 0.8rem; color: var(--sl-color-neutral-600, #555); }
251
+ .method-row input { cursor: pointer; }
252
+ .method-row label { cursor: pointer; }
253
+ .rotation-row { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.5rem; }
254
+ .rotation-row input[type=range] {
255
+ flex: 1;
256
+ -webkit-appearance: none;
257
+ appearance: none;
258
+ height: 4px;
259
+ background: var(--sl-color-neutral-300, #ccc);
260
+ border-radius: 2px;
261
+ outline: none;
262
+ }
263
+ .rotation-row input[type=range]::-webkit-slider-thumb {
264
+ -webkit-appearance: none;
265
+ appearance: none;
266
+ width: 14px;
267
+ height: 14px;
268
+ border-radius: 50%;
269
+ background: var(--sl-color-primary-600, #3b82f6);
270
+ cursor: pointer;
271
+ }
272
+ .rotation-row input[type=range]::-moz-range-thumb {
273
+ width: 14px;
274
+ height: 14px;
275
+ border: none;
276
+ border-radius: 50%;
277
+ background: var(--sl-color-primary-600, #3b82f6);
278
+ cursor: pointer;
279
+ }
280
+ .rotation-reset { border: none; background: none; cursor: pointer; padding: 0 2px; font-size: 1rem; line-height: 1; color: var(--sl-color-neutral-600, #555); }
281
+ .rotation-reset:hover { color: var(--sl-color-primary-600, #3b82f6); }
282
+ .rotation-value { font-variant-numeric: tabular-nums; min-width: 3.5em; text-align: right; font-size: 0.8rem; color: var(--sl-color-neutral-600, #555); }
283
+ `;
284
+ }
285
+ onMapAttached(t) {
286
+ super.onMapAttached(t), this.mapElement = e(this), this.refreshLayers(t.store.getState()), this.active && (t.setTouchCaptureEnabled(!1), this.bindEvents());
287
+ }
288
+ onMapDetached() {
289
+ this.cleanupEvents(), this.cleanupLayers(), this.dragState = null, this.dragging = !1, this.features = [], this.copies = [], this.copyMeta.clear(), this.availableLayers = [], this.mapElement = null, super.onMapDetached();
290
+ }
291
+ onStateChanged(e) {
292
+ this.refreshLayers(e);
293
+ }
294
+ refreshLayers(e) {
295
+ let t = e.mapLayers ?? {}, n = [];
296
+ for (let [e, r] of Object.entries(t)) {
297
+ if (e === D || e.startsWith("truearea-")) continue;
298
+ let t = r.sourceData;
299
+ if (!t || !this.hasPolygonFeatures(t)) continue;
300
+ let i = r.label ?? e;
301
+ n.push({
302
+ id: e,
303
+ label: String(i),
304
+ sourceId: e
305
+ });
306
+ }
307
+ this.availableLayers = n, this.selectedLayerId && !n.find((e) => e.id === this.selectedLayerId) && (this.selectedLayerId = n[0]?.id ?? ""), !this.selectedLayerId && n.length > 0 && (this.selectedLayerId = n[0].id);
308
+ }
309
+ hasPolygonFeatures(e) {
310
+ return e.features.some((e) => e.geometry?.type === "Polygon" || e.geometry?.type === "MultiPolygon");
311
+ }
312
+ async setupLayers() {
313
+ !this.adapter || !this.mapElement || (this.adapter.hasLayer(D) || await this.mapElement.addLayerRequest({
314
+ id: D,
315
+ type: "style",
316
+ version: 8,
317
+ metadata: {
318
+ label: "TrueArea copies",
319
+ legendRole: "overlay",
320
+ attribution: "<a href=\"https://thetruesize.com\">The True Size Of</a>"
321
+ },
322
+ sources: { data: {
323
+ type: "geojson",
324
+ data: {
325
+ type: "FeatureCollection",
326
+ features: []
327
+ }
328
+ } },
329
+ layers: [{
330
+ id: "truearea-fill",
331
+ type: "fill",
332
+ source: "data",
333
+ paint: {
334
+ "fill-color": ["get", "color"],
335
+ "fill-opacity": .35
336
+ }
337
+ }, {
338
+ id: "truearea-line",
339
+ type: "line",
340
+ source: "data",
341
+ paint: {
342
+ "line-color": ["get", "color"],
343
+ "line-width": 2
344
+ }
345
+ }]
346
+ }), this.adapter.hasLayer(k) || await this.mapElement.addLayerRequest({
347
+ id: k,
348
+ type: "style",
349
+ version: 8,
350
+ metadata: { hideFromLegend: !0 },
351
+ sources: { data: {
352
+ type: "geojson",
353
+ data: {
354
+ type: "FeatureCollection",
355
+ features: []
356
+ }
357
+ } },
358
+ layers: [{
359
+ id: "truearea-ghost-fill",
360
+ type: "fill",
361
+ source: "data",
362
+ paint: {
363
+ "fill-color": ["get", "color"],
364
+ "fill-opacity": .2
365
+ }
366
+ }, {
367
+ id: "truearea-ghost-line",
368
+ type: "line",
369
+ source: "data",
370
+ paint: {
371
+ "line-color": ["get", "color"],
372
+ "line-width": 2,
373
+ "line-dasharray": [4, 3]
374
+ },
375
+ hideFromLegend: !0
376
+ }]
377
+ }));
378
+ }
379
+ cleanupLayers() {
380
+ !this.adapter || !this.mapElement || [k, D].forEach((e) => {
381
+ this.adapter.hasLayer(e) && this.mapElement.removeInlineLayer(e);
382
+ });
383
+ }
384
+ bindEvents() {
385
+ if (!this.adapter) return;
386
+ this.cleanupEvents();
387
+ let e = this.adapter.events.on("pointer-down", (e) => this.onPointerDown(e)), t = this.adapter.events.on("pointer-move", (e) => this.onDrag(e)), n = this.adapter.events.on("pointer-up", (e) => this.onDragEnd(e)), r = this.adapter.events.on("pointer-cancel", () => this.onDragCancel());
388
+ this.unsubEvents = [
389
+ e,
390
+ t,
391
+ n,
392
+ r
393
+ ];
394
+ }
395
+ cleanupEvents() {
396
+ this.unsubEvents.forEach((e) => e()), this.unsubEvents = [];
397
+ }
398
+ getSelectedSource() {
399
+ let e = this.availableLayers.find((e) => e.id === this.selectedLayerId);
400
+ return e ? {
401
+ sourceId: e.sourceId,
402
+ label: e.label
403
+ } : null;
404
+ }
405
+ async onPointerDown(e) {
406
+ if (!this.adapter) return;
407
+ await this.setupLayers();
408
+ let t = e.coords, n = this.features.find((e) => e.geometry && N(t, e.geometry));
409
+ if (n) {
410
+ let e = n.properties?.copyId, r = this.copies.find((t) => t.id === e), i = n.properties?.color ?? E[0], a = r?.label ?? e;
411
+ this.features = this.features.filter((t) => t.properties?.copyId !== e), this.updateTrueAreaSource();
412
+ let o = P(t, n.geometry), s = L(n.geometry, o);
413
+ if (this.dragState = {
414
+ feature: n,
415
+ centroid: o,
416
+ startCoords: t,
417
+ color: i,
418
+ label: a,
419
+ existingCopyId: e,
420
+ bearingDistances: s
421
+ }, this.dragging = !0, e !== this.lastTouchedCopyId) {
422
+ this.lastTouchedCopyId = e, this.rotationDeg = n.properties?.rotation ?? 0;
423
+ let t = this.copyMeta.get(e);
424
+ t && (this.geodesic = t.geodesic);
425
+ }
426
+ this.adapter.setPanEnabled(!1), this.updateGhost(t);
427
+ return;
428
+ }
429
+ let r = this.getSelectedSource();
430
+ if (!r) return;
431
+ let i = (this.adapter.store.getState().mapLayers ?? {})[r.sourceId]?.sourceData;
432
+ if (!i) return;
433
+ let a = i.features.find((e) => e.geometry && N(t, e.geometry));
434
+ if (!a) return;
435
+ let o = P(t, a.geometry), s = L(a.geometry, o), c = E[this.colorIdx % E.length], l = String(a.properties?.name ?? a.properties?.label ?? a.properties?.id ?? `Copy ${this.copies.length + 1}`);
436
+ this.dragState = {
437
+ feature: a,
438
+ centroid: o,
439
+ startCoords: t,
440
+ color: c,
441
+ label: l,
442
+ bearingDistances: s
443
+ }, this.dragging = !0, this.adapter.setPanEnabled(!1), this.updateGhost(t);
444
+ }
445
+ onDrag(e) {
446
+ this.dragState && this.updateGhost(e.coords);
447
+ }
448
+ updateGhost(e) {
449
+ if (!this.dragState || !this.adapter) return;
450
+ let { centroid: t, startCoords: n, color: r, bearingDistances: i, feature: a } = this.dragState, o = e[0] - n[0], s = e[1] - n[1], c = [t[0] + o, t[1] + s], l = {
451
+ type: "FeatureCollection",
452
+ features: [{
453
+ type: "Feature",
454
+ geometry: this.geodesic ? R(a.geometry, c, i) : I(a.geometry, o, s, t[0]),
455
+ properties: { color: r }
456
+ }]
457
+ };
458
+ this.adapter.getSource(A)?.setData(l);
459
+ }
460
+ onDragCancel() {
461
+ this.adapter && (this.adapter.setPanEnabled(!0), this.dragState?.existingCopyId && (this.features = [...this.features, this.dragState.feature], this.updateTrueAreaSource()), this.dragState = null, this.dragging = !1, this.clearGhost());
462
+ }
463
+ onDragEnd(e) {
464
+ if (!this.adapter) {
465
+ this.dragState = null, this.dragging = !1;
466
+ return;
467
+ }
468
+ if (this.adapter.setPanEnabled(!0), !this.dragState) return;
469
+ let { feature: t, centroid: n, startCoords: r, color: i, label: a, bearingDistances: o } = this.dragState, s = e.coords[0] - r[0], c = e.coords[1] - r[1], { existingCopyId: l } = this.dragState;
470
+ if (Math.abs(s) < 1e-6 && Math.abs(c) < 1e-6) {
471
+ l && (this.features = [...this.features, t], this.updateTrueAreaSource()), this.dragState = null, this.dragging = !1, this.clearGhost();
472
+ return;
473
+ }
474
+ let u = [n[0] + s, n[1] + c], d = this.geodesic ? R(t.geometry, u, o) : I(t.geometry, s, c, n[0]), f = l ?? `copy-${Date.now()}`, p = l ? this.lastTouchedCopyId === l ? this.rotationDeg : t.properties?.rotation ?? 0 : 0;
475
+ if (l) {
476
+ let e = this.copyMeta.get(l);
477
+ if (e) {
478
+ let t = [e.placedCentroid[0] + s, e.placedCentroid[1] + c];
479
+ this.copyMeta.set(l, {
480
+ ...e,
481
+ placedCentroid: t,
482
+ geodesic: this.geodesic
483
+ });
484
+ }
485
+ } else this.copyMeta.set(f, {
486
+ origGeom: t.geometry,
487
+ origCentroid: n,
488
+ placedCentroid: u,
489
+ bearingDistances: o,
490
+ geodesic: this.geodesic
491
+ });
492
+ this.features = [...this.features, {
493
+ type: "Feature",
494
+ geometry: d,
495
+ properties: {
496
+ ...t.properties,
497
+ color: i,
498
+ copyId: f,
499
+ rotation: p
500
+ }
501
+ }];
502
+ let m = {
503
+ type: "FeatureCollection",
504
+ features: this.features
505
+ };
506
+ this.adapter.getSource(O)?.setData(m), l || (this.copies = [...this.copies, {
507
+ id: f,
508
+ label: a,
509
+ color: i
510
+ }], this.colorIdx++, this.lastTouchedCopyId = f, this.rotationDeg = 0), this.dragState = null, this.dragging = !1, this.clearGhost();
511
+ }
512
+ clearGhost() {
513
+ this.adapter && this.adapter.getSource(A)?.setData({
514
+ type: "FeatureCollection",
515
+ features: []
516
+ });
517
+ }
518
+ recomputeLastCopy() {
519
+ if (!this.lastTouchedCopyId) return;
520
+ let e = this.copyMeta.get(this.lastTouchedCopyId);
521
+ if (!e) return;
522
+ let { origGeom: t, origCentroid: n, placedCentroid: r, bearingDistances: i } = e;
523
+ this.copyMeta.set(this.lastTouchedCopyId, {
524
+ ...e,
525
+ geodesic: this.geodesic
526
+ });
527
+ let a = r[0] - n[0], o = r[1] - n[1], s = this.geodesic ? R(t, r, i) : I(t, a, o, n[0]), c = this.rotationDeg, l = c === 0 ? s : F(s, c, r), u = this.lastTouchedCopyId;
528
+ this.features = this.features.map((e) => e.properties?.copyId === u ? {
529
+ ...e,
530
+ geometry: l,
531
+ properties: {
532
+ ...e.properties,
533
+ rotation: c
534
+ }
535
+ } : e), this.updateTrueAreaSource();
536
+ }
537
+ removeCopy(e) {
538
+ if (this.copies = this.copies.filter((t) => t.id !== e), this.features = this.features.filter((t) => t.properties?.copyId !== e), this.copyMeta.delete(e), this.lastTouchedCopyId === e) if (this.lastTouchedCopyId = this.copies[this.copies.length - 1]?.id ?? null, this.lastTouchedCopyId) {
539
+ this.rotationDeg = this.features.find((e) => e.properties?.copyId === this.lastTouchedCopyId)?.properties?.rotation ?? 0;
540
+ let e = this.copyMeta.get(this.lastTouchedCopyId);
541
+ e && (this.geodesic = e.geodesic);
542
+ } else this.rotationDeg = 0;
543
+ this.updateTrueAreaSource();
544
+ }
545
+ rotateLastCopy(e) {
546
+ if (!this.lastTouchedCopyId) return;
547
+ let t = this.features.find((e) => e.properties?.copyId === this.lastTouchedCopyId);
548
+ if (!t?.geometry) return;
549
+ let n = e - (t.properties?.rotation ?? 0), r = this.copyMeta.get(this.lastTouchedCopyId), i = r ? r.placedCentroid : j(t.geometry), a = F(t.geometry, n, i);
550
+ this.features = this.features.map((t) => t.properties?.copyId === this.lastTouchedCopyId ? {
551
+ ...t,
552
+ geometry: a,
553
+ properties: {
554
+ ...t.properties,
555
+ rotation: e
556
+ }
557
+ } : t), this.rotationDeg = e, this.updateTrueAreaSource();
558
+ }
559
+ clearAll() {
560
+ this.copies = [], this.features = [], this.copyMeta.clear(), this.lastTouchedCopyId = null, this.rotationDeg = 0, this.updateTrueAreaSource();
561
+ }
562
+ updateTrueAreaSource() {
563
+ this.adapter && this.adapter.getSource(O)?.setData({
564
+ type: "FeatureCollection",
565
+ features: this.features
566
+ });
567
+ }
568
+ render() {
569
+ return s`
570
+ <label>Source layer</label>
571
+ ${this.availableLayers.length === 0 ? s`<div class="hint">No visible polygon layers on map.</div>` : s`
572
+ <select @change=${(e) => {
573
+ this.selectedLayerId = e.target.value;
574
+ }}>
575
+ ${this.availableLayers.map((e) => s`
576
+ <option value=${e.id} ?selected=${e.id === this.selectedLayerId}>${e.label}</option>
577
+ `)}
578
+ </select>
579
+ ${this.dragging ? s`<div class="dragging-hint">Drag to target location, release to place.</div>` : s`<div class="hint">Click and drag a polygon to compare sizes.</div>`}
580
+ `}
581
+
582
+ ${(() => {
583
+ let e = this.copies.find((e) => e.id === this.lastTouchedCopyId);
584
+ return !e && this.availableLayers.length === 0 ? "" : e ? s`
585
+ <div class="copy-item">
586
+ <div class="copy-swatch" style="background:${e.color}"></div>
587
+ <span class="copy-label" title=${e.label}>${e.label}</span>
588
+ <button class="copy-remove" @click=${() => this.removeCopy(e.id)} title="Remove">✕</button>
589
+ </div>
590
+ <div class="rotation-row">
591
+ <input type="range" min="-180" max="180" step="1"
592
+ .value=${String(this.rotationDeg)}
593
+ @input=${(e) => this.rotateLastCopy(Number(e.target.value))}
594
+ />
595
+ <button class="rotation-reset" title="Reset to 0°" @click=${() => this.rotateLastCopy(0)}>↺</button>
596
+ <span class="rotation-value">${this.rotationDeg}°</span>
597
+ </div>
598
+ <div class="method-row">
599
+ <input type="checkbox" id="geodesic-toggle" .checked=${this.geodesic}
600
+ @change=${(e) => {
601
+ this.geodesic = e.target.checked, this.recomputeLastCopy();
602
+ }}
603
+ />
604
+ <label for="geodesic-toggle">Geodesic (shape-accurate, may rotate borders)</label>
605
+ </div>
606
+
607
+ ${this.copies.length > 0 ? s`<button class="clear-btn" @click=${() => this.clearAll()}>Clear all</button>` : ""}
608
+ ` : s`<div class="no-copies">No copy selected. Click a polygon on the map.</div>`;
609
+ })()}
610
+ `;
611
+ }
612
+ };
613
+ t([n()], z.prototype, "availableLayers", void 0), t([n()], z.prototype, "selectedLayerId", void 0), t([n()], z.prototype, "copies", void 0), t([n()], z.prototype, "dragging", void 0), t([n()], z.prototype, "lastTouchedCopyId", void 0), t([n()], z.prototype, "rotationDeg", void 0), t([n()], z.prototype, "geodesic", void 0), z = t([r("webmapx-truearea-tool")], z);
614
+ //#endregion
615
+ export { z as WebmapxTrueAreaTool };