@panoramax/web-viewer 3.2.3-develop-d7e5a16d → 3.2.3-develop-f9c0224b

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 +5 -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
@@ -1,14 +1,13 @@
1
1
  import "./Map.css";
2
2
  import {
3
- forwardGeocodingBAN, forwardGeocodingNominatim, VECTOR_STYLES,
4
- TILES_PICTURES_ZOOM, getThumbGif, RASTER_LAYER_ID, combineStyles,
5
- getMissingLayerStyles, isLabelLayer, getUserLayerId, getUserSourceId, switchCoefValue,
6
- } from "../utils/Map";
7
- import { COLORS } from "../utils/Utils";
8
- import MarkerBaseSVG from "../img/marker.svg";
9
- import MarkerSelectedSVG from "../img/marker_blue.svg";
10
- import ArrowFlatSVG from "../img/arrow_flat.svg";
11
- import Arrow360SVG from "../img/arrow_360.svg";
3
+ VECTOR_STYLES, TILES_PICTURES_ZOOM, getThumbGif, RASTER_LAYER_ID, combineStyles,
4
+ getMissingLayerStyles, isLabelLayer, getUserLayerId, getUserSourceId,
5
+ } from "../../utils/map";
6
+ import { COLORS } from "../../utils/utils";
7
+ import MarkerBaseSVG from "../../img/marker.svg";
8
+ import MarkerSelectedSVG from "../../img/marker_blue.svg";
9
+ import ArrowFlatSVG from "../../img/arrow_flat.svg";
10
+ import Arrow360SVG from "../../img/arrow_360.svg";
12
11
 
13
12
  // MapLibre imports
14
13
  import "maplibre-gl/dist/maplibre-gl.css";
