@abi-software/flatmap-viewer 2.7.1 → 2.7.3-a.1

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 (122) hide show
  1. package/README.rst +1 -1
  2. package/dist/flatmapviewer.es.js +80577 -0
  3. package/dist/flatmapviewer.umd.js +1687 -0
  4. package/dist/lib/index.d.ts +4 -0
  5. package/dist/style.css +1 -0
  6. package/package.json +10 -8
  7. package/lib/index.ts +0 -10
  8. package/src/contextmenu.js +0 -97
  9. package/src/controls/annotation.js +0 -302
  10. package/src/controls/controls.js +0 -645
  11. package/src/controls/flightpaths.js +0 -95
  12. package/src/controls/info.js +0 -291
  13. package/src/controls/minimap.js +0 -442
  14. package/src/controls/paths.js +0 -143
  15. package/src/controls/search.js +0 -113
  16. package/src/controls/systems.js +0 -75
  17. package/src/controls/taxons.js +0 -73
  18. package/src/flatmap-viewer.js +0 -1789
  19. package/src/images.js +0 -66
  20. package/src/interactions.js +0 -1569
  21. package/src/layers/cluster.js +0 -178
  22. package/src/layers/filter.js +0 -310
  23. package/src/layers/flightpaths.js +0 -383
  24. package/src/layers/index.js +0 -478
  25. package/src/layers/styling.js +0 -1077
  26. package/src/main.js +0 -272
  27. package/src/mapserver.js +0 -64
  28. package/src/mathjax.js +0 -100
  29. package/src/pathways.js +0 -427
  30. package/src/search.js +0 -137
  31. package/src/systems.js +0 -146
  32. package/src/utils.js +0 -152
  33. package/static/css/flatmap-viewer.css +0 -238
  34. package/static/icons/favicon.ico +0 -0
  35. package/static/images/active.png +0 -0
  36. package/static/images/inactive.png +0 -0
  37. package/static/images/reset-map-active.png +0 -0
  38. package/static/images/reset-map-button.png +0 -0
  39. package/static/images/rounded-background.png +0 -0
  40. package/static/images/zoom-in-active.png +0 -0
  41. package/static/images/zoom-in-button.png +0 -0
  42. package/static/images/zoom-out-active.png +0 -0
  43. package/static/images/zoom-out-button.png +0 -0
  44. package/thirdParty/maplibre-gl-svg/CHANGELOG.md +0 -13
  45. package/thirdParty/maplibre-gl-svg/LICENSE +0 -21
  46. package/thirdParty/maplibre-gl-svg/LICENSE.md +0 -21
  47. package/thirdParty/maplibre-gl-svg/README.md +0 -24
  48. package/thirdParty/maplibre-gl-svg/assets/Add custom SVG template to template manager.jpg +0 -0
  49. package/thirdParty/maplibre-gl-svg/assets/All built-in SVG templates as HTML markers.jpg +0 -0
  50. package/thirdParty/maplibre-gl-svg/assets/All built-in SVG templates as symbols.jpg +0 -0
  51. package/thirdParty/maplibre-gl-svg/assets/Fill polygon with built-in SVG template.jpg +0 -0
  52. package/thirdParty/maplibre-gl-svg/assets/HTML Marker with Custom SVG Template.jpg +0 -0
  53. package/thirdParty/maplibre-gl-svg/assets/HTML Marker with built-in SVG template.jpg +0 -0
  54. package/thirdParty/maplibre-gl-svg/assets/Line layer with built-in SVG template.jpg +0 -0
  55. package/thirdParty/maplibre-gl-svg/assets/Load SVG from URL.jpg +0 -0
  56. package/thirdParty/maplibre-gl-svg/assets/SVG template options.jpg +0 -0
  57. package/thirdParty/maplibre-gl-svg/assets/Smiley_face_changed.svg +0 -37
  58. package/thirdParty/maplibre-gl-svg/assets/Symbol layer with built-in SVG template.jpg +0 -0
  59. package/thirdParty/maplibre-gl-svg/assets/image-templates/arrow-up-thin.png +0 -0
  60. package/thirdParty/maplibre-gl-svg/assets/image-templates/arrow-up.png +0 -0
  61. package/thirdParty/maplibre-gl-svg/assets/image-templates/car.png +0 -0
  62. package/thirdParty/maplibre-gl-svg/assets/image-templates/checker-rotated.png +0 -0
  63. package/thirdParty/maplibre-gl-svg/assets/image-templates/checker.png +0 -0
  64. package/thirdParty/maplibre-gl-svg/assets/image-templates/circles-spaced.png +0 -0
  65. package/thirdParty/maplibre-gl-svg/assets/image-templates/circles.png +0 -0
  66. package/thirdParty/maplibre-gl-svg/assets/image-templates/diagonal-lines-down.png +0 -0
  67. package/thirdParty/maplibre-gl-svg/assets/image-templates/diagonal-lines-up.png +0 -0
  68. package/thirdParty/maplibre-gl-svg/assets/image-templates/diagonal-stripes-down.png +0 -0
  69. package/thirdParty/maplibre-gl-svg/assets/image-templates/diagonal-stripes-up.png +0 -0
  70. package/thirdParty/maplibre-gl-svg/assets/image-templates/dots.png +0 -0
  71. package/thirdParty/maplibre-gl-svg/assets/image-templates/flag-triangle.png +0 -0
  72. package/thirdParty/maplibre-gl-svg/assets/image-templates/flag.png +0 -0
  73. package/thirdParty/maplibre-gl-svg/assets/image-templates/grid-lines.png +0 -0
  74. package/thirdParty/maplibre-gl-svg/assets/image-templates/hexagon-rounded-thick.png +0 -0
  75. package/thirdParty/maplibre-gl-svg/assets/image-templates/hexagon-rounded.png +0 -0
  76. package/thirdParty/maplibre-gl-svg/assets/image-templates/hexagon-thick.png +0 -0
  77. package/thirdParty/maplibre-gl-svg/assets/image-templates/hexagon.png +0 -0
  78. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-arrow.png +0 -0
  79. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-ball-pin.png +0 -0
  80. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-circle.png +0 -0
  81. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-flat.png +0 -0
  82. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-square-cluster.png +0 -0
  83. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-square-rounded-cluster.png +0 -0
  84. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-square-rounded.png +0 -0
  85. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-square.png +0 -0
  86. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker-thick.png +0 -0
  87. package/thirdParty/maplibre-gl-svg/assets/image-templates/marker.png +0 -0
  88. package/thirdParty/maplibre-gl-svg/assets/image-templates/pin-round.png +0 -0
  89. package/thirdParty/maplibre-gl-svg/assets/image-templates/pin.png +0 -0
  90. package/thirdParty/maplibre-gl-svg/assets/image-templates/rotated-grid-lines.png +0 -0
  91. package/thirdParty/maplibre-gl-svg/assets/image-templates/rotated-grid-stripes.png +0 -0
  92. package/thirdParty/maplibre-gl-svg/assets/image-templates/rounded-square-thick.png +0 -0
  93. package/thirdParty/maplibre-gl-svg/assets/image-templates/rounded-square.png +0 -0
  94. package/thirdParty/maplibre-gl-svg/assets/image-templates/triangle-arrow-left.png +0 -0
  95. package/thirdParty/maplibre-gl-svg/assets/image-templates/triangle-arrow-up.png +0 -0
  96. package/thirdParty/maplibre-gl-svg/assets/image-templates/triangle-thick.png +0 -0
  97. package/thirdParty/maplibre-gl-svg/assets/image-templates/triangle.png +0 -0
  98. package/thirdParty/maplibre-gl-svg/assets/image-templates/x-fill.png +0 -0
  99. package/thirdParty/maplibre-gl-svg/assets/image-templates/zig-zag-vertical.png +0 -0
  100. package/thirdParty/maplibre-gl-svg/assets/image-templates/zig-zag.png +0 -0
  101. package/thirdParty/maplibre-gl-svg/build/build.js +0 -210
  102. package/thirdParty/maplibre-gl-svg/dist/maplibre-gl-svg.js +0 -339
  103. package/thirdParty/maplibre-gl-svg/dist/maplibre-gl-svg.min.js +0 -4
  104. package/thirdParty/maplibre-gl-svg/docs/docs.md +0 -375
  105. package/thirdParty/maplibre-gl-svg/examples/Add custom SVG template to template manager.html +0 -101
  106. package/thirdParty/maplibre-gl-svg/examples/All built-in SVG templates as HTML markers.html +0 -82
  107. package/thirdParty/maplibre-gl-svg/examples/All built-in SVG templates as symbols.html +0 -124
  108. package/thirdParty/maplibre-gl-svg/examples/Fill polygon with built-in SVG template.html +0 -94
  109. package/thirdParty/maplibre-gl-svg/examples/HTML Marker with Custom SVG Template.html +0 -86
  110. package/thirdParty/maplibre-gl-svg/examples/HTML Marker with built-in SVG template.html +0 -83
  111. package/thirdParty/maplibre-gl-svg/examples/Line layer with built-in SVG template.html +0 -129
  112. package/thirdParty/maplibre-gl-svg/examples/Load SVG from URL.html +0 -96
  113. package/thirdParty/maplibre-gl-svg/examples/SVG template options.html +0 -264
  114. package/thirdParty/maplibre-gl-svg/examples/Symbol layer with built-in SVG template.html +0 -93
  115. package/thirdParty/maplibre-gl-svg/index.html +0 -151
  116. package/thirdParty/maplibre-gl-svg/package-lock.json +0 -5882
  117. package/thirdParty/maplibre-gl-svg/package.json +0 -49
  118. package/thirdParty/maplibre-gl-svg/src/SvgManager.ts +0 -186
  119. package/thirdParty/maplibre-gl-svg/src/SvgTemplateManager.ts +0 -144
  120. package/thirdParty/maplibre-gl-svg/src/index.ts +0 -4
  121. package/thirdParty/maplibre-gl-svg/tsconfig.json +0 -31
  122. package/thirdParty/maplibre-gl-svg/typings/index.d.ts +0 -111
