@geogirafe/lib-geoportal 1.1.0-dev.2536443365 → 1.1.0-dev.2545448597
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 +1 -0
- package/api/apigeogirafeapp.js +42 -11
- package/components/map/component.js +9 -8
- package/package.json +1 -1
- package/templates/api.html +16 -1
- package/templates/public/about.json +1 -1
- package/tools/main.d.ts +1 -1
- package/tools/main.js +1 -1
- package/tools/state/mapposition.d.ts +2 -0
- package/tools/state/mapposition.js +3 -1
- package/tools/url/permalinkmanager.d.ts +5 -0
- package/tools/url/permalinkmanager.js +55 -27
- package/tools/utils/utils.d.ts +5 -0
- package/tools/utils/utils.js +10 -0
package/api/apigeogirafeapp.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
26
26
|
private manageCrosshairAttribute;
|
|
27
27
|
private manageTooltipAttribute;
|
|
28
28
|
private manageMarkersAttribute;
|
|
29
|
+
private markerStringToMapMarker;
|
|
29
30
|
private initialize;
|
|
30
31
|
private injectConfigMetaTags;
|
|
31
32
|
}
|
package/api/apigeogirafeapp.js
CHANGED
|
@@ -10,6 +10,7 @@ import MenuButtonComponent from '../components/menubutton/component.js';
|
|
|
10
10
|
import MapCustomContextMenuComponent from '../components/context-menu/custom-context-menu/component.js';
|
|
11
11
|
import SearchComponent from '../components/search/component.js';
|
|
12
12
|
import SelectionWindowComponent from '../components/selectionwindow/component.js';
|
|
13
|
+
import { splitTrimAndConvertToNumber } from '../tools/utils/utils.js';
|
|
13
14
|
export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
14
15
|
templateUrl = null;
|
|
15
16
|
styleUrls = null;
|
|
@@ -245,17 +246,10 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
245
246
|
const markers = this.getAttributeFromConfig('markers');
|
|
246
247
|
if (markers) {
|
|
247
248
|
const markerValues = markers.split(';');
|
|
248
|
-
for (const
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const y = Number(coords[1].trim());
|
|
253
|
-
if (!Number.isNaN(x) && !Number.isNaN(y)) {
|
|
254
|
-
const imageUrl = content[1].trim();
|
|
255
|
-
this.context.stateManager.state.position.markers.push({
|
|
256
|
-
position: [x, y],
|
|
257
|
-
imageUrl: imageUrl
|
|
258
|
-
});
|
|
249
|
+
for (const markerValue of markerValues) {
|
|
250
|
+
const marker = this.markerStringToMapMarker(markerValue);
|
|
251
|
+
if (marker) {
|
|
252
|
+
this.context.stateManager.state.position.markers.push(marker);
|
|
259
253
|
}
|
|
260
254
|
else {
|
|
261
255
|
console.warn('Invalid marker coordinates');
|
|
@@ -263,6 +257,43 @@ export default class GeoGirafeApi extends GirafeHTMLElement {
|
|
|
263
257
|
}
|
|
264
258
|
}
|
|
265
259
|
}
|
|
260
|
+
markerStringToMapMarker(markerValue) {
|
|
261
|
+
console.log('markerStringToMapMarker', markerValue);
|
|
262
|
+
const contentParts = markerValue.split('|');
|
|
263
|
+
const needToGuessThirdParameter = contentParts.length == 3;
|
|
264
|
+
if (needToGuessThirdParameter) {
|
|
265
|
+
console.warn(`Marker has only 3 Parameters! Guessing if third Parameter '${contentParts[2]}' is Size or Offset`);
|
|
266
|
+
}
|
|
267
|
+
const coords = contentParts[0].split(',');
|
|
268
|
+
const x = Number(coords[0].trim());
|
|
269
|
+
const y = Number(coords[1].trim());
|
|
270
|
+
if (!Number.isNaN(x) && !Number.isNaN(y)) {
|
|
271
|
+
const imageUrl = contentParts[1].trim();
|
|
272
|
+
let size;
|
|
273
|
+
let offset;
|
|
274
|
+
if (needToGuessThirdParameter) {
|
|
275
|
+
if (contentParts[2].match(/[+-]+/gm)) {
|
|
276
|
+
offset = splitTrimAndConvertToNumber(contentParts[2]);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
size = splitTrimAndConvertToNumber(contentParts[2]);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else if (contentParts.length > 2) {
|
|
283
|
+
size = splitTrimAndConvertToNumber(contentParts[2]);
|
|
284
|
+
offset = splitTrimAndConvertToNumber(contentParts[3]);
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
position: [x, y],
|
|
288
|
+
imageUrl: imageUrl,
|
|
289
|
+
size: size,
|
|
290
|
+
offset: offset
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
266
297
|
async initialize() {
|
|
267
298
|
await this.context.initialize();
|
|
268
299
|
// Register Coordinate Reference Systems (CRS) definitions in PROJ4
|
|
@@ -135,7 +135,7 @@ export default class MapComponent extends GirafeHTMLElement {
|
|
|
135
135
|
this.subscribe('position.markers', () => {
|
|
136
136
|
this.clearAllMarkers();
|
|
137
137
|
for (const marker of this.state.position.markers) {
|
|
138
|
-
this.addMarker(marker
|
|
138
|
+
this.addMarker(marker);
|
|
139
139
|
}
|
|
140
140
|
});
|
|
141
141
|
this.subscribe('globe.display', async () => {
|
|
@@ -177,7 +177,7 @@ export default class MapComponent extends GirafeHTMLElement {
|
|
|
177
177
|
}
|
|
178
178
|
this.showCrosshair(this.state.position);
|
|
179
179
|
for (const marker of this.state.position.markers) {
|
|
180
|
-
this.addMarker(marker
|
|
180
|
+
this.addMarker(marker);
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
});
|
|
@@ -1017,23 +1017,24 @@ export default class MapComponent extends GirafeHTMLElement {
|
|
|
1017
1017
|
this.state.position = position;
|
|
1018
1018
|
if (position.markers.length > 0) {
|
|
1019
1019
|
// Add marker to the map
|
|
1020
|
-
this.addMarker(position.markers[0]
|
|
1020
|
+
this.addMarker(position.markers[0]);
|
|
1021
1021
|
}
|
|
1022
1022
|
}
|
|
1023
1023
|
}
|
|
1024
1024
|
clearAllMarkers() {
|
|
1025
1025
|
this.markerSource.clear();
|
|
1026
1026
|
}
|
|
1027
|
-
addMarker(
|
|
1027
|
+
addMarker(mapMarker) {
|
|
1028
1028
|
const iconStyle = new Style({
|
|
1029
1029
|
image: new Icon({
|
|
1030
|
-
|
|
1031
|
-
src: imageUrl
|
|
1032
|
-
|
|
1030
|
+
displacement: mapMarker.offset,
|
|
1031
|
+
src: mapMarker.imageUrl,
|
|
1032
|
+
width: mapMarker.size ? mapMarker.size[0] : undefined,
|
|
1033
|
+
height: mapMarker.size ? mapMarker.size[1] : undefined
|
|
1033
1034
|
})
|
|
1034
1035
|
});
|
|
1035
1036
|
const marker = new Feature({
|
|
1036
|
-
geometry: new Point(position)
|
|
1037
|
+
geometry: new Point(mapMarker.position)
|
|
1037
1038
|
});
|
|
1038
1039
|
marker.setStyle(iconStyle);
|
|
1039
1040
|
this.markerSource.addFeature(marker);
|
package/package.json
CHANGED
package/templates/api.html
CHANGED
|
@@ -290,6 +290,21 @@
|
|
|
290
290
|
</div>
|
|
291
291
|
</section>
|
|
292
292
|
|
|
293
|
+
<!-- Multiple markers with size and/or offset -->
|
|
294
|
+
<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>).
|
|
298
|
+
</p>
|
|
299
|
+
<section>
|
|
300
|
+
<div class="row">
|
|
301
|
+
<div class="left">
|
|
302
|
+
<geogirafe-map markers="api.demo.markersWithSizeAndOrOffset" />
|
|
303
|
+
</div>
|
|
304
|
+
<div class="right"></div>
|
|
305
|
+
</div>
|
|
306
|
+
</section>
|
|
307
|
+
|
|
293
308
|
<!-- Layers -->
|
|
294
309
|
<h2>Add a layer to the map</h2>
|
|
295
310
|
<p class="descr">Add a layer to the map. The layer name must be defined in the themes.json file.</p>
|
|
@@ -302,7 +317,7 @@
|
|
|
302
317
|
</div>
|
|
303
318
|
</section>
|
|
304
319
|
|
|
305
|
-
<!--
|
|
320
|
+
<!-- Multiple layers -->
|
|
306
321
|
<h2>Add multiple layers to the map</h2>
|
|
307
322
|
<p class="descr">Add multiple layers to the map. The layer names must be defined in the themes.json file.</p>
|
|
308
323
|
<section>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.1.0-dev.
|
|
1
|
+
{"version":"1.1.0-dev.2545448597", "build":"2545448597", "date":"22/05/2026"}
|
package/tools/main.d.ts
CHANGED
|
@@ -120,7 +120,7 @@ export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle,
|
|
|
120
120
|
export { getPropertyByPath, setPropertyByPath, createObjectFromPath, deletePropertyByPath, mergeObjects } from './utils/pathUtils.js';
|
|
121
121
|
export { generateQrCode } from './utils/qrcode.js';
|
|
122
122
|
export { default as ServiceWorkerHelper } from './utils/swhelper.js';
|
|
123
|
-
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl } from './utils/utils.js';
|
|
123
|
+
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl, splitTrimAndConvertToNumber } from './utils/utils.js';
|
|
124
124
|
export { default as VendorSpecificOgcServerManager } from './vendorspecificogcservermanager.js';
|
|
125
125
|
export type { WfsClientOptions, WfsClientOptionalOptions, QueryableLayerWms, GetFeatureOptionsPartial } from './wfs/wfsclient.js';
|
|
126
126
|
export { default as WfsClient, WfsClientMapServer, WfsClientQgis, WfsClientGeorama, WfsClientDefault, WfsClientGeoServer } from './wfs/wfsclient.js';
|
package/tools/main.js
CHANGED
|
@@ -94,7 +94,7 @@ export { unByKeyAll, getOlayerByName, removeUnwantedOlParams, polygonFromCircle,
|
|
|
94
94
|
export { getPropertyByPath, setPropertyByPath, createObjectFromPath, deletePropertyByPath, mergeObjects } from './utils/pathUtils.js';
|
|
95
95
|
export { generateQrCode } from './utils/qrcode.js';
|
|
96
96
|
export { default as ServiceWorkerHelper } from './utils/swhelper.js';
|
|
97
|
-
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl } from './utils/utils.js';
|
|
97
|
+
export { systemIsInDarkMode, isSafari, isFirefox, getValidIndex, minMax, hexToRgbaArray, rgbStrToRgbaArray, colorToRgbaArray, isValidEmail, applyOpacityToLayers, applyFeaturesToSelection, linkify, applyDefaultPrefixToUrl, splitTrimAndConvertToNumber } from './utils/utils.js';
|
|
98
98
|
export { default as VendorSpecificOgcServerManager } from './vendorspecificogcservermanager.js';
|
|
99
99
|
export { default as WfsClient, WfsClientMapServer, WfsClientQgis, WfsClientGeorama, WfsClientDefault, WfsClientGeoServer } from './wfs/wfsclient.js';
|
|
100
100
|
export { default as WfsFilter } from './wfs/wfsfilter.js';
|
|
@@ -21,7 +21,12 @@ export default class PermalinkManager extends GirafeSingleton {
|
|
|
21
21
|
hasMapPosition(): boolean | "" | null;
|
|
22
22
|
private hasToolTip;
|
|
23
23
|
private hasMarker;
|
|
24
|
+
private hasMarkerSize;
|
|
25
|
+
private hasMarkerOffset;
|
|
24
26
|
getMapPosition(targetProjection: Projection): MapPosition | undefined;
|
|
27
|
+
private addCenter;
|
|
28
|
+
private addTooltip;
|
|
29
|
+
private addMarker;
|
|
25
30
|
hasSearch(): boolean;
|
|
26
31
|
getSearchTerm(): string;
|
|
27
32
|
hasThemes(): boolean;
|
|
@@ -5,6 +5,7 @@ import MapPosition from '../state/mapposition.js';
|
|
|
5
5
|
import { get as getProjection, transform } from 'ol/proj.js';
|
|
6
6
|
import { isCoordinateInDegrees } from '../utils/olutils.js';
|
|
7
7
|
import { BASEMAP_VISIBLE_PARAMETER, SEARCH_VISIBLE_PARAMETER } from './permalinkmanager-constants.js';
|
|
8
|
+
import { splitTrimAndConvertToNumber } from '../utils/utils.js';
|
|
8
9
|
export default class PermalinkManager extends GirafeSingleton {
|
|
9
10
|
urlParamKeys = [
|
|
10
11
|
'map_x',
|
|
@@ -13,6 +14,8 @@ export default class PermalinkManager extends GirafeSingleton {
|
|
|
13
14
|
'map_crosshair',
|
|
14
15
|
'map_tooltip',
|
|
15
16
|
'map_marker',
|
|
17
|
+
'map_marker_size',
|
|
18
|
+
'map_marker_offset',
|
|
16
19
|
'search',
|
|
17
20
|
'basemap',
|
|
18
21
|
'themes',
|
|
@@ -83,46 +86,71 @@ export default class PermalinkManager extends GirafeSingleton {
|
|
|
83
86
|
hasMarker() {
|
|
84
87
|
return this.params['map_marker'] !== null;
|
|
85
88
|
}
|
|
89
|
+
hasMarkerSize() {
|
|
90
|
+
return this.params['map_marker_size'] !== null;
|
|
91
|
+
}
|
|
92
|
+
hasMarkerOffset() {
|
|
93
|
+
return this.params['map_marker_offset'] !== null;
|
|
94
|
+
}
|
|
86
95
|
getMapPosition(targetProjection) {
|
|
87
96
|
if (this.hasMapPosition()) {
|
|
88
97
|
const position = new MapPosition();
|
|
89
|
-
|
|
90
|
-
// Transform position to the target projection by making an educated guess about the current CRS
|
|
91
|
-
// of the permalink map position
|
|
92
|
-
const defaultProjection = this.context.configManager.getDefaultConfigValue('map.srid');
|
|
93
|
-
const projectionInUrl = getProjection(isCoordinateInDegrees(position.center) ? 'EPSG:4326' : defaultProjection);
|
|
94
|
-
if (projectionInUrl.getCode() !== this.state.projection) {
|
|
95
|
-
center = transform(center, projectionInUrl, targetProjection);
|
|
96
|
-
}
|
|
97
|
-
position.center = center;
|
|
98
|
+
this.addCenter(position, targetProjection);
|
|
98
99
|
const defaultZoom = this.context.configManager.getDefaultConfigValue('map.startZoom');
|
|
99
100
|
position.zoom = Number.parseInt(this.params['map_zoom'] ?? defaultZoom);
|
|
100
101
|
if (this.params['map_crosshair'] === 'true') {
|
|
101
|
-
position.crosshair = center;
|
|
102
|
-
}
|
|
103
|
-
if (this.hasToolTip()) {
|
|
104
|
-
const content = DOMPurify.sanitize(this.params['map_tooltip'], {
|
|
105
|
-
ALLOWED_TAGS: ['br', 'b', 'div', 'em', 'i', 'p', 'strong'],
|
|
106
|
-
ALLOWED_ATTR: []
|
|
107
|
-
});
|
|
108
|
-
position.tooltip = {
|
|
109
|
-
content: content,
|
|
110
|
-
position: center
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
if (this.hasMarker()) {
|
|
114
|
-
const imageUrl = DOMPurify.sanitize(this.params['map_marker']);
|
|
115
|
-
position.markers.push({
|
|
116
|
-
imageUrl: imageUrl,
|
|
117
|
-
position: center
|
|
118
|
-
});
|
|
102
|
+
position.crosshair = position.center;
|
|
119
103
|
}
|
|
104
|
+
this.addTooltip(position);
|
|
105
|
+
this.addMarker(position);
|
|
120
106
|
if (position.isValid) {
|
|
121
107
|
return position;
|
|
122
108
|
}
|
|
123
109
|
}
|
|
124
110
|
return undefined;
|
|
125
111
|
}
|
|
112
|
+
addCenter(position, targetProjection) {
|
|
113
|
+
let center = [Number.parseFloat(this.params['map_x']), Number.parseFloat(this.params['map_y'])];
|
|
114
|
+
// Transform position to the target projection by making an educated guess about the current CRS
|
|
115
|
+
// of the permalink map position
|
|
116
|
+
const defaultProjection = this.context.configManager.getDefaultConfigValue('map.srid');
|
|
117
|
+
const projectionInUrl = getProjection(isCoordinateInDegrees(position.center) ? 'EPSG:4326' : defaultProjection);
|
|
118
|
+
if (projectionInUrl.getCode() !== this.state.projection) {
|
|
119
|
+
center = transform(center, projectionInUrl, targetProjection);
|
|
120
|
+
}
|
|
121
|
+
position.center = center;
|
|
122
|
+
}
|
|
123
|
+
addTooltip(position) {
|
|
124
|
+
if (this.hasToolTip()) {
|
|
125
|
+
const content = DOMPurify.sanitize(this.params['map_tooltip'], {
|
|
126
|
+
ALLOWED_TAGS: ['br', 'b', 'div', 'em', 'i', 'p', 'strong'],
|
|
127
|
+
ALLOWED_ATTR: []
|
|
128
|
+
});
|
|
129
|
+
position.tooltip = {
|
|
130
|
+
content: content,
|
|
131
|
+
position: position.center
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
addMarker(position) {
|
|
136
|
+
if (this.hasMarker()) {
|
|
137
|
+
const imageUrl = DOMPurify.sanitize(this.params['map_marker']);
|
|
138
|
+
let size;
|
|
139
|
+
let offset;
|
|
140
|
+
if (this.hasMarkerSize()) {
|
|
141
|
+
size = splitTrimAndConvertToNumber(DOMPurify.sanitize(this.params['map_marker_size']));
|
|
142
|
+
}
|
|
143
|
+
if (this.hasMarkerOffset()) {
|
|
144
|
+
offset = splitTrimAndConvertToNumber(DOMPurify.sanitize(this.params['map_marker_offset']));
|
|
145
|
+
}
|
|
146
|
+
position.markers.push({
|
|
147
|
+
imageUrl: imageUrl,
|
|
148
|
+
position: position.center,
|
|
149
|
+
size: size,
|
|
150
|
+
offset: offset
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
126
154
|
hasSearch() {
|
|
127
155
|
return this.params['search'] !== null;
|
|
128
156
|
}
|
package/tools/utils/utils.d.ts
CHANGED
|
@@ -77,3 +77,8 @@ export declare const linkify: (str: string) => string;
|
|
|
77
77
|
* @returns
|
|
78
78
|
*/
|
|
79
79
|
export declare function applyDefaultPrefixToUrl(context: IGirafeContext, metadataUrl?: string): string | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Splits a String containing Numbers into an Array of Numbers. The Separator is a comma.
|
|
82
|
+
* @param numbersAsString The String containing Numbers.
|
|
83
|
+
*/
|
|
84
|
+
export declare const splitTrimAndConvertToNumber: (numbersAsString: string) => number[];
|
package/tools/utils/utils.js
CHANGED
|
@@ -199,3 +199,13 @@ export function applyDefaultPrefixToUrl(context, metadataUrl) {
|
|
|
199
199
|
}
|
|
200
200
|
return metadataUrl;
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Splits a String containing Numbers into an Array of Numbers. The Separator is a comma.
|
|
204
|
+
* @param numbersAsString The String containing Numbers.
|
|
205
|
+
*/
|
|
206
|
+
export const splitTrimAndConvertToNumber = (numbersAsString) => {
|
|
207
|
+
return numbersAsString
|
|
208
|
+
.split(',')
|
|
209
|
+
.map((e) => e.trim())
|
|
210
|
+
.map(Number);
|
|
211
|
+
};
|