@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
|
@@ -94,7 +94,7 @@ export default class Photo extends PSViewer {
|
|
|
94
94
|
resolution: parent.isWidthSmall() ? 32 : 64,
|
|
95
95
|
shouldGoFast: options.shouldGoFast,
|
|
96
96
|
}],
|
|
97
|
-
withCredentials: parent
|
|
97
|
+
withCredentials: parent.api._getPSVWithCredentials(),
|
|
98
98
|
requestHeaders: parent?.fetchOptions?.headers,
|
|
99
99
|
panorama: BASE_PANORAMA,
|
|
100
100
|
lang: parent._t.psv,
|
|
@@ -803,6 +803,7 @@ export default class Photo extends PSViewer {
|
|
|
803
803
|
*/
|
|
804
804
|
playSequence() {
|
|
805
805
|
this._sequencePlaying = true;
|
|
806
|
+
this.container.classList.add("pnx-psv-playing");
|
|
806
807
|
|
|
807
808
|
/**
|
|
808
809
|
* Event for sequence starting to play
|
|
@@ -841,6 +842,7 @@ export default class Photo extends PSViewer {
|
|
|
841
842
|
*/
|
|
842
843
|
stopSequence() {
|
|
843
844
|
this._sequencePlaying = false;
|
|
845
|
+
this.container.classList.remove("pnx-psv-playing");
|
|
844
846
|
|
|
845
847
|
// Next picture timer is pending
|
|
846
848
|
if(this._playTimer) {
|
|
@@ -952,8 +954,8 @@ export default class Photo extends PSViewer {
|
|
|
952
954
|
|
|
953
955
|
if(!visible) { this._myMarkers.clearMarkers(); }
|
|
954
956
|
else {
|
|
955
|
-
let annotations = meta.properties.annotations;
|
|
956
|
-
if(annotations
|
|
957
|
+
let annotations = meta.properties.annotations || [];
|
|
958
|
+
if(annotations?.length === 0) { console.warn("No annotation available on picture", meta.id); }
|
|
957
959
|
|
|
958
960
|
const picBData = this.state.textureData.panoData?.baseData;
|
|
959
961
|
|
|
@@ -990,6 +992,7 @@ export default class Photo extends PSViewer {
|
|
|
990
992
|
id: `annotation-${a.id}`,
|
|
991
993
|
polygon: shape,
|
|
992
994
|
data: { id: a.id },
|
|
995
|
+
className: "pnx-psv-annotation",
|
|
993
996
|
svgStyle: {
|
|
994
997
|
stroke: "var(--orange)",
|
|
995
998
|
strokeWidth: "3px",
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import Basic from "../core/Basic";
|
|
3
|
+
import { parseSemanticsString, computeDiffTags } from "../../utils/semantics";
|
|
4
|
+
import { textarea } from "../styles";
|
|
5
|
+
import JSON5 from "json5";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Semantics Editor offer an easy-to-use input for adding or editing semantics tags.
|
|
9
|
+
*
|
|
10
|
+
* It manipulates list of `{key: "mypanokey", value: "myvalue"}` entries through `semantics` attribute.
|
|
11
|
+
*
|
|
12
|
+
* @class Panoramax.components.ui.SemanticsEditor
|
|
13
|
+
* @element pnx-semantics-editor
|
|
14
|
+
* @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
|
|
15
|
+
* @fires Panoramax.components.ui.SemanticsEditor#change
|
|
16
|
+
* @example
|
|
17
|
+
* ```html
|
|
18
|
+
* <!-- Basic example -->
|
|
19
|
+
* <pnx-semantics-editor
|
|
20
|
+
* id="editor"
|
|
21
|
+
* semantics=${mypic.semantics}
|
|
22
|
+
* ._t=${viewer._t}
|
|
23
|
+
* onchange=${e => console.log(e.detail.semantics)}
|
|
24
|
+
* />
|
|
25
|
+
*
|
|
26
|
+
* <!-- You can access editor and check its validity through native web browser functions -->
|
|
27
|
+
* <script>
|
|
28
|
+
* const editor = document.getElementById("editor");
|
|
29
|
+
* console.log(editor.checkValidity()); // True if input is valid
|
|
30
|
+
* </script>
|
|
31
|
+
*
|
|
32
|
+
* <!-- You can change specifically style of textarea -->
|
|
33
|
+
* <style>
|
|
34
|
+
* pnx-semantics-editor::part(text) {
|
|
35
|
+
* color: blue;
|
|
36
|
+
* }
|
|
37
|
+
* </style>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export default class SemanticsEditor extends LitElement {
|
|
41
|
+
static styles = [textarea, css`
|
|
42
|
+
textarea:invalid {
|
|
43
|
+
border: 2px solid var(--red);
|
|
44
|
+
background-color:var(--beige);
|
|
45
|
+
}
|
|
46
|
+
`];
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Component properties.
|
|
50
|
+
* @memberof Panoramax.components.ui.SemanticsEditor#
|
|
51
|
+
* @type {Object}
|
|
52
|
+
* @property {object} [semantics] The `semantics` field of a picture or annotation feature. It is updated when field changes, but reflect the whole list of new tags (not delta needed by API). If you want delta, please use getDiff function.
|
|
53
|
+
* @property {number} [rows=3] The amount of rows shown for textarea
|
|
54
|
+
*/
|
|
55
|
+
static properties = {
|
|
56
|
+
semantics: {converter: Basic.GetJSONConverter(), reflect: true},
|
|
57
|
+
rows: {type: Number},
|
|
58
|
+
_valid: {state: true},
|
|
59
|
+
_t: {converter: Basic.GetJSONConverter()},
|
|
60
|
+
_firstSemantics: {state: true},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
constructor() {
|
|
64
|
+
super();
|
|
65
|
+
this.semantics = null;
|
|
66
|
+
this._valid = true;
|
|
67
|
+
this._firstSemantics = null;
|
|
68
|
+
this.rows = 3;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** @private */
|
|
72
|
+
connectedCallback() {
|
|
73
|
+
super.connectedCallback();
|
|
74
|
+
this._firstSemantics = this.semantics === null ? [] : JSON5.parse(JSON5.stringify(this.semantics));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Get current delta between initial tags and user changes.
|
|
79
|
+
* @memberof Panoramax.components.ui.SemanticsEditor#
|
|
80
|
+
* @returns {object[]} The list of tag changes (in API format)
|
|
81
|
+
*/
|
|
82
|
+
getDiff() {
|
|
83
|
+
return computeDiffTags(this._firstSemantics || [], this.semantics);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Check if input is having a valid value.
|
|
88
|
+
* @memberof Panoramax.components.ui.SemanticsEditor#
|
|
89
|
+
* @returns {boolean} True if it's valid
|
|
90
|
+
*/
|
|
91
|
+
checkValidity() {
|
|
92
|
+
return this._valid;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** @private */
|
|
96
|
+
_onInput(e) {
|
|
97
|
+
const tarea = e.target;
|
|
98
|
+
try {
|
|
99
|
+
this.semantics = parseSemanticsString(tarea.value) || [];
|
|
100
|
+
this._valid = true;
|
|
101
|
+
} catch (err) {
|
|
102
|
+
if(err.message !== "Invalid tags") { console.error(err); }
|
|
103
|
+
this._valid = false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** @private */
|
|
108
|
+
_onBlur(e) {
|
|
109
|
+
const prevValidity = e.target.checkValidity();
|
|
110
|
+
|
|
111
|
+
if(this._valid) {
|
|
112
|
+
e.target.setCustomValidity("");
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Event for value change.
|
|
116
|
+
*
|
|
117
|
+
* Note that this event is launched only on valid input.
|
|
118
|
+
*
|
|
119
|
+
* @event Panoramax.components.ui.SemanticsEditor#change
|
|
120
|
+
* @type {CustomEvent}
|
|
121
|
+
* @property {object[]} detail.semantics The new tags list (in API semantics property format)
|
|
122
|
+
* @property {object[]} detail.delta The delta between old and current tags (expected by API)
|
|
123
|
+
*/
|
|
124
|
+
this.dispatchEvent(new CustomEvent("change", {
|
|
125
|
+
detail: {
|
|
126
|
+
semantics: this.semantics || [],
|
|
127
|
+
delta: computeDiffTags(this._firstSemantics || [], this.semantics),
|
|
128
|
+
}
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
else if(prevValidity) { // Do not call again if already shows up, to fix Chrome issue
|
|
132
|
+
e.target.setCustomValidity(this._t?.pnx.semantics_editor_error || "Invalid syntax");
|
|
133
|
+
e.target.reportValidity();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** @private */
|
|
138
|
+
render() {
|
|
139
|
+
/* eslint-disable indent */
|
|
140
|
+
return html`
|
|
141
|
+
<textarea
|
|
142
|
+
part="text"
|
|
143
|
+
autocomplete="off"
|
|
144
|
+
autocorrect="off"
|
|
145
|
+
autocapitalize="off"
|
|
146
|
+
spellcheck="false"
|
|
147
|
+
placeholder="key1=value1\nprefix|key2=value2"
|
|
148
|
+
@input=${this._onInput}
|
|
149
|
+
@blur=${this._onBlur}
|
|
150
|
+
rows=${this.rows}
|
|
151
|
+
.value=${(this.semantics || []).map(s => `${s.key}=${s.value}`).join("\n")}
|
|
152
|
+
></textarea>
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
customElements.define("pnx-semantics-editor", SemanticsEditor);
|
|
@@ -7,7 +7,7 @@ export {default as ButtonGroup} from "./ButtonGroup";
|
|
|
7
7
|
export {default as Button} from "./Button";
|
|
8
8
|
export {default as CopyButton} from "./CopyButton";
|
|
9
9
|
export {default as Grade} from "./Grade";
|
|
10
|
-
export {default as
|
|
10
|
+
export {default as AnnotationsSwitch} from "./AnnotationsSwitch";
|
|
11
11
|
export {default as LinkButton} from "./LinkButton";
|
|
12
12
|
export {default as ListGroup} from "./ListGroup";
|
|
13
13
|
export {default as ListItem} from "./ListItem";
|
|
@@ -19,6 +19,7 @@ export {default as Popup} from "./Popup";
|
|
|
19
19
|
export {default as ProgressBar} from "./ProgressBar";
|
|
20
20
|
export {default as QualityScore} from "./QualityScore";
|
|
21
21
|
export {default as SearchBar} from "./SearchBar";
|
|
22
|
+
export {default as SemanticsEditor} from "./SemanticsEditor";
|
|
22
23
|
export {default as SemanticsTable} from "./SemanticsTable";
|
|
23
24
|
export {default as TogglableGroup} from "./TogglableGroup";
|
|
24
25
|
import * as widgets from "./widgets";
|
|
@@ -3,6 +3,7 @@ import maplibregl from "!maplibre-gl";
|
|
|
3
3
|
|
|
4
4
|
import { LitElement, html } from "lit";
|
|
5
5
|
import { forwardGeocodingBAN, forwardGeocodingStandard, forwardGeocodingNominatim } from "../../../utils/geocoder";
|
|
6
|
+
import { onceParentAvailable } from "../../../utils/widgets";
|
|
6
7
|
import "./GeoSearch.css";
|
|
7
8
|
|
|
8
9
|
const GEOCODER_ENGINES = {
|
|
@@ -63,10 +64,10 @@ export default class GeoSearch extends LitElement {
|
|
|
63
64
|
super.connectedCallback();
|
|
64
65
|
|
|
65
66
|
this._geocoderEngine = GEOCODER_ENGINES[this.geocoder] || (config => GEOCODER_ENGINES.standard(config, this.geocoder));
|
|
66
|
-
this._parent?.onceMapReady?.().then(() => {
|
|
67
|
+
onceParentAvailable(this).then(() => this._parent?.onceMapReady?.().then(() => {
|
|
67
68
|
this._geolocate = this._geolocateCtrl.onAdd(this._parent.map);
|
|
68
69
|
this._geolocate.setAttribute("slot", "pre");
|
|
69
|
-
});
|
|
70
|
+
}));
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
/** @private */
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {LitElement, html, css} from "lit";
|
|
1
|
+
import { LitElement, html, css, nothing } from "lit";
|
|
2
2
|
import { panel } from "../../styles";
|
|
3
3
|
import { fa } from "../../../utils/widgets";
|
|
4
4
|
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons/faInfoCircle";
|
|
5
5
|
import PanoramaxImg from "../../../img/panoramax.svg";
|
|
6
6
|
import { classMap } from "lit/directives/class-map.js";
|
|
7
|
+
import { PanoramaxWebsiteURL } from "../../../utils/services";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Legend widget, handling switch between map and photo components.
|
|
@@ -37,7 +38,7 @@ export default class Legend extends LitElement {
|
|
|
37
38
|
.pnx-panel[part="panel"] {
|
|
38
39
|
border-radius: 10px;
|
|
39
40
|
position: relative;
|
|
40
|
-
max-width:
|
|
41
|
+
max-width: 450px;
|
|
41
42
|
z-index: 121; /* To appear above mini component */
|
|
42
43
|
min-width: unset;
|
|
43
44
|
}
|
|
@@ -46,7 +47,8 @@ export default class Legend extends LitElement {
|
|
|
46
47
|
width: 250px;
|
|
47
48
|
}
|
|
48
49
|
.presentation {
|
|
49
|
-
font-size: 0.
|
|
50
|
+
font-size: 0.85em;
|
|
51
|
+
line-height: 1em;
|
|
50
52
|
display: flex;
|
|
51
53
|
gap: 5px;
|
|
52
54
|
align-items: center;
|
|
@@ -54,6 +56,40 @@ export default class Legend extends LitElement {
|
|
|
54
56
|
.logo {
|
|
55
57
|
width: 45px;
|
|
56
58
|
}
|
|
59
|
+
pnx-map-legend {
|
|
60
|
+
display: block;
|
|
61
|
+
margin-top: 5px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Lighter/smaller version */
|
|
65
|
+
.pnx-panel[part="panel"].pnx-legend-light {
|
|
66
|
+
display: flex;
|
|
67
|
+
gap: 3px;
|
|
68
|
+
padding: 3px 8px 3px 3px;
|
|
69
|
+
width: unset;
|
|
70
|
+
min-width: unset;
|
|
71
|
+
align-items: center;
|
|
72
|
+
font-size: 10px;
|
|
73
|
+
margin-right: -10px;
|
|
74
|
+
margin-bottom: -10px;
|
|
75
|
+
border-radius: 0;
|
|
76
|
+
border-top-left-radius: 5px;
|
|
77
|
+
border-right: none;
|
|
78
|
+
border-bottom: none;
|
|
79
|
+
}
|
|
80
|
+
.pnx-legend-light a,
|
|
81
|
+
.pnx-legend-light .presentation {
|
|
82
|
+
font-size: 10px;
|
|
83
|
+
}
|
|
84
|
+
.pnx-legend-light .logo {
|
|
85
|
+
width: 15px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.pnx-legend-light pnx-map-legend {
|
|
89
|
+
width: max-content;
|
|
90
|
+
margin-top: unset;
|
|
91
|
+
font-size: 10px;
|
|
92
|
+
}
|
|
57
93
|
`];
|
|
58
94
|
|
|
59
95
|
/**
|
|
@@ -62,41 +98,59 @@ export default class Legend extends LitElement {
|
|
|
62
98
|
* @type {Object}
|
|
63
99
|
* @property {string} [focus] The focused main component (map, pic)
|
|
64
100
|
* @property {string} [picture] The picture ID
|
|
101
|
+
* @property {boolean} [light=false] Lighter version (for iframes)
|
|
65
102
|
*/
|
|
66
103
|
static properties = {
|
|
67
104
|
focus: {type: String},
|
|
68
105
|
picture: {type: String},
|
|
106
|
+
light: {type: Boolean},
|
|
69
107
|
};
|
|
70
108
|
|
|
109
|
+
constructor() {
|
|
110
|
+
super();
|
|
111
|
+
this.light = false;
|
|
112
|
+
}
|
|
113
|
+
|
|
71
114
|
render() {
|
|
72
115
|
const classes = {
|
|
73
116
|
"pnx-panel": true,
|
|
74
117
|
"pnx-padded": this.focus == "map",
|
|
118
|
+
"pnx-legend-light": this.light,
|
|
75
119
|
};
|
|
76
120
|
|
|
77
121
|
return html`<div class=${classMap(classes)} part="panel">
|
|
78
122
|
<div
|
|
79
123
|
class="presentation"
|
|
80
|
-
style=${this.focus != "map" && this.picture ? "display: none": ""}
|
|
124
|
+
style=${!this.light && this.focus != "map" && this.picture ? "display: none": ""}
|
|
81
125
|
>
|
|
82
126
|
<img class="logo" src=${PanoramaxImg} alt="" />
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
127
|
+
|
|
128
|
+
${this.light ? html`
|
|
129
|
+
© <a
|
|
130
|
+
href=${PanoramaxWebsiteURL()}
|
|
86
131
|
title=${this._parent?._t.map.more_panoramax}
|
|
87
|
-
kind="superinline"
|
|
88
|
-
href="https://panoramax.fr"
|
|
89
132
|
target="_blank"
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
133
|
+
>${this._parent?._t.pnx.panoramax}</a> |
|
|
134
|
+
` : html`
|
|
135
|
+
<div>
|
|
136
|
+
${this._parent?._t.pnx.whats_panoramax}
|
|
137
|
+
<pnx-link-button
|
|
138
|
+
title=${this._parent?._t.map.more_panoramax}
|
|
139
|
+
kind="superinline"
|
|
140
|
+
href=${PanoramaxWebsiteURL()}
|
|
141
|
+
target="_blank"
|
|
142
|
+
size="sm"
|
|
143
|
+
>
|
|
144
|
+
${fa(faInfoCircle)}
|
|
145
|
+
</pnx-link-button>
|
|
146
|
+
</div>
|
|
147
|
+
`}
|
|
95
148
|
</div>
|
|
96
149
|
<pnx-picture-legend
|
|
97
150
|
._parent=${this._parent}
|
|
98
151
|
style=${this.focus == "map" ? "display: none": ""}
|
|
99
152
|
collapsable
|
|
153
|
+
light=${this.light || nothing}
|
|
100
154
|
>
|
|
101
155
|
<slot slot="editors" name="editors">
|
|
102
156
|
<pnx-widget-osmeditors ._parent=${this._parent} />
|
|
@@ -105,6 +159,7 @@ export default class Legend extends LitElement {
|
|
|
105
159
|
<pnx-map-legend
|
|
106
160
|
._parent=${this._parent}
|
|
107
161
|
style=${this.focus != "map" ? "display: none": ""}
|
|
162
|
+
light=${this.light || nothing}
|
|
108
163
|
></pnx-map-legend>
|
|
109
164
|
</div>`;
|
|
110
165
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, nothing } from "lit";
|
|
2
|
-
import { fa } from "../../../utils/widgets";
|
|
2
|
+
import { fa, onceParentAvailable } from "../../../utils/widgets";
|
|
3
3
|
import { faSliders } from "@fortawesome/free-solid-svg-icons/faSliders";
|
|
4
4
|
import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
|
|
5
5
|
import { faXmark } from "@fortawesome/free-solid-svg-icons/faXmark";
|
|
@@ -45,7 +45,7 @@ export default class MapFiltersButton extends LitElement {
|
|
|
45
45
|
super.connectedCallback();
|
|
46
46
|
|
|
47
47
|
// Listen to user visibility changes to switch the filter active icon
|
|
48
|
-
this._parent?.onceMapReady?.().then(() => {
|
|
48
|
+
onceParentAvailable(this).then(() => this._parent?.onceMapReady?.().then(() => {
|
|
49
49
|
this._active = (
|
|
50
50
|
Object.keys(this._parent.map._mapFilters).filter(d => d && d !== "theme").length > 0
|
|
51
51
|
|| this._parent.map.getVisibleUsers().filter(u => u !== "geovisio").length > 0
|
|
@@ -64,7 +64,7 @@ export default class MapFiltersButton extends LitElement {
|
|
|
64
64
|
|| e.usersIds.filter(u => u !== "geovisio").length > 0
|
|
65
65
|
);
|
|
66
66
|
});
|
|
67
|
-
});
|
|
67
|
+
}));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/** @private */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, nothing } from "lit";
|
|
2
|
-
import { fa } from "../../../utils/widgets";
|
|
2
|
+
import { fa, onceParentAvailable } from "../../../utils/widgets";
|
|
3
3
|
import { faLayerGroup } from "@fortawesome/free-solid-svg-icons/faLayerGroup";
|
|
4
4
|
import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown";
|
|
5
5
|
import { faXmark } from "@fortawesome/free-solid-svg-icons/faXmark";
|
|
@@ -35,12 +35,12 @@ export default class MapLayersButton extends LitElement {
|
|
|
35
35
|
|
|
36
36
|
const nullThemes = [undefined, null, "", "default"];
|
|
37
37
|
|
|
38
|
-
this._parent?.onceMapReady?.().then(() => {
|
|
38
|
+
onceParentAvailable(this).then(() => this._parent?.onceMapReady?.().then(() => {
|
|
39
39
|
this._active = !nullThemes.includes(this._parent.map._mapFilters.theme);
|
|
40
40
|
this._parent.map.on("filters-changed", e => {
|
|
41
41
|
this._active = !nullThemes.includes(e.theme);
|
|
42
42
|
});
|
|
43
|
-
});
|
|
43
|
+
}));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/** @private */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, nothing, css } from "lit";
|
|
2
|
-
import { fa } from "../../../utils/widgets";
|
|
2
|
+
import { fa, onceParentAvailable } from "../../../utils/widgets";
|
|
3
3
|
import { josmBboxParameters } from "../../../utils/utils";
|
|
4
4
|
import { IdEditorURL } from "../../../utils/services";
|
|
5
5
|
import { faLocationDot } from "@fortawesome/free-solid-svg-icons/faLocationDot";
|
|
@@ -40,7 +40,7 @@ export default class OSMEditors extends LitElement {
|
|
|
40
40
|
/** @private */
|
|
41
41
|
connectedCallback() {
|
|
42
42
|
super.connectedCallback();
|
|
43
|
-
this._parent
|
|
43
|
+
onceParentAvailable(this).then(() => this._parent.onceReady()).then(() => {
|
|
44
44
|
this._parent.onceFirstPicLoaded().then(this._onPictureLoad.bind(this));
|
|
45
45
|
this._parent.psv.addEventListener("picture-loaded", this._onPictureLoad.bind(this));
|
|
46
46
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, nothing, css } from "lit";
|
|
2
|
-
import { fa } from "../../../utils/widgets";
|
|
2
|
+
import { fa, onceParentAvailable } from "../../../utils/widgets";
|
|
3
3
|
import { faEllipsisV } from "@fortawesome/free-solid-svg-icons/faEllipsisV";
|
|
4
4
|
import { noprint } from "../../styles";
|
|
5
5
|
|
|
@@ -42,7 +42,7 @@ export default class PictureLegendActions extends LitElement {
|
|
|
42
42
|
connectedCallback() {
|
|
43
43
|
super.connectedCallback();
|
|
44
44
|
|
|
45
|
-
this._parent
|
|
45
|
+
onceParentAvailable(this).then(() => this._parent.onceReady()).then(() => {
|
|
46
46
|
this._meta = this._parent.psv.getPictureMetadata();
|
|
47
47
|
this._parent.psv.addEventListener("picture-loaded", () => {
|
|
48
48
|
this._meta = this._parent.psv.getPictureMetadata();
|
|
@@ -61,54 +61,36 @@ export default class PictureLegendActions extends LitElement {
|
|
|
61
61
|
this.renderRoot.querySelector("#pic-legend-headline-menu").close();
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
/** @private */
|
|
65
|
-
_onShareClick() {
|
|
66
|
-
this._closeGroup();
|
|
67
|
-
this._parent._showShareOptions();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** @private */
|
|
71
|
-
_onReportClick() {
|
|
72
|
-
this._closeGroup();
|
|
73
|
-
this._parent._showReportForm();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
64
|
/** @private */
|
|
77
65
|
render() {
|
|
78
66
|
return html`<pnx-togglable-group padded="false" id="pic-legend-headline-menu" ._parent=${this._parent}>
|
|
79
67
|
<pnx-button slot="button" kind="inline">${fa(faEllipsisV)}</pnx-button>
|
|
80
68
|
<pnx-list-group class="pnx-print-hidden" @click=${this._closeMenu}>
|
|
81
|
-
${this.
|
|
69
|
+
${this._meta ? html`<pnx-copy-button ._t=${this._parent?._t} text=${this._meta.id} unstyled>
|
|
70
|
+
${this._parent?._t.pnx.metadata_general_copy_picid}
|
|
71
|
+
</pnx-copy-button>` : nothing}
|
|
72
|
+
|
|
73
|
+
<a
|
|
74
|
+
download
|
|
75
|
+
target="_blank"
|
|
76
|
+
href=${this._meta?.panorama?.hdUrl}
|
|
77
|
+
@click=${this._closeGroup}
|
|
78
|
+
>${this._parent?._t.pnx.share_image}</a>
|
|
79
|
+
|
|
80
|
+
${this._parent.isWidthSmall() ? nothing : html`<button @click=${this._onPrint}>
|
|
81
|
+
${this._parent?._t.pnx.share_print}
|
|
82
|
+
</button>`}
|
|
83
|
+
|
|
84
|
+
${this._parent?.api?.getRSSURL() && html`
|
|
82
85
|
<a
|
|
83
|
-
download
|
|
84
86
|
target="_blank"
|
|
85
|
-
href=${this.
|
|
87
|
+
href=${this._parent?.api.getRSSURL(this._parent?.map?.getBounds?.())}
|
|
88
|
+
title=${this._parent?._t.pnx.share_rss_title}
|
|
86
89
|
@click=${this._closeGroup}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
${this._parent?.api?.getRSSURL() && html`
|
|
92
|
-
<a
|
|
93
|
-
target="_blank"
|
|
94
|
-
href=${this._parent?.api.getRSSURL(this._parent?.map?.getBounds?.())}
|
|
95
|
-
title=${this._parent?._t.pnx.share_rss_title}
|
|
96
|
-
@click=${this._closeGroup}
|
|
97
|
-
>
|
|
98
|
-
${this._parent?._t.pnx.share_rss}
|
|
99
|
-
</a>
|
|
100
|
-
`}
|
|
101
|
-
` : html`
|
|
102
|
-
<button @click=${this._onReportClick}>
|
|
103
|
-
${this._parent?._t.pnx.report}
|
|
104
|
-
</button>
|
|
105
|
-
<button @click=${this._onShareClick}>
|
|
106
|
-
${this._parent?._t.pnx.share}
|
|
107
|
-
</button>
|
|
108
|
-
${this._meta ? html`<pnx-copy-button ._t=${this._parent?._t} text=${this._meta.id} unstyled>
|
|
109
|
-
${this._parent?._t.pnx.metadata_general_copy_picid}
|
|
110
|
-
</pnx-copy-button>` : nothing}
|
|
111
|
-
` }
|
|
90
|
+
>
|
|
91
|
+
${this._parent?._t.pnx.share_rss}
|
|
92
|
+
</a>
|
|
93
|
+
`}
|
|
112
94
|
</pnx-list-group>
|
|
113
95
|
</pnx-togglable-group>`;
|
|
114
96
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, nothing } from "lit";
|
|
2
|
-
import { fa } from "../../../utils/widgets";
|
|
2
|
+
import { fa, onceParentAvailable } from "../../../utils/widgets";
|
|
3
3
|
import { faBackward } from "@fortawesome/free-solid-svg-icons/faBackward";
|
|
4
4
|
import { faPlay } from "@fortawesome/free-solid-svg-icons/faPlay";
|
|
5
5
|
import { faPause } from "@fortawesome/free-solid-svg-icons/faPause";
|
|
@@ -52,13 +52,13 @@ export default class Player extends LitElement {
|
|
|
52
52
|
connectedCallback() {
|
|
53
53
|
super.connectedCallback();
|
|
54
54
|
|
|
55
|
-
this._parent?.oncePSVReady?.().then(() => {
|
|
55
|
+
onceParentAvailable(this).then(() => this._parent?.oncePSVReady?.().then(() => {
|
|
56
56
|
this._parent.psv.addEventListener("sequence-playing", () => this.playing = true);
|
|
57
57
|
this._parent.psv.addEventListener("sequence-stopped", () => this.playing = false);
|
|
58
58
|
this._parent.psv.addEventListener("picture-loaded", this._changeActiveStates.bind(this));
|
|
59
59
|
this._parent.addEventListener("pictures-navigation-changed", this._changeActiveStates.bind(this));
|
|
60
60
|
this._changeActiveStates();
|
|
61
|
-
});
|
|
61
|
+
}));
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
/** @private */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LitElement, html } from "lit";
|
|
2
2
|
import { PSV_DEFAULT_ZOOM, PSV_ANIM_DURATION } from "../Photo";
|
|
3
3
|
import { PSV_ZOOM_DELTA } from "../../core/Viewer";
|
|
4
|
-
import { fa } from "../../../utils/widgets";
|
|
4
|
+
import { fa, onceParentAvailable } from "../../../utils/widgets";
|
|
5
5
|
import { faPlus } from "@fortawesome/free-solid-svg-icons/faPlus";
|
|
6
6
|
import { faMinus } from "@fortawesome/free-solid-svg-icons/faMinus";
|
|
7
7
|
import "../ButtonGroup.css";
|
|
@@ -30,7 +30,9 @@ export default class Zoom extends LitElement {
|
|
|
30
30
|
/** @private */
|
|
31
31
|
connectedCallback() {
|
|
32
32
|
super.connectedCallback();
|
|
33
|
-
this
|
|
33
|
+
onceParentAvailable(this).then(() => this._parent?.oncePSVReady?.().then(() => {
|
|
34
|
+
this._lastWantedZoom = this._parent?.psv?.getZoomLevel() || PSV_DEFAULT_ZOOM;
|
|
35
|
+
}));
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/** @private */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
package/src/translations/da.json
CHANGED
|
@@ -187,7 +187,8 @@
|
|
|
187
187
|
"metadata_general_copy_id": "Kopi-ID",
|
|
188
188
|
"metadata_general_copy_picid": "Kopi billed-ID",
|
|
189
189
|
"filter_date_6months": "6 måneder",
|
|
190
|
-
"picture_all": "Alle"
|
|
190
|
+
"picture_all": "Alle",
|
|
191
|
+
"panoramax": "Panoramax"
|
|
191
192
|
},
|
|
192
193
|
"psv": {
|
|
193
194
|
"loadError": "Panoramaet kan ikke indlæses",
|
|
@@ -199,7 +200,7 @@
|
|
|
199
200
|
"thumbnail": "Miniature af billedet, der holdes",
|
|
200
201
|
"not_public": "Ikke offentligt synlig",
|
|
201
202
|
"slow_loading": "Kortet indlæses langsomt og kan virke defekt",
|
|
202
|
-
"map_data": "Kortdata:",
|
|
203
|
+
"map_data": "Kortdata: {m}",
|
|
203
204
|
"more_panoramax": "Få mere at vide om Panoramax"
|
|
204
205
|
}
|
|
205
206
|
}
|