@geogirafe/lib-geoportal 1.1.0-dev.2545448597 → 1.1.0-dev.2557861681
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/api/apigeogirafeapp.d.ts +3 -0
- package/api/apigeogirafeapp.js +96 -1
- package/package.json +1 -1
- package/templates/api.html +39 -7
- package/templates/public/about.json +1 -1
- package/templates/public/api/data-cartoriviera.txt +8 -0
- package/templates/public/api/data-mapbs.txt +6 -0
- package/templates/public/api/marker-huge.png +0 -0
- package/templates/public/api/marker-plus.png +0 -0
- package/templates/public/api/marker2-plus.png +0 -0
package/api/apigeogirafeapp.d.ts
CHANGED
|
@@ -27,6 +27,9 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
27
27
|
private manageTooltipAttribute;
|
|
28
28
|
private manageMarkersAttribute;
|
|
29
29
|
private markerStringToMapMarker;
|
|
30
|
+
private manageMarkersFileAttribute;
|
|
31
|
+
private readMarkersFromFile;
|
|
32
|
+
private lineToMarker;
|
|
30
33
|
private initialize;
|
|
31
34
|
private injectConfigMetaTags;
|
|
32
35
|
}
|
package/api/apigeogirafeapp.js
CHANGED
|
@@ -11,6 +11,21 @@ import MapCustomContextMenuComponent from '../components/context-menu/custom-con
|
|
|
11
11
|
import SearchComponent from '../components/search/component.js';
|
|
12
12
|
import SelectionWindowComponent from '../components/selectionwindow/component.js';
|
|
13
13
|
import { splitTrimAndConvertToNumber } from '../tools/utils/utils.js';
|
|
14
|
+
const getImageSize = (url) => {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const img = new Image();
|
|
17
|
+
img.onload = () => {
|
|
18
|
+
resolve({
|
|
19
|
+
width: img.naturalWidth,
|
|
20
|
+
height: img.naturalHeight
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
img.onerror = () => {
|
|
24
|
+
reject(new Error(`Failed to load image: ${url}`));
|
|
25
|
+
};
|
|
26
|
+
img.src = url;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
14
29
|
export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
15
30
|
templateUrl = null;
|
|
16
31
|
styleUrls = null;
|
|
@@ -47,7 +62,7 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
47
62
|
});
|
|
48
63
|
}
|
|
49
64
|
static get observedAttributes() {
|
|
50
|
-
return ['center', 'zoom', 'basemap', 'basemapselector', 'crosshair', 'tooltip', 'markers', 'layers'];
|
|
65
|
+
return ['center', 'zoom', 'basemap', 'basemapselector', 'crosshair', 'tooltip', 'markers', 'markersfile', 'layers'];
|
|
51
66
|
}
|
|
52
67
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
53
68
|
if (this.isInitialized) {
|
|
@@ -74,6 +89,9 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
74
89
|
else if (name === 'markers') {
|
|
75
90
|
this.manageMarkersAttribute();
|
|
76
91
|
}
|
|
92
|
+
else if (name === 'markersfile') {
|
|
93
|
+
this.manageMarkersFileAttribute();
|
|
94
|
+
}
|
|
77
95
|
else if (name === 'layers') {
|
|
78
96
|
this.manageLayersAttribute();
|
|
79
97
|
}
|
|
@@ -96,6 +114,7 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
96
114
|
this.manageCrosshairAttribute();
|
|
97
115
|
this.manageTooltipAttribute();
|
|
98
116
|
this.manageMarkersAttribute();
|
|
117
|
+
this.manageMarkersFileAttribute();
|
|
99
118
|
this.manageLayersAttribute();
|
|
100
119
|
this.manageSelectionboxAttribute();
|
|
101
120
|
this.manageUserInteraction();
|
|
@@ -294,6 +313,82 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
294
313
|
return undefined;
|
|
295
314
|
}
|
|
296
315
|
}
|
|
316
|
+
manageMarkersFileAttribute() {
|
|
317
|
+
const markersFile = this.getAttributeFromConfig('markersfile');
|
|
318
|
+
if (markersFile) {
|
|
319
|
+
void this.readMarkersFromFile(markersFile).then((markers) => {
|
|
320
|
+
this.context.stateManager.state.position.markers.push(...markers);
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
async readMarkersFromFile(fileUrl) {
|
|
325
|
+
const response = await fetch(fileUrl);
|
|
326
|
+
if (!response.ok) {
|
|
327
|
+
console.warn(`Cannot read markers file '${fileUrl}': ${response.status} ${response.statusText}`);
|
|
328
|
+
return [];
|
|
329
|
+
}
|
|
330
|
+
const fileContent = await response.text();
|
|
331
|
+
const lines = fileContent
|
|
332
|
+
.split(/\r?\n/)
|
|
333
|
+
.map((line) => line.trim())
|
|
334
|
+
.filter((line) => line.length > 0);
|
|
335
|
+
if (lines.length < 2) {
|
|
336
|
+
return [];
|
|
337
|
+
}
|
|
338
|
+
const headers = lines[0].split('\t').map((header) => header.trim());
|
|
339
|
+
const pointIndex = headers.indexOf('point');
|
|
340
|
+
const iconIndex = headers.indexOf('icon');
|
|
341
|
+
const iconSizeIndex = headers.indexOf('iconSize');
|
|
342
|
+
const iconOffsetIndex = headers.indexOf('iconOffset');
|
|
343
|
+
if (pointIndex === -1 || iconIndex === -1) {
|
|
344
|
+
console.warn(`Invalid markers file '${fileUrl}': missing required 'point' or 'icon' column`);
|
|
345
|
+
return [];
|
|
346
|
+
}
|
|
347
|
+
const markers = [];
|
|
348
|
+
const legacy = fileUrl.includes('legacy');
|
|
349
|
+
for (const line of lines.slice(1)) {
|
|
350
|
+
await this.lineToMarker(line, pointIndex, iconIndex, iconSizeIndex, iconOffsetIndex, legacy).then((marker) => {
|
|
351
|
+
if (marker) {
|
|
352
|
+
markers.push(marker);
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return markers;
|
|
357
|
+
}
|
|
358
|
+
async lineToMarker(line, pointIndex, iconIndex, iconSizeIndex, iconOffsetIndex, legacy) {
|
|
359
|
+
const columns = line.split('\t');
|
|
360
|
+
const coords = splitTrimAndConvertToNumber(columns[pointIndex]);
|
|
361
|
+
const imageUrl = columns[iconIndex]?.trim();
|
|
362
|
+
if (coords.length < 2 || !imageUrl || Number.isNaN(coords[0]) || Number.isNaN(coords[1])) {
|
|
363
|
+
console.warn(`Invalid marker line ': ${line}`);
|
|
364
|
+
return undefined;
|
|
365
|
+
}
|
|
366
|
+
// In the old WebGIS the coordinates are in the wrong order. This is to ensure compatibility with older data.
|
|
367
|
+
if (coords[0] < coords[1] && this.context.stateManager.state.projection === 'EPSG:2056') {
|
|
368
|
+
coords.reverse();
|
|
369
|
+
}
|
|
370
|
+
const size = iconSizeIndex >= 0 && columns[iconSizeIndex]?.trim()
|
|
371
|
+
? splitTrimAndConvertToNumber(columns[iconSizeIndex])
|
|
372
|
+
: undefined;
|
|
373
|
+
let offset = iconOffsetIndex >= 0 && columns[iconOffsetIndex]?.trim()
|
|
374
|
+
? splitTrimAndConvertToNumber(columns[iconOffsetIndex])
|
|
375
|
+
: undefined;
|
|
376
|
+
// In the old WebGIS the Offset referred to the Size of the original Image, while now it refers to the Size of the
|
|
377
|
+
// resized Image. This is to ensure compatibility with older data.
|
|
378
|
+
if (offset && size && legacy) {
|
|
379
|
+
await getImageSize(imageUrl).then((imageSize) => {
|
|
380
|
+
const scaleX = size[0] / imageSize.width;
|
|
381
|
+
const scaleY = size[1] / imageSize.height;
|
|
382
|
+
offset = [offset[0] * scaleX, offset[1] * scaleY];
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
position: [coords[0], coords[1]],
|
|
387
|
+
imageUrl,
|
|
388
|
+
size,
|
|
389
|
+
offset
|
|
390
|
+
};
|
|
391
|
+
}
|
|
297
392
|
async initialize() {
|
|
298
393
|
await this.context.initialize();
|
|
299
394
|
// Register Coordinate Reference Systems (CRS) definitions in PROJ4
|
package/package.json
CHANGED
package/templates/api.html
CHANGED
|
@@ -113,6 +113,10 @@
|
|
|
113
113
|
text-align: left;
|
|
114
114
|
margin-bottom: 1rem;
|
|
115
115
|
}
|
|
116
|
+
ul {
|
|
117
|
+
width: 100%;
|
|
118
|
+
margin: 0;
|
|
119
|
+
}
|
|
116
120
|
</style>
|
|
117
121
|
|
|
118
122
|
<script type="module" src="src/main.api.ts"></script>
|
|
@@ -292,9 +296,12 @@
|
|
|
292
296
|
|
|
293
297
|
<!-- Multiple markers with size and/or offset -->
|
|
294
298
|
<h2>Add multiple markers with size and/or offset on the map</h2>
|
|
295
|
-
<p class="descr">
|
|
296
|
-
|
|
297
|
-
|
|
299
|
+
<p class="descr">
|
|
300
|
+
Add multiple markers at the defined coordinates. <br />
|
|
301
|
+
You can specify size and offset.<br />
|
|
302
|
+
If you only specify three parameters, the third parameter can be the size if you <strong>don't</strong> include
|
|
303
|
+
a sign (e.g. <code>24,24</code>) or the offset if you <strong>do</strong> include a sign (e.g.
|
|
304
|
+
<code>+2,-6</code>).
|
|
298
305
|
</p>
|
|
299
306
|
<section>
|
|
300
307
|
<div class="row">
|
|
@@ -305,6 +312,35 @@
|
|
|
305
312
|
</div>
|
|
306
313
|
</section>
|
|
307
314
|
|
|
315
|
+
<!-- Multiple markers with size and/or offset -->
|
|
316
|
+
<h2>Add multiple markers on the map by providing a File/URL</h2>
|
|
317
|
+
<p class="descr">
|
|
318
|
+
You can provide a URL to a TXT file containing markers.<br />
|
|
319
|
+
Each line represents a marker with TAB-separated values.<br />
|
|
320
|
+
The file must contain the column names as header.
|
|
321
|
+
</p>
|
|
322
|
+
<p class="descr">Allowed column names:</p>
|
|
323
|
+
<ul>
|
|
324
|
+
<li><strong>point</strong>: coordinates where the amrker should be added.</li>
|
|
325
|
+
<li><strong>icon</strong>: url to the marker image</li>
|
|
326
|
+
<li><strong>iconSize</strong> (optional): size if the marker should be resized</li>
|
|
327
|
+
<li><strong>iconOffset</strong> (optional): offset if the marker should be shifted</li>
|
|
328
|
+
</ul>
|
|
329
|
+
<p class="descr">
|
|
330
|
+
Other columns will be ignored.<br />
|
|
331
|
+
Compatibility with the format used in the old GeoMapFish API will be managed if the URL to fo file contains the
|
|
332
|
+
keyword <code>legacy</code>.<br />
|
|
333
|
+
Coordinates can be given in both way (North,East) or (East,North) only if the SRID <code>CH:2056</code> is used.
|
|
334
|
+
</p>
|
|
335
|
+
<section>
|
|
336
|
+
<div class="row">
|
|
337
|
+
<div class="left">
|
|
338
|
+
<geogirafe-map markersfile="api.demo.markersFile" />
|
|
339
|
+
</div>
|
|
340
|
+
<div class="right"></div>
|
|
341
|
+
</div>
|
|
342
|
+
</section>
|
|
343
|
+
|
|
308
344
|
<!-- Layers -->
|
|
309
345
|
<h2>Add a layer to the map</h2>
|
|
310
346
|
<p class="descr">Add a layer to the map. The layer name must be defined in the themes.json file.</p>
|
|
@@ -409,10 +445,6 @@
|
|
|
409
445
|
- projection: configure map projection
|
|
410
446
|
- legend:
|
|
411
447
|
- embeded: deactivate mouse scroll
|
|
412
|
-
- marker: offset, size, ...
|
|
413
|
-
- load markers from file
|
|
414
|
-
- load data from file
|
|
415
|
-
|
|
416
448
|
-->
|
|
417
449
|
</body>
|
|
418
450
|
</html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.1.0-dev.
|
|
1
|
+
{"version":"1.1.0-dev.2557861681", "build":"2557861681", "date":"28/05/2026"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
id point title description icon iconSize iconOffset
|
|
2
|
+
1 1146337,2554168 Information Office de l'information<br />Tél: 032 000 00 00<br>Email: <a href="mailto:info@example.com">info@example.com</a><br />Internet: <a href="http://fr.wikipedia.org/wiki/La_Chaux-de-Fonds" target=new>Cliquer ici</a> api/marker-plus.png 21,25 -51,-90
|
|
3
|
+
2 1146205,2554168 Ma première station Diesel pas cher api/marker2-plus.png 21,25 -51,-90
|
|
4
|
+
3 1145605,2554168 Mon parking C'est celui-là le meilleur. api/marker2-plus.png 21,25 -51,-90
|
|
5
|
+
4 1145542,2554168 Mon parking Ce parking est<br/>le meillleur. api/marker2-plus.png 21,25 -51,-90
|
|
6
|
+
5 1145977,2554168 Ma deuxième station Sans-plomb pas cher. api/marker-plus.png 21,25 -51,-90
|
|
7
|
+
6 1145631,2554175 Test marker 1. api/marker-plus.png 21,25 -51,-90
|
|
8
|
+
7 1145472,2554507 Test marker 2. api/marker2-plus.png 21,25 -51,-90
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
id point title description icon iconSize iconOffset
|
|
2
|
+
1 2611778,1266865 Popups konfigurieren <br>Popups können via der Text-Datei beliebig mit Inhalt gefüllt werden!<br/>Die anderen zwei Beispiel-Popups zeigen weitere Beispiele.<br><img src="/static/api/apihelp/img/geoportal-bs.jpg" width="300px"> api/marker-blue.png 21,25 -10.5,-25
|
|
3
|
+
2 2611542,1267266 Klänge der Basler Fasnacht <br/><br/>Audio-Dateien in ein Popup einbinden:<br/><br/><audio controls><source src="/static/api/apihelp/BS_N19_Fasnacht_v1.mp3" type="audio/mp3">Your browser does not support the audio element.</audio> api/marker-green.png 21,25 -10.5,-25
|
|
4
|
+
3 2613089,1267566 FILM AB! Für den GEO-Beruf <br>IFrames in ein Popup einbinden: <br/><br/><iframe width="312" height="175" src="https://www.youtube.com/embed/-Mw277Rgcyc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> api/parking.png 21,25 -10.5,-25
|
|
5
|
+
4 2611738,1267123 Test for Offset/Size Test for Offset/Size api/marker-huge.png 24,38 -162,-512
|
|
6
|
+
5 2611738,1267123 Test for Offset/Size Test for Offset/Size api/marker-huge.png 24,38 -12,-38
|
|
Binary file
|
|
Binary file
|
|
Binary file
|