@panoramax/web-viewer 4.0.1-develop-676dfe51 → 4.0.1-develop-35288366
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/CHANGELOG.md +3 -1
- package/build/index.js +4 -4
- package/build/index.js.map +1 -1
- package/config/jest/mocks.js +2 -1
- package/docs/reference/components/ui/Map.md +13 -0
- package/docs/reference/components/ui/MapMore.md +13 -0
- package/package.json +1 -1
- package/src/components/core/CoverageMap.js +2 -2
- package/src/components/core/Viewer.js +1 -1
- package/src/components/menus/PictureLegend.js +7 -4
- package/src/components/ui/Map.js +35 -4
- package/src/utils/InitParameters.js +2 -2
- package/tests/components/ui/Map.test.js +7 -3
- package/tests/utils/InitParameters.test.js +15 -15
package/config/jest/mocks.js
CHANGED
|
@@ -97,9 +97,10 @@ jest.mock("maplibre-gl", () => ({
|
|
|
97
97
|
addControl() {;}
|
|
98
98
|
addSource() {;}
|
|
99
99
|
addLayer() {;}
|
|
100
|
-
getLayer() {;}
|
|
100
|
+
getLayer(l) { return {id: l}; }
|
|
101
101
|
setLayoutProperty() {;}
|
|
102
102
|
setPaintProperty() {;}
|
|
103
|
+
loaded() { return true; }
|
|
103
104
|
getStyle() {
|
|
104
105
|
return {
|
|
105
106
|
layers: [],
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* [.getBackground()](#Panoramax.components.ui.Map+getBackground) ⇒ <code>string</code>
|
|
15
15
|
* [.setBackground(bg)](#Panoramax.components.ui.Map+setBackground)
|
|
16
16
|
* [.getVisibleUsers()](#Panoramax.components.ui.Map+getVisibleUsers) ⇒ <code>Array.<string></code>
|
|
17
|
+
* [.onceLayerReady(layerId)](#Panoramax.components.ui.Map+onceLayerReady) ⇒ <code>Promise</code>
|
|
17
18
|
* [.setVisibleUsers(visibleIds)](#Panoramax.components.ui.Map+setVisibleUsers)
|
|
18
19
|
* [.filterUserLayersContent(dataType, filter)](#Panoramax.components.ui.Map+filterUserLayersContent)
|
|
19
20
|
* [.displayPictureMarker(lon, lat, heading, [skipCenter])](#Panoramax.components.ui.Map+displayPictureMarker)
|
|
@@ -109,6 +110,18 @@ Get the currently visible users
|
|
|
109
110
|
|
|
110
111
|
**Kind**: instance method of [<code>Map</code>](#Panoramax.components.ui.Map)
|
|
111
112
|
**Returns**: <code>Array.<string></code> - List of visible users
|
|
113
|
+
<a name="Panoramax.components.ui.Map+onceLayerReady"></a>
|
|
114
|
+
|
|
115
|
+
### map.onceLayerReady(layerId) ⇒ <code>Promise</code>
|
|
116
|
+
Wait for a given map layer to be really available.
|
|
117
|
+
|
|
118
|
+
**Kind**: instance method of [<code>Map</code>](#Panoramax.components.ui.Map)
|
|
119
|
+
**Fulfil**: <code>null</code> When layer is ready.
|
|
120
|
+
|
|
121
|
+
| Param | Type | Description |
|
|
122
|
+
| --- | --- | --- |
|
|
123
|
+
| layerId | <code>string</code> | the layer ID |
|
|
124
|
+
|
|
112
125
|
<a name="Panoramax.components.ui.Map+setVisibleUsers"></a>
|
|
113
126
|
|
|
114
127
|
### map.setVisibleUsers(visibleIds)
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* [.getBackground()](Map.md/#Panoramax.components.ui.Map+getBackground) ⇒ <code>string</code>
|
|
15
15
|
* [.setBackground(bg)](Map.md/#Panoramax.components.ui.Map+setBackground)
|
|
16
16
|
* [.getVisibleUsers()](Map.md/#Panoramax.components.ui.Map+getVisibleUsers) ⇒ <code>Array.<string></code>
|
|
17
|
+
* [.onceLayerReady(layerId)](Map.md/#Panoramax.components.ui.Map+onceLayerReady) ⇒ <code>Promise</code>
|
|
17
18
|
* [.setVisibleUsers(visibleIds)](Map.md/#Panoramax.components.ui.Map+setVisibleUsers)
|
|
18
19
|
* [.filterUserLayersContent(dataType, filter)](Map.md/#Panoramax.components.ui.Map+filterUserLayersContent)
|
|
19
20
|
* [.displayPictureMarker(lon, lat, heading, [skipCenter])](#Panoramax.components.ui.Map+displayPictureMarker)
|
|
@@ -109,6 +110,18 @@ Get the currently visible users
|
|
|
109
110
|
|
|
110
111
|
**Kind**: instance method of [<code>MapMore</code>](#Panoramax.components.ui.MapMore)
|
|
111
112
|
**Returns**: <code>Array.<string></code> - List of visible users
|
|
113
|
+
<a name="Panoramax.components.ui.Map+onceLayerReady"></a>
|
|
114
|
+
|
|
115
|
+
### mapMore.onceLayerReady(layerId) ⇒ <code>Promise</code>
|
|
116
|
+
Wait for a given map layer to be really available.
|
|
117
|
+
|
|
118
|
+
**Kind**: instance method of [<code>MapMore</code>](#Panoramax.components.ui.MapMore)
|
|
119
|
+
**Fulfil**: <code>null</code> When layer is ready.
|
|
120
|
+
|
|
121
|
+
| Param | Type | Description |
|
|
122
|
+
| --- | --- | --- |
|
|
123
|
+
| layerId | <code>string</code> | the layer ID |
|
|
124
|
+
|
|
112
125
|
<a name="Panoramax.components.ui.Map+setVisibleUsers"></a>
|
|
113
126
|
|
|
114
127
|
### mapMore.setVisibleUsers(visibleIds)
|
package/package.json
CHANGED
|
@@ -108,8 +108,8 @@ export default class CoverageMap extends Basic {
|
|
|
108
108
|
this.map.on("picture-click", e => this.select(e.seqId, e.picId));
|
|
109
109
|
this.map.on("sequence-click", e => this.select(e.seqId));
|
|
110
110
|
|
|
111
|
-
this.map.waitForEnoughMapLoaded().then(() => {
|
|
112
|
-
alterMapState(this.map, this._initParams.getMapPostInit());
|
|
111
|
+
this.map.waitForEnoughMapLoaded().then(async () => {
|
|
112
|
+
await alterMapState(this.map, this._initParams.getMapPostInit());
|
|
113
113
|
this.map.reloadLayersStyles();
|
|
114
114
|
this.loader.dismiss();
|
|
115
115
|
});
|
|
@@ -294,7 +294,7 @@ export default class Viewer extends PhotoViewer {
|
|
|
294
294
|
});
|
|
295
295
|
});
|
|
296
296
|
|
|
297
|
-
alterMapState(this.map, this._initParams.getMapPostInit());
|
|
297
|
+
await alterMapState(this.map, this._initParams.getMapPostInit());
|
|
298
298
|
initMapKeyboardHandler(this);
|
|
299
299
|
linkMapAndPhoto(this);
|
|
300
300
|
}
|
|
@@ -145,6 +145,9 @@ export default class PictureLegend extends LitElement {
|
|
|
145
145
|
this._parent.psv.addEventListener("picture-loaded", () => {
|
|
146
146
|
this._onPicChange(this._parent.psv.getPictureMetadata());
|
|
147
147
|
});
|
|
148
|
+
this._parent.psv.addEventListener("sequence-stopped", () => {
|
|
149
|
+
this._onPicChange(this._parent.psv.getPictureMetadata());
|
|
150
|
+
});
|
|
148
151
|
});
|
|
149
152
|
}
|
|
150
153
|
|
|
@@ -154,12 +157,12 @@ export default class PictureLegend extends LitElement {
|
|
|
154
157
|
this._caption = picMeta?.caption;
|
|
155
158
|
|
|
156
159
|
if(picMeta) {
|
|
157
|
-
const coordsHash = `${picMeta.gps[0]}/${picMeta.gps[1]}`;
|
|
160
|
+
const coordsHash = `${picMeta.gps[0].toFixed(4)}/${picMeta.gps[1].toFixed(4)}`;
|
|
158
161
|
if(this._prevSearches[coordsHash]) {
|
|
159
162
|
this._addr = this._prevSearches[coordsHash];
|
|
160
163
|
}
|
|
161
|
-
else {
|
|
162
|
-
this.
|
|
164
|
+
else if(!this._parent.psv._sequencePlaying) {
|
|
165
|
+
this._addr = "";
|
|
163
166
|
this._addrTimer1 = setTimeout(() => {
|
|
164
167
|
reverseGeocodingNominatim(picMeta.gps[1], picMeta.gps[0])
|
|
165
168
|
.then(addr => {
|
|
@@ -167,7 +170,7 @@ export default class PictureLegend extends LitElement {
|
|
|
167
170
|
this._addr = addr;
|
|
168
171
|
this._prevSearches[coordsHash] = addr;
|
|
169
172
|
});
|
|
170
|
-
},
|
|
173
|
+
}, 500);
|
|
171
174
|
}
|
|
172
175
|
}
|
|
173
176
|
else {
|
package/src/components/ui/Map.js
CHANGED
|
@@ -326,10 +326,29 @@ export default class Map extends maplibregl.Map {
|
|
|
326
326
|
*/
|
|
327
327
|
getVisibleUsers() {
|
|
328
328
|
return [...this._userLayers].filter(l => (
|
|
329
|
-
this.
|
|
329
|
+
this.getLayer(getUserLayerId(l, "pictures"))
|
|
330
|
+
&& this.getLayoutProperty(getUserLayerId(l, "pictures"), "visibility") === "visible"
|
|
330
331
|
));
|
|
331
332
|
}
|
|
332
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Wait for a given map layer to be really available.
|
|
336
|
+
* @param {string} layerId the layer ID
|
|
337
|
+
* @returns {Promise}
|
|
338
|
+
* @fulfil {null} When layer is ready.
|
|
339
|
+
* @memberof Panoramax.components.ui.Map#
|
|
340
|
+
*/
|
|
341
|
+
onceLayerReady(layerId) {
|
|
342
|
+
if(this.getLayer(layerId)) {
|
|
343
|
+
return Promise.resolve();
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
return new Promise(resolve => {
|
|
347
|
+
setTimeout(resolve, 250);
|
|
348
|
+
}).then(() => this.onceLayerReady(layerId));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
333
352
|
/**
|
|
334
353
|
* Make given user layers visible on map, and hide all others (if any)
|
|
335
354
|
* @memberof Panoramax.components.ui.Map#
|
|
@@ -343,7 +362,10 @@ export default class Map extends maplibregl.Map {
|
|
|
343
362
|
await Promise.all(
|
|
344
363
|
visibleIds
|
|
345
364
|
.filter(id => id != "" && !this._userLayers.has(id))
|
|
346
|
-
.map(id =>
|
|
365
|
+
.map(id => {
|
|
366
|
+
this._createPicturesTilesLayer(id);
|
|
367
|
+
return this.onceLayerReady(getUserLayerId(id, "pictures"));
|
|
368
|
+
})
|
|
347
369
|
);
|
|
348
370
|
|
|
349
371
|
// Switch visibility
|
|
@@ -375,6 +397,10 @@ export default class Map extends maplibregl.Map {
|
|
|
375
397
|
*/
|
|
376
398
|
filterUserLayersContent(dataType, filter) {
|
|
377
399
|
[...this._userLayers].forEach(l => {
|
|
400
|
+
if(!this.getLayer(getUserLayerId(l, dataType))) {
|
|
401
|
+
console.warn("Layer", getUserLayerId(l, dataType), "not ready");
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
378
404
|
this.setFilter(getUserLayerId(l, dataType), filter);
|
|
379
405
|
if(dataType === "sequences" && this.getLayer(getUserLayerId(l, "sequences_plus"))) {
|
|
380
406
|
this.setFilter(getUserLayerId(l, "sequences_plus"), filter);
|
|
@@ -428,11 +454,16 @@ export default class Map extends maplibregl.Map {
|
|
|
428
454
|
reloadLayersStyles() {
|
|
429
455
|
const updateStyle = (layer, style) => {
|
|
430
456
|
[...this._userLayers].forEach(l => {
|
|
457
|
+
const layerId = getUserLayerId(l, layer);
|
|
458
|
+
if(!this.getLayer(layerId)) {
|
|
459
|
+
console.warn("Layer", layerId, "not ready");
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
431
462
|
for(let p in style.layout) {
|
|
432
|
-
this.setLayoutProperty(
|
|
463
|
+
this.setLayoutProperty(layerId, p, style.layout[p]);
|
|
433
464
|
}
|
|
434
465
|
for(let p in style.paint) {
|
|
435
|
-
this.setPaintProperty(
|
|
466
|
+
this.setPaintProperty(layerId, p, style.paint[p]);
|
|
436
467
|
}
|
|
437
468
|
});
|
|
438
469
|
};
|
|
@@ -323,7 +323,7 @@ export function alterPSVState(psv, params) {
|
|
|
323
323
|
* @param {Map} map The MapLibre component to change.
|
|
324
324
|
* @param {object} params The parameters to apply.
|
|
325
325
|
*/
|
|
326
|
-
export function alterMapState(map, params) {
|
|
326
|
+
export async function alterMapState(map, params) {
|
|
327
327
|
// Map position
|
|
328
328
|
const mapOpts = getMapPositionFromString(params.map, map);
|
|
329
329
|
if(mapOpts) {
|
|
@@ -333,7 +333,7 @@ export function alterMapState(map, params) {
|
|
|
333
333
|
// Visible users
|
|
334
334
|
let vu = Array.isArray(params.users) ? params.users : (params.users || "").split(",");
|
|
335
335
|
if(vu.length === 0 || (vu.length === 1 && vu[0].trim() === "")) { vu = ["geovisio"]; }
|
|
336
|
-
map.setVisibleUsers(vu);
|
|
336
|
+
await map.setVisibleUsers(vu);
|
|
337
337
|
|
|
338
338
|
// Change map filters
|
|
339
339
|
map.setFilters?.(paramsToMapFilters(params));
|
|
@@ -81,6 +81,7 @@ describe("getBackground", () => {
|
|
|
81
81
|
const p = createParent();
|
|
82
82
|
const c = document.createElement("div");
|
|
83
83
|
const m = new Map(p, c);
|
|
84
|
+
m.getLayer = () => undefined;
|
|
84
85
|
expect(m.getBackground()).toBe("streets");
|
|
85
86
|
});
|
|
86
87
|
});
|
|
@@ -99,7 +100,7 @@ describe("setBackground", () => {
|
|
|
99
100
|
resolve();
|
|
100
101
|
});
|
|
101
102
|
m.setBackground("aerial");
|
|
102
|
-
})
|
|
103
|
+
});
|
|
103
104
|
});
|
|
104
105
|
|
|
105
106
|
it("skips if setting streets and no raster available", () => {
|
|
@@ -107,6 +108,7 @@ describe("setBackground", () => {
|
|
|
107
108
|
const c = document.createElement("div");
|
|
108
109
|
const m = new Map(p, c);
|
|
109
110
|
m.setLayoutProperty = jest.fn();
|
|
111
|
+
m.getLayer = () => undefined;
|
|
110
112
|
m.setBackground("streets");
|
|
111
113
|
expect(m.setLayoutProperty.mock.calls.length).toBe(0);
|
|
112
114
|
});
|
|
@@ -115,6 +117,7 @@ describe("setBackground", () => {
|
|
|
115
117
|
const p = createParent();
|
|
116
118
|
const c = document.createElement("div");
|
|
117
119
|
const m = new Map(p, c);
|
|
120
|
+
m.getLayer = () => undefined;
|
|
118
121
|
expect(() => m.setBackground("aerial")).toThrowError("No aerial imagery available");
|
|
119
122
|
});
|
|
120
123
|
});
|
|
@@ -138,9 +141,10 @@ describe("setVisibleUsers", () => {
|
|
|
138
141
|
const c = document.createElement("div");
|
|
139
142
|
const m = new Map(p, c);
|
|
140
143
|
m._createPicturesTilesLayer = (url, id) => m._userLayers.add(id);
|
|
141
|
-
m.
|
|
144
|
+
m._addedLayers = [];
|
|
145
|
+
m.addLayer = jest.fn();
|
|
142
146
|
await m.setVisibleUsers(["blabla"]);
|
|
143
|
-
expect(m.
|
|
147
|
+
expect(m.addLayer.mock.calls).toMatchSnapshot();
|
|
144
148
|
expect(p.dispatchEvent.mock.calls).toMatchSnapshot();
|
|
145
149
|
});
|
|
146
150
|
|
|
@@ -372,47 +372,47 @@ describe("alterMapState", () => {
|
|
|
372
372
|
|
|
373
373
|
afterEach(() => jest.clearAllMocks());
|
|
374
374
|
|
|
375
|
-
it("should jump to map position when map param is provided", () => {
|
|
375
|
+
it("should jump to map position when map param is provided", async () => {
|
|
376
376
|
const params = { map: "10/20/30" };
|
|
377
377
|
const mapOpts = { center: [30,20], zoom: 10, pitch: 0 };
|
|
378
378
|
|
|
379
|
-
alterMapState(map, params);
|
|
379
|
+
await alterMapState(map, params);
|
|
380
380
|
expect(map.jumpTo).toHaveBeenCalledWith(mapOpts);
|
|
381
381
|
});
|
|
382
382
|
|
|
383
|
-
it("should set visible users when users param is provided", () => {
|
|
383
|
+
it("should set visible users when users param is provided", async () => {
|
|
384
384
|
const params = { users: "user1,user2" };
|
|
385
|
-
alterMapState(map, params);
|
|
385
|
+
await alterMapState(map, params);
|
|
386
386
|
expect(map.setVisibleUsers).toHaveBeenCalledWith(["user1", "user2"]);
|
|
387
387
|
});
|
|
388
388
|
|
|
389
|
-
it("should set default visible user when users param is empty", () => {
|
|
389
|
+
it("should set default visible user when users param is empty", async () => {
|
|
390
390
|
const params = { users: "" };
|
|
391
|
-
alterMapState(map, params);
|
|
391
|
+
await alterMapState(map, params);
|
|
392
392
|
expect(map.setVisibleUsers).toHaveBeenCalledWith(["geovisio"]);
|
|
393
393
|
});
|
|
394
394
|
|
|
395
|
-
it("should set map filters when params are provided", () => {
|
|
395
|
+
it("should set map filters when params are provided", async () => {
|
|
396
396
|
const params = { "date_from": "2024-01-01", "pic_score": "ABC" };
|
|
397
397
|
const filters = { "minDate": "2024-01-01", "qualityscore": [5,4,3] };
|
|
398
|
-
|
|
399
|
-
alterMapState(map, params);
|
|
398
|
+
await alterMapState(map, params);
|
|
400
399
|
expect(map.setFilters).toHaveBeenCalledWith(filters);
|
|
401
400
|
});
|
|
402
401
|
|
|
403
|
-
it("should set map background when background param is valid", () => {
|
|
402
|
+
it("should set map background when background param is valid", async () => {
|
|
404
403
|
const params = { background: "aerial" };
|
|
405
|
-
|
|
404
|
+
map.setVisibleUsers = () => Promise.resolve();
|
|
405
|
+
await alterMapState(map, params);
|
|
406
406
|
expect(map.setBackground).toHaveBeenCalledWith("aerial");
|
|
407
407
|
});
|
|
408
408
|
|
|
409
|
-
it("should not set map background when background param is invalid", () => {
|
|
409
|
+
it("should not set map background when background param is invalid", async () => {
|
|
410
410
|
const params = { background: "invalid" };
|
|
411
|
-
alterMapState(map, params);
|
|
411
|
+
await alterMapState(map, params);
|
|
412
412
|
expect(map.setBackground).not.toHaveBeenCalled();
|
|
413
413
|
});
|
|
414
414
|
|
|
415
|
-
it("should handle multiple params correctly", () => {
|
|
415
|
+
it("should handle multiple params correctly", async () => {
|
|
416
416
|
const params = {
|
|
417
417
|
map: "15/7/6",
|
|
418
418
|
users: "user1,user2",
|
|
@@ -422,7 +422,7 @@ describe("alterMapState", () => {
|
|
|
422
422
|
const mapOpts = { center: [6, 7], zoom: 15, pitch: 0 };
|
|
423
423
|
const filters = { camera: "value1" };
|
|
424
424
|
|
|
425
|
-
alterMapState(map, params);
|
|
425
|
+
await alterMapState(map, params);
|
|
426
426
|
expect(map.jumpTo).toHaveBeenCalledWith(mapOpts);
|
|
427
427
|
expect(map.setVisibleUsers).toHaveBeenCalledWith(["user1", "user2"]);
|
|
428
428
|
expect(map.setFilters).toHaveBeenCalledWith(filters);
|