@panoramax/web-viewer 4.0.3 → 4.1.0
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 +40 -1
- package/build/index.css +9 -9
- package/build/index.css.map +1 -1
- package/build/index.js +640 -456
- package/build/index.js.map +1 -1
- package/build/photo.html +1 -1
- package/build/viewer.html +3 -3
- package/build/widgets.html +1 -1
- package/config/jest/mocks.js +9 -1
- package/docs/03_URL_settings.md +21 -0
- package/docs/09_Develop.md +6 -0
- package/docs/images/comparative_3drender.jpg +0 -0
- package/docs/index.md +13 -0
- package/docs/reference/components/core/Editor.md +18 -0
- package/docs/reference/components/core/PhotoViewer.md +1 -0
- package/docs/reference/components/core/Viewer.md +1 -0
- package/docs/reference/components/menus/MapLegend.md +17 -0
- package/docs/reference/components/menus/MiniPictureLegend.md +15 -0
- package/docs/reference/components/menus/PictureLegend.md +17 -0
- package/docs/reference/components/ui/AnnotationsSwitch.md +15 -0
- package/docs/reference/components/ui/Button.md +1 -1
- package/docs/reference/components/ui/CopyButton.md +1 -1
- package/docs/reference/components/ui/LinkButton.md +1 -1
- package/docs/reference/components/ui/Map.md +18 -2
- package/docs/reference/components/ui/MapMore.md +6 -2
- package/docs/reference/components/ui/SemanticsEditor.md +87 -0
- package/docs/reference/components/ui/widgets/Legend.md +5 -4
- package/docs/reference/utils/URLHandler.md +7 -0
- package/docs/reference.md +3 -1
- package/docs/tutorials/aerial_imagery.md +13 -11
- package/mkdocs.yml +3 -1
- package/package.json +7 -7
- package/public/photo.html +1 -1
- package/public/viewer.html +3 -3
- package/public/widgets.html +32 -0
- package/src/components/core/Basic.css +2 -0
- package/src/components/core/Basic.js +3 -1
- package/src/components/core/CoverageMap.js +6 -0
- package/src/components/core/Editor.css +1 -0
- package/src/components/core/Editor.js +58 -7
- package/src/components/core/PhotoViewer.css +5 -10
- package/src/components/core/PhotoViewer.js +55 -20
- package/src/components/core/Viewer.css +9 -2
- package/src/components/core/Viewer.js +62 -33
- package/src/components/layout/BottomDrawer.js +2 -1
- package/src/components/layout/Tabs.js +4 -0
- package/src/components/menus/AnnotationsList.js +13 -9
- package/src/components/menus/MapBackground.js +8 -3
- package/src/components/menus/MapFilters.js +11 -2
- package/src/components/menus/MapLayers.js +3 -2
- package/src/components/menus/MapLegend.js +28 -4
- package/src/components/menus/MiniPictureLegend.js +74 -0
- package/src/components/menus/PictureLegend.js +88 -33
- package/src/components/menus/PictureMetadata.js +49 -17
- package/src/components/menus/PlayerOptions.js +3 -3
- package/src/components/menus/Share.js +3 -3
- package/src/components/menus/index.js +5 -4
- package/src/components/styles.js +11 -0
- package/src/components/ui/AnnotationsSwitch.js +169 -0
- package/src/components/ui/Button.js +1 -1
- package/src/components/ui/CopyButton.js +1 -1
- package/src/components/ui/LinkButton.js +1 -1
- package/src/components/ui/Map.css +4 -0
- package/src/components/ui/Map.js +17 -5
- package/src/components/ui/MapMore.js +61 -25
- package/src/components/ui/Photo.css +11 -2
- package/src/components/ui/Photo.js +6 -3
- package/src/components/ui/SemanticsEditor.js +157 -0
- package/src/components/ui/index.js +2 -1
- package/src/components/ui/widgets/GeoSearch.js +3 -2
- package/src/components/ui/widgets/Legend.js +69 -14
- package/src/components/ui/widgets/MapFiltersButton.js +3 -3
- package/src/components/ui/widgets/MapLayersButton.js +3 -3
- package/src/components/ui/widgets/OSMEditors.js +2 -2
- package/src/components/ui/widgets/PictureLegendActions.js +24 -42
- package/src/components/ui/widgets/Player.js +3 -3
- package/src/components/ui/widgets/Zoom.js +4 -2
- package/src/translations/ar.json +1 -0
- package/src/translations/da.json +3 -2
- package/src/translations/de.json +64 -13
- package/src/translations/en.json +5 -1
- package/src/translations/eo.json +32 -2
- package/src/translations/fr.json +7 -1
- package/src/translations/it.json +33 -2
- package/src/translations/nl.json +53 -11
- package/src/translations/zh_Hant.json +29 -2
- package/src/utils/API.js +17 -1
- package/src/utils/InitParameters.js +46 -4
- package/src/utils/URLHandler.js +9 -1
- package/src/utils/map.js +24 -1
- package/src/utils/semantics.js +53 -1
- package/src/utils/services.js +16 -0
- package/src/utils/widgets.js +20 -0
- package/tests/components/core/Editor.test.js +1 -1
- package/tests/components/core/__snapshots__/PhotoViewer.test.js.snap +18 -6
- package/tests/components/core/__snapshots__/Viewer.test.js.snap +15 -3
- package/tests/components/ui/Photo.test.js +1 -0
- package/tests/components/ui/__snapshots__/Map.test.js.snap +164 -0
- package/tests/utils/InitParameters.test.js +27 -0
- package/tests/utils/map.test.js +12 -0
- package/tests/utils/semantics.test.js +34 -5
- package/docs/reference/components/ui/HashTags.md +0 -15
- package/src/components/ui/HashTags.js +0 -98
package/src/utils/URLHandler.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
// List of supported parameters
|
|
6
6
|
const MANAGED_PARAMETERS = [
|
|
7
7
|
"speed", "nav", "focus", "pic", "xyz", "map",
|
|
8
|
-
"background", "users", "pic_score", "s"
|
|
8
|
+
"background", "users", "pic_score", "s", "xywh",
|
|
9
9
|
].concat(Object.values(MAP_FILTERS_JS2URL));
|
|
10
10
|
|
|
11
11
|
// Events to listen on parent and PSV
|
|
@@ -45,6 +45,14 @@ export default class URLHandler extends EventTarget {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Call this function to stop listening to global events.
|
|
50
|
+
* @memberof Panoramax.utils.URLHandler#
|
|
51
|
+
*/
|
|
52
|
+
destroy() {
|
|
53
|
+
window.removeEventListener("popstate", this._onURLChange);
|
|
54
|
+
}
|
|
55
|
+
|
|
48
56
|
/**
|
|
49
57
|
* Compute next values to insert in URL
|
|
50
58
|
* @returns {object} Query parameters
|
package/src/utils/map.js
CHANGED
|
@@ -95,6 +95,17 @@ export function getThumbGif(lang) {
|
|
|
95
95
|
return thumbGif;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
export function isNullCoordinates(c) {
|
|
99
|
+
return (
|
|
100
|
+
c === null
|
|
101
|
+
|| c === undefined
|
|
102
|
+
|| (Array.isArray(c) && (
|
|
103
|
+
(c.length === 2 && c[0] === 0 && c[1] === 0)
|
|
104
|
+
|| c.length < 2
|
|
105
|
+
))
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
98
109
|
/**
|
|
99
110
|
* Is given layer a label layer.
|
|
100
111
|
*
|
|
@@ -220,6 +231,11 @@ export function combineStyles(parent, options) {
|
|
|
220
231
|
style.layers.push(capitalLayer);
|
|
221
232
|
}
|
|
222
233
|
|
|
234
|
+
// Fix for maxzoom on IGN tiles
|
|
235
|
+
if(style?.sources?.plan_ign) {
|
|
236
|
+
style.sources.plan_ign.maxzoom = 18;
|
|
237
|
+
}
|
|
238
|
+
|
|
223
239
|
return style;
|
|
224
240
|
}
|
|
225
241
|
|
|
@@ -408,7 +424,14 @@ export function linkMapAndPhoto(parent) {
|
|
|
408
424
|
}
|
|
409
425
|
}
|
|
410
426
|
else {
|
|
411
|
-
parent.map.displayPictureMarker(
|
|
427
|
+
parent.map.displayPictureMarker(
|
|
428
|
+
e.detail.lon,
|
|
429
|
+
e.detail.lat,
|
|
430
|
+
parent.psv.getXY().x,
|
|
431
|
+
e.detail.first && !isNullCoordinates(parent._initParams?.getMapPostInit()?.center), // Skip centering if precise coordinates are set from URL
|
|
432
|
+
e.detail.picId
|
|
433
|
+
);
|
|
434
|
+
|
|
412
435
|
if(parent?.isMapWide?.()) {
|
|
413
436
|
parent?.mini?.removeAttribute("collapsed");
|
|
414
437
|
}
|
package/src/utils/semantics.js
CHANGED
|
@@ -79,7 +79,7 @@ const KNOWN_PREFIXES = {
|
|
|
79
79
|
* @private
|
|
80
80
|
*/
|
|
81
81
|
export function decodeBasicTag(tag) {
|
|
82
|
-
const firstEqual = (tag || "").
|
|
82
|
+
const firstEqual = (tag || "").lastIndexOf("=");
|
|
83
83
|
if(firstEqual < 0) { return null; }
|
|
84
84
|
return {
|
|
85
85
|
key: decodeKey(tag.substring(0, firstEqual)),
|
|
@@ -99,6 +99,7 @@ export function decodeKey(key = "") {
|
|
|
99
99
|
|
|
100
100
|
const [, prefix, subkey, qualifies ] = match;
|
|
101
101
|
return {
|
|
102
|
+
key: key,
|
|
102
103
|
prefix: prefix || "",
|
|
103
104
|
subkey,
|
|
104
105
|
qualifies: decodeBasicTag(qualifies),
|
|
@@ -106,6 +107,57 @@ export function decodeKey(key = "") {
|
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Transforms a string containing a list of tags in a ready-to-use parsed object list.
|
|
112
|
+
* @param {string} str The string to read (each tag separated by newline `\n`)
|
|
113
|
+
* @returns {object[]} List of API-formatted tags
|
|
114
|
+
*/
|
|
115
|
+
export function parseSemanticsString(str) {
|
|
116
|
+
const parsedTags = str.split("\n").map(t => {
|
|
117
|
+
const parts = decodeBasicTag(t);
|
|
118
|
+
if(
|
|
119
|
+
parts
|
|
120
|
+
&& parts.key.key.length <= 256
|
|
121
|
+
&& parts.value.length <= 2048
|
|
122
|
+
) {
|
|
123
|
+
return { key: parts.key.key, value: parts.value };
|
|
124
|
+
} else { return null; }
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
if(parsedTags.findIndex(v => !v) >= 0) {
|
|
128
|
+
if(str.trim().length === 0 && parsedTags.length === 1) { return []; }
|
|
129
|
+
throw new Error("Invalid tags");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return parsedTags;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Computes the difference between two set of API tags.
|
|
138
|
+
* API expects a delta between old & new, so result contains only
|
|
139
|
+
* added and deleted tags.
|
|
140
|
+
* @param {object[]} prev The previous set of tags
|
|
141
|
+
* @param {object[]} next The new set of tags
|
|
142
|
+
* @returns {object[]} The new set of tags, with only added/deleted tags
|
|
143
|
+
*/
|
|
144
|
+
export function computeDiffTags(prev = [], next = []) {
|
|
145
|
+
const res = [];
|
|
146
|
+
|
|
147
|
+
// Look for new values
|
|
148
|
+
(next || [])
|
|
149
|
+
.filter(nt => prev.find(pt => pt.key == nt.key && pt.value == nt.value) === undefined)
|
|
150
|
+
.forEach(t => res.push({key: t.key, value: t.value, action: "add"}));
|
|
151
|
+
|
|
152
|
+
// Look for prev values missing in next
|
|
153
|
+
(prev || [])
|
|
154
|
+
.filter(pt => next.find(nt => pt.key == nt.key && pt.value == nt.value) === undefined)
|
|
155
|
+
.forEach(t => res.push({key: t.key, value: t.value, action: "delete"}));
|
|
156
|
+
|
|
157
|
+
return res;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
109
161
|
/**
|
|
110
162
|
* Transforms raw API semantics properties into ready-to-display container.
|
|
111
163
|
* @param {object[]} tags The API semantics tags
|
package/src/utils/services.js
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Panoramax website URL
|
|
9
|
+
* @returns {string} The website URL
|
|
10
|
+
*/
|
|
11
|
+
export function PanoramaxWebsiteURL() {
|
|
12
|
+
return "https://panoramax.fr";
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
/**
|
|
8
16
|
* Panoramax Presets URL
|
|
9
17
|
* @returns {string} The presets URL
|
|
@@ -12,6 +20,14 @@ export function PanoramaxPresetsURL() {
|
|
|
12
20
|
return "https://presets.panoramax.fr";
|
|
13
21
|
}
|
|
14
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Panoramax meta-catalog URL
|
|
25
|
+
* @returns {string} The metacatalog URL
|
|
26
|
+
*/
|
|
27
|
+
export function PanoramaxMetaCatalogURL() {
|
|
28
|
+
return "https://explore.panoramax.fr";
|
|
29
|
+
}
|
|
30
|
+
|
|
15
31
|
/**
|
|
16
32
|
* Temaki icons URL
|
|
17
33
|
* @param {string} [iconName] The icon name to insert in URL
|
package/src/utils/widgets.js
CHANGED
|
@@ -70,3 +70,23 @@ export function listenForMenuClosure(me, callback) {
|
|
|
70
70
|
me._parent.legend?.addEventListener("click", () => callback());
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Wait for parent availability
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
export function onceParentAvailable(comp) {
|
|
79
|
+
if(comp._parent) {
|
|
80
|
+
return Promise.resolve(comp._parent);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return new Promise(resolve => {
|
|
84
|
+
const itv = setInterval(() => {
|
|
85
|
+
if(comp._parent) {
|
|
86
|
+
clearInterval(itv);
|
|
87
|
+
resolve(comp._parent);
|
|
88
|
+
}
|
|
89
|
+
}, 100);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -15,6 +15,6 @@ describe("getClassName", () => {
|
|
|
15
15
|
|
|
16
16
|
describe("getSubComponentsNames", () => {
|
|
17
17
|
it("works", () => {
|
|
18
|
-
expect(comp.getSubComponentsNames()).toEqual(["loader", "api", "map", "psv"]);
|
|
18
|
+
expect(comp.getSubComponentsNames()).toEqual(["loader", "api", "map", "psv", "grid"]);
|
|
19
19
|
});
|
|
20
20
|
});
|
|
@@ -10,6 +10,13 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
|
|
|
10
10
|
slot="top"
|
|
11
11
|
/>,
|
|
12
12
|
],
|
|
13
|
+
Array [
|
|
14
|
+
<pnx-annotations-switch
|
|
15
|
+
class="pnx-only-psv pnx-print-hidden"
|
|
16
|
+
size="xl"
|
|
17
|
+
slot="top"
|
|
18
|
+
/>,
|
|
19
|
+
],
|
|
13
20
|
Array [
|
|
14
21
|
<pnx-widget-zoom
|
|
15
22
|
class="pnx-print-hidden"
|
|
@@ -23,12 +30,6 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
|
|
|
23
30
|
slot="top-left"
|
|
24
31
|
/>,
|
|
25
32
|
],
|
|
26
|
-
Array [
|
|
27
|
-
<pnx-hashtags
|
|
28
|
-
class="pnx-only-psv pnx-print-hidden"
|
|
29
|
-
slot="top-right"
|
|
30
|
-
/>,
|
|
31
|
-
],
|
|
32
33
|
],
|
|
33
34
|
"results": Array [
|
|
34
35
|
Object {
|
|
@@ -61,6 +62,13 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
|
|
|
61
62
|
slot="top"
|
|
62
63
|
/>,
|
|
63
64
|
],
|
|
65
|
+
Array [
|
|
66
|
+
<pnx-annotations-switch
|
|
67
|
+
class="pnx-only-psv pnx-print-hidden"
|
|
68
|
+
size="xl"
|
|
69
|
+
slot="top"
|
|
70
|
+
/>,
|
|
71
|
+
],
|
|
64
72
|
Array [
|
|
65
73
|
<pnx-bottom-drawer
|
|
66
74
|
slot="bottom"
|
|
@@ -78,6 +86,10 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
|
|
|
78
86
|
"type": "return",
|
|
79
87
|
"value": undefined,
|
|
80
88
|
},
|
|
89
|
+
Object {
|
|
90
|
+
"type": "return",
|
|
91
|
+
"value": undefined,
|
|
92
|
+
},
|
|
81
93
|
],
|
|
82
94
|
}
|
|
83
95
|
`;
|
|
@@ -17,13 +17,14 @@ exports[`_initWidgets should handle widgets if width is not small 1`] = `
|
|
|
17
17
|
/>,
|
|
18
18
|
],
|
|
19
19
|
Array [
|
|
20
|
-
<pnx-
|
|
20
|
+
<pnx-widget-player
|
|
21
21
|
class="pnx-only-psv pnx-print-hidden"
|
|
22
|
-
|
|
22
|
+
size="xl"
|
|
23
|
+
slot="top"
|
|
23
24
|
/>,
|
|
24
25
|
],
|
|
25
26
|
Array [
|
|
26
|
-
<pnx-
|
|
27
|
+
<pnx-annotations-switch
|
|
27
28
|
class="pnx-only-psv pnx-print-hidden"
|
|
28
29
|
size="xl"
|
|
29
30
|
slot="top"
|
|
@@ -105,6 +106,13 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
|
|
|
105
106
|
slot="top"
|
|
106
107
|
/>,
|
|
107
108
|
],
|
|
109
|
+
Array [
|
|
110
|
+
<pnx-annotations-switch
|
|
111
|
+
class="pnx-only-psv pnx-print-hidden"
|
|
112
|
+
size="xl"
|
|
113
|
+
slot="top"
|
|
114
|
+
/>,
|
|
115
|
+
],
|
|
108
116
|
Array [
|
|
109
117
|
<pnx-widget-geosearch
|
|
110
118
|
class="pnx-only-map pnx-print-hidden"
|
|
@@ -150,6 +158,10 @@ exports[`_initWidgets should handle widgets if width is small 1`] = `
|
|
|
150
158
|
"type": "return",
|
|
151
159
|
"value": undefined,
|
|
152
160
|
},
|
|
161
|
+
Object {
|
|
162
|
+
"type": "return",
|
|
163
|
+
"value": undefined,
|
|
164
|
+
},
|
|
153
165
|
],
|
|
154
166
|
}
|
|
155
167
|
`;
|
|
@@ -736,5 +736,169 @@ Array [
|
|
|
736
736
|
"visibility",
|
|
737
737
|
"none",
|
|
738
738
|
],
|
|
739
|
+
Array [
|
|
740
|
+
"geovisio_blabla_pictures",
|
|
741
|
+
"circle-sort-key",
|
|
742
|
+
Array [
|
|
743
|
+
"case",
|
|
744
|
+
Array [
|
|
745
|
+
"==",
|
|
746
|
+
Array [
|
|
747
|
+
"get",
|
|
748
|
+
"hidden",
|
|
749
|
+
],
|
|
750
|
+
true,
|
|
751
|
+
],
|
|
752
|
+
90,
|
|
753
|
+
10,
|
|
754
|
+
],
|
|
755
|
+
],
|
|
756
|
+
Array [
|
|
757
|
+
"geovisio_pictures",
|
|
758
|
+
"circle-sort-key",
|
|
759
|
+
Array [
|
|
760
|
+
"case",
|
|
761
|
+
Array [
|
|
762
|
+
"==",
|
|
763
|
+
Array [
|
|
764
|
+
"get",
|
|
765
|
+
"hidden",
|
|
766
|
+
],
|
|
767
|
+
true,
|
|
768
|
+
],
|
|
769
|
+
90,
|
|
770
|
+
10,
|
|
771
|
+
],
|
|
772
|
+
],
|
|
773
|
+
Array [
|
|
774
|
+
"geovisio_blabla_pictures_symbols",
|
|
775
|
+
"icon-image",
|
|
776
|
+
Array [
|
|
777
|
+
"case",
|
|
778
|
+
Array [
|
|
779
|
+
"==",
|
|
780
|
+
Array [
|
|
781
|
+
"get",
|
|
782
|
+
"id",
|
|
783
|
+
],
|
|
784
|
+
undefined,
|
|
785
|
+
],
|
|
786
|
+
"",
|
|
787
|
+
Array [
|
|
788
|
+
"==",
|
|
789
|
+
Array [
|
|
790
|
+
"get",
|
|
791
|
+
"type",
|
|
792
|
+
],
|
|
793
|
+
"equirectangular",
|
|
794
|
+
],
|
|
795
|
+
"pnx-arrow-360",
|
|
796
|
+
"pnx-arrow-flat",
|
|
797
|
+
],
|
|
798
|
+
],
|
|
799
|
+
Array [
|
|
800
|
+
"geovisio_blabla_pictures_symbols",
|
|
801
|
+
"symbol-sort-key",
|
|
802
|
+
Array [
|
|
803
|
+
"case",
|
|
804
|
+
Array [
|
|
805
|
+
"==",
|
|
806
|
+
Array [
|
|
807
|
+
"get",
|
|
808
|
+
"hidden",
|
|
809
|
+
],
|
|
810
|
+
true,
|
|
811
|
+
],
|
|
812
|
+
90,
|
|
813
|
+
10,
|
|
814
|
+
],
|
|
815
|
+
],
|
|
816
|
+
Array [
|
|
817
|
+
"geovisio_pictures_symbols",
|
|
818
|
+
"icon-image",
|
|
819
|
+
Array [
|
|
820
|
+
"case",
|
|
821
|
+
Array [
|
|
822
|
+
"==",
|
|
823
|
+
Array [
|
|
824
|
+
"get",
|
|
825
|
+
"id",
|
|
826
|
+
],
|
|
827
|
+
undefined,
|
|
828
|
+
],
|
|
829
|
+
"",
|
|
830
|
+
Array [
|
|
831
|
+
"==",
|
|
832
|
+
Array [
|
|
833
|
+
"get",
|
|
834
|
+
"type",
|
|
835
|
+
],
|
|
836
|
+
"equirectangular",
|
|
837
|
+
],
|
|
838
|
+
"pnx-arrow-360",
|
|
839
|
+
"pnx-arrow-flat",
|
|
840
|
+
],
|
|
841
|
+
],
|
|
842
|
+
Array [
|
|
843
|
+
"geovisio_pictures_symbols",
|
|
844
|
+
"symbol-sort-key",
|
|
845
|
+
Array [
|
|
846
|
+
"case",
|
|
847
|
+
Array [
|
|
848
|
+
"==",
|
|
849
|
+
Array [
|
|
850
|
+
"get",
|
|
851
|
+
"hidden",
|
|
852
|
+
],
|
|
853
|
+
true,
|
|
854
|
+
],
|
|
855
|
+
90,
|
|
856
|
+
10,
|
|
857
|
+
],
|
|
858
|
+
],
|
|
859
|
+
Array [
|
|
860
|
+
"geovisio_blabla_sequences",
|
|
861
|
+
"line-sort-key",
|
|
862
|
+
Array [
|
|
863
|
+
"case",
|
|
864
|
+
Array [
|
|
865
|
+
"==",
|
|
866
|
+
Array [
|
|
867
|
+
"get",
|
|
868
|
+
"hidden",
|
|
869
|
+
],
|
|
870
|
+
true,
|
|
871
|
+
],
|
|
872
|
+
90,
|
|
873
|
+
10,
|
|
874
|
+
],
|
|
875
|
+
],
|
|
876
|
+
Array [
|
|
877
|
+
"geovisio_blabla_sequences",
|
|
878
|
+
"line-cap",
|
|
879
|
+
"square",
|
|
880
|
+
],
|
|
881
|
+
Array [
|
|
882
|
+
"geovisio_sequences",
|
|
883
|
+
"line-sort-key",
|
|
884
|
+
Array [
|
|
885
|
+
"case",
|
|
886
|
+
Array [
|
|
887
|
+
"==",
|
|
888
|
+
Array [
|
|
889
|
+
"get",
|
|
890
|
+
"hidden",
|
|
891
|
+
],
|
|
892
|
+
true,
|
|
893
|
+
],
|
|
894
|
+
90,
|
|
895
|
+
10,
|
|
896
|
+
],
|
|
897
|
+
],
|
|
898
|
+
Array [
|
|
899
|
+
"geovisio_sequences",
|
|
900
|
+
"line-cap",
|
|
901
|
+
"square",
|
|
902
|
+
],
|
|
739
903
|
]
|
|
740
904
|
`;
|
|
@@ -66,6 +66,7 @@ describe("InitParameters", () => {
|
|
|
66
66
|
geocoder: true,
|
|
67
67
|
widgets: true,
|
|
68
68
|
forceFocus: true,
|
|
69
|
+
keyboardShortcuts: true,
|
|
69
70
|
});
|
|
70
71
|
expect(initParams._psvInit).toEqual({});
|
|
71
72
|
expect(initParams._psvAny).toEqual({
|
|
@@ -111,11 +112,13 @@ describe("InitParameters", () => {
|
|
|
111
112
|
geocoder: true,
|
|
112
113
|
widgets: true,
|
|
113
114
|
forceFocus: true,
|
|
115
|
+
keyboardShortcuts: true,
|
|
114
116
|
});
|
|
115
117
|
});
|
|
116
118
|
|
|
117
119
|
it("uses browserStorage parameters if no URL parameter is available", () => {
|
|
118
120
|
componentAttrs.map.raster = {};
|
|
121
|
+
componentAttrs.picture = undefined;
|
|
119
122
|
const initParams = new InitParameters(componentAttrs, undefined, browserStorage);
|
|
120
123
|
expect(initParams._mapAny).toEqual({
|
|
121
124
|
theme: "qualityscore",
|
|
@@ -128,6 +131,20 @@ describe("InitParameters", () => {
|
|
|
128
131
|
});
|
|
129
132
|
});
|
|
130
133
|
|
|
134
|
+
it("uses browserStorage parameters if no URL parameter is available, except map coords if picture is set", () => {
|
|
135
|
+
componentAttrs.map.raster = {};
|
|
136
|
+
const initParams = new InitParameters(componentAttrs, undefined, browserStorage);
|
|
137
|
+
expect(initParams._mapAny).toEqual({
|
|
138
|
+
theme: "qualityscore",
|
|
139
|
+
background: "aerial",
|
|
140
|
+
center: [0,0],
|
|
141
|
+
zoom: 19,
|
|
142
|
+
pitch: undefined,
|
|
143
|
+
bearing: undefined,
|
|
144
|
+
users: "user1,user2",
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
131
148
|
it("should sanitize objects correctly", () => {
|
|
132
149
|
const initParams = new InitParameters(componentAttrs, urlParams);
|
|
133
150
|
const obj = { a: 1, b: undefined, c: 3 };
|
|
@@ -161,6 +178,7 @@ describe("InitParameters", () => {
|
|
|
161
178
|
geocoder: true,
|
|
162
179
|
widgets: true,
|
|
163
180
|
forceFocus: true,
|
|
181
|
+
keyboardShortcuts: true,
|
|
164
182
|
});
|
|
165
183
|
});
|
|
166
184
|
|
|
@@ -243,6 +261,15 @@ describe("InitParameters", () => {
|
|
|
243
261
|
expect(initParams._mapAny.background).toBe("streets");
|
|
244
262
|
expect(console.warn).toHaveBeenCalledWith("Parameter background can't be 'aerial' as no aerial imagery is available");
|
|
245
263
|
});
|
|
264
|
+
|
|
265
|
+
it("should handle keyboardShortcuts=false", () => {
|
|
266
|
+
componentAttrs["keyboard-shortcuts"] = "false";
|
|
267
|
+
const initParams = new InitParameters(componentAttrs, urlParams);
|
|
268
|
+
expect(initParams._mapInit.keyboard).toBe(false);
|
|
269
|
+
expect(initParams._parentPostInit.keyboardShortcuts).toBe(false);
|
|
270
|
+
expect(initParams._psvInit.keyboard).toBe(false);
|
|
271
|
+
expect(initParams._psvInit.keyboardActions).toEqual({});
|
|
272
|
+
});
|
|
246
273
|
});
|
|
247
274
|
|
|
248
275
|
describe("getMapPositionFromString", () => {
|
package/tests/utils/map.test.js
CHANGED
|
@@ -11,6 +11,18 @@ describe("getThumbGif", () => {
|
|
|
11
11
|
});
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
describe("isNullCoordinates", () => {
|
|
15
|
+
it.each([
|
|
16
|
+
[undefined, true],
|
|
17
|
+
[null, true],
|
|
18
|
+
[[0,0], true],
|
|
19
|
+
[[48.7, -1.5], false],
|
|
20
|
+
[[], true],
|
|
21
|
+
])("works with %s", (input, expected) => {
|
|
22
|
+
expect(map.isNullCoordinates(input)).toBe(expected);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
14
26
|
describe("isLabelLayer", () => {
|
|
15
27
|
it("works with just text-field", () => {
|
|
16
28
|
const layer = { type: "symbol", layout: { "text-field": "Label" } };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
decodeKey, decodeBasicTag, computeDiffTags, groupByPrefix
|
|
3
|
+
} from "../../src/utils/semantics";
|
|
2
4
|
|
|
3
5
|
describe("decodeBasicTag", () => {
|
|
4
6
|
test("should return null if no equal sign is present", () => {
|
|
@@ -7,14 +9,14 @@ describe("decodeBasicTag", () => {
|
|
|
7
9
|
|
|
8
10
|
test("should correctly decode a tag with an equal sign", () => {
|
|
9
11
|
expect(decodeBasicTag("key=value")).toEqual({
|
|
10
|
-
key: { prefix: "", subkey: "key", qualifies: null },
|
|
12
|
+
key: { key: "key", prefix: "", subkey: "key", qualifies: null },
|
|
11
13
|
value: "value"
|
|
12
14
|
});
|
|
13
15
|
});
|
|
14
16
|
|
|
15
17
|
test("should correctly decode a tag with a prefix", () => {
|
|
16
18
|
expect(decodeBasicTag("osm|key=value")).toEqual({
|
|
17
|
-
key: { prefix: "osm", subkey: "key", qualifies: null },
|
|
19
|
+
key: { key: "osm|key", prefix: "osm", subkey: "key", qualifies: null },
|
|
18
20
|
value: "value"
|
|
19
21
|
});
|
|
20
22
|
});
|
|
@@ -23,6 +25,7 @@ describe("decodeBasicTag", () => {
|
|
|
23
25
|
describe("decodeKey", () => {
|
|
24
26
|
test("should return default structure if key does not match regex", () => {
|
|
25
27
|
expect(decodeKey("panoKey")).toEqual({
|
|
28
|
+
key: "panoKey",
|
|
26
29
|
prefix: "",
|
|
27
30
|
subkey: "panoKey",
|
|
28
31
|
qualifies: null
|
|
@@ -31,6 +34,7 @@ describe("decodeKey", () => {
|
|
|
31
34
|
|
|
32
35
|
test("should correctly decode a key with a prefix", () => {
|
|
33
36
|
expect(decodeKey("osm|traffic_sign")).toEqual({
|
|
37
|
+
key: "osm|traffic_sign",
|
|
34
38
|
prefix: "osm",
|
|
35
39
|
subkey: "traffic_sign",
|
|
36
40
|
qualifies: null
|
|
@@ -39,21 +43,46 @@ describe("decodeKey", () => {
|
|
|
39
43
|
|
|
40
44
|
test("should correctly decode a key with qualifiers", () => {
|
|
41
45
|
expect(decodeKey("detection_model[camera_mount=pole]")).toEqual({
|
|
46
|
+
key: "detection_model[camera_mount=pole]",
|
|
42
47
|
prefix: "",
|
|
43
48
|
subkey: "detection_model",
|
|
44
|
-
qualifies: { key: { prefix: "", subkey: "camera_mount", qualifies: null }, value: "pole" }
|
|
49
|
+
qualifies: { key: { key: "camera_mount", prefix: "", subkey: "camera_mount", qualifies: null }, value: "pole" }
|
|
45
50
|
});
|
|
46
51
|
});
|
|
47
52
|
|
|
48
53
|
test("should correctly decode a key with a prefix and qualifiers", () => {
|
|
49
54
|
expect(decodeKey("osm|source[osm|traffic_sign=stop]")).toEqual({
|
|
55
|
+
key: "osm|source[osm|traffic_sign=stop]",
|
|
50
56
|
prefix: "osm",
|
|
51
57
|
subkey: "source",
|
|
52
|
-
qualifies: { key: { prefix: "osm", subkey: "traffic_sign", qualifies: null }, value: "stop" }
|
|
58
|
+
qualifies: { key: { key: "osm|traffic_sign", prefix: "osm", subkey: "traffic_sign", qualifies: null }, value: "stop" }
|
|
53
59
|
});
|
|
54
60
|
});
|
|
55
61
|
});
|
|
56
62
|
|
|
63
|
+
describe("computeDiffTags", () => {
|
|
64
|
+
it("should return new set of tags when no tag is missing in next", () => {
|
|
65
|
+
const prev = [{key: "tag1", value: "value1"}, {key: "tag2", value: "value2"}];
|
|
66
|
+
const next = [{key: "tag1", value: "value1"}, {key: "tag2", value: "value2"}, {key: "tag3", value: "value3"}];
|
|
67
|
+
|
|
68
|
+
expect(computeDiffTags(prev, next)).toEqual([{key: "tag3", value: "value3", action: "add"}]);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should return new set of tags with missing tags marked as delete when some tag is missing in next", () => {
|
|
72
|
+
const prev = [{key: "tag1", value: "value1"}, {key: "tag2", value: "value2"}];
|
|
73
|
+
const next = [{key: "tag1", value: "value1"}];
|
|
74
|
+
|
|
75
|
+
expect(computeDiffTags(prev, next)).toEqual([{key: "tag2", value: "value2", action: "delete"}]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("should return new set of tags with all tags marked as delete when all tags are missing in next", () => {
|
|
79
|
+
const prev = [{key: "tag1", value: "value1"}, {key: "tag2", value: "value2"}];
|
|
80
|
+
const next = [];
|
|
81
|
+
|
|
82
|
+
expect(computeDiffTags(prev, next)).toEqual([{key: "tag1", value: "value1", action: "delete"}, {key: "tag2", value: "value2", action: "delete"}]);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
57
86
|
describe("groupByPrefix", () => {
|
|
58
87
|
test("should group tags by prefix", () => {
|
|
59
88
|
const tags = [
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<a name="Panoramax.components.ui.HashTags"></a>
|
|
2
|
-
|
|
3
|
-
## Panoramax.components.ui.HashTags ⇐ <code>[lit.LitElement](https://lit.dev/docs/api/LitElement/)</code>
|
|
4
|
-
**Kind**: static class of <code>Panoramax.components.ui</code>
|
|
5
|
-
**Extends**: <code>[lit.LitElement](https://lit.dev/docs/api/LitElement/)</code>
|
|
6
|
-
**Element**: pnx-hashtags
|
|
7
|
-
<a name="new_Panoramax.components.ui.HashTags_new"></a>
|
|
8
|
-
|
|
9
|
-
### new HashTags()
|
|
10
|
-
HashTags component shows the list of hashtags associated to a picture.
|
|
11
|
-
|
|
12
|
-
**Example**
|
|
13
|
-
```html
|
|
14
|
-
<pnx-hashtags ._parent=${viewer} />
|
|
15
|
-
```
|