@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,258 @@
1
+ import { LitElement, html } from "lit";
2
+ import API from "../../utils/API";
3
+ import { getTranslations } from "../../utils/i18n";
4
+ import { DEFAULT_TILES } from "../../utils/map";
5
+ import { createWebComp } from "../../utils/widgets";
6
+ import { isInternetFast } from "../../utils/utils";
7
+ import PACKAGE_JSON from "../../../package.json";
8
+ import "./Basic.css";
9
+
10
+ /**
11
+ * Event for overlaying menu opening
12
+ * @event Panoramax.components.core.Basic#menu-opened
13
+ * @type {CustomEvent}
14
+ * @property {Element} detail.menu The opened menu
15
+ */
16
+
17
+ /**
18
+ * Basic core component is a basic container for common functions through all core components.
19
+ * It is not intended to be used directly, it's only to be extended by other core components.
20
+ * @class Panoramax.components.core.Basic
21
+ * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
22
+ * @fires Panoramax.components.core.Basic#select
23
+ * @fires Panoramax.components.core.Basic#ready
24
+ * @fires Panoramax.components.core.Basic#broken
25
+ * @fires Panoramax.components.core.Basic#menu-opened
26
+ * @property {Panoramax.components.ui.Loader} loader The loader screen
27
+ * @property {Panoramax.utils.API} api The API manager
28
+ */
29
+ export default class Basic extends LitElement {
30
+ /**
31
+ * Component properties.
32
+ * @memberof Panoramax.components.core.Basic#
33
+ * @type {Object}
34
+ * @mixin
35
+ * @property {string} [picture] The picture ID to display
36
+ * @property {string} [sequence] The sequence ID of the picture displayed
37
+ * @property {object} [fetchOptions] Set custom options for fetch calls made against API ([same syntax as fetch options parameter](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters))
38
+ * @property {string[]} [users=[geovisio]] List of users IDs to use for map display (defaults to general map, identified as "geovisio")
39
+ * @property {string|object} [style] The map's MapLibre style. This can be an a JSON object conforming to the schema described in the [MapLibre Style Specification](https://maplibre.org/maplibre-gl-js-docs/style-spec/), or a URL string pointing to one. Defaults to OSM vector tiles.
40
+ * @property {string} [lang] To override language used for labels. Defaults to using user's preferred languages.
41
+ * @property {string} endpoint URL to API to use (must be a [STAC API](https://github.com/radiantearth/stac-api-spec/blob/main/overview.md))
42
+ */
43
+ static properties = {
44
+ picture: {type: String, reflect: true},
45
+ sequence: {type: String, reflect: true},
46
+ fetchOptions: {type: Object, attribute: false},
47
+ users: {type: Array, reflect: true},
48
+ style: {type: Object},
49
+ lang: {type: String},
50
+ endpoint: {type: String},
51
+ };
52
+
53
+ constructor(testing = false) {
54
+ super();
55
+
56
+ // Some defaults
57
+ this.users = ["geovisio"];
58
+ this.style = DEFAULT_TILES;
59
+ this.lang = this.getAttribute("lang") || null;
60
+ this.endpoint = this.getAttribute("endpoint") || null; // No default
61
+ this.picture = null;
62
+ this.sequence = null;
63
+
64
+ // Display version in logs
65
+ console.info(`📷 Panoramax ${this.getClassName()} - Version ${PACKAGE_JSON.version} (${__COMMIT_HASH__})
66
+
67
+ 🆘 Issues can be reported at ${PACKAGE_JSON.repository.url}`);
68
+
69
+ // Translations
70
+ this._t = getTranslations(this.lang);
71
+
72
+ if(testing) { return; }
73
+
74
+ // Show loader
75
+ this.loader = createWebComp("pnx-loader", {_parent: this});
76
+
77
+ // Internet speed check
78
+ this._isInternetFast = null;
79
+ isInternetFast().then(isFast => this._isInternetFast = isFast);
80
+
81
+ if(this.endpoint) { this._setupAPI(this.endpoint); }
82
+ }
83
+
84
+ /**
85
+ * Creates API and wait for initial loading
86
+ * @private
87
+ */
88
+ _setupAPI(endpoint) {
89
+ // Loader init
90
+ this.loader = this.loader || createWebComp("pnx-loader", {_parent: this});
91
+
92
+ if(!this.endpoint) {
93
+ console.warn("No endpoint is defined");
94
+ return;
95
+ }
96
+
97
+ // API init)
98
+ try {
99
+ this.api = new API(endpoint, {
100
+ users: this.users,
101
+ fetch: this.fetchOptions,
102
+ style: this.style,
103
+ });
104
+ this.api.onceReady()
105
+ .then(() => {
106
+ let unavailable = this.api.getUnavailableFeatures();
107
+ let available = this.api.getAvailableFeatures();
108
+ available = unavailable.length === 0 ? "✅ All features available" : "✅ Available features: "+available.join(", ");
109
+ unavailable = unavailable.length === 0 ? "" : "🚫 Unavailable features: "+unavailable.join(", ");
110
+ console.info(`🌐 Connected to API "${this.api._metadata.name}" (${this.api._endpoint})
111
+ ℹ️ API runs STAC ${this.api._metadata.stac_version} ${this.api._metadata.geovisio_version ? "& GeoVisio "+this.api._metadata.geovisio_version : ""}
112
+ ${available}
113
+ ${unavailable}
114
+ `.trim());
115
+ })
116
+ .catch(e => this.loader.dismiss(e, this._t.pnx.error_api));
117
+ }
118
+ catch(e) {
119
+ if(this.loader?.dismiss) {
120
+ this.loader.dismiss(e, this._t.pnx.error_api);
121
+ }
122
+ else {
123
+ console.error(e);
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Waits for component to have its first loading done.
130
+ *
131
+ * Each inheriting class must override this method.
132
+ * @memberof Panoramax.components.core.Basic#
133
+ * @returns {Promise}
134
+ * @fulfil {null} When initialization is complete.
135
+ * @reject {string} Error message
136
+ */
137
+ onceReady() {
138
+ throw new Error("You must override this method on sub-class");
139
+ }
140
+
141
+ /**
142
+ * Waits for initial API setup.
143
+ * @memberof Panoramax.components.core.Basic#
144
+ * @returns {Promise}
145
+ * @fulfil {null} When API is ready.
146
+ * @reject {string} Error message
147
+ */
148
+ onceAPIReady() {
149
+ if(this.api) {
150
+ return this.api.onceReady();
151
+ }
152
+ else {
153
+ return new Promise(resolve => setTimeout(resolve, 100)).then(this.onceAPIReady.bind(this));
154
+ }
155
+ }
156
+
157
+ /** @private */
158
+ createRenderRoot() {
159
+ return this;
160
+ }
161
+
162
+ /** @private */
163
+ attributeChangedCallback(name, _old, value) {
164
+ super.attributeChangedCallback(name, _old, value);
165
+
166
+ if(name === "endpoint") {
167
+ if(!this.api || this.api._endpoint !== value) { this._setupAPI(value); }
168
+ }
169
+ if(["picture", "sequence"].includes(name)) {
170
+ let seqId, picId, prevSeqId, prevPicId;
171
+
172
+ if(name === "picture") {
173
+ seqId = this.sequence;
174
+ prevSeqId = this.sequence;
175
+ picId = value;
176
+ prevPicId = _old;
177
+ }
178
+ else {
179
+ seqId = value;
180
+ prevSeqId = _old;
181
+ picId = this.picture;
182
+ prevPicId = this.picture;
183
+ }
184
+
185
+ /**
186
+ * Event for sequence/picture selection
187
+ * @event Panoramax.components.core.Basic#select
188
+ * @type {CustomEvent}
189
+ * @property {string} detail.seqId The selected sequence ID
190
+ * @property {string} detail.picId The selected picture ID (or null if not a precise picture clicked)
191
+ * @property {string} [detail.prevSeqId] The previously selected sequence ID (or null if none)
192
+ * @property {string} [detail.prevPicId] The previously selected picture ID (or null if none)
193
+ */
194
+ this.dispatchEvent(new CustomEvent("select", {
195
+ bubbles: true,
196
+ composed: true,
197
+ detail: {
198
+ seqId,
199
+ picId,
200
+ prevSeqId,
201
+ prevPicId,
202
+ }
203
+ }));
204
+ }
205
+ }
206
+
207
+ /**
208
+ * This allows to retrieve an always correct class name.
209
+ * This is crap, but avoids issues with Webpack & so on.
210
+ *
211
+ * Each inheriting class must override this method.
212
+ * @returns {string} The class name (for example "Basic")
213
+ * @memberof Panoramax.components.core.Basic#
214
+ */
215
+ getClassName() {
216
+ return "Basic";
217
+ }
218
+
219
+ /**
220
+ * Change the currently picture and/or sequence.
221
+ * Calling the method without parameters unselects.
222
+ * @param {string} [seqId] The sequence UUID
223
+ * @param {string} [picId] The picture UUID
224
+ * @param {boolean} [force=false] Force select even if already selected
225
+ * @memberof Panoramax.components.core.Basic#
226
+ */
227
+ select(seqId = null, picId = null, force = false) {
228
+ if(force) {
229
+ this.picture = null;
230
+ this.sequence = null;
231
+ }
232
+ this.picture = picId;
233
+ this.sequence = seqId;
234
+ }
235
+
236
+ /**
237
+ * Is the view running in a small container (small embed or smartphone)
238
+ * @returns {boolean} True if container is small
239
+ * @memberof Panoramax.components.core.Basic#
240
+ */
241
+ isWidthSmall() {
242
+ return this?.offsetWidth < 576;
243
+ }
244
+
245
+ /**
246
+ * Is the view running in a small-height container (small embed or smartphone)
247
+ * @returns {boolean} True if container height is small
248
+ * @memberof Panoramax.components.core.Basic#
249
+ */
250
+ isHeightSmall() {
251
+ return this?.offsetHeight < 400;
252
+ }
253
+
254
+ /** @private */
255
+ render() {
256
+ return html`<p>Should not be used directly, use Viewer/CoverageMap/Editor instead</p>`;
257
+ }
258
+ }
@@ -0,0 +1,9 @@
1
+ pnx-coverage-map {
2
+ display: block;
3
+ }
4
+
5
+ pnx-coverage-map .maplibregl-map {
6
+ position: absolute;
7
+ inset: 0;
8
+ background-color: white;
9
+ }
@@ -0,0 +1,105 @@
1
+ import Basic from "./Basic";
2
+ import Map from "../ui/Map";
3
+ import { getUserLayerId } from "../../utils/map";
4
+ import { NavigationControl } from "!maplibre-gl"; // DO NOT REMOVE THE "!": bundled builds breaks otherwise !!!
5
+ import "./CoverageMap.css";
6
+
7
+
8
+ /**
9
+ * Coverage Map is a basic map showing Panoramax coverage.
10
+ * @class Panoramax.components.core.CoverageMap
11
+ * @element pnx-coverage-map
12
+ * @extends Panoramax.components.core.Basic
13
+ * @fires Panoramax.components.core.Basic#select
14
+ * @fires Panoramax.components.core.Basic#ready
15
+ * @fires Panoramax.components.core.Basic#broken
16
+ * @property {Panoramax.components.ui.Loader} loader The loader screen
17
+ * @property {Panoramax.utils.API} api The API manager
18
+ * @property {Panoramax.components.ui.Map} map The MapLibre GL map itself
19
+ * @example
20
+ * ```html
21
+ * <pnx-coverage-map
22
+ * endpoint="https://panoramax.openstreetmap.fr/"
23
+ * />
24
+ * ```
25
+ */
26
+ export default class CoverageMap extends Basic {
27
+ constructor() {
28
+ super();
29
+
30
+ this._mapContainer = document.createElement("div");
31
+ this.onceAPIReady().then(() => this._initMap());
32
+
33
+ // Events handlers
34
+ this.addEventListener("select", this._onSelect.bind(this));
35
+ }
36
+
37
+ getClassName() {
38
+ return "CoverageMap";
39
+ }
40
+
41
+ onceReady() {
42
+ if(this.map && this.map.waitForEnoughMapLoaded) {
43
+ return this.map.waitForEnoughMapLoaded();
44
+ }
45
+ else {
46
+ return new Promise(resolve => setTimeout(resolve, 100)).then(this.onceReady.bind(this));
47
+ }
48
+ }
49
+
50
+ /** @private */
51
+ render() {
52
+ return [this.loader, this._mapContainer];
53
+ }
54
+
55
+ /**
56
+ * Creates map object
57
+ * @private
58
+ */
59
+ _initMap() {
60
+ const mapOptions = { hash: true };
61
+
62
+ // Override to avoid display of pictures symbols
63
+ class MyMap extends Map {
64
+ _getLayerStyleProperties(layer) {
65
+ if(layer === "pictures_symbols") {
66
+ return { layout: { visibility: "none" } };
67
+ }
68
+ else {
69
+ return super._getLayerStyleProperties(layer);
70
+ }
71
+ }
72
+ }
73
+
74
+ this.map = new MyMap(this, this._mapContainer, mapOptions);
75
+ this.map.addControl(new NavigationControl({ showCompass: false }));
76
+ this.map.waitForEnoughMapLoaded().then(() => {
77
+ this.map.reloadLayersStyles();
78
+ this.loader.dismiss();
79
+ });
80
+ this.map.on("picture-click", e => this.select(e.seqId, e.picId));
81
+ this.map.on("sequence-click", e => this.select(e.seqId));
82
+ }
83
+
84
+ /**
85
+ * Select event handler
86
+ * @private
87
+ * @param {object} e Event details
88
+ */
89
+ _onSelect(e) {
90
+ // Move thumbnail to match selected element
91
+ if(e.detail.picId || e.detail.seqId) {
92
+ const layer = e.detail.picId ? "pictures" : "sequences";
93
+ const features = this.map.queryRenderedFeatures({
94
+ layers: [...this.map._userLayers].map(l => getUserLayerId(l, layer)),
95
+ filter: ["==", ["get", "id"], e.detail.picId || e.detail.seqId]
96
+ });
97
+
98
+ if(features.length >= 0 && features[0] != null) {
99
+ this.map._attachPreviewToPictures({ features }, layer);
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ customElements.define("pnx-coverage-map", CoverageMap);
@@ -0,0 +1,23 @@
1
+ /* General layout */
2
+ pnx-editor {
3
+ display: flex;
4
+ flex-direction: column;
5
+ }
6
+
7
+ pnx-editor .pnx-map,
8
+ pnx-editor .pnx-psv {
9
+ height: 50%;
10
+ }
11
+
12
+ /* Map background widget */
13
+ pnx-editor pnx-map-background {
14
+ position: absolute;
15
+ padding: 7px;
16
+ z-index: 120;
17
+ border-radius: 10px;
18
+ border: 1px solid var(--widget-border-div);
19
+ background-color: var(--widget-bg);
20
+ color: var(--widget-font);
21
+ bottom: 10px;
22
+ left: 10px;
23
+ }