@panoramax/web-viewer 5.1.0-develop-e8b88add → 5.1.0-develop-876a76e8

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.
@@ -9,7 +9,7 @@ import BasicStyles from "./Basic.css" with { type: "css" };
9
9
  document.adoptedStyleSheets.push(AtkinsonStyles);
10
10
  document.adoptedStyleSheets.push(BasicStyles);
11
11
 
12
- const __COMMIT_HASH__ = "e8b88ad";
12
+ const __COMMIT_HASH__ = "876a76e";
13
13
  const __PACKAGE_VERSION__ = "5.1.0";
14
14
  const __PACKAGE_ISSUES_URL__ = "https://gitlab.com/panoramax/clients/web-viewer/-/work_items";
15
15
 
@@ -168,6 +168,8 @@ export default class CoverageMap extends Basic {
168
168
  if(features.length >= 0 && features[0] != null) {
169
169
  this.map._attachPreviewToPictures({ features }, layer);
170
170
  }
171
+ } else {
172
+ this.map._dropPreview();
171
173
  }
172
174
  }
173
175
  }
@@ -24,6 +24,7 @@ maplibregl.addProtocol("panoras", new PanoraMapProtocol().tile());
24
24
 
25
25
  const MarkerBaseSVG = await fetch(new URL("../../img/marker.svg", import.meta.url).href).then(res => res.text());
26
26
  const MarkerSelectedSVG = await fetch(new URL("../../img/marker_blue.svg", import.meta.url).href).then(res => res.text());
27
+ const MarkerPinSVG = await fetch(new URL("../../img/pin.svg", import.meta.url).href).then(res => res.text());
27
28
 
28
29
 
29
30
  /**
@@ -52,6 +53,7 @@ const MarkerSelectedSVG = await fetch(new URL("../../img/marker_blue.svg", impor
52
53
  * @param {object} [options.indoor] The indoor= MapLibre plugin options. This must be a JSON object following [IndoorEqual parameters](https://indoorequal.com/doc/maplibre-gl-indoorequal/api#parameters). Note that this is only available if [maplibre-gl-indoorequal](https://indoorequal.com/doc/maplibre-gl-indoorequal) plugin is loaded in your web page.
53
54
  * @param {string} [options.indoor.level] (only if indoor= plugin is enabled) The initial indoor level to display. Defaults to ground or disabled depending on indoor map availability. Do not use if visible=false.
54
55
  * @param {boolean} [options.indoor.visible=true] (only if indoor= plugin is enabled) The initial indoor visibility. Set to false to avoid data loading before user explicitly enables indoor through widgets. If set to false, you may not set any level option in component.
56
+ * @param {string} [options.preview=thumb] Change kind of preview for picture/sequence selection (thumb (default), marker, none)
55
57
  * @fires Panoramax.components.ui.Map#sequence-hover
56
58
  * @fires Panoramax.components.ui.Map#sequence-click
57
59
  * @fires Panoramax.components.ui.Map#picture-click
@@ -203,6 +205,7 @@ export default class Map extends maplibregl.Map {
203
205
  delete this._picPopup._loading;
204
206
  this._picPopup.remove();
205
207
  this._picMarkerPreview.remove();
208
+ this._picPinMarker?.remove?.();
206
209
  }
207
210
  }
208
211
 
@@ -222,6 +225,7 @@ export default class Map extends maplibregl.Map {
222
225
  delete this._picPopup;
223
226
  delete this._picThumbUrl;
224
227
  delete this._seqPictures;
228
+ delete this._picPinMarker;
225
229
  }
226
230
 
227
231
  /**
@@ -397,6 +401,7 @@ export default class Map extends maplibregl.Map {
397
401
  */
