@panoramax/web-viewer 3.2.3-develop-7f50ae7f → 3.2.3-develop-17bc8da1
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 +2 -0
- package/build/index.js +4 -4
- package/build/index.js.map +1 -1
- package/docs/reference/utils/InitParameters.md +3 -2
- package/package.json +1 -1
- package/src/components/core/Viewer.js +12 -5
- package/src/components/menus/PictureLegend.js +17 -9
- package/src/components/ui/SearchBar.js +4 -2
- package/src/utils/InitParameters.js +8 -5
- package/src/utils/geocoder.js +66 -32
- package/src/utils/map.js +41 -1
- package/tests/utils/InitParameters.test.js +20 -3
- package/tests/utils/__snapshots__/geocoder.test.js.snap +1 -1
- package/tests/utils/__snapshots__/map.test.js.snap +11 -0
- package/tests/utils/map.test.js +83 -24
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
**Kind**: static class of <code>Panoramax.utils</code>
|
|
5
5
|
|
|
6
6
|
* [.InitParameters](#Panoramax.utils.InitParameters)
|
|
7
|
-
* [new InitParameters([componentAttrs], [urlParams])](#new_Panoramax.utils.InitParameters_new)
|
|
7
|
+
* [new InitParameters([componentAttrs], [urlParams], [browserStorage])](#new_Panoramax.utils.InitParameters_new)
|
|
8
8
|
* [.getParentInit()](#Panoramax.utils.InitParameters+getParentInit)
|
|
9
9
|
* [.getParentPostInit()](#Panoramax.utils.InitParameters+getParentPostInit)
|
|
10
10
|
* [.getPSVInit()](#Panoramax.utils.InitParameters+getPSVInit)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
<a name="new_Panoramax.utils.InitParameters_new"></a>
|
|
16
16
|
|
|
17
|
-
### new InitParameters([componentAttrs], [urlParams])
|
|
17
|
+
### new InitParameters([componentAttrs], [urlParams], [browserStorage])
|
|
18
18
|
Merges all URL parameters and component attributes into a single set of coherent settings.
|
|
19
19
|
|
|
20
20
|
|
|
@@ -22,6 +22,7 @@ Merges all URL parameters and component attributes into a single set of coherent
|
|
|
22
22
|
| --- | --- | --- |
|
|
23
23
|
| [componentAttrs] | <code>object</code> | HTML attributes from parent component |
|
|
24
24
|
| [urlParams] | <code>object</code> | Parameters extracted from URL |
|
|
25
|
+
| [browserStorage] | <code>object</code> | Parameters read from local/session storage |
|
|
25
26
|
|
|
26
27
|
<a name="Panoramax.utils.InitParameters+getParentInit"></a>
|
|
27
28
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import "./Viewer.css";
|
|
4
4
|
import { SYSTEM as PSSystem, DEFAULTS as PSDefaults } from "@photo-sphere-viewer/core";
|
|
5
5
|
import URLHandler from "../../utils/URLHandler";
|
|
6
|
-
import { linkMapAndPhoto } from "../../utils/map";
|
|
6
|
+
import { linkMapAndPhoto, saveMapParamsToLocalStorage, getMapParamsFromLocalStorage } from "../../utils/map";
|
|
7
7
|
import Basic from "./Basic";
|
|
8
8
|
import Photo, { PSV_DEFAULT_ZOOM, PSV_ANIM_DURATION } from "../ui/Photo";
|
|
9
9
|
import MapMore from "../ui/MapMore";
|
|
@@ -139,7 +139,8 @@ export default class Viewer extends Basic {
|
|
|
139
139
|
this.loader.setAttribute("value", 30);
|
|
140
140
|
this._initParams = new InitParameters(
|
|
141
141
|
InitParameters.GetComponentProperties(Viewer, this),
|
|
142
|
-
Object.assign({}, this.urlHandler?.currentURLParams(), this.urlHandler?.currentURLParams(true))
|
|
142
|
+
Object.assign({}, this.urlHandler?.currentURLParams(), this.urlHandler?.currentURLParams(true)),
|
|
143
|
+
{ map: getMapParamsFromLocalStorage() },
|
|
143
144
|
);
|
|
144
145
|
|
|
145
146
|
const myInitParams = this._initParams.getParentInit();
|
|
@@ -296,9 +297,14 @@ export default class Viewer extends Basic {
|
|
|
296
297
|
* @memberof Panoramax.components.core.Viewer#
|
|
297
298
|
*/
|
|
298
299
|
onceFirstPicLoaded() {
|
|
299
|
-
return this.oncePSVReady().then(() =>
|
|
300
|
-
this.psv.
|
|
301
|
-
|
|
300
|
+
return this.oncePSVReady().then(() => {
|
|
301
|
+
if(this.psv.getPictureMetadata()) { return Promise.resolve(); }
|
|
302
|
+
else {
|
|
303
|
+
return new Promise(resolve => {
|
|
304
|
+
this.psv.addEventListener("picture-loaded", resolve, {once: true});
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
});
|
|
302
308
|
}
|
|
303
309
|
|
|
304
310
|
/** @private */
|
|
@@ -354,6 +360,7 @@ export default class Viewer extends Basic {
|
|
|
354
360
|
async _initMap() {
|
|
355
361
|
await new Promise(resolve => {
|
|
356
362
|
this.map = new MapMore(this, this.mapContainer, this._initParams.getMapInit());
|
|
363
|
+
saveMapParamsToLocalStorage(this.map);
|
|
357
364
|
this.map.once("users-changed", () => {
|
|
358
365
|
this.loader.setAttribute("value", 75);
|
|
359
366
|
resolve();
|
|
@@ -49,6 +49,8 @@ export default class PictureLegend extends LitElement {
|
|
|
49
49
|
connectedCallback() {
|
|
50
50
|
super.connectedCallback();
|
|
51
51
|
|
|
52
|
+
this._prevSearches = {};
|
|
53
|
+
|
|
52
54
|
this._parent.onceReady().then(() => {
|
|
53
55
|
this._onPicChange(this._parent.psv.getPictureMetadata());
|
|
54
56
|
this._parent.psv.addEventListener("picture-loaded", () => {
|
|
@@ -63,15 +65,21 @@ export default class PictureLegend extends LitElement {
|
|
|
63
65
|
this._caption = picMeta?.caption;
|
|
64
66
|
|
|
65
67
|
if(picMeta) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
const coordsHash = `${picMeta.gps[0]}/${picMeta.gps[1]}`;
|
|
69
|
+
if(this._prevSearches[coordsHash]) {
|
|
70
|
+
this._addr = this._prevSearches[coordsHash];
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this._addrTimer2 = setTimeout(() => this._addr = "", 250);
|
|
74
|
+
this._addrTimer1 = setTimeout(() => {
|
|
75
|
+
reverseGeocodingNominatim(picMeta.gps[1], picMeta.gps[0])
|
|
76
|
+
.then(addr => {
|
|
77
|
+
clearTimeout(this._addrTimer2);
|
|
78
|
+
this._addr = addr;
|
|
79
|
+
this._prevSearches[coordsHash] = addr;
|
|
80
|
+
});
|
|
81
|
+
}, 750);
|
|
82
|
+
}
|
|
75
83
|
}
|
|
76
84
|
else {
|
|
77
85
|
this._addr = "";
|
|
@@ -246,7 +246,7 @@ export default class SearchBar extends LitElement {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
/**
|
|
249
|
-
* Limit search calls to every
|
|
249
|
+
* Limit search calls to every 500ms
|
|
250
250
|
* @private
|
|
251
251
|
*/
|
|
252
252
|
_throttledSearch() {
|
|
@@ -255,7 +255,7 @@ export default class SearchBar extends LitElement {
|
|
|
255
255
|
delete this._throttler;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
-
this._throttler = setTimeout(this._search.bind(this),
|
|
258
|
+
this._throttler = setTimeout(this._search.bind(this), 500);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
/**
|
|
@@ -277,6 +277,8 @@ export default class SearchBar extends LitElement {
|
|
|
277
277
|
this._results = null;
|
|
278
278
|
|
|
279
279
|
this.searcher(this.value).then(data => {
|
|
280
|
+
if(this._icon !== "loading") { return; }
|
|
281
|
+
|
|
280
282
|
this._icon = "empty";
|
|
281
283
|
if(!data || data.length == 0) {
|
|
282
284
|
this._results = [];
|
|
@@ -16,9 +16,10 @@ const MAP_NONE = ["none", "null", "false", false];
|
|
|
16
16
|
* @class Panoramax.utils.InitParameters
|
|
17
17
|
* @param {object} [componentAttrs] HTML attributes from parent component
|
|
18
18
|
* @param {object} [urlParams] Parameters extracted from URL
|
|
19
|
+
* @param {object} [browserStorage] Parameters read from local/session storage
|
|
19
20
|
*/
|
|
20
21
|
export default class InitParameters { // eslint-disable-line import/no-unused-modules
|
|
21
|
-
constructor(componentAttrs = {}, urlParams = {}) {
|
|
22
|
+
constructor(componentAttrs = {}, urlParams = {}, browserStorage = {}) {
|
|
22
23
|
// Skip URL parameters if disabled by component
|
|
23
24
|
if(componentAttrs["url-parameters"] === "false") { urlParams = {}; }
|
|
24
25
|
|
|
@@ -29,6 +30,8 @@ export default class InitParameters { // eslint-disable-line import/no-unused-mo
|
|
|
29
30
|
// Sanitize Map parameters
|
|
30
31
|
let componentMap = {};
|
|
31
32
|
if(typeof componentAttrs?.map === "object") { componentMap = componentAttrs.map; }
|
|
33
|
+
let browserMap = {};
|
|
34
|
+
if(typeof browserStorage?.map === "object") { browserMap = browserStorage.map; }
|
|
32
35
|
|
|
33
36
|
// Extract map position from URL
|
|
34
37
|
let urlMap = urlParams.map && urlParams.map !== "none" ? getMapPositionFromString(urlParams.map) : null;
|
|
@@ -41,10 +44,10 @@ export default class InitParameters { // eslint-disable-line import/no-unused-mo
|
|
|
41
44
|
let users = urlParams.users || componentAttrs.users;
|
|
42
45
|
let psv_speed = urlParams.speed || componentPsv?.transitionDuration;
|
|
43
46
|
let psv_nav = urlParams.nav || componentPsv?.picturesNavigation;
|
|
44
|
-
let map_theme = urlParams.theme || componentMap.theme;
|
|
45
|
-
let map_background = urlParams.background || componentMap.background;
|
|
46
|
-
let map_center = urlMap?.center || componentMap.center;
|
|
47
|
-
let map_zoom = urlMap?.zoom || componentMap.zoom;
|
|
47
|
+
let map_theme = urlParams.theme || browserMap?.theme || componentMap.theme;
|
|
48
|
+
let map_background = urlParams.background || browserMap?.background || componentMap.background;
|
|
49
|
+
let map_center = urlMap?.center || browserMap?.center || componentMap.center;
|
|
50
|
+
let map_zoom = urlMap?.zoom || browserMap?.zoom || componentMap.zoom;
|
|
48
51
|
let map_pitch = urlMap?.pitch || componentMap.pitch;
|
|
49
52
|
let map_bearing = urlMap?.bearing || componentMap.bearing;
|
|
50
53
|
|
package/src/utils/geocoder.js
CHANGED
|
@@ -18,6 +18,67 @@ function geocoderParamsToURLString(params) {
|
|
|
18
18
|
return new URLSearchParams(p).toString();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Transforms Nominatim search result into a nice-to-display address.
|
|
23
|
+
* @param {object} addr The Nominatim API "address" property
|
|
24
|
+
* @returns {string} The clean-up string for display
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
function nominatimAddressToPlaceName(addr) {
|
|
28
|
+
// API format @ https://nominatim.org/release-docs/develop/api/Output/#addressdetails
|
|
29
|
+
if(!addr || typeof addr != "object") { return ""; }
|
|
30
|
+
|
|
31
|
+
let res = "";
|
|
32
|
+
|
|
33
|
+
// House n°-like
|
|
34
|
+
if(addr.house_number) { res = addr.house_number; }
|
|
35
|
+
else if(addr.house_name) { res = addr.house_name; }
|
|
36
|
+
else {
|
|
37
|
+
const potentialNames = [
|
|
38
|
+
"emergency", "historic", "military", "natural", "landuse", "place", "railway", "man_made",
|
|
39
|
+
"aerialway", "boundary", "amenity", "aeroway", "club", "craft", "leisure", "office",
|
|
40
|
+
"mountain_pass", "shop", "tourism", "bridge", "tunnel", "waterway", "park"
|
|
41
|
+
];
|
|
42
|
+
for(let pn of potentialNames) {
|
|
43
|
+
if(addr[pn]) {
|
|
44
|
+
res = addr[pn];
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Street-like
|
|
51
|
+
let street;
|
|
52
|
+
if(addr.road && addr.road.length > 6) { street = addr.road; }
|
|
53
|
+
else {
|
|
54
|
+
const potentialNames = [
|
|
55
|
+
// Hamlet-like
|
|
56
|
+
"hamlet", "croft", "isolated_dwelling",
|
|
57
|
+
// Zone Indus-like
|
|
58
|
+
"farm", "farmyard", "industrial", "commercial", "retail", "city_block", "residential",
|
|
59
|
+
// Quarter-like
|
|
60
|
+
"neighbourhood", "allotments", "quarter"
|
|
61
|
+
];
|
|
62
|
+
for(let pn of potentialNames) {
|
|
63
|
+
if(addr[pn]) {
|
|
64
|
+
street = addr[pn];
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if(street && res.length > 0) { res += (addr.house_number ? " " : ", ")+street; }
|
|
71
|
+
else if(street) { res = street; }
|
|
72
|
+
|
|
73
|
+
// City
|
|
74
|
+
if(addr.village || addr.town || addr.city || addr.municipality) {
|
|
75
|
+
if(res.length > 0) { res += ", "; }
|
|
76
|
+
res += addr.village || addr.town || addr.city || addr.municipality;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return res;
|
|
80
|
+
}
|
|
81
|
+
|
|
21
82
|
/**
|
|
22
83
|
* Nominatim (OSM) geocoder, ready to use for our Map
|
|
23
84
|
* @private
|
|
@@ -37,13 +98,14 @@ export function forwardGeocodingNominatim(config) {
|
|
|
37
98
|
const finalRes = { features: [] };
|
|
38
99
|
const listedNames = [];
|
|
39
100
|
res.features.forEach(f => {
|
|
40
|
-
|
|
101
|
+
const plname = nominatimAddressToPlaceName(f.properties.address) || f.properties.display_name;
|
|
102
|
+
if(!listedNames.includes(plname)) {
|
|
41
103
|
finalRes.features.push({
|
|
42
104
|
place_type: ["place"],
|
|
43
|
-
place_name:
|
|
105
|
+
place_name: plname,
|
|
44
106
|
bounds: new maplibregl.LngLatBounds(f.bbox),
|
|
45
107
|
});
|
|
46
|
-
listedNames.push(
|
|
108
|
+
listedNames.push(plname);
|
|
47
109
|
}
|
|
48
110
|
});
|
|
49
111
|
return finalRes;
|
|
@@ -53,35 +115,7 @@ export function forwardGeocodingNominatim(config) {
|
|
|
53
115
|
export function reverseGeocodingNominatim(lat, lon) {
|
|
54
116
|
return fetch(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&zoom=18&format=jsonv2`)
|
|
55
117
|
.then(res => res.json())
|
|
56
|
-
.then(res =>
|
|
57
|
-
let addr = "";
|
|
58
|
-
|
|
59
|
-
if(res?.address) {
|
|
60
|
-
if(res.address.house_number) { addr = res.address.house_number; }
|
|
61
|
-
|
|
62
|
-
// Street/place/hamlet
|
|
63
|
-
let street;
|
|
64
|
-
if(res.address.road && res.address.road.length > 6) {
|
|
65
|
-
street = res.address.road;
|
|
66
|
-
}
|
|
67
|
-
else if(res.address.hamlet) {
|
|
68
|
-
street = res.address.hamlet;
|
|
69
|
-
}
|
|
70
|
-
else if(res.address.isolated_dwelling) {
|
|
71
|
-
street = res.address.isolated_dwelling;
|
|
72
|
-
}
|
|
73
|
-
if(street && addr.length > 0) { addr += " "+street; }
|
|
74
|
-
else if(street) { addr = street; }
|
|
75
|
-
|
|
76
|
-
// City
|
|
77
|
-
if(res.address.village || res.address.town || res.address.city) {
|
|
78
|
-
if(addr.length > 0) { addr += ", "; }
|
|
79
|
-
addr += res.address.village || res.address.town || res.address.city;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return addr;
|
|
84
|
-
});
|
|
118
|
+
.then(res => nominatimAddressToPlaceName(res?.address));
|
|
85
119
|
}
|
|
86
120
|
|
|
87
121
|
/**
|
package/src/utils/map.js
CHANGED
|
@@ -602,4 +602,44 @@ export function initMapKeyboardHandler(parent) {
|
|
|
602
602
|
}
|
|
603
603
|
};
|
|
604
604
|
}.bind(parent.map.keyboard);
|
|
605
|
-
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
const MAP_PARAMS_STORAGE = "pnx-map-parameters";
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Reads map parameters from localStorage
|
|
611
|
+
* @private
|
|
612
|
+
*/
|
|
613
|
+
export function getMapParamsFromLocalStorage() {
|
|
614
|
+
const params = localStorage.getItem(MAP_PARAMS_STORAGE);
|
|
615
|
+
if(!params) { return {}; }
|
|
616
|
+
try {
|
|
617
|
+
return JSON.parse(params);
|
|
618
|
+
}
|
|
619
|
+
catch(e) {
|
|
620
|
+
console.warn("Can't read map parameters stored in localStorage", e);
|
|
621
|
+
return {};
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Save map parameters into localStorage.
|
|
627
|
+
* @private
|
|
628
|
+
*/
|
|
629
|
+
export function saveMapParamsToLocalStorage(map) {
|
|
630
|
+
// Save map state in localStorage
|
|
631
|
+
const save = () => localStorage.setItem(MAP_PARAMS_STORAGE, JSON.stringify({
|
|
632
|
+
center: Object.fromEntries(Object.entries(map.getCenter()).map(([k,v]) => ([k,v.toFixed(7)]))),
|
|
633
|
+
zoom: map.getZoom().toFixed(1),
|
|
634
|
+
background: map.getBackground(),
|
|
635
|
+
theme: map._mapFilters.theme
|
|
636
|
+
}));
|
|
637
|
+
|
|
638
|
+
// Add events to know when to rewrite info
|
|
639
|
+
map.on("background-changed", save);
|
|
640
|
+
map.on("filters-changed", save);
|
|
641
|
+
map.on("moveend", save);
|
|
642
|
+
map.on("zoomend", save);
|
|
643
|
+
map.on("dragend", save);
|
|
644
|
+
map.on("boxzoomend", save);
|
|
645
|
+
}
|
|
@@ -4,8 +4,7 @@ import {
|
|
|
4
4
|
} from "../../src/utils/InitParameters";
|
|
5
5
|
|
|
6
6
|
describe("InitParameters", () => {
|
|
7
|
-
let componentAttrs;
|
|
8
|
-
let urlParams;
|
|
7
|
+
let componentAttrs, urlParams, browserStorage;
|
|
9
8
|
|
|
10
9
|
beforeEach(() => {
|
|
11
10
|
console.warn = jest.fn();
|
|
@@ -41,12 +40,16 @@ describe("InitParameters", () => {
|
|
|
41
40
|
camera: "cam1",
|
|
42
41
|
pic_score: "high",
|
|
43
42
|
};
|
|
43
|
+
|
|
44
|
+
browserStorage = {
|
|
45
|
+
map: { theme: "qualityscore", background: "aerial", center: [-10, -20], zoom: 19 },
|
|
46
|
+
};
|
|
44
47
|
});
|
|
45
48
|
|
|
46
49
|
afterEach(() => jest.clearAllMocks());
|
|
47
50
|
|
|
48
51
|
it("should initialize with componentAttrs and urlParams", () => {
|
|
49
|
-
const initParams = new InitParameters(componentAttrs, urlParams);
|
|
52
|
+
const initParams = new InitParameters(componentAttrs, urlParams, browserStorage);
|
|
50
53
|
|
|
51
54
|
expect(initParams._parentInit).toEqual({
|
|
52
55
|
map: true,
|
|
@@ -111,6 +114,20 @@ describe("InitParameters", () => {
|
|
|
111
114
|
});
|
|
112
115
|
});
|
|
113
116
|
|
|
117
|
+
it("uses browserStorage parameters if no URL parameter is available", () => {
|
|
118
|
+
componentAttrs.map.raster = {};
|
|
119
|
+
const initParams = new InitParameters(componentAttrs, undefined, browserStorage);
|
|
120
|
+
expect(initParams._mapAny).toEqual({
|
|
121
|
+
theme: "qualityscore",
|
|
122
|
+
background: "aerial",
|
|
123
|
+
center: [-10,-20],
|
|
124
|
+
zoom: 19,
|
|
125
|
+
pitch: undefined,
|
|
126
|
+
bearing: undefined,
|
|
127
|
+
users: "user1,user2",
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
114
131
|
it("should sanitize objects correctly", () => {
|
|
115
132
|
const initParams = new InitParameters(componentAttrs, urlParams);
|
|
116
133
|
const obj = { a: 1, b: undefined, c: 3 };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`getMapParamsFromLocalStorage should return parsed params if they exist in localStorage 1`] = `
|
|
4
|
+
Array [
|
|
5
|
+
Array [
|
|
6
|
+
"pnx-map-parameters",
|
|
7
|
+
],
|
|
8
|
+
]
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
exports[`saveMapParamsToLocalStorage should save map parameters to localStorage 1`] = `Array []`;
|
package/tests/utils/map.test.js
CHANGED
|
@@ -12,30 +12,30 @@ describe("getThumbGif", () => {
|
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
describe("isLabelLayer", () => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
15
|
+
it("works with just text-field", () => {
|
|
16
|
+
const layer = { type: "symbol", layout: { "text-field": "Label" } };
|
|
17
|
+
expect(map.isLabelLayer(layer)).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("works with text-field + minzoom < 15", () => {
|
|
21
|
+
const layer = { type: "symbol", layout: { "text-field": "Label" }, minzoom: 10 };
|
|
22
|
+
expect(map.isLabelLayer(layer)).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("works with text-field + minzoom >= 15", () => {
|
|
26
|
+
const layer = { type: "symbol", layout: { "text-field": "Label" }, minzoom: 15 };
|
|
27
|
+
expect(map.isLabelLayer(layer)).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("works with non-symbol layer", () => {
|
|
31
|
+
const layer = { type: "fill", layout: { "text-field": "Label" } };
|
|
32
|
+
expect(map.isLabelLayer(layer)).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("works without text-field", () => {
|
|
36
|
+
const layer = { type: "symbol", layout: {} };
|
|
37
|
+
expect(map.isLabelLayer(layer)).toBe(false);
|
|
38
|
+
});
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
describe("getUserLayerId", () => {
|
|
@@ -65,3 +65,62 @@ describe("switchCoefValue", () => {
|
|
|
65
65
|
expect(res).toEqual({id: "bla", paint: { "circle-radius": ["bla", ["get", "coef_360"]]}, layout: {"circle-sort": "coef_360"}})
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Object.defineProperty(window, "localStorage", { value: {
|
|
71
|
+
setItem: jest.fn(),
|
|
72
|
+
getItem: jest.fn(),
|
|
73
|
+
} });
|
|
74
|
+
|
|
75
|
+
describe("getMapParamsFromLocalStorage", () => {
|
|
76
|
+
it("should return an empty object if no params are stored", () => {
|
|
77
|
+
localStorage.getItem.mockReturnValue(null);
|
|
78
|
+
const result = map.getMapParamsFromLocalStorage();
|
|
79
|
+
expect(result).toEqual({});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("should return parsed params if they exist in localStorage", () => {
|
|
83
|
+
const params = { center: { lat: "48.8566000", lng: "2.3522000" }, zoom: "10.0", background: "aerial", theme: "age" };
|
|
84
|
+
localStorage.getItem.mockReturnValue(JSON.stringify(params));
|
|
85
|
+
const result = map.getMapParamsFromLocalStorage();
|
|
86
|
+
expect(localStorage.getItem.mock.calls).toMatchSnapshot();
|
|
87
|
+
expect(result).toEqual(params);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should return an empty object if JSON parsing fails", () => {
|
|
91
|
+
console.warn = jest.fn();
|
|
92
|
+
localStorage.getItem.mockReturnValue("invalid-json");
|
|
93
|
+
const result = map.getMapParamsFromLocalStorage();
|
|
94
|
+
expect(result).toEqual({});
|
|
95
|
+
expect(console.warn.mock.calls[0][0]).toEqual("Can't read map parameters stored in localStorage");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe("saveMapParamsToLocalStorage", () => {
|
|
100
|
+
const mockMap = {
|
|
101
|
+
getCenter: jest.fn().mockReturnValue({ lat: 48.8566, lng: 2.3522 }),
|
|
102
|
+
getZoom: jest.fn().mockReturnValue(10),
|
|
103
|
+
getBackground: jest.fn().mockReturnValue("streets"),
|
|
104
|
+
_mapFilters: { theme: "qualityscore" },
|
|
105
|
+
on: jest.fn(),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
beforeEach(() => {
|
|
109
|
+
jest.clearAllMocks();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("should add event listeners to the map", () => {
|
|
113
|
+
map.saveMapParamsToLocalStorage(mockMap);
|
|
114
|
+
expect(mockMap.on).toHaveBeenCalledWith("background-changed", expect.any(Function));
|
|
115
|
+
expect(mockMap.on).toHaveBeenCalledWith("filters-changed", expect.any(Function));
|
|
116
|
+
expect(mockMap.on).toHaveBeenCalledWith("moveend", expect.any(Function));
|
|
117
|
+
expect(mockMap.on).toHaveBeenCalledWith("zoomend", expect.any(Function));
|
|
118
|
+
expect(mockMap.on).toHaveBeenCalledWith("dragend", expect.any(Function));
|
|
119
|
+
expect(mockMap.on).toHaveBeenCalledWith("boxzoomend", expect.any(Function));
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("should save map parameters to localStorage", () => {
|
|
123
|
+
map.saveMapParamsToLocalStorage(mockMap);
|
|
124
|
+
expect(localStorage.setItem.mock.calls).toMatchSnapshot();
|
|
125
|
+
});
|
|
126
|
+
});
|