@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.
Files changed (221) hide show
  1. package/.gitlab-ci.yml +3 -0
  2. package/CHANGELOG.md +19 -0
  3. package/CODE_OF_CONDUCT.md +1 -1
  4. package/README.md +1 -1
  5. package/build/editor.html +10 -1
  6. package/build/index.css +2 -2
  7. package/build/index.css.map +1 -1
  8. package/build/index.html +1 -1
  9. package/build/index.js +1682 -5
  10. package/build/index.js.map +1 -1
  11. package/build/map.html +1 -1
  12. package/build/viewer.html +10 -1
  13. package/build/widgets.html +1 -0
  14. package/config/jest/mocks.js +172 -0
  15. package/config/paths.js +1 -0
  16. package/config/webpack.config.js +26 -0
  17. package/docs/03_URL_settings.md +3 -11
  18. package/docs/05_Compatibility.md +59 -76
  19. package/docs/09_Develop.md +30 -11
  20. package/docs/90_Releases.md +2 -2
  21. package/docs/images/class_diagram.drawio +28 -28
  22. package/docs/images/class_diagram.jpg +0 -0
  23. package/docs/index.md +112 -0
  24. package/docs/reference/components/core/Basic.md +153 -0
  25. package/docs/reference/components/core/CoverageMap.md +160 -0
  26. package/docs/reference/components/core/Editor.md +172 -0
  27. package/docs/reference/components/core/Viewer.md +288 -0
  28. package/docs/reference/components/layout/CorneredGrid.md +29 -0
  29. package/docs/reference/components/layout/Mini.md +45 -0
  30. package/docs/reference/components/menus/MapBackground.md +32 -0
  31. package/docs/reference/components/menus/MapFilters.md +15 -0
  32. package/docs/reference/components/menus/MapLayers.md +15 -0
  33. package/docs/reference/components/menus/MapLegend.md +15 -0
  34. package/docs/reference/components/menus/PictureLegend.md +15 -0
  35. package/docs/reference/components/menus/PictureMetadata.md +15 -0
  36. package/docs/reference/components/menus/PlayerOptions.md +15 -0
  37. package/docs/reference/components/menus/QualityScoreDoc.md +15 -0
  38. package/docs/reference/components/menus/ReportForm.md +15 -0
  39. package/docs/reference/components/menus/ShareMenu.md +15 -0
  40. package/docs/reference/components/ui/Button.md +39 -0
  41. package/docs/reference/components/ui/ButtonGroup.md +36 -0
  42. package/docs/reference/components/ui/CopyButton.md +35 -0
  43. package/docs/reference/components/ui/Grade.md +32 -0
  44. package/docs/reference/components/ui/LinkButton.md +44 -0
  45. package/docs/reference/components/ui/Loader.md +54 -0
  46. package/docs/reference/components/ui/Map.md +214 -0
  47. package/docs/reference/components/ui/MapMore.md +233 -0
  48. package/docs/reference/components/ui/Photo.md +369 -0
  49. package/docs/reference/components/ui/Popup.md +56 -0
  50. package/docs/reference/components/ui/QualityScore.md +45 -0
  51. package/docs/reference/components/ui/SearchBar.md +63 -0
  52. package/docs/reference/components/ui/TogglableGroup.md +39 -0
  53. package/docs/reference/components/ui/widgets/GeoSearch.md +32 -0
  54. package/docs/reference/components/ui/widgets/Legend.md +32 -0
  55. package/docs/reference/components/ui/widgets/MapFiltersButton.md +33 -0
  56. package/docs/reference/components/ui/widgets/MapLayersButton.md +15 -0
  57. package/docs/reference/components/ui/widgets/Player.md +32 -0
  58. package/docs/reference/components/ui/widgets/Share.md +15 -0
  59. package/docs/reference/components/ui/widgets/Zoom.md +15 -0
  60. package/docs/reference/utils/API.md +311 -0
  61. package/docs/reference/utils/InitParameters.md +67 -0
  62. package/docs/reference/utils/URLHandler.md +102 -0
  63. package/docs/reference.md +73 -0
  64. package/docs/shortcuts.md +11 -0
  65. package/docs/tutorials/aerial_imagery.md +19 -0
  66. package/docs/tutorials/authentication.md +10 -0
  67. package/docs/tutorials/custom_widgets.md +64 -0
  68. package/docs/tutorials/map_style.md +27 -0
  69. package/docs/tutorials/migrate_v4.md +122 -0
  70. package/docs/tutorials/synced_coverage.md +42 -0
  71. package/mkdocs.yml +60 -5
  72. package/package.json +10 -7
  73. package/public/editor.html +21 -29
  74. package/public/index.html +3 -3
  75. package/public/map.html +19 -18
  76. package/public/viewer.html +18 -24
  77. package/public/widgets.html +265 -0
  78. package/scripts/doc.js +77 -0
  79. package/src/components/core/Basic.css +44 -0
  80. package/src/components/core/Basic.js +258 -0
  81. package/src/components/core/CoverageMap.css +9 -0
  82. package/src/components/core/CoverageMap.js +105 -0
  83. package/src/components/core/Editor.css +23 -0
  84. package/src/components/core/Editor.js +354 -0
  85. package/src/components/core/Viewer.css +109 -0
  86. package/src/components/core/Viewer.js +707 -0
  87. package/src/components/core/index.js +11 -0
  88. package/src/components/index.js +13 -0
  89. package/src/components/layout/CorneredGrid.js +109 -0
  90. package/src/components/layout/Mini.js +117 -0
  91. package/src/components/layout/index.js +7 -0
  92. package/src/components/menus/MapBackground.js +106 -0
  93. package/src/components/menus/MapFilters.js +386 -0
  94. package/src/components/menus/MapLayers.js +143 -0
  95. package/src/components/menus/MapLegend.js +54 -0
  96. package/src/components/menus/PictureLegend.js +103 -0
  97. package/src/components/menus/PictureMetadata.js +188 -0
  98. package/src/components/menus/PlayerOptions.js +96 -0
  99. package/src/components/menus/QualityScoreDoc.js +36 -0
  100. package/src/components/menus/ReportForm.js +133 -0
  101. package/src/components/menus/Share.js +228 -0
  102. package/src/components/menus/index.js +15 -0
  103. package/src/components/styles.js +365 -0
  104. package/src/components/ui/Button.js +75 -0
  105. package/src/components/ui/ButtonGroup.css +49 -0
  106. package/src/components/ui/ButtonGroup.js +68 -0
  107. package/src/components/ui/CopyButton.js +71 -0
  108. package/src/components/ui/Grade.js +54 -0
  109. package/src/components/ui/LinkButton.js +68 -0
  110. package/src/components/ui/Loader.js +188 -0
  111. package/src/components/{Map.css → ui/Map.css} +5 -17
  112. package/src/components/{Map.js → ui/Map.js} +114 -138
  113. package/src/components/ui/MapMore.js +324 -0
  114. package/src/components/{Photo.css → ui/Photo.css} +6 -6
  115. package/src/components/{Photo.js → ui/Photo.js} +279 -90
  116. package/src/components/ui/Popup.js +145 -0
  117. package/src/components/ui/QualityScore.js +152 -0
  118. package/src/components/ui/SearchBar.js +363 -0
  119. package/src/components/ui/TogglableGroup.js +162 -0
  120. package/src/components/ui/index.js +20 -0
  121. package/src/components/ui/widgets/GeoSearch.css +21 -0
  122. package/src/components/ui/widgets/GeoSearch.js +139 -0
  123. package/src/components/ui/widgets/Legend.js +51 -0
  124. package/src/components/ui/widgets/MapFiltersButton.js +104 -0
  125. package/src/components/ui/widgets/MapLayersButton.js +79 -0
  126. package/src/components/ui/widgets/Player.css +7 -0
  127. package/src/components/ui/widgets/Player.js +148 -0
  128. package/src/components/ui/widgets/Share.js +30 -0
  129. package/src/components/ui/widgets/Zoom.js +82 -0
  130. package/src/components/ui/widgets/index.js +12 -0
  131. package/src/img/panoramax.svg +13 -0
  132. package/src/img/switch_big.svg +20 -10
  133. package/src/index.js +6 -9
  134. package/src/translations/da.json +1 -1
  135. package/src/translations/de.json +1 -1
  136. package/src/translations/en.json +5 -3
  137. package/src/translations/eo.json +1 -1
  138. package/src/translations/es.json +1 -1
  139. package/src/translations/fr.json +5 -3
  140. package/src/translations/hu.json +1 -1
  141. package/src/translations/it.json +1 -1
  142. package/src/translations/ja.json +1 -1
  143. package/src/translations/nl.json +1 -1
  144. package/src/translations/pl.json +1 -1
  145. package/src/translations/sv.json +1 -1
  146. package/src/translations/zh_Hant.json +1 -1
  147. package/src/utils/API.js +74 -42
  148. package/src/utils/InitParameters.js +354 -0
  149. package/src/utils/URLHandler.js +364 -0
  150. package/src/utils/geocoder.js +116 -0
  151. package/src/utils/{I18n.js → i18n.js} +3 -1
  152. package/src/utils/index.js +11 -0
  153. package/src/utils/{Map.js → map.js} +216 -80
  154. package/src/utils/picture.js +433 -0
  155. package/src/utils/utils.js +315 -0
  156. package/src/utils/widgets.js +93 -0
  157. package/tests/components/ui/CopyButton.test.js +52 -0
  158. package/tests/components/ui/Loader.test.js +54 -0
  159. package/tests/components/{Map.test.js → ui/Map.test.js} +19 -61
  160. package/tests/components/{Photo.test.js → ui/Photo.test.js} +89 -57
  161. package/tests/components/ui/Popup.test.js +24 -0
  162. package/tests/components/ui/QualityScore.test.js +17 -0
  163. package/tests/components/ui/SearchBar.test.js +107 -0
  164. package/tests/components/ui/__snapshots__/CopyButton.test.js.snap +34 -0
  165. package/tests/components/ui/__snapshots__/Loader.test.js.snap +56 -0
  166. package/tests/components/{__snapshots__ → ui/__snapshots__}/Map.test.js.snap +11 -38
  167. package/tests/components/{__snapshots__ → ui/__snapshots__}/Photo.test.js.snap +57 -4
  168. package/tests/components/ui/__snapshots__/Popup.test.js.snap +29 -0
  169. package/tests/components/ui/__snapshots__/QualityScore.test.js.snap +11 -0
  170. package/tests/components/ui/__snapshots__/SearchBar.test.js.snap +65 -0
  171. package/tests/utils/API.test.js +1 -14
  172. package/tests/utils/InitParameters.test.js +485 -0
  173. package/tests/utils/URLHandler.test.js +350 -0
  174. package/tests/utils/__snapshots__/URLHandler.test.js.snap +21 -0
  175. package/tests/utils/__snapshots__/picture.test.js.snap +315 -0
  176. package/tests/utils/__snapshots__/widgets.test.js.snap +19 -0
  177. package/tests/utils/geocoder.test.js +37 -0
  178. package/tests/utils/{I18n.test.js → i18n.test.js} +1 -1
  179. package/tests/utils/map.test.js +67 -0
  180. package/tests/utils/picture.test.js +745 -0
  181. package/tests/utils/utils.test.js +288 -0
  182. package/tests/utils/widgets.test.js +90 -0
  183. package/docs/01_Start.md +0 -149
  184. package/docs/02_Usage.md +0 -831
  185. package/docs/04_Advanced_examples.md +0 -216
  186. package/src/Editor.css +0 -37
  187. package/src/Editor.js +0 -361
  188. package/src/StandaloneMap.js +0 -114
  189. package/src/Viewer.css +0 -203
  190. package/src/Viewer.js +0 -1246
  191. package/src/components/CoreView.css +0 -70
  192. package/src/components/CoreView.js +0 -175
  193. package/src/components/Loader.css +0 -74
  194. package/src/components/Loader.js +0 -120
  195. package/src/utils/Exif.js +0 -193
  196. package/src/utils/Utils.js +0 -631
  197. package/src/utils/Widgets.js +0 -562
  198. package/src/viewer/URLHash.js +0 -469
  199. package/src/viewer/Widgets.css +0 -880
  200. package/src/viewer/Widgets.js +0 -1470
  201. package/tests/Editor.test.js +0 -126
  202. package/tests/StandaloneMap.test.js +0 -45
  203. package/tests/Viewer.test.js +0 -366
  204. package/tests/__snapshots__/Editor.test.js.snap +0 -298
  205. package/tests/__snapshots__/StandaloneMap.test.js.snap +0 -30
  206. package/tests/__snapshots__/Viewer.test.js.snap +0 -195
  207. package/tests/components/CoreView.test.js +0 -92
  208. package/tests/components/Loader.test.js +0 -38
  209. package/tests/components/__snapshots__/Loader.test.js.snap +0 -15
  210. package/tests/utils/Exif.test.js +0 -124
  211. package/tests/utils/Map.test.js +0 -113
  212. package/tests/utils/Utils.test.js +0 -300
  213. package/tests/utils/Widgets.test.js +0 -107
  214. package/tests/utils/__snapshots__/Exif.test.js.snap +0 -43
  215. package/tests/utils/__snapshots__/Utils.test.js.snap +0 -41
  216. package/tests/utils/__snapshots__/Widgets.test.js.snap +0 -44
  217. package/tests/viewer/URLHash.test.js +0 -559
  218. package/tests/viewer/Widgets.test.js +0 -127
  219. package/tests/viewer/__snapshots__/URLHash.test.js.snap +0 -108
  220. package/tests/viewer/__snapshots__/Widgets.test.js.snap +0 -403
  221. /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
+ }