398
402
  displayPictureMarker(lon, lat, heading, skipCenter = false, picId = null) {
399
403
  this._picMarkerPreview.remove();
404
+ this._picPinMarker?.remove?.();
400
405
 
401
406
  // Show marker corresponding to selection
402
407
  if(lon !== undefined && lat !== undefined) {
@@ -496,8 +501,12 @@ export default class Map extends maplibregl.Map {
496
501
  */
497
502
  _attachPreviewToPictures(e, from) {
498
503
  let f = e.features.pop();
504
+ if(!f) {
505
+ this._picPinMarker?.remove?.();
506
+ return;
507
+ }
499
508
  // eslint-disable-next-line eqeqeq
500
- if(!f || f.properties.id == this._picPopup._picId) { return; }
509
+ else if(f.properties.id == this._picPopup._picId) { return; }
501
510
 
502
511
  clearTimeout(this._picPreviewTimer);
503
512
  clearTimeout(this._picDropPreviewTimer);
@@ -551,9 +560,28 @@ export default class Map extends maplibregl.Map {
551
560
  */
552
561
 
553
562
  let thumbCoords = picPreview ? picPreview.geometry.coordinates : e.lngLat;
554
- this._picPopup
555
- .setLngLat(thumbCoords)
556
- .addTo(this);
563
+ if(this._options.preview === "thumb") {
564
+ this._picPopup
565
+ .setLngLat(thumbCoords)
566
+ .addTo(this);
567
+ } else if(this._options.preview === "marker") {
568
+ // Only show if no marker preview showing up
569
+ if(!picPreview || picPreview.properties.heading === undefined) {
570
+ if(!this._picPinMarker) {
571
+ const imgsvg = svgToImg(MarkerPinSVG);
572
+ imgsvg.style.width = "40px";
573
+ // eslint-disable-next-line no-undef
574
+ this._picPinMarker = new maplibregl.Marker({
575
+ element: imgsvg,
576
+ anchor: "bottom",
577
+ offset: [0,10],
578
+ });
579
+ }
580
+ this._picPinMarker
581
+ .setLngLat(thumbCoords)
582
+ .addTo(this);
583
+ }
584
+ }
557
585
 
558
586
  // Only show GIF loader if thumbnail is not in browser cache
559
587
  if(!picPreview && !this._picThumbUrl[f.properties.id]) {
@@ -561,6 +589,8 @@ export default class Map extends maplibregl.Map {
561
589
  }
562
590
 
563
591
  const displayThumb = thumbUrl => {
592
+ if(this._options.preview !== "thumb") { return; }
593
+
564
594
  if(this._picPopup._loading === f.properties.id) {
565
595
  if(thumbUrl) {
566
596
  let content = document.createElement("img");
@@ -609,6 +639,7 @@ export default class Map extends maplibregl.Map {
609
639
  clearTimeout(this._picPreviewTimer);
610
640
  this._picPreviewTimer = setTimeout(() => {
611
641
  if(this._picPopup._loading !== f.properties.id) { return; }
642
+ if(this._options.preview !== "thumb") { return; }
612
643
 
613
644
  // Hover on a single picture
614
645
  if(picPreview) {
@@ -200,17 +200,22 @@ export default class Photo extends PSViewer {
200
200
  * @returns {Promise} Resolves on PSV node metadata
201
201
  * @memberof Panoramax.components.ui.Photo#
202
202
  */
203
- async _getNodeFromAPI(picId) {
203
+ async _getNodeFromAPI(picId, forceFromLocalAPI = false) {
204
204
  if(isNullId(picId)) { return BASE_PANORAMA_NODE; }
205
205
 
206
+ const api = forceFromLocalAPI ? this._parent.api : this._parent.getAPI();
206
207
  const picApiResponse = await fetch(
207
- this._parent.getAPI().getPictureMetadataUrl(picId, this._picturesSequences[picId]),
208
- this._parent.getAPI()._getFetchOptions()
208
+ api.getPictureMetadataUrl(picId, this._picturesSequences[picId]),
209
+ api._getFetchOptions()
209
210
  );
210
211
  let metadata = await picApiResponse.json();
211
212
 
212
213
  if(metadata.features) { metadata = metadata.features.pop(); }
213
214
  if(!metadata || Object.keys(metadata).length === 0 || !picApiResponse.ok) {
215
+ if(this._parent.hasTwoAPIs?.() && !forceFromLocalAPI) {
216
+ console.log("Failed to find picture on metacatalog, check local API");
217
+ return await this._getNodeFromAPI(picId, true);
218
+ }
214
219
  throw new Error("Picture with ID " + picId + " was not found");
215
220
  }
216
221
 
@@ -0,0 +1,77 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+
4
+ <svg
5
+ version="1.1"
6
+ id="Capa_1"
7
+ x="0px"
8
+ y="0px"
9
+ width="32"
10
+ height="32"
11
+ viewBox="0 0 32 32"
12
+ xml:space="preserve"
13
+ xmlns:xlink="http://www.w3.org/1999/xlink"
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
16
+ id="defs19"><linearGradient
17
+ y2="195.90816"
18
+ x2="212.88858"
19
+ y1="98.091812"
20
+ x1="382.31149"
21
+ gradientUnits="userSpaceOnUse"
22
+ id="SVGID_1_"
23
+ gradientTransform="matrix(4.4379641,0,0,4.4379641,-886.70524,-217.09784)"
24
+ spreadMethod="pad">
25
+ <stop
26
+ id="stop4"
27
+ style="stop-color:#8F2A85"
28
+ offset="0" />
29
+ <stop
30
+ id="stop6"
31
+ style="stop-color:#2570B6"
32
+ offset="1" />
33
+ </linearGradient><linearGradient
34
+ xlink:href="#SVGID_1_"
35
+ id="linearGradient27"
36
+ x1="30.55006"
37
+ y1="29.297422"
38
+ x2="17.272936"
39
+ y2="8.0495806"
40
+ gradientUnits="userSpaceOnUse"
41
+ gradientTransform="matrix(0.66910611,0,0,0.66910611,0,1.2499974)" /></defs>
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+ <circle
58
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:5.30813;stroke-linecap:square;stroke-linejoin:round;paint-order:markers stroke fill"
59
+ id="path3"
60
+ cx="15.999331"
61
+ cy="9.2110214"
62
+ r="4.1819134" /><path
63
+ d="m 24.381558,9.7115132 c 0,-4.6295451 -3.752348,-8.3818922 -8.382562,-8.3818922 -4.630214,0 -8.381892,3.7523471 -8.381892,8.3818922 0,6.6328488 8.381892,16.4479668 8.381892,16.4479668 0,0 8.382562,-9.849242 8.382562,-16.4479668 z M 11.865259,9.2110219 c 0,-2.2836592 1.851416,-4.1344067 4.134406,-4.1344067 2.28299,0 4.134407,1.8507475 4.134407,4.1344067 0,2.2836591 -1.851417,4.1344071 -4.134407,4.1344071 -2.28299,0 -4.134406,-1.850748 -4.134406,-4.1344071 z"
64
+ fill="#006df0"
65
+ id="path1"
66
+ style="fill:url(#linearGradient27);stroke-width:0.414563;stroke-dasharray:none" /><circle
67
+ cx="15.998996"
68
+ cy="9.2110214"
69
+ r="2.0327444"
70
+ fill="#006df0"
71
+ id="circle1"
72
+ style="fill:url(#SVGID_1_);stroke-width:0.414543" /><path
73
+ d="m 20.738275,20.743521 c -0.683158,0.9876 -1.324161,1.847402 -1.858108,2.537919 5.296644,0.318495 8.767967,1.461997 10.059341,2.312431 -1.512849,0.997637 -6.007903,2.400083 -12.939174,2.400083 -6.9306007,0 -11.4263246,-1.403115 -12.9391735,-2.400083 1.2913747,-0.850434 4.7600208,-1.993267 10.0513115,-2.311762 -0.535284,-0.690517 -1.176957,-1.54965 -1.860784,-2.53725 C 4.7339257,21.386532 0,23.314895 0,25.593202 0,28.396756 7.1641191,30.670379 16.000334,30.670379 24.837219,30.670379 32,28.398095 32,25.593202 32.0013,23.313557 27.262059,21.384524 20.738275,20.743521 Z"
74
+ fill="#006df0"
75
+ id="path2"
76
+ style="fill:#8f2a85;fill-opacity:1;stroke-width:0.414543" />
77
+ </svg>
@@ -85,6 +85,7 @@ export default class InitParameters {
85
85
  let map_basemaps = componentMap.basemaps;
86
86
  let map_indoor = componentMap.indoor;
87
87
  let map_attribution = componentMap.attributionControl;
88
+ let map_preview = componentMap.preview;
88
89
  let map_others = filterMapLibreOptions(componentMap);
89
90
  let keyboardShortcuts = componentAttrs["keyboard-shortcuts"];
90
91
  let skipTagsMenuOpening = componentAttrs["skip-tags-menu-opening"];
@@ -131,6 +132,12 @@ export default class InitParameters {
131
132
  // Related to https://gitlab.com/panoramax/clients/web-viewer/-/issues/347
132
133
  console.error("Parameter annot can only be used in combination with 'picture'");
133
134
  }
135
+ if(!["thumb", "marker", "none"].includes(map_preview)) {
136
+ if(map_preview && map_preview.length > 0) {
137
+ console.warn("Parameter map-options.preview is invalid, should be 'thumb', 'marker' or 'none'");
138
+ }
139
+ map_preview = "thumb";
140
+ }
134
141
 
135
142
  // Put all attributes in appropriate container
136
143
  this._parentInit = { map, fetchOptions, style, lang, endpoint };
@@ -163,6 +170,7 @@ export default class InitParameters {
163
170
  indoor: map_indoor,
164
171
  attributionControl: map_attribution,
165
172
  basemaps: map_basemaps,
173
+ preview: map_preview,
166
174
  ...map_others
167
175
  };
168
176
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoramax/web-viewer",
3
- "version": "5.1.0-develop-e8b88add",
3
+ "version": "5.1.0-develop-876a76e8",
4
4
  "description": "Panoramax web viewer for geolocated pictures",
5
5
  "main": "./build/cjs/index.js",
6
6
  "module": "./build/esm/index.js",