@@ -1,645 +0,0 @@
1
- /******************************************************************************
2
-
3
- Flatmap viewer and annotation tool
4
-
5
- Copyright (c) 2019 - 2023 David Brooks
6
-
7
- Licensed under the Apache License, Version 2.0 (the "License");
8
- you may not use this file except in compliance with the License.
9
- You may obtain a copy of the License at
10
-
11
- http://www.apache.org/licenses/LICENSE-2.0
12
-
13
- Unless required by applicable law or agreed to in writing, software
14
- distributed under the License is distributed on an "AS IS" BASIS,
15
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- See the License for the specific language governing permissions and
17
- limitations under the License.
18
-
19
- ******************************************************************************/
20
-
21
- // Make sure colour string is in `#rrggbb` form.
22
- // Based on https://stackoverflow.com/a/47355187
23
-
24
- function standardise_color(str){
25
- const canvas = document.createElement("canvas");
26
- const ctx = canvas.getContext("2d");
27
- ctx.fillStyle = str;
28
- const colour = ctx.fillStyle;
29
- canvas.remove()
30
- return colour;
31
- }
32
-
33
- //==============================================================================
34
-
35
- export class Control
36
- {
37
- constructor(flatmap, id, name)
38
- {
39
- this.__flatmap = flatmap;
40
- this.__id = id;
41
- this.__name = name;
42
- this.__map = undefined;
43
- this.__prefix = `${this.__id}-`
44
- }
45
-
46
- getDefaultPosition()
47
- //==================
48
- {
49
- return 'top-right';
50
- }
51
-
52
- _addControlDetails()
53
- //==================
54
- {
55
- return {
56
- enabled: 0,
57
- total: 0
58
- }
59
- }
60
-
61
- _enableAll(enable)
62
- //================
63
- {
64
- }
65
-
66
- __setAllCheckedState()
67
- //====================
68
- {
69
- if (this.__checkedCount === 0) {
70
- this.__allCheckbox.checked = false;
71
- this.__allCheckbox.indeterminate = false;
72
- } else if (this.__checkedCount === this.__totalCount) {
73
- this.__allCheckbox.checked = true;
74
- this.__allCheckbox.indeterminate = false;
75
- } else {
76
- this.__allCheckbox.indeterminate = true;
77
- }
78
- }
79
-
80
- _addControlLine(id, name, style=null)
81
- //===================================
82
- {
83
- const label = document.createElement('label');
84
- label.setAttribute('for', id);
85
- if (style !== null) {
86
- label.setAttribute('style', style);
87
- }
88
- label.textContent = name;
89
- this.__control.appendChild(label);
90
- const input = document.createElement('input');
91
- input.setAttribute('type', 'checkbox');
92
- input.id = id;
93
- this.__control.appendChild(input);
94
- return input;
95
- }
96
-
97
- onAdd(map)
98
- //========
99
- {
100
- this.__map = map;
101
- this.__container = document.createElement('div');
102
- this.__container.className = 'maplibregl-ctrl flatmap-control';
103
- this.__control = document.createElement('div');
104
- this.__control.className = 'flatmap-control-grid';
105
-
106
- this.__allCheckbox = this._addControlLine(`control-all-${this.__id}`, `ALL ${this.__name.toUpperCase()}:`);
107
- const controlDetails = this._addControlDetails();
108
- this.__totalCount = controlDetails.total;
109
- this.__halfCount = Math.trunc(this.__totalCount/2);
110
- this.__checkedCount = controlDetails.enabled;
111
- this.__setAllCheckedState();
112
-
113
- /*
114
- const innerDetails = this._innerLinesHTML();
115
- const innerHTML = innerDetails.html;
116
- innerHTML.splice(0, 0, `<label for="control-all-${this.__id}">ALL ${this.__name.toUpperCase()}:</label><input id="control-all-${this.__id}" type="checkbox"/>`);
117
- this.__control.innerHTML = innerHTML.join('\n');
118
-
119
- this.__totalCount = innerHTML.length;
120
- this.__halfCount = Math.trunc(this.__totalCount/2);
121
- this.__checkedCount = innerDetails.enabled;
122
- this.__allCheckbox = document.getElementById(`control-all-${this.__id}`);
123
- this.__setAllCheckedState();
124
- */
125
-
126
- this.__button = document.createElement('button');
127
- this.__button.id = `flatmap-${this.__id}-button`;
128
- this.__button.className = 'control-button text-button';
129
- this.__button.setAttribute('type', 'button');
130
- this.__button.setAttribute('aria-label', `Show/hide map's ${this.__name}`);
131
- this.__button.setAttribute('control-visible', 'false');
132
- this.__button.textContent = this.__name.toUpperCase().substring(0, 6);
133
- this.__button.title = `Show/hide map's ${this.__name}`;
134
- this.__container.appendChild(this.__button);
135
-
136
- this.__container.addEventListener('click', this.onClick_.bind(this));
137
- return this.__container;
138
- }
139
-
140
- onRemove()
141
- //========
142
- {
143
- this.__container.parentNode.removeChild(this.__container);
144
- this.__map = undefined;
145
- }
146
-
147
- onClick_(event)
148
- //=============
149
- {
150
- if (event.target.id === `flatmap-${this.__id}-button`) {
151
- if (this.__button.getAttribute('control-visible') === 'false') {
152
- this.__container.appendChild(this.__control);
153
- this.__button.setAttribute('control-visible', 'true');
154
- this.__control.focus();
155
- } else {
156
- this.__control = this.__container.removeChild(this.__control);
157
- this.__button.setAttribute('control-visible', 'false');
158
- }
159
- } else if (event.target.tagName === 'INPUT') {
160
- if (event.target.id === `control-all-${this.__id}`) {
161
- if (event.target.indeterminate) {
162
- event.target.checked = (this.__checkedCount >= this.__halfCount);
163
- event.target.indeterminate = false;
164
- }
165
- this.__checkedCount = event.target.checked ? this.__totalCount : 0;
166
- this._enableAll(event.target.checked);
167
- } else if (event.target.id.startsWith(`${this.__id}-`)) {
168
- this.__enableControl(event.target.id.substring(this.__prefix.length),
169
- event.target.checked);
170
- this.__checkedCount += (event.target.checked ? 1 : -1);
171
- this.__setAllCheckedState();
172
- }
173
- }
174
- event.stopPropagation();
175
- }
176
- }
177
-
178
- //==============================================================================
179
-
180
- export class NavigationControl
181
- {
182
- constructor(flatmap)
183
- {
184
- this._flatmap = flatmap;
185
- this._map = undefined;
186
- }
187
-
188
- getDefaultPosition()
189
- //==================
190
- {
191
- return 'top-right';
192
- }
193
-
194
- onAdd(map)
195
- //========
196
- {
197
- this._map = map;
198
- this._container = document.createElement('div');
199
- this._container.className = 'maplibregl-ctrl navigation-group';
200
- this._container.innerHTML = `<button id="flatmap-zoom-in" class="navigation-zoom-in" type="button" title="Zoom in" aria-label="Zoom in"></button>
201
- <button id="flatmap-zoom-out" class="navigation-zoom-out" type="button" title="Zoom out" aria-label="Zoom out"></button>
202
- <button id="flatmap-reset" class="navigation-reset" type="button" title="Reset" aria-label="Reset"></button>`;
203
- this._container.onclick = this.onClick_.bind(this);
204
- return this._container;
205
- }
206
-
207
- onRemove()
208
- //========
209
- {
210
- this._container.parentNode.removeChild(this._container);
211
- this._map = undefined;
212
- }
213
-
214
- onClick_(e)
215
- //=========
216
- {
217
- if (e.target.id === 'flatmap-zoom-in') {
218
- this._flatmap.zoomIn();
219
- } else if (e.target.id === 'flatmap-zoom-out') {
220
- this._flatmap.zoomOut();
221
- } else if (e.target.id === 'flatmap-reset') {
222
- this._flatmap.resetMap();
223
- }
224
- }
225
- }
226
-
227
- //==============================================================================
228
-
229
- export class LayerControl
230
- {
231
- constructor(flatmap, layerManager)
232
- {
233
- this.__flatmap = flatmap;
234
- this.__layers = layerManager.layers;
235
- this.__map = undefined;
236
- }
237
-
238
- getDefaultPosition()
239
- //==================
240
- {
241
- return 'top-right';
242
- }
243
-
244
- onAdd(map)
245
- //========
246
- {
247
- this.__map = map;
248
- this.__container = document.createElement('div');
249
- this.__container.className = 'maplibregl-ctrl flatmap-control';
250
- this.__layersControl = document.createElement('div');
251
- this.__layersControl.className = 'flatmap-control-grid';
252
-
253
- const innerHTML = [];
254
- innerHTML.push(`<label for="layer-all-layers">ALL LAYERS:</label><input id="layer-all-layers" type="checkbox" checked/>`);
255
- for (const layer of this.__layers) {
256
- innerHTML.push(`<label for="layer-${layer.id}">${layer.description}</label><input id="layer-${layer.id}" type="checkbox" checked/>`);
257
- }
258
- this.__layersControl.innerHTML = innerHTML.join('\n');
259
-
260
- this.__layersCount = this.__layers;
261
- this.__checkedCount = this.__layersCount;
262
- this.__halfCount = Math.trunc(this.__checkedCount/2);
263
-
264
- this.__button = document.createElement('button');
265
- this.__button.id = 'map-layers-button';
266
- this.__button.className = 'control-button text-button';
267
- this.__button.setAttribute('type', 'button');
268
- this.__button.setAttribute('aria-label', 'Show/hide map layers');
269
- this.__button.setAttribute('control-visible', 'false');
270
- this.__button.textContent = 'LAYERS';
271
- this.__button.title = 'Show/hide map layers';
272
- this.__container.appendChild(this.__button);
273
-
274
- this.__container.addEventListener('click', this.onClick_.bind(this));
275
- return this.__container;
276
- }
277
-
278
- onRemove()
279
- //========
280
- {
281
- this.__container.parentNode.removeChild(this.__container);
282
- this.__map = undefined;
283
- }
284
-
285
- onClick_(event)
286
- //=============
287
- {
288
- if (event.target.id === 'map-layers-button') {
289
- if (this.__button.getAttribute('control-visible') === 'false') {
290
- this.__container.appendChild(this.__layersControl);
291
- this.__button.setAttribute('control-visible', 'true');
292
- this.__layersControl.focus();
293
- } else {
294
- this.__layersControl = this.__container.removeChild(this.__layersControl);
295
- this.__button.setAttribute('control-visible', 'false');
296
- }
297
- } else if (event.target.tagName === 'INPUT') {
298
- if (event.target.id === 'layer-all-layers') {
299
- if (event.target.indeterminate) {
300
- event.target.checked = (this.__checkedCount >= this.__halfCount);
301
- event.target.indeterminate = false;
302
- }
303
- if (event.target.checked) {
304
- this.__checkedCount = this.__layersCount;
305
- } else {
306
- this.__checkedCount = 0;
307
- }
308
- for (const layer of this.__layers) {
309
- const layerCheckbox = document.getElementById(`layer-${layer.id}`);
310
- if (layerCheckbox) {
311
- layerCheckbox.checked = event.target.checked;
312
- this.__flatmap.enableLayer(layer.id, event.target.checked);
313
- }
314
- }
315
- } else if (event.target.id.startsWith('layer-')) {
316
- const layerId = event.target.id.substring(6);
317
- this.__flatmap.enableLayer(layerId, event.target.checked);
318
- if (event.target.checked) {
319
- this.__checkedCount += 1;
320
- } else {
321
- this.__checkedCount -= 1;
322
- }
323
- const allLayersCheckbox = document.getElementById('layer-all-layers');
324
- if (this.__checkedCount === 0) {
325
- allLayersCheckbox.checked = false;
326
- allLayersCheckbox.indeterminate = false;
327
- } else if (this.__checkedCount === this.__layersCount) {
328
- allLayersCheckbox.checked = true;
329
- allLayersCheckbox.indeterminate = false;
330
- } else {
331
- allLayersCheckbox.indeterminate = true;
332
- }
333
- }
334
- }
335
- event.stopPropagation();
336
- }
337
- }
338
-
339
- //==============================================================================
340
-
341
- const SCKAN_STATES = [
342
- {
343
- 'id': 'VALID',
344
- 'description': 'Path consistent with SCKAN'
345
- },
346
- {
347
- 'id': 'INVALID',
348
- 'description': 'Path inconsistent with SCKAN'
349
- }
350
- ];
351
-
352
-
353
- export class SCKANControl
354
- {
355
- constructor(flatmap, options={sckan: 'valid'})
356
- {
357
- this.__flatmap = flatmap;
358
- this.__map = undefined;
359
- this.__initialState = options.sckan || 'valid';
360
- }
361
-
362
- getDefaultPosition()
363
- //==================
364
- {
365
- return 'top-right';
366
- }
367
-
368
- onAdd(map)
369
- //========
370
- {
371
- this.__map = map;
372
- this.__container = document.createElement('div');
373
- this.__container.className = 'maplibregl-ctrl flatmap-control';
374
- this.__sckan = document.createElement('div');
375
- this.__sckan.className = 'flatmap-control-grid';
376
-
377
- const innerHTML = [];
378
- let checked = (this.__initialState === 'all') ? 'checked' : '';
379
- innerHTML.push(`<label for="sckan-all-paths">ALL PATHS:</label><input id="sckan-all-paths" type="checkbox" ${checked}/>`);
380
- for (const state of SCKAN_STATES) {
381
- checked = (this.__initialState.toUpperCase() === state.id) ? 'checked' : '';
382
- innerHTML.push(`<label for="sckan-${state.id}">${state.description}</label><input id="sckan-${state.id}" type="checkbox" ${checked}/>`);
383
- }
384
- this.__sckan.innerHTML = innerHTML.join('\n');
385
-
386
- this.__sckanCount = SCKAN_STATES.length;
387
- this.__checkedCount = (this.__initialState === 'all') ? this.__sckanCount
388
- : (this.__initialState === 'none') ? 0
389
- : 1;
390
- this.__halfCount = Math.trunc(this.__sckanCount/2);
391
-
392
- this.__button = document.createElement('button');
393
- this.__button.id = 'map-sckan-button';
394
- this.__button.className = 'control-button text-button';
395
- this.__button.setAttribute('type', 'button');
396
- this.__button.setAttribute('aria-label', 'Show/hide valid SCKAN paths');
397
- this.__button.setAttribute('control-visible', 'false');
398
- this.__button.textContent = 'SCKAN';
399
- this.__button.title = 'Show/hide valid SCKAN paths';
400
- this.__container.appendChild(this.__button);
401
-
402
- this.__container.addEventListener('click', this.onClick_.bind(this));
403
- return this.__container;
404
- }
405
-
406
- onRemove()
407
- //========
408
- {
409
- this.__container.parentNode.removeChild(this.__container);
410
- this.__map = undefined;
411
- }
412
-
413
- onClick_(event)
414
- //=============
415
- {
416
- if (event.target.id === 'map-sckan-button') {
417
- if (this.__button.getAttribute('control-visible') === 'false') {
418
- this.__container.appendChild(this.__sckan);
419
- this.__button.setAttribute('control-visible', 'true');
420
- const allLayersCheckbox = document.getElementById('sckan-all-paths');
421
- allLayersCheckbox.indeterminate = (this.__checkedCount > 0)
422
- && (this.__checkedCount < this.__sckanCount);
423
- this.__sckan.focus();
424
- } else {
425
- this.__sckan = this.__container.removeChild(this.__sckan);
426
- this.__button.setAttribute('control-visible', 'false');
427
- }
428
- } else if (event.target.tagName === 'INPUT') {
429
- if (event.target.id === 'sckan-all-paths') {
430
- if (event.target.indeterminate) {
431
- event.target.checked = (this.__checkedCount >= this.__halfCount);
432
- event.target.indeterminate = false;
433
- }
434
- if (event.target.checked) {
435
- this.__state = 'all';
436
- this.__checkedCount = this.__sckanCount;
437
- } else {
438
- this.__state = 'none';
439
- this.__checkedCount = 0;
440
- }
441
- for (const state of SCKAN_STATES) {
442
- const sckanCheckbox = document.getElementById(`sckan-${state.id}`);
443
- if (sckanCheckbox) {
444
- sckanCheckbox.checked = event.target.checked;
445
- this.__flatmap.enableSckanPath(state.id, event.target.checked);
446
- }
447
- }
448
- } else if (event.target.id.startsWith('sckan-')) {
449
- const sckanId = event.target.id.substring(6);
450
- this.__flatmap.enableSckanPath(sckanId, event.target.checked);
451
- if (event.target.checked) {
452
- this.__checkedCount += 1;
453
- } else {
454
- this.__checkedCount -= 1;
455
- }
456
- const allLayersCheckbox = document.getElementById('sckan-all-paths');
457
- if (this.__checkedCount === 0) {
458
- allLayersCheckbox.checked = false;
459
- allLayersCheckbox.indeterminate = false;
460
- } else if (this.__checkedCount === this.__sckanCount) {
461
- allLayersCheckbox.checked = true;
462
- allLayersCheckbox.indeterminate = false;
463
- } else {
464
- allLayersCheckbox.indeterminate = true;
465
- }
466
- }
467
- }
468
- event.stopPropagation();
469
- }
470
- }
471
-
472
- //==============================================================================
473
-
474
- export class NerveControl
475
- {
476
- constructor(flatmap, options={showCentrelines: false})
477
- {
478
- this.__flatmap = flatmap;
479
- this.__map = undefined;
480
- this.__visible = options.showCentrelines || false;
481
- }
482
-
483
- getDefaultPosition()
484
- //==================
485
- {
486
- return 'top-right';
487
- }
488
-
489
- onAdd(map)
490
- //========
491
- {
492
- this.__map = map;
493
- this.__container = document.createElement('div');
494
- this.__container.className = 'maplibregl-ctrl';
495
-
496
- this.__button = document.createElement('button');
497
- this.__button.id = 'map-nerve-button';
498
- this.__button.className = 'control-button text-button';
499
- this.__button.setAttribute('type', 'button');
500
- this.__button.setAttribute('aria-label', 'Show/hide nerve centrelines');
501
- this.__button.textContent = 'NERVES';
502
- this.__button.title = 'Show/hide nerve centrelines';
503
- this.__container.appendChild(this.__button);
504
-
505
- this.__container.addEventListener('click', this.onClick_.bind(this));
506
- return this.__container;
507
- }
508
-
509
- onRemove()
510
- //========
511
- {
512
- this.__container.parentNode.removeChild(this.__container);
513
- this.__map = undefined;
514
- }
515
-
516
- onClick_(event)
517
- //=============
518
- {
519
- if (event.target.id === 'map-nerve-button') {
520
- this.__visible = !this.__visible;
521
- this.__flatmap.enableCentrelines(this.__visible);
522
- }
523
- event.stopPropagation();
524
- }
525
- }
526
-
527
- //==============================================================================
528
-
529
- export class AnnotatorControl
530
- {
531
- #enabled = false
532
-
533
- constructor(flatmap)
534
- {
535
- this.__flatmap = flatmap
536
- this.__map = null
537
- }
538
-
539
- getDefaultPosition()
540
- //==================
541
- {
542
- return 'top-right'
543
- }
544
-
545
- onAdd(map)
546
- //========
547
- {
548
- this.__map = map;
549
- this.__container = document.createElement('div');
550
- this.__container.className = 'maplibregl-ctrl';
551
-
552
- this.__button = document.createElement('button');
553
- this.__button.id = 'map-annotated-button';
554
- this.__button.className = 'control-button text-button';
555
- this.__button.setAttribute('type', 'button');
556
- this.__button.setAttribute('aria-label', 'Draw on map for annotation');
557
- this.__button.textContent = 'DRAW';
558
- this.__button.title = 'Draw on map for annotation';
559
- this.__container.appendChild(this.__button);
560
-
561
- this.__container.addEventListener('click', this.onClick_.bind(this));
562
- this.__setBackground();
563
- return this.__container;
564
- }
565
-
566
- __setBackground()
567
- //===============
568
- {
569
- if (this.#enabled) {
570
- this.__button.setAttribute('style', 'background: red');
571
- } else {
572
- this.__button.removeAttribute('style');
573
- }
574
- }
575
-
576
- onRemove()
577
- //========
578
- {
579
- this.__container.parentNode.removeChild(this.__container)
580
- this.__map = null
581
- }
582
-
583
- onClick_(event)
584
- //=============
585
- {
586
- if (event.target.id === 'map-annotated-button') {
587
- this.#enabled = !this.#enabled
588
- this.__setBackground()
589
- this.__flatmap.showAnnotator(this.#enabled)
590
- }
591
- event.stopPropagation();
592
- }
593
- }
594
-
595
- //==============================================================================
596
-
597
- export class BackgroundControl
598
- {
599
- constructor(flatmap)
600
- {
601
- this.__flatmap = flatmap;
602
- this.__map = undefined;
603
- }
604
-
605
- getDefaultPosition()
606
- //==================
607
- {
608
- return 'bottom-right';
609
- }
610
-
611
- onAdd(map)
612
- //========
613
- {
614
- this.__map = map;
615
- this.__container = document.createElement('div');
616
- this.__container.className = 'maplibregl-ctrl';
617
- this.__colourDiv = document.createElement('div');
618
- this.__colourDiv.setAttribute('aria-label', 'Change background colour');
619
- this.__colourDiv.title = 'Change background colour';
620
- const background = standardise_color(this.__flatmap.getBackgroundColour());
621
- this.__colourDiv.innerHTML = `<input type="color" id="colourPicker" value="${background}">`;
622
- this.__container.appendChild(this.__colourDiv);
623
- this.__colourDiv.addEventListener('input', this.__updateColour.bind(this), false);
624
- this.__colourDiv.addEventListener('change', this.__updateColour.bind(this), false);
625
- return this.__container;
626
- }
627
-
628
- onRemove()
629
- //========
630
- {
631
- this.__container.parentNode.removeChild(this.__container);
632
- this.__map = undefined;
633
- }
634
-
635
- __updateColour(event)
636
- //===================
637
- {
638
- const colour = event.target.value;
639
- this.__flatmap.setBackgroundColour(colour);
640
- this.__flatmap.controlEvent('change', 'background', colour)
641
- event.stopPropagation();
642
- }
643
- }
644
-
645
- //==============================================================================