@geogirafe/lib-geoportal 1.1.0-dev.2545448597 → 1.1.0-dev.2563862728

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.
@@ -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
  }
@@ -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
@@ -50,7 +50,7 @@ export default class MapComponent extends GirafeHTMLElement {
50
50
  return uHtml `<style>
51
51
  *{font-family:Arial,sans-serif}.hidden{display:none!important}.gg-rotate90{transform:rotate(90deg)}.gg-rotate180{transform:rotate(180deg)}.gg-rotate270{transform:rotate(270deg)}img{filter:var(--svg-filter)}img.legend-image{filter:var(--svg-map-filter);background:var(--svg-legend-bkg)}div{scrollbar-width:thin}a,a:visited{color:var(--link-color)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes spin-wait{0%{transform:rotate(0)}7%{transform:rotate(360deg)}to{transform:rotate(360deg)}}.gg-spin{animation-name:spin;animation-duration:2s;animation-timing-function:linear;animation-iteration-count:infinite}.gg-spin-wait{animation-name:spin-wait;animation-duration:10s;animation-timing-function:linear;animation-iteration-count:infinite}::-webkit-scrollbar{width:5px}::-webkit-scrollbar-thumb{background:#999}.gg-button,.gg-select,.gg-input,.gg-textarea{background-color:var(--bkg-color);color:var(--text-color);border:var(--app-standard-border);box-sizing:border-box;cursor:pointer;border-radius:3px;outline:0;margin:0;padding:0 0 0 .5rem;display:inline-block}.gg-label{background-color:var(--bkg-color);color:var(--text-color);border:none;align-items:center;margin:0;padding:0;display:flex}.gg-button,.gg-select,.gg-input,.gg-label{min-height:calc(var(--app-standard-height) / 1.5)}.gg-textarea{max-height:initial;resize:vertical;height:6rem;padding:.5rem;line-height:1.3rem}.gg-input{cursor:text}.gg-checkbox{accent-color:var(--text-color);width:1.2rem}.gg-range{accent-color:var(--text-color)}.gg-button{padding:0 .5rem}.gg-button.active{border:solid 1px var(--text-color-grad2);background-color:var(--text-color-grad2);color:var(--bkg-color)}.gg-button:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3;border:none}.gg-input:disabled,.gg-select:disabled,.gg-textarea:disabled{color:gray;cursor:not-allowed;background-color:#d3d3d3}.gg-button>img{vertical-align:middle}.gg-icon-button{color:var(--text-color);cursor:pointer;background-color:#0000;border:none;flex-direction:column;justify-content:center;align-items:center;padding:0;display:flex}.gg-icon{justify-content:center;align-items:center;display:flex}.gg-big,.gg-big-withtext{min-width:var(--app-standard-height);min-height:var(--app-standard-height);max-height:var(--app-standard-height)}.gg-big img,.gg-big-withtext img{width:calc(var(--app-standard-height) - 1.5rem);margin:0}.gg-big-withtext span{font-variant:small-caps;padding:0 1rem;font-size:.9rem}.gg-medium,.gg-medium-withtext{min-width:calc(var(--app-standard-height) / 1.2);min-height:calc(var(--app-standard-height) / 1.2);max-height:calc(var(--app-standard-height) / 1.2);flex-direction:row}.gg-medium img{width:calc(var(--app-standard-height) / 2.4);margin:0}.gg-medium-withtext img{width:calc(var(--app-standard-height) / 2.4);margin-left:.5rem}.gg-medium-withtext span{padding:0 1rem 0 .5rem;font-size:.9rem}.gg-small,.gg-small-withtext{min-width:calc(var(--app-standard-height) / 2);min-height:calc(var(--app-standard-height) / 2);max-height:calc(var(--app-standard-height) / 2);flex-direction:row}.gg-small img{width:calc(var(--app-standard-height) / 3);margin:0}.gg-small-withtext img{width:calc(var(--app-standard-height) / 3);margin-left:.5rem}.gg-small-withtext span{padding:0 .5rem 0 .3rem;font-size:.9rem}.gg-button:hover,.gg-select:hover,.gg-input:hover,.gg-textarea:hover,.gg-icon-button:hover{background-color:var(--bkg-color-grad1)}.gg-opacity{opacity:.5}.gg-opacity:hover{opacity:1;background-color:#0000}.gg-tabs{cursor:pointer;grid-auto-flow:column;padding-bottom:1rem;font-size:1rem;display:grid}.gg-tab{border:none;border-bottom:var(--app-standard-border);cursor:pointer;color:var(--text-color);background:0 0;padding:.5rem}.gg-tab.active{border-bottom:solid 1px var(--text-color)}.girafe-button-big,.girafe-button-large,.girafe-button-small,.girafe-button-tiny{color:var(--text-color);background-color:#0000;border:none;flex-direction:column;display:flex}.girafe-button-big:hover,.girafe-button-large:hover,.girafe-button-small:hover,.girafe-button-tiny:hover{background-color:var(--bkg-color-grad1);cursor:pointer}.girafe-button-big.dark,.girafe-button-large.dark,.girafe-button-small.dark,.girafe-button-tiny.dark{background-color:var(--bkg-color);filter:invert()}.girafe-button-big{width:var(--app-standard-height);height:var(--app-standard-height);align-items:center;padding:1rem}.girafe-button-big img{overflow:hidden}.girafe-button-large{flex-direction:row}.girafe-button-large img{height:2rem;margin:.3rem}.girafe-button-large span{height:2rem;margin:.3rem;line-height:2rem}.girafe-button-small{min-width:calc(var(--app-standard-height) / 2);height:calc(var(--app-standard-height) / 2);align-items:center;padding:.5rem}.girafe-button-small img{overflow:hidden}.girafe-button-small span{text-align:left;text-overflow:ellipsis;width:100%;overflow:hidden}.girafe-button-tiny{align-items:center;width:1rem;height:1rem;padding:0}.girafe-button-tiny img{overflow:hidden}.girafe-onboarding-theme{background-color:var(--bkg-color)!important;color:var(--text-color)!important}.girafe-onboarding-theme button{background-color:var(--bkg-color)!important;color:var(--text-color)!important;text-shadow:none!important}.girafe-onboarding-theme button.driver-popover-close-btn{z-index:10000}
52
52
  </style><style>
53
- #container,#ol-map{background-color:var(--bkg-color);width:100%;height:100%;position:relative}#ol-map.darkmap canvas{filter:invert()hue-rotate(180deg)}.hidden{display:none}.center{text-align:center;margin:10px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.loading span{color:var(--text-color);margin-top:1rem;font-weight:600;display:block}.loading span.quote{font-style:italic;font-weight:300}#cs-map{background-color:var(--bkg-color);border-left:3px solid #444;height:100%;display:none;position:absolute;overflow:hidden}.ol-control{background-color:#0000;border:none;box-shadow:0 1px 4px #0000004d;right:2rem!important;left:unset!important}.ol-zoom{top:2rem!important}.ol-rotate{top:9.3rem!important}.ol-location{top:7rem!important}.img-location,.img-disable-location{width:55%;height:auto}.ol-zoom-in,.ol-zoom-out,.btn-location,.btn-disable-location,.ol-rotate-reset{cursor:pointer;background-color:#fff;width:2rem!important;height:2rem!important;font-size:1.2rem!important}.ol-scale-line{bottom:.5rem!important;right:1rem!important;left:unset!important}#swiper{width:100%;height:0;margin:0;display:none;position:absolute;top:50%}input[type=range]{-webkit-appearance:none;width:100%}input[type=range]::-webkit-slider-runnable-track{height:0}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:6px;height:0;margin-top:-1000px;padding-top:1000px;padding-bottom:1000px}input[type=range]::-moz-range-thumb{background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:3px;height:0;padding-top:1000px;padding-bottom:1000px}.close-swiper{--button-size:2rem;transform:translateX(calc(-1 * var(--button-size) / 2));width:var(--button-size);height:var(--button-size);background-color:var(--bkg-color);color:var(--text-color);cursor:pointer;border-width:1px;border-radius:4px;display:none;position:absolute;top:0}.close-swiper:hover,.close-swiper:focus{outline:1px solid var(--text-color);color:var(--text-color-grad1)}.ol-viewport .tooltip{color:#fff;opacity:.7;white-space:nowrap;background:#00000080;border-radius:0;padding:.32rem .62rem;position:relative}@media screen and (hover:none){.ol-zoom,.ol-rotate,.ol-location{display:none!important}}.contextmenu{background-color:var(--bkg-color);color:var(--text-color);border:1px solid #ccc;box-shadow:1px 3px 4px #0006;& .hidden{display:none}& .menu-entry{cursor:pointer;padding:10px}& .menu-entry:hover{background-color:var(--bkg-color-grad1)}& .menu-entry[aria-disabled=true]{pointer-events:none;color:var(--text-color-grad1)}}
53
+ #container,#ol-map{background-color:var(--bkg-color);width:100%;height:100%;position:relative}#ol-map.darkmap canvas{filter:invert()hue-rotate(180deg)}.hidden{display:none}.center{text-align:center;margin:10px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.loading span{color:var(--text-color);margin-top:1rem;font-weight:600;display:block}.loading span.quote{font-style:italic;font-weight:300}#cs-map{background-color:var(--bkg-color);border-left:3px solid #444;height:100%;display:none;position:absolute;overflow:hidden}.ol-control{background-color:#0000;border:none;box-shadow:0 1px 4px #0000004d;right:2rem!important;left:unset!important}.ol-zoom{top:2rem!important}.ol-rotate{top:9.3rem!important}.ol-location{top:7rem!important}.img-location,.img-disable-location{width:55%;height:auto}.ol-zoom-in,.ol-zoom-out,.btn-location,.btn-disable-location,.ol-rotate-reset{cursor:pointer;background-color:var(--bkg-color)!important;width:2rem!important;height:2rem!important;color:var(--text-color)!important;font-size:1.2rem!important}.ol-scale-line{bottom:.5rem!important;right:1rem!important;left:unset!important}#swiper{width:100%;height:0;margin:0;display:none;position:absolute;top:50%}input[type=range]{-webkit-appearance:none;width:100%}input[type=range]::-webkit-slider-runnable-track{height:0}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:6px;height:0;margin-top:-1000px;padding-top:1000px;padding-bottom:1000px}input[type=range]::-moz-range-thumb{background:var(--bkg-color);cursor:ew-resize;border:2px solid #444;width:3px;height:0;padding-top:1000px;padding-bottom:1000px}.close-swiper{--button-size:2rem;transform:translateX(calc(-1 * var(--button-size) / 2));width:var(--button-size);height:var(--button-size);background-color:var(--bkg-color);color:var(--text-color);cursor:pointer;border-width:1px;border-radius:4px;display:none;position:absolute;top:0}.close-swiper:hover,.close-swiper:focus{outline:1px solid var(--text-color);color:var(--text-color-grad1)}.ol-viewport .tooltip{color:#fff;opacity:.7;white-space:nowrap;background:#00000080;border-radius:0;padding:.32rem .62rem;position:relative}@media screen and (hover:none){.ol-zoom,.ol-rotate,.ol-location{display:none!important}}.contextmenu{background-color:var(--bkg-color);color:var(--text-color);border:1px solid #ccc;box-shadow:1px 3px 4px #0006;& .hidden{display:none}& .menu-entry{cursor:pointer;padding:10px}& .menu-entry:hover{background-color:var(--bkg-color-grad1)}& .menu-entry[aria-disabled=true]{pointer-events:none;color:var(--text-color-grad1)}}
54
54
  </style>
55
55
  <style>${this.customStyle}</style>
56
56
  <link rel="stylesheet" href="lib/ol/ol.css"><div id="container"><div id="ol-map"></div><div class="ol-location ol-unselectable ol-control"><button onclick="${() => this.locateUser()}" class="btn-location"><img class="img-location" alt="location-icon" src="icons/adjust.svg"></button> <button id="disable-location" onclick="${() => this.disableLocateUser()}" class="btn-disable-location hidden"><img class="img-disable-location" alt="disable-location-icon" src="icons/adjust-disable.svg"></button></div><div id="cs-map"><div class="${this.loading ? 'loading center' : 'loading hidden'}"><img alt="loading-icon" src="icons/loading.svg" class="gg-spin"> <span i18n="Loading cesium...">Loading cesium...</span> <span class="quote" i18n="cesium-loading-quote">Please be patient, like a giraffe reaching for the tastiest leaves.</span></div></div><input id="swiper" type="range" min="0" max="1000" step="1"> <button tip="Hide Swiper" id="close-swiper" class="close-swiper">×</button></div>`;
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.2545448597",
8
+ "version": "1.1.0-dev.2563862728",
9
9
  "type": "module",
10
10
  "engines": {
11
11
  "node": ">=20.19.0"
@@ -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">Add multiple markers at the defined coordinates. You can specify size and offset. If you only
296
- specify three parameters, the third parameter can be the size if you <strong>don't</strong> include a sign
297
- (e.g. <code>24,24</code>) or the offset if you <strong>do</strong> include a sign (e.g. <code>+2,-6</code>).
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.2545448597", "build":"2545448597", "date":"22/05/2026"}
1
+ {"version":"1.1.0-dev.2563862728", "build":"2563862728", "date":"30/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