@panoramax/web-viewer 3.2.3-develop-d7e5a16d → 3.2.3-develop-6257391e
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/.gitlab-ci.yml +3 -0
- package/CHANGELOG.md +19 -0
- package/CODE_OF_CONDUCT.md +1 -1
- package/README.md +1 -1
- package/build/editor.html +10 -1
- package/build/index.css +2 -2
- package/build/index.css.map +1 -1
- package/build/index.html +1 -1
- package/build/index.js +1682 -5
- package/build/index.js.map +1 -1
- package/build/map.html +1 -1
- package/build/viewer.html +10 -1
- package/build/widgets.html +1 -0
- package/config/jest/mocks.js +172 -0
- package/config/paths.js +1 -0
- package/config/webpack.config.js +26 -0
- package/docs/03_URL_settings.md +3 -11
- package/docs/05_Compatibility.md +59 -76
- package/docs/09_Develop.md +30 -11
- package/docs/90_Releases.md +2 -2
- package/docs/images/class_diagram.drawio +28 -28
- package/docs/images/class_diagram.jpg +0 -0
- package/docs/index.md +112 -0
- package/docs/reference/components/core/Basic.md +153 -0
- package/docs/reference/components/core/CoverageMap.md +160 -0
- package/docs/reference/components/core/Editor.md +172 -0
- package/docs/reference/components/core/Viewer.md +288 -0
- package/docs/reference/components/layout/CorneredGrid.md +29 -0
- package/docs/reference/components/layout/Mini.md +45 -0
- package/docs/reference/components/menus/MapBackground.md +32 -0
- package/docs/reference/components/menus/MapFilters.md +15 -0
- package/docs/reference/components/menus/MapLayers.md +15 -0
- package/docs/reference/components/menus/MapLegend.md +15 -0
- package/docs/reference/components/menus/PictureLegend.md +15 -0
- package/docs/reference/components/menus/PictureMetadata.md +15 -0
- package/docs/reference/components/menus/PlayerOptions.md +15 -0
- package/docs/reference/components/menus/QualityScoreDoc.md +15 -0
- package/docs/reference/components/menus/ReportForm.md +15 -0
- package/docs/reference/components/menus/ShareMenu.md +15 -0
- package/docs/reference/components/ui/Button.md +39 -0
- package/docs/reference/components/ui/ButtonGroup.md +36 -0
- package/docs/reference/components/ui/CopyButton.md +35 -0
- package/docs/reference/components/ui/Grade.md +32 -0
- package/docs/reference/components/ui/LinkButton.md +44 -0
- package/docs/reference/components/ui/Loader.md +54 -0
- package/docs/reference/components/ui/Map.md +214 -0
- package/docs/reference/components/ui/MapMore.md +233 -0
- package/docs/reference/components/ui/Photo.md +369 -0
- package/docs/reference/components/ui/Popup.md +56 -0
- package/docs/reference/components/ui/QualityScore.md +45 -0
- package/docs/reference/components/ui/SearchBar.md +63 -0
- package/docs/reference/components/ui/TogglableGroup.md +39 -0
- package/docs/reference/components/ui/widgets/GeoSearch.md +32 -0
- package/docs/reference/components/ui/widgets/Legend.md +32 -0
- package/docs/reference/components/ui/widgets/MapFiltersButton.md +33 -0
- package/docs/reference/components/ui/widgets/MapLayersButton.md +15 -0
- package/docs/reference/components/ui/widgets/Player.md +32 -0
- package/docs/reference/components/ui/widgets/Share.md +15 -0
- package/docs/reference/components/ui/widgets/Zoom.md +15 -0
- package/docs/reference/utils/API.md +311 -0
- package/docs/reference/utils/InitParameters.md +67 -0
- package/docs/reference/utils/URLHandler.md +102 -0
- package/docs/reference.md +73 -0
- package/docs/shortcuts.md +11 -0
- package/docs/tutorials/aerial_imagery.md +19 -0
- package/docs/tutorials/authentication.md +10 -0
- package/docs/tutorials/custom_widgets.md +64 -0
- package/docs/tutorials/map_style.md +27 -0
- package/docs/tutorials/migrate_v4.md +122 -0
- package/docs/tutorials/synced_coverage.md +42 -0
- package/mkdocs.yml +60 -5
- package/package.json +10 -7
- package/public/editor.html +21 -29
- package/public/index.html +3 -3
- package/public/map.html +19 -18
- package/public/viewer.html +18 -24
- package/public/widgets.html +265 -0
- package/scripts/doc.js +77 -0
- package/src/components/core/Basic.css +44 -0
- package/src/components/core/Basic.js +258 -0
- package/src/components/core/CoverageMap.css +9 -0
- package/src/components/core/CoverageMap.js +105 -0
- package/src/components/core/Editor.css +23 -0
- package/src/components/core/Editor.js +354 -0
- package/src/components/core/Viewer.css +109 -0
- package/src/components/core/Viewer.js +707 -0
- package/src/components/core/index.js +11 -0
- package/src/components/index.js +13 -0
- package/src/components/layout/CorneredGrid.js +109 -0
- package/src/components/layout/Mini.js +117 -0
- package/src/components/layout/index.js +7 -0
- package/src/components/menus/MapBackground.js +106 -0
- package/src/components/menus/MapFilters.js +386 -0
- package/src/components/menus/MapLayers.js +143 -0
- package/src/components/menus/MapLegend.js +54 -0
- package/src/components/menus/PictureLegend.js +103 -0
- package/src/components/menus/PictureMetadata.js +188 -0
- package/src/components/menus/PlayerOptions.js +96 -0
- package/src/components/menus/QualityScoreDoc.js +36 -0
- package/src/components/menus/ReportForm.js +133 -0
- package/src/components/menus/Share.js +228 -0
- package/src/components/menus/index.js +15 -0
- package/src/components/styles.js +365 -0
- package/src/components/ui/Button.js +75 -0
- package/src/components/ui/ButtonGroup.css +49 -0
- package/src/components/ui/ButtonGroup.js +68 -0
- package/src/components/ui/CopyButton.js +71 -0
- package/src/components/ui/Grade.js +54 -0
- package/src/components/ui/LinkButton.js +68 -0
- package/src/components/ui/Loader.js +188 -0
- package/src/components/{Map.css → ui/Map.css} +5 -17
- package/src/components/{Map.js → ui/Map.js} +114 -138
- package/src/components/ui/MapMore.js +324 -0
- package/src/components/{Photo.css → ui/Photo.css} +6 -6
- package/src/components/{Photo.js → ui/Photo.js} +279 -90
- package/src/components/ui/Popup.js +145 -0
- package/src/components/ui/QualityScore.js +152 -0
- package/src/components/ui/SearchBar.js +363 -0
- package/src/components/ui/TogglableGroup.js +162 -0
- package/src/components/ui/index.js +20 -0
- package/src/components/ui/widgets/GeoSearch.css +21 -0
- package/src/components/ui/widgets/GeoSearch.js +139 -0
- package/src/components/ui/widgets/Legend.js +51 -0
- package/src/components/ui/widgets/MapFiltersButton.js +104 -0
- package/src/components/ui/widgets/MapLayersButton.js +79 -0
- package/src/components/ui/widgets/Player.css +7 -0
- package/src/components/ui/widgets/Player.js +148 -0
- package/src/components/ui/widgets/Share.js +30 -0
- package/src/components/ui/widgets/Zoom.js +82 -0
- package/src/components/ui/widgets/index.js +12 -0
- package/src/img/panoramax.svg +13 -0
- package/src/img/switch_big.svg +20 -10
- package/src/index.js +6 -9
- package/src/translations/da.json +1 -1
- package/src/translations/de.json +1 -1
- package/src/translations/en.json +5 -3
- package/src/translations/eo.json +1 -1
- package/src/translations/es.json +1 -1
- package/src/translations/fr.json +5 -3
- package/src/translations/hu.json +1 -1
- package/src/translations/it.json +1 -1
- package/src/translations/ja.json +1 -1
- package/src/translations/nl.json +1 -1
- package/src/translations/pl.json +1 -1
- package/src/translations/sv.json +1 -1
- package/src/translations/zh_Hant.json +1 -1
- package/src/utils/API.js +74 -42
- package/src/utils/InitParameters.js +354 -0
- package/src/utils/URLHandler.js +364 -0
- package/src/utils/geocoder.js +116 -0
- package/src/utils/{I18n.js → i18n.js} +3 -1
- package/src/utils/index.js +11 -0
- package/src/utils/{Map.js → map.js} +216 -80
- package/src/utils/picture.js +433 -0
- package/src/utils/utils.js +315 -0
- package/src/utils/widgets.js +93 -0
- package/tests/components/ui/CopyButton.test.js +52 -0
- package/tests/components/ui/Loader.test.js +54 -0
- package/tests/components/{Map.test.js → ui/Map.test.js} +19 -61
- package/tests/components/{Photo.test.js → ui/Photo.test.js} +89 -57
- package/tests/components/ui/Popup.test.js +24 -0
- package/tests/components/ui/QualityScore.test.js +17 -0
- package/tests/components/ui/SearchBar.test.js +107 -0
- package/tests/components/ui/__snapshots__/CopyButton.test.js.snap +34 -0
- package/tests/components/ui/__snapshots__/Loader.test.js.snap +56 -0
- package/tests/components/{__snapshots__ → ui/__snapshots__}/Map.test.js.snap +11 -38
- package/tests/components/{__snapshots__ → ui/__snapshots__}/Photo.test.js.snap +57 -4
- package/tests/components/ui/__snapshots__/Popup.test.js.snap +29 -0
- package/tests/components/ui/__snapshots__/QualityScore.test.js.snap +11 -0
- package/tests/components/ui/__snapshots__/SearchBar.test.js.snap +65 -0
- package/tests/utils/API.test.js +1 -14
- package/tests/utils/InitParameters.test.js +485 -0
- package/tests/utils/URLHandler.test.js +350 -0
- package/tests/utils/__snapshots__/URLHandler.test.js.snap +21 -0
- package/tests/utils/__snapshots__/picture.test.js.snap +315 -0
- package/tests/utils/__snapshots__/widgets.test.js.snap +19 -0
- package/tests/utils/geocoder.test.js +37 -0
- package/tests/utils/{I18n.test.js → i18n.test.js} +1 -1
- package/tests/utils/map.test.js +67 -0
- package/tests/utils/picture.test.js +745 -0
- package/tests/utils/utils.test.js +288 -0
- package/tests/utils/widgets.test.js +90 -0
- package/docs/01_Start.md +0 -149
- package/docs/02_Usage.md +0 -831
- package/docs/04_Advanced_examples.md +0 -216
- package/src/Editor.css +0 -37
- package/src/Editor.js +0 -361
- package/src/StandaloneMap.js +0 -114
- package/src/Viewer.css +0 -203
- package/src/Viewer.js +0 -1246
- package/src/components/CoreView.css +0 -70
- package/src/components/CoreView.js +0 -175
- package/src/components/Loader.css +0 -74
- package/src/components/Loader.js +0 -120
- package/src/utils/Exif.js +0 -193
- package/src/utils/Utils.js +0 -631
- package/src/utils/Widgets.js +0 -562
- package/src/viewer/URLHash.js +0 -469
- package/src/viewer/Widgets.css +0 -880
- package/src/viewer/Widgets.js +0 -1470
- package/tests/Editor.test.js +0 -126
- package/tests/StandaloneMap.test.js +0 -45
- package/tests/Viewer.test.js +0 -366
- package/tests/__snapshots__/Editor.test.js.snap +0 -298
- package/tests/__snapshots__/StandaloneMap.test.js.snap +0 -30
- package/tests/__snapshots__/Viewer.test.js.snap +0 -195
- package/tests/components/CoreView.test.js +0 -92
- package/tests/components/Loader.test.js +0 -38
- package/tests/components/__snapshots__/Loader.test.js.snap +0 -15
- package/tests/utils/Exif.test.js +0 -124
- package/tests/utils/Map.test.js +0 -113
- package/tests/utils/Utils.test.js +0 -300
- package/tests/utils/Widgets.test.js +0 -107
- package/tests/utils/__snapshots__/Exif.test.js.snap +0 -43
- package/tests/utils/__snapshots__/Utils.test.js.snap +0 -41
- package/tests/utils/__snapshots__/Widgets.test.js.snap +0 -44
- package/tests/viewer/URLHash.test.js +0 -559
- package/tests/viewer/Widgets.test.js +0 -127
- package/tests/viewer/__snapshots__/URLHash.test.js.snap +0 -108
- package/tests/viewer/__snapshots__/Widgets.test.js.snap +0 -403
- /package/tests/utils/__snapshots__/{Map.test.js.snap → geocoder.test.js.snap} +0 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
import "./Editor.css";
|
|
3
|
+
import Basic from "./Basic";
|
|
4
|
+
import Map from "../ui/Map";
|
|
5
|
+
import Photo from "../ui/Photo";
|
|
6
|
+
import BackgroundAerial from "../../img/bg_aerial.jpg";
|
|
7
|
+
import BackgroundStreets from "../../img/bg_streets.jpg";
|
|
8
|
+
import { apiFeatureToPSVNode } from "../../utils/picture";
|
|
9
|
+
import { linkMapAndPhoto } from "../../utils/map";
|
|
10
|
+
import { VECTOR_STYLES } from "../../utils/map";
|
|
11
|
+
import { SYSTEM as PSSystem } from "@photo-sphere-viewer/core";
|
|
12
|
+
import { css } from "lit";
|
|
13
|
+
import { createWebComp } from "../../utils/widgets";
|
|
14
|
+
|
|
15
|
+
const LAYER_HEADING_ID = "sequence-headings";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Editor allows to focus on a single sequence, and preview what you edits would look like.
|
|
19
|
+
* It shows both picture and map.
|
|
20
|
+
* @class Panoramax.components.core.Editor
|
|
21
|
+
* @element pnx-editor
|
|
22
|
+
* @extends Panoramax.components.core.Basic
|
|
23
|
+
* @fires Panoramax.components.core.Basic#select
|
|
24
|
+
* @fires Panoramax.components.core.Basic#ready
|
|
25
|
+
* @fires Panoramax.components.core.Basic#broken
|
|
26
|
+
* @property {Panoramax.components.ui.Loader} loader The loader screen
|
|
27
|
+
* @property {Panoramax.utils.API} api The API manager
|
|
28
|
+
* @property {Panoramax.components.ui.Map} map The MapLibre GL map itself
|
|
29
|
+
* @property {Panoramax.components.ui.Photo} psv The Photo Sphere Viewer component itself
|
|
30
|
+
* @example
|
|
31
|
+
* ```html
|
|
32
|
+
* <pnx-editor
|
|
33
|
+
* endpoint="https://panoramax.openstreetmap.fr/"
|
|
34
|
+
* />
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export default class Editor extends Basic {
|
|
38
|
+
/**
|
|
39
|
+
* Component properties. All of [Basic properties](#Panoramax.components.core.Basic+properties) are available as well.
|
|
40
|
+
* @memberof Panoramax.components.core.Editor#
|
|
41
|
+
* @mixes Panoramax.components.core.Basic#properties
|
|
42
|
+
* @type {Object}
|
|
43
|
+
* @property {object} [raster] The MapLibre raster source for aerial background. This must be a JSON object following [MapLibre raster source definition](https://maplibre.org/maplibre-style-spec/sources/#raster).
|
|
44
|
+
* @property {string} [background=streets] Choose default map background to display (streets or aerial, if raster aerial background available). Defaults to street.
|
|
45
|
+
*/
|
|
46
|
+
static properties = {
|
|
47
|
+
raster: {type: Object},
|
|
48
|
+
background: {type: String},
|
|
49
|
+
...Basic.properties
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
constructor() {
|
|
53
|
+
super();
|
|
54
|
+
|
|
55
|
+
this.raster = null;
|
|
56
|
+
this.background = "streets";
|
|
57
|
+
this.users = []; // Avoid default map data showing up
|
|
58
|
+
|
|
59
|
+
// Create sub-containers
|
|
60
|
+
this._psvContainer = document.createElement("div");
|
|
61
|
+
this._mapContainer = document.createElement("div");
|
|
62
|
+
|
|
63
|
+
this.onceAPIReady().then(() => {
|
|
64
|
+
// Check sequence ID is set
|
|
65
|
+
if(!this.sequence) { this.loader.dismiss({}, "No sequence is selected"); }
|
|
66
|
+
|
|
67
|
+
// Events
|
|
68
|
+
this.addEventListener("select", this._onSelect.bind(this));
|
|
69
|
+
|
|
70
|
+
this._initPSV();
|
|
71
|
+
this._initMap();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getClassName() {
|
|
76
|
+
return "Editor";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
onceReady() {
|
|
80
|
+
if(this.map && this.psv && this.map.loaded?.()) {
|
|
81
|
+
return Promise.resolve();
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return new Promise(resolve => setTimeout(resolve, 100)).then(this.onceReady.bind(this));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** @private */
|
|
89
|
+
render() {
|
|
90
|
+
return [this.loader, this._psvContainer, this._mapContainer];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** @private */
|
|
94
|
+
_initPSV() {
|
|
95
|
+
try {
|
|
96
|
+
this.psv = new Photo(this, this._psvContainer);
|
|
97
|
+
this.psv._myVTour.datasource.nodeResolver = this._getNode.bind(this);
|
|
98
|
+
}
|
|
99
|
+
catch(e) {
|
|
100
|
+
let err = !PSSystem.isWebGLSupported ? this._t.pnx.error_webgl : this._t.pnx.error_psv;
|
|
101
|
+
this.loader.dismiss(e, err);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** @private */
|
|
106
|
+
_initMap() {
|
|
107
|
+
try {
|
|
108
|
+
this.map = new Map(this, this._mapContainer, {
|
|
109
|
+
raster: this.raster,
|
|
110
|
+
background: this.background,
|
|
111
|
+
supplementaryStyle: this._createMapStyle(),
|
|
112
|
+
zoom: 15, // Hack to avoid _initMapPosition call
|
|
113
|
+
});
|
|
114
|
+
linkMapAndPhoto(this);
|
|
115
|
+
this._loadSequence();
|
|
116
|
+
this.map.once("load", () => {
|
|
117
|
+
if(this.map.hasTwoBackgrounds()) { this._addMapBackgroundWidget(); }
|
|
118
|
+
this._bindPicturesEvents();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Override picMarker setRotation for heading preview
|
|
122
|
+
const oldRot = this.map._picMarker.setRotation.bind(this.map._picMarker);
|
|
123
|
+
this.map._picMarker.setRotation = h => {
|
|
124
|
+
h = this._lastRelHeading === undefined ? h : h + this._lastRelHeading - this.psv.getPictureRelativeHeading();
|
|
125
|
+
return oldRot(h);
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
catch(e) {
|
|
129
|
+
this.loader.dismiss(e, this._t.pnx.error_psv);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Create style for GeoJSON sequence data.
|
|
135
|
+
* @private
|
|
136
|
+
*/
|
|
137
|
+
_createMapStyle() {
|
|
138
|
+
return {
|
|
139
|
+
sources: {
|
|
140
|
+
geovisio_editor_sequences: {
|
|
141
|
+
type: "geojson",
|
|
142
|
+
data: {"type": "FeatureCollection", "features": [] }
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
layers: [
|
|
146
|
+
{
|
|
147
|
+
"id": "geovisio_editor_sequences",
|
|
148
|
+
"type": "line",
|
|
149
|
+
"source": "geovisio_editor_sequences",
|
|
150
|
+
"layout": {
|
|
151
|
+
...VECTOR_STYLES.SEQUENCES.layout
|
|
152
|
+
},
|
|
153
|
+
"paint": {
|
|
154
|
+
...VECTOR_STYLES.SEQUENCES.paint
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"id": "geovisio_editor_pictures",
|
|
159
|
+
"type": "circle",
|
|
160
|
+
"source": "geovisio_editor_sequences",
|
|
161
|
+
"layout": {
|
|
162
|
+
...VECTOR_STYLES.PICTURES.layout
|
|
163
|
+
},
|
|
164
|
+
"paint": {
|
|
165
|
+
...VECTOR_STYLES.PICTURES.paint
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Creates events handlers on pictures layer
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
_bindPicturesEvents() {
|
|
177
|
+
// Pictures events
|
|
178
|
+
this.map.on("mousemove", "geovisio_editor_pictures", () => {
|
|
179
|
+
this.map.getCanvas().style.cursor = "pointer";
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
this.map.on("mouseleave", "geovisio_editor_pictures", () => {
|
|
183
|
+
this.map.getCanvas().style.cursor = "";
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
this.map.on("click", "geovisio_editor_pictures", this.map._onPictureClick.bind(this.map));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Displays currently selected sequence on map
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
193
|
+
_loadSequence() {
|
|
194
|
+
return this.api.getSequenceItems(this.sequence).then(seq => {
|
|
195
|
+
// Hide loader after source load
|
|
196
|
+
this.map.once("sourcedata", () => {
|
|
197
|
+
this.map.setPaintProperty("geovisio_editor_sequences", "line-color", this.map._getLayerColorStyle("sequences"));
|
|
198
|
+
this.map.setPaintProperty("geovisio_editor_pictures", "circle-color", this.map._getLayerColorStyle("pictures"));
|
|
199
|
+
this.map.setLayoutProperty("geovisio_editor_sequences", "visibility", "visible");
|
|
200
|
+
this.map.setLayoutProperty("geovisio_editor_pictures", "visibility", "visible");
|
|
201
|
+
this.map.once("styledata", () => this.loader.dismiss());
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Create data source
|
|
205
|
+
this._sequenceData = seq.features;
|
|
206
|
+
this.map.getSource("geovisio_editor_sequences").setData({
|
|
207
|
+
"type": "FeatureCollection",
|
|
208
|
+
"features": [
|
|
209
|
+
{
|
|
210
|
+
"type": "Feature",
|
|
211
|
+
"properties": {
|
|
212
|
+
"id": this.sequence,
|
|
213
|
+
},
|
|
214
|
+
"geometry":
|
|
215
|
+
{
|
|
216
|
+
"type": "LineString",
|
|
217
|
+
"coordinates": seq.features.map(p => p.geometry.coordinates)
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
...seq.features.map(f => {
|
|
221
|
+
f.properties.id = f.id;
|
|
222
|
+
f.properties.sequences = [this.sequence];
|
|
223
|
+
return f;
|
|
224
|
+
})
|
|
225
|
+
]
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// Select picture if any
|
|
229
|
+
if(this.picture) {
|
|
230
|
+
const pic = seq.features.find(p => p.id === this.picture);
|
|
231
|
+
if(pic) {
|
|
232
|
+
this.select(this.sequence, this.picture, true);
|
|
233
|
+
this.map.jumpTo({ center: pic.geometry.coordinates, zoom: 18 });
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
console.log("Picture with ID", pic, "was not found");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Show area of sequence otherwise
|
|
240
|
+
else {
|
|
241
|
+
const bbox = [
|
|
242
|
+
...seq.features[0].geometry.coordinates,
|
|
243
|
+
...seq.features[0].geometry.coordinates
|
|
244
|
+
];
|
|
245
|
+
|
|
246
|
+
for(let i=1; i < seq.features.length; i++) {
|
|
247
|
+
const c = seq.features[i].geometry.coordinates;
|
|
248
|
+
if(c[0] < bbox[0]) { bbox[0] = c[0]; }
|
|
249
|
+
if(c[1] < bbox[1]) { bbox[1] = c[1]; }
|
|
250
|
+
if(c[0] > bbox[2]) { bbox[2] = c[0]; }
|
|
251
|
+
if(c[1] > bbox[3]) { bbox[3] = c[1]; }
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
this.map.fitBounds(bbox, {animate: false});
|
|
255
|
+
}
|
|
256
|
+
}).catch(e => this.loader.dismiss(e, this._t.pnx.error_api));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Get the PSV node for wanted picture.
|
|
261
|
+
*
|
|
262
|
+
* @param {string} picId The picture ID
|
|
263
|
+
* @returns The PSV node
|
|
264
|
+
* @private
|
|
265
|
+
*/
|
|
266
|
+
_getNode(picId) {
|
|
267
|
+
const f = this._sequenceData.find(f => f.properties.id === picId);
|
|
268
|
+
const n = f ? apiFeatureToPSVNode(f, this._t, this._isInternetFast) : null;
|
|
269
|
+
if(n) { delete n.links; }
|
|
270
|
+
return n;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Creates the widget to switch between aerial and streets imagery
|
|
275
|
+
* @private
|
|
276
|
+
*/
|
|
277
|
+
_addMapBackgroundWidget() {
|
|
278
|
+
// Container
|
|
279
|
+
const pnlLayers = createWebComp("pnx-map-background", {_parent: this, size: "sm"});
|
|
280
|
+
this._mapContainer.appendChild(pnlLayers);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Preview on map how the new relative heading would reflect on all pictures.
|
|
285
|
+
* This doesn't change anything on API-side, it's just a preview.
|
|
286
|
+
* @memberof Panoramax.components.core.Editor#
|
|
287
|
+
* @param {number} [relHeading] The new relative heading compared to sequence path. In degrees, between -180 and 180 (0 = front, -90 = left, 90 = right). Set to null to remove preview.
|
|
288
|
+
*/
|
|
289
|
+
previewSequenceHeadingChange(relHeading) {
|
|
290
|
+
const layerExists = this.map.getLayer(LAYER_HEADING_ID) !== undefined;
|
|
291
|
+
this.map._picMarkerPreview.remove();
|
|
292
|
+
|
|
293
|
+
// If no value set, remove layer
|
|
294
|
+
if(relHeading === undefined) {
|
|
295
|
+
delete this._lastRelHeading;
|
|
296
|
+
if(layerExists) {
|
|
297
|
+
this.map.setLayoutProperty(LAYER_HEADING_ID, "visibility", "none");
|
|
298
|
+
}
|
|
299
|
+
// Update selected picture marker
|
|
300
|
+
if(this.picture) {
|
|
301
|
+
this.map._picMarker.setRotation(this.psv.getXY().x);
|
|
302
|
+
}
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
this._lastRelHeading = relHeading;
|
|
307
|
+
|
|
308
|
+
// Create preview layer
|
|
309
|
+
if(!layerExists) {
|
|
310
|
+
this.map.addLayer({
|
|
311
|
+
"id": LAYER_HEADING_ID,
|
|
312
|
+
"type": "symbol",
|
|
313
|
+
"source": "geovisio_editor_sequences",
|
|
314
|
+
"layout": {
|
|
315
|
+
"icon-image": "pnx-marker",
|
|
316
|
+
"icon-overlap": "always",
|
|
317
|
+
"icon-size": 0.8,
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Change heading
|
|
323
|
+
const currentRelHeading = - this.psv.getPictureRelativeHeading();
|
|
324
|
+
this.map.setLayoutProperty(LAYER_HEADING_ID, "visibility", "visible");
|
|
325
|
+
this.map.setLayoutProperty(
|
|
326
|
+
LAYER_HEADING_ID,
|
|
327
|
+
"icon-rotate",
|
|
328
|
+
["+", ["get", "view:azimuth"], currentRelHeading, relHeading ]
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
// Skip selected picture and linestring geom
|
|
332
|
+
const filters = [["==", ["geometry-type"], "Point"]];
|
|
333
|
+
if(this.picture) { filters.push(["!=", ["get", "id"], this.picture]); }
|
|
334
|
+
this.map.setFilter(LAYER_HEADING_ID, ["all", ...filters]);
|
|
335
|
+
|
|
336
|
+
// Update selected picture marker
|
|
337
|
+
if(this.picture) {
|
|
338
|
+
this.map._picMarker.setRotation(this.psv.getXY().x);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Event handler for picture loading
|
|
344
|
+
* @private
|
|
345
|
+
*/
|
|
346
|
+
_onSelect() {
|
|
347
|
+
// Update preview of heading change
|
|
348
|
+
if(this._lastRelHeading !== undefined) {
|
|
349
|
+
this.previewSequenceHeadingChange(this._lastRelHeading);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
customElements.define("pnx-editor", Editor);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* Maximized components */
|
|
2
|
+
pnx-viewer .pnx-map.maplibregl-map,
|
|
3
|
+
pnx-viewer .pnx-psv {
|
|
4
|
+
position: absolute;
|
|
5
|
+
inset: 0;
|
|
6
|
+
z-index: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/* No PSV loader */
|
|
10
|
+
pnx-viewer .psv-loader {
|
|
11
|
+
display: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Search bar over other components */
|
|
15
|
+
pnx-widget-geosearch {
|
|
16
|
+
z-index: 129;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Cornered grid layout */
|
|
20
|
+
pnx-viewer pnx-cornered-grid::part(corner-top-left),
|
|
21
|
+
pnx-viewer pnx-cornered-grid::part(corner-top),
|
|
22
|
+
pnx-viewer pnx-cornered-grid::part(corner-top-right),
|
|
23
|
+
pnx-viewer pnx-cornered-grid::part(corner-bottom-left),
|
|
24
|
+
pnx-viewer pnx-cornered-grid::part(corner-bottom),
|
|
25
|
+
pnx-viewer pnx-cornered-grid::part(corner-bottom-right) {
|
|
26
|
+
gap: 10px;
|
|
27
|
+
padding: 10px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@media screen and (max-width: 576px) {
|
|
31
|
+
pnx-viewer pnx-cornered-grid::part(corner-top-right) {
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
align-items: flex-end;
|
|
34
|
+
justify-content: flex-start;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Mini component */
|
|
39
|
+
pnx-viewer pnx-mini {
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
aspect-ratio: 1/1;
|
|
42
|
+
width: 250px;
|
|
43
|
+
height: 250px;
|
|
44
|
+
position: relative;
|
|
45
|
+
display: block;
|
|
46
|
+
z-index: 120;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@media screen and (max-width: 576px) {
|
|
50
|
+
pnx-viewer pnx-mini {
|
|
51
|
+
width: unset;
|
|
52
|
+
height: unset;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
pnx-viewer pnx-mini .psv-container,
|
|
57
|
+
pnx-viewer pnx-mini .pnx-map {
|
|
58
|
+
border-radius: 10px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Hidden elements depending on focus */
|
|
62
|
+
pnx-viewer:not(pnx-viewer[focus="map"]) .pnx-only-map,
|
|
63
|
+
pnx-viewer:not(pnx-viewer[focus="pic"]) .pnx-only-psv {
|
|
64
|
+
display: none;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Override legend positioning */
|
|
68
|
+
@media screen and (max-width: 576px) {
|
|
69
|
+
pnx-viewer[focus="map"] pnx-widget-legend {
|
|
70
|
+
display: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
pnx-viewer[focus="pic"] pnx-widget-legend {
|
|
74
|
+
position: fixed;
|
|
75
|
+
top: 0;
|
|
76
|
+
left: 0;
|
|
77
|
+
right: 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
pnx-viewer[focus="pic"] pnx-widget-legend::part(panel) {
|
|
81
|
+
border-radius: 0;
|
|
82
|
+
border-top: none;
|
|
83
|
+
border-left: none;
|
|
84
|
+
border-right: none;
|
|
85
|
+
width: unset;
|
|
86
|
+
max-width: unset;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
pnx-viewer[focus="pic"] pnx-widget-player {
|
|
90
|
+
margin-top: 60px;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@media screen and (min-width: 576px) {
|
|
95
|
+
pnx-viewer pnx-widget-legend {
|
|
96
|
+
position: absolute;
|
|
97
|
+
left: 10px;
|
|
98
|
+
top: 60px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
pnx-viewer[focus="pic"] pnx-widget-legend {
|
|
102
|
+
top: 10px;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Hide default map legend */
|
|
107
|
+
pnx-viewer .pnx-map .maplibregl-ctrl-attrib {
|
|
108
|
+
display: none;
|
|
109
|
+
}
|