@@ -38,13 +37,25 @@ const filterMapLibreOptions = opts => Object.fromEntries(Object.entries(opts).fi
38
37
  *
39
38
  * Note that all functions of [MapLibre GL JS class Map](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/) are also available.
40
39
  *
41
- * @param {CoreView} parent The parent view
40
+ * A more complete version of Map (with filters & themes) is available through [MapMore class](#Panoramax.components.ui.MapMore)
41
+ *
42
+ * ⚠️ This class doesn't inherit from [EventTarget](https://developer.mozilla.org/fr/docs/Web/API/EventTarget), so it doesn't have `addEventListener` and `dispatchEvent` functions.
43
+ * It uses instead [`on`](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#on) and `fire` functions from MapLibre Map class.
44
+ * `fire` function doesn't take directly [`Event`](https://developer.mozilla.org/fr/docs/Web/API/Event) objects, but a string and object data.
45
+ * @class Panoramax.components.ui.Map
46
+ * @extends [maplibregl.Map](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/)
47
+ * @param {Panoramax.components.core.Basic} parent The parent view
42
48
  * @param {Element} container The DOM element to create into
43
49
  * @param {object} [options] The map options (any of [MapLibre GL settings](https://maplibre.org/maplibre-gl-js-docs/api/map/#map-parameters) or any supplementary option defined here)
44
50
  * @param {object} [options.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).
45
- * @param {string} [options.background] Choose default map background to display (streets or aerial, if raster aerial background available). Defaults to street.
46
- * @param {object} [options.geocoder] Optional geocoder settings
47
- * @param {string} [options.geocoder.engine] Set the geocoder engine to use (nominatim, ban)
51
+ * @param {string} [options.background=streets] Choose default map background to display (streets or aerial, if raster aerial background available). Defaults to street.
52
+ * @fires Panoramax.components.ui.Map#background-changed
53
+ * @fires Panoramax.components.ui.Map#users-changed
54
+ * @fires Panoramax.components.ui.Map#sequence-hover
55
+ * @fires Panoramax.components.ui.Map#sequence-click
56
+ * @fires Panoramax.components.ui.Map#picture-click
57
+ * @example
58
+ * const map = new Panoramax.components.ui.Map(viewer, mapNode, {center: {lat: 48.7, lng: -1.7}});
48
59
  */
49
60
  export default class Map extends maplibregl.Map {
50
61
  constructor(parent, container, options = {}) {
@@ -59,16 +70,18 @@ export default class Map extends maplibregl.Map {
59
70
  pitchWithRotate: false,
60
71
  touchZoomRotate: true,
61
72
  touchPitch: false,
73
+ doubleClickZoom: false,
62
74
  preserveDrawingBuffer: !parent.isWidthSmall(),
63
- transformRequest: parent._api._getMapRequestTransform(),
75
+ transformRequest: parent.api._getMapRequestTransform(),
64
76
  locale: parent._t.maplibre,
77
+ hash: false,
65
78
  ...filterMapLibreOptions(options)
66
79
  });
67
80
  this._loadMarkerImages();
68
81
 
69
82
  this._parent = parent;
70
83
  this._options = options;
71
- this.getContainer().classList.add("gvs-map");
84
+ this.getContainer().classList.add("pnx-map");
72
85
 
73
86
  // Disable touch rotate
74
87
  if(options.touchZoomRotate === undefined) {
@@ -83,7 +96,6 @@ export default class Map extends maplibregl.Map {
83
96
  this._attribution = new maplibregl.AttributionControl({ compact: false });
84
97
  this.addControl(this._attribution);
85
98
 
86
- this._initGeocoder();
87
99
  this._initMapPosition();
88
100
 
89
101
  // Widgets and markers
@@ -97,16 +109,13 @@ export default class Map extends maplibregl.Map {
97
109
  // Sequences and pictures per users
98
110
  this._userLayers = new Set();
99
111
 
100
- // Hover event
101
- this.on("mousemove", "sequences", this._onSequenceHover.bind(this));
102
-
103
112
  // Parent selection
104
113
  this._parent.addEventListener("select", this.reloadLayersStyles.bind(this));
105
114
 
106
115
  // Timeout for initial loading
107
116
  setTimeout(() => {
108
- if(!this.loaded() && this._parent._loader.isVisible()) {
109
- this._parent._loader.dismiss({}, this._parent._t.map.slow_loading, () => {});
117
+ if(!this.loaded() && this._parent.loader.isVisible()) {
118
+ this._parent.loader.dismiss({}, this._parent._t.map.slow_loading, () => {});
110
119
  }
111
120
  }, 15000);
112
121
 
@@ -118,12 +127,13 @@ export default class Map extends maplibregl.Map {
118
127
  */
119
128
  async _postLoad() {
120
129
  this.resize();
121
- await this.setVisibleUsers(this._parent._options.users);
130
+ await this.setVisibleUsers(this._parent.users);
122
131
  this.reloadLayersStyles();
123
132
  }
124
133
 
125
134
  /**
126
135
  * Destroy any form of life in this component
136
+ * @memberof Panoramax.components.ui.Map#
127
137
  */
128
138
  destroy() {
129
139
  this.remove();
@@ -140,6 +150,7 @@ export default class Map extends maplibregl.Map {
140
150
  /**
141
151
  * Helper to know when enough map background and Panoramax tiles are loaded for a proper display.
142
152
  * @returns {Promise} Resolves when enough is loaded
153
+ * @memberof Panoramax.components.ui.Map#
143
154
  */
144
155
  waitForEnoughMapLoaded() {
145
156
  return new Promise((resolve) => {
@@ -173,7 +184,7 @@ export default class Map extends maplibregl.Map {
173
184
  };
174
185
 
175
186
  const checkEnoughLoaded = () => {
176
- if(nbLoadedBgTiles / nbBgTiles >= 0.75 && nbLoadedFgTiles / nbFgTiles >= 0.75) {
187
+ if(nbLoadedBgTiles / nbBgTiles >= 0.75 && (nbFgTiles === 0 || nbLoadedFgTiles / nbFgTiles >= 0.75)) {
177
188
  this.off("sourcedata", onSourceData);
178
189
  this.off("sourcedataloading", onSourceDataLoading);
179
190
  resolve();
@@ -188,6 +199,7 @@ export default class Map extends maplibregl.Map {
188
199
  /**
189
200
  * Sets map view based on returned API bbox (if no precise option given by user).
190
201
  * @private
202
+ * @memberof Panoramax.components.ui.Map#
191
203
  */
192
204
  _initMapPosition() {
193
205
  if(
@@ -195,8 +207,8 @@ export default class Map extends maplibregl.Map {
195
207
  && (!this._options.zoom || this._options.zoom === 0)
196
208
  && (!this._options.hash)
197
209
  ) {
198
- this._parent._api.onceReady().then(() => {
199
- let bbox = this._parent?._api?.getDataBbox();
210
+ this._parent.onceAPIReady().then(() => {
211
+ let bbox = this._parent?.api?.getDataBbox();
200
212
  if(bbox) {
201
213
  try {
202
214
  bbox = new maplibregl.LngLatBounds(bbox);
@@ -211,35 +223,16 @@ export default class Map extends maplibregl.Map {
211
223
  }
212
224
  }
213
225
 
214
- /**
215
- * Creates the geocoder search bar
216
- * @private
217
- */
218
- _initGeocoder() {
219
- const engines = { "ban": forwardGeocodingBAN, "nominatim": forwardGeocodingNominatim };
220
- const engine = this._options?.geocoder?.engine || "nominatim";
221
- this.geocoder = engines[engine];
222
- this._geolocate = new maplibregl.GeolocateControl({
223
- positionOptions: {
224
- enableHighAccuracy: true,
225
- timeout: 60000, // Max 1 minute for first position
226
- maximumAge: 300000, // Accepts 5 minutes old position
227
- },
228
- showAccuracyCircle: true,
229
- showUserLocation: true,
230
- trackUserLocation: true,
231
- }).onAdd(this);
232
- }
233
-
234
226
  /**
235
227
  * Load markers into map for use in map layers.
236
228
  * @private
229
+ * @memberof Panoramax.components.ui.Map#
237
230
  */
238
231
  _loadMarkerImages() {
239
232
  [
240
- { id: "gvs-marker", img: MarkerBaseSVG },
241
- { id: "gvs-arrow-flat", img: ArrowFlatSVG },
242
- { id: "gvs-arrow-360", img: Arrow360SVG },
233
+ { id: "pnx-marker", img: MarkerBaseSVG },
234
+ { id: "pnx-arrow-flat", img: ArrowFlatSVG },
235
+ { id: "pnx-arrow-360", img: Arrow360SVG },
243
236
  ].forEach(m => {
244
237
  const img = new Image(64, 64);
245
238
  img.onload = () => this.addImage(m.id, img);
@@ -250,6 +243,7 @@ export default class Map extends maplibregl.Map {
250
243
  /**
251
244
  * Is Quality Score available in vector tiles ?
252
245
  * @private
246
+ * @memberof Panoramax.components.ui.Map#
253
247
  */
254
248
  _hasQualityScore() {
255
249
  const fields = this.getStyle()?.metadata?.["panoramax:fields"] || {};
@@ -259,6 +253,7 @@ export default class Map extends maplibregl.Map {
259
253
  /**
260
254
  * Are 360/flat pictures stats available in vector tiles for grid layer ?
261
255
  * @private
256
+ * @memberof Panoramax.components.ui.Map#
262
257
  */
263
258
  _hasGridStats() {
264
259
  const fields = this.getStyle()?.metadata?.["panoramax:fields"] || {};
@@ -268,6 +263,7 @@ export default class Map extends maplibregl.Map {
268
263
 
269
264
  /**
270
265
  * Force refresh of vector tiles data
266
+ * @memberof Panoramax.components.ui.Map#
271
267
  */
272
268
  reloadVectorTiles() {
273
269
  [...this._userLayers].forEach(dl => {
@@ -279,6 +275,7 @@ export default class Map extends maplibregl.Map {
279
275
  /**
280
276
  * Check if map offers aerial imagery as well as streets rendering.
281
277
  * @returns {boolean} True if aerial imagery is available for display
278
+ * @memberof Panoramax.components.ui.Map#
282
279
  */
283
280
  hasTwoBackgrounds() {
284
281
  return this.getLayer(RASTER_LAYER_ID) !== undefined;
@@ -287,6 +284,7 @@ export default class Map extends maplibregl.Map {
287
284
  /**
288
285
  * Get the currently selected map background
289
286
  * @returns {string} aerial or streets
287
+ * @memberof Panoramax.components.ui.Map#
290
288
  */
291
289
  getBackground() {
292
290
  if(!this.getLayer(RASTER_LAYER_ID)) {
@@ -300,6 +298,8 @@ export default class Map extends maplibregl.Map {
300
298
  /**
301
299
  * Change the shown background in map.
302
300
  * @param {string} bg The new background to display (aerial or streets)
301
+ * @memberof Panoramax.components.ui.Map#
302
+ * @throws {Error} If not aerial imagery is available
303
303
  */
304
304
  setBackground(bg) {
305
305
  if(!this.getLayer(RASTER_LAYER_ID) && bg === "aerial") { throw new Error("No aerial imagery available"); }
@@ -309,20 +309,18 @@ export default class Map extends maplibregl.Map {
309
309
  /**
310
310
  * Event for map background changes
311
311
  *
312
- * @event map:background-changed
313
- * @memberof CoreView
314
- * @type {object}
315
- * @property {object} detail Event information
316
- * @property {string} [detail.background] The new selected background (aerial, streets)
312
+ * @event Panoramax.components.ui.Map#background-changed
313
+ * @type {maplibregl.util.evented.Event}
314
+ * @property {string} [background] The new selected background (aerial, streets)
317
315
  */
318
- const event = new CustomEvent("map:background-changed", { detail: { background: bg || "streets" }});
319
- this._parent.dispatchEvent(event);
316
+ this.fire("background-changed", { background: bg || "streets" });
320
317
  }
321
318
  }
322
319
 
323
320
  /**
324
321
  * Get the currently visible users
325
322
  * @returns {string[]} List of visible users
323
+ * @memberof Panoramax.components.ui.Map#
326
324
  */
327
325
  getVisibleUsers() {
328
326
  return [...this._userLayers].filter(l => (
@@ -332,7 +330,7 @@ export default class Map extends maplibregl.Map {
332
330
 
333
331
  /**
334
332
  * Make given user layers visible on map, and hide all others (if any)
335
- *
333
+ * @memberof Panoramax.components.ui.Map#
336
334
  * @param {string|string[]} visibleIds The user layers IDs to display
337
335
  */
338
336
  async setVisibleUsers(visibleIds = []) {
@@ -359,20 +357,18 @@ export default class Map extends maplibregl.Map {
359
357
  /**
360
358
  * Event for visible users changes
361
359
  *
362
- * @event map:users-changed
363
- * @memberof CoreView
364
- * @type {object}
365
- * @property {object} detail Event information
366
- * @property {string[]} [detail.usersIds] The list of newly selected users
360
+ * @event Panoramax.components.ui.Map#users-changed
361
+ * @type {maplibregl.util.evented.Event}
362
+ * @property {string[]} [usersIds] The list of newly selected users
367
363
  */
368
- const event = new CustomEvent("map:users-changed", { detail: { usersIds: visibleIds }});
369
- this._parent.dispatchEvent(event);
364
+ this.fire("users-changed", { usersIds: visibleIds });
370
365
  }
371
366
 
372
367
  /**
373
368
  * Filter the visible data content in all visible map layers
374
369
  * @param {string} dataType sequences or pictures
375
370
  * @param {object} filter The MapLibre GL filter rule to apply
371
+ * @memberof Panoramax.components.ui.Map#
376
372
  */
377
373
  filterUserLayersContent(dataType, filter) {
378
374
  [...this._userLayers].forEach(l => {
@@ -388,12 +384,13 @@ export default class Map extends maplibregl.Map {
388
384
 
389
385
  /**
390
386
  * Shows on map a picture position and heading.
391
- *
387
+ * @memberof Panoramax.components.ui.Map#
392
388
  * @param {number} lon The longitude
393
389
  * @param {number} lat The latitude
394
390
  * @param {number} heading The heading
391
+ * @param {boolean} [skipCenter=false] Set to true to avoid map centering on marker
395
392
  */
396
- displayPictureMarker(lon, lat, heading) {
393
+ displayPictureMarker(lon, lat, heading, skipCenter = false) {
397
394
  this._picMarkerPreview.remove();
398
395
 
399
396
  // Show marker corresponding to selection
@@ -411,7 +408,7 @@ export default class Map extends maplibregl.Map {
411
408
  this.reloadLayersStyles();
412
409
 
413
410
  // Move map to picture coordinates
414
- if(lon !== undefined && lat !== undefined) {
411
+ if(!skipCenter && lon !== undefined && lat !== undefined) {
415
412
  this.flyTo({
416
413
  center: [lon, lat],
417
414
  zoom: this.getZoom() < TILES_PICTURES_ZOOM+2 ? TILES_PICTURES_ZOOM+2 : this.getZoom(),
@@ -423,6 +420,7 @@ export default class Map extends maplibregl.Map {
423
420
  /**
424
421
  * Forces reload of pictures/sequences layer styles.
425
422
  * This is useful after a map theme change.
423
+ * @memberof Panoramax.components.ui.Map#
426
424
  */
427
425
  reloadLayersStyles() {
428
426
  const updateStyle = (layer, style) => {
@@ -438,30 +436,12 @@ export default class Map extends maplibregl.Map {
438
436
  ["pictures", "pictures_symbols", "sequences"].forEach(l => {
439
437
  updateStyle(l, this._getLayerStyleProperties(l));
440
438
  });
441
-
442
- // Also handle the grid stats
443
- if(this._hasGridStats() && this._parent?._mapFilters) {
444
- let newType = "coef";
445
- if(this._parent._mapFilters?.type) {
446
- newType = this._parent._mapFilters.type == "flat" ? "coef_flat_pictures" : "coef_360_pictures";
447
- }
448
- this.getStyle().layers
449
- .filter(l => l.id.endsWith("_grid"))
450
- .forEach(l => {
451
- const newl = switchCoefValue(l, newType);
452
- for(let p in newl.layout) {
453
- this.setLayoutProperty(l.id, p, newl.layout[p]);
454
- }
455
- for(let p in newl.paint) {
456
- this.setPaintProperty(l.id, p, newl.paint[p]);
457
- }
458
- });
459
- }
460
439
  }
461
440
 
462
441
  /**
463
442
  * Creates source and layers for pictures and sequences.
464
443
  * @private
444
+ * @memberof Panoramax.components.ui.Map#
465
445
  * @param {string} id The source and layer ID prefix
466
446
  */
467
447
  async _createPicturesTilesLayer(id) {
@@ -470,7 +450,7 @@ export default class Map extends maplibregl.Map {
470
450
 
471
451
  // Load style from API
472
452
  if(id !== "geovisio" && !this.getSource(`geovisio_${id}`)) {
473
- const style = await this._parent._api.getUserMapStyle(id);
453
+ const style = await this._parent.api.getUserMapStyle(id);
474
454
  Object.entries(style.sources).forEach(([sId, s]) => this.addSource(sId, s));
475
455
  style.layers = style.layers || [];
476
456
  const layers = style.layers.concat(getMissingLayerStyles(style.sources, style.layers));
@@ -511,6 +491,7 @@ export default class Map extends maplibregl.Map {
511
491
  // Sequences
512
492
  const seqPlusLayerId = getUserLayerId(id, "sequences_plus");
513
493
  this.on("mousemove", seqPlusLayerId, e => {
494
+ this._onSequenceHover(e);
514
495
  if(this.getZoom() <= TILES_PICTURES_ZOOM+1) {
515
496
  this.getCanvas().style.cursor = "pointer";
516
497
  if(e.features[0].properties.id) {
@@ -580,6 +561,7 @@ export default class Map extends maplibregl.Map {
580
561
  *
581
562
  * @returns {object} Paint/layout properties
582
563
  * @private
564
+ * @memberof Panoramax.components.ui.Map#
583
565
  */
584
566
  _getLayerStyleProperties(layer) {
585
567
  if(layer === "pictures_symbols") {
@@ -587,9 +569,9 @@ export default class Map extends maplibregl.Map {
587
569
  "paint": {},
588
570
  "layout": {
589
571
  "icon-image": ["case",
590
- ["==", ["get", "id"], this._parent._selectedPicId], "",
591
- ["==", ["get", "type"], "equirectangular"], "gvs-arrow-360",
592
- "gvs-arrow-flat"
572
+ ["==", ["get", "id"], this._parent.picture], "",
573
+ ["==", ["get", "type"], "equirectangular"], "pnx-arrow-360",
574
+ "pnx-arrow-flat"
593
575
  ],
594
576
  "symbol-sort-key": this._getLayerSortStyle(layer),
595
577
  },
@@ -614,6 +596,7 @@ export default class Map extends maplibregl.Map {
614
596
  /**
615
597
  * Retrieve map layer color scheme according to selected theme.
616
598
  * @private
599
+ * @memberof Panoramax.components.ui.Map#
617
600
  */
618
601
  _getLayerColorStyle(layer) {
619
602
  // Hidden style
@@ -623,7 +606,7 @@ export default class Map extends maplibregl.Map {
623
606
  ];
624
607
 
625
608
  // Selected sequence style
626
- const seqId = this._parent._selectedSeqId;
609
+ const seqId = this._parent.sequence;
627
610
  if(layer == "sequences" && seqId) {
628
611
  s.push(["==", ["get", "id"], seqId], COLORS.SELECTED);
629
612
  }
@@ -640,6 +623,7 @@ export default class Map extends maplibregl.Map {
640
623
  /**
641
624
  * Retrieve map sort key according to selected theme.
642
625
  * @private
626
+ * @memberof Panoramax.components.ui.Map#
643
627
  */
644
628
  _getLayerSortStyle(layer) {
645
629
  // Values
@@ -654,7 +638,7 @@ export default class Map extends maplibregl.Map {
654
638
  ];
655
639
 
656
640
  // Selected sequence style
657
- const seqId = this._parent._selectedSeqId;
641
+ const seqId = this._parent.sequence;
658
642
  if(layer == "sequences" && seqId) {
659
643
  s.push(["==", ["get", "id"], seqId], 100);
660
644
  }
@@ -671,6 +655,7 @@ export default class Map extends maplibregl.Map {
671
655
  * @private
672
656
  * @param {object} e The event thrown by MapLibre
673
657
  * @param {string} from The event source layer
658
+ * @memberof Panoramax.components.ui.Map#
674
659
  */
675
660
  _attachPreviewToPictures(e, from) {
676
661
  let f = e.features.pop();
@@ -720,7 +705,7 @@ export default class Map extends maplibregl.Map {
720
705
 
721
706
  if(thumbUrl) {
722
707
  let content = document.createElement("img");
723
- content.classList.add("gvs-map-thumb");
708
+ content.classList.add("pnx-map-thumb");
724
709
  content.alt = this._parent._t.map.thumbnail;
725
710
  let img = new Image();
726
711
  img.src = thumbUrl;
@@ -737,7 +722,7 @@ export default class Map extends maplibregl.Map {
737
722
 
738
723
  if(f.properties.hidden) {
739
724
  const legend = document.createElement("div");
740
- legend.classList.add("gvs-map-thumb-legend");
725
+ legend.classList.add("pnx-map-thumb-legend");
741
726
  legend.appendChild(document.createTextNode(this._parent._t.map.not_public));
742
727
  const container = document.createElement("div");
743
728
  container.appendChild(content);
@@ -772,11 +757,12 @@ export default class Map extends maplibregl.Map {
772
757
  * @param {LngLat} coordinates The map coordinates
773
758
  * @returns {Promise} Promise resolving on picture thumbnail URL, or null on timeout
774
759
  * @private
760
+ * @memberof Panoramax.components.ui.Map#
775
761
  */
776
762
  _getThumbURL(coordinates) {
777
- return this._parent._api.getPicturesAroundCoordinates(coordinates[1], coordinates[0], 0.1, 1).then(res => {
763
+ return this._parent.api.getPicturesAroundCoordinates(coordinates[1], coordinates[0], 0.1, 1).then(res => {
778
764
  const p = res?.features?.pop();
779
- return p ? this._parent._api.findThumbnailInPictureFeature(p) : null;
765
+ return p ? this._parent.api.findThumbnailInPictureFeature(p) : null;
780
766
  });
781
767
  }
782
768
 
@@ -788,21 +774,22 @@ export default class Map extends maplibregl.Map {
788
774
  * @param {LngLat} [coordinates] The map coordinates
789
775
  * @returns {Promise} Promise resolving on picture thumbnail URL, or null on timeout
790
776
  * @private
777
+ * @memberof Panoramax.components.ui.Map#
791
778
  */
792
779
  _getSequenceThumbURL(seqId, coordinates) {
793
780
  if(coordinates) {
794
- return this._parent._api.getPicturesAroundCoordinates(coordinates.lat, coordinates.lng, 1, 1, seqId)
781
+ return this._parent.api.getPicturesAroundCoordinates(coordinates.lat, coordinates.lng, 1, 1, seqId)
795
782
  .then(results => {
796
783
  if(results?.features?.length > 0) {
797
- return this._parent._api.findThumbnailInPictureFeature(results.features[0]);
784
+ return this._parent.api.findThumbnailInPictureFeature(results.features[0]);
798
785
  }
799
786
  else {
800
- return this._parent._api.getPictureThumbnailURLForSequence(seqId);
787
+ return this._parent.api.getPictureThumbnailURLForSequence(seqId);
801
788
  }
802
789
  });
803
790
  }
804
791
  else {
805
- return this._parent._api.getPictureThumbnailURLForSequence(seqId);
792
+ return this._parent.api.getPictureThumbnailURLForSequence(seqId);
806
793
  }
807
794
  }
808
795
 
@@ -813,7 +800,7 @@ export default class Map extends maplibregl.Map {
813
800
  * @param {string} picId The picture ID
814
801
  * @param {string} [seqId] The sequence ID (can speed up search if available)
815
802
  * @returns {Promise} Promise resolving on picture thumbnail URL, or null on timeout
816
- *
803
+ * @memberof Panoramax.components.ui.Map#
817
804
  * @private
818
805
  */
819
806
  _getPictureThumbURL(picId, seqId) {
@@ -824,7 +811,7 @@ export default class Map extends maplibregl.Map {
824
811
  res = typeof this._picThumbUrl[picId] === "string" ? Promise.resolve(this._picThumbUrl[picId]) : this._picThumbUrl[picId];
825
812
  }
826
813
  else {
827
- this._picThumbUrl[picId] = this._parent._api.getPictureThumbnailURL(picId, seqId).then(url => {
814
+ this._picThumbUrl[picId] = this._parent.api.getPictureThumbnailURL(picId, seqId).then(url => {
828
815
  if(url) {
829
816
  this._picThumbUrl[picId] = url;
830
817
  return url;
@@ -849,6 +836,7 @@ export default class Map extends maplibregl.Map {
849
836
  *
850
837
  * @returns {maplibregl.Marker} The generated marker
851
838
  * @private
839
+ * @memberof Panoramax.components.ui.Map#
852
840
  */
853
841
  _getPictureMarker(selected = true) {
854
842
  const img = document.createElement("img");
@@ -863,6 +851,7 @@ export default class Map extends maplibregl.Map {
863
851
  * Event handler for sequence hover
864
852
  * @private
865
853
  * @param {object} e Event data
854
+ * @memberof Panoramax.components.ui.Map#
866
855
  */
867
856
  _onSequenceHover(e) {
868
857
  e.preventDefault();
@@ -870,17 +859,11 @@ export default class Map extends maplibregl.Map {
870
859
  /**
871
860
  * Event when a sequence on map is hovered (not selected)
872
861
  *
873
- * @event map:sequence-hover
874
- * @memberof CoreView
875
- * @type {object}
876
- * @property {object} detail Event information
877
- * @property {string} detail.seqId The hovered sequence ID
862
+ * @event Panoramax.components.ui.Map#sequence-hover
863
+ * @type {maplibregl.util.evented.Event}
864
+ * @property {string} seqId The hovered sequence ID
878
865
  */
879
- this._parent.dispatchEvent(new CustomEvent("map:sequence-hover", {
880
- detail: {
881
- seqId: e.features[0].properties.id
882
- }
883
- }));
866
+ this.fire("sequence-hover", { seqId: e.features[0].properties.id });
884
867
  }
885
868
  }
886
869
 
@@ -888,26 +871,22 @@ export default class Map extends maplibregl.Map {
888
871
  * Event handler for sequence click
889
872
  * @private
890
873
  * @param {object} e Event data
874
+ * @memberof Panoramax.components.ui.Map#
891
875
  */
892
876
  _onSequenceClick(e) {
893
877
  e.preventDefault();
894
878
  if(e.features.length > 0 && e.features[0].properties?.id) {
895
879
  /**
896
880
  * Event when a sequence on map is clicked
897
- *
898
- * @event map:sequence-click
899
- * @memberof CoreView
900
- * @type {object}
901
- * @property {object} detail Event information
902
- * @property {string} detail.seqId The clicked sequence ID
903
- * @property {maplibregl.LngLat} detail.coordinates The coordinates of user click
881
+ * @event Panoramax.components.ui.Map#sequence-click
882
+ * @type {maplibregl.util.evented.Event}
883
+ * @property {string} seqId The clicked sequence ID
884
+ * @property {maplibregl.LngLat} coordinates The coordinates of user click
904
885
  */
905
- this._parent.dispatchEvent(new CustomEvent("map:sequence-click", {
906
- detail: {
907
- seqId: e.features[0].properties.id,
908
- coordinates: e.lngLat
909
- }
910
- }));
886
+ this.fire("sequence-click", {
887
+ seqId: e.features[0].properties.id,
888
+ coordinates: e.lngLat
889
+ });
911
890
  }
912
891
  }
913
892
 
@@ -915,6 +894,7 @@ export default class Map extends maplibregl.Map {
915
894
  * Event handler for picture click
916
895
  * @private
917
896
  * @param {object} e Event data
897
+ * @memberof Panoramax.components.ui.Map#
918
898
  */
919
899
  _onPictureClick(e) {
920
900
  e.preventDefault();
@@ -935,21 +915,17 @@ export default class Map extends maplibregl.Map {
935
915
  /**
936
916
  * Event when a picture on map is clicked
937
917
  *
938
- * @event map:picture-click
939
- * @memberof CoreView
940
- * @type {object}
941
- * @property {object} detail Event information
942
- * @property {string} detail.picId The clicked picture ID
943
- * @property {string} detail.seqId The clicked picture's sequence ID
944
- * @property {object} detail.feature The GeoJSON feature of the picture
918
+ * @event Panoramax.components.ui.Map#picture-click
919
+ * @type {maplibregl.util.evented.Event}
920
+ * @property {string} picId The clicked picture ID
921
+ * @property {string} seqId The clicked picture's sequence ID
922
+ * @property {object} feature The GeoJSON feature of the picture
945
923
  */
946
- this._parent.dispatchEvent(new CustomEvent("map:picture-click", {
947
- detail: {
948
- picId: f.properties.id,
949
- seqId,
950
- feature: f
951
- }
952
- }));
924
+ this.fire("picture-click", {
925
+ picId: f.properties.id,
926
+ seqId,
927
+ feature: f
928
+ });
953
929
  }
954
930
  }
955
931
  }