@panoramax/web-viewer 3.2.3-develop-7f50ae7f → 3.2.3-develop-54fea60b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoramax/web-viewer",
3
- "version": "3.2.3-develop-7f50ae7f",
3
+ "version": "3.2.3-develop-54fea60b",
4
4
  "description": "Panoramax web viewer for geolocated pictures",
5
5
  "main": "build/index.js",
6
6
  "author": "Panoramax team",
@@ -296,9 +296,14 @@ export default class Viewer extends Basic {
296
296
  * @memberof Panoramax.components.core.Viewer#
297
297
  */
298
298
  onceFirstPicLoaded() {
299
- return this.oncePSVReady().then(() => new Promise(resolve => {
300
- this.psv.addEventListener("picture-loaded", resolve, {once: true});
301
- }));
299
+ return this.oncePSVReady().then(() => {
300
+ if(this.psv.getPictureMetadata()) { return Promise.resolve(); }
301
+ else {
302
+ return new Promise(resolve => {
303
+ this.psv.addEventListener("picture-loaded", resolve, {once: true});
304
+ });
305
+ }
306
+ });
302
307
  }
303
308
 
304
309
  /** @private */
@@ -49,6 +49,8 @@ export default class PictureLegend extends LitElement {
49
49
  connectedCallback() {
50
50
  super.connectedCallback();
51
51
 
52
+ this._prevSearches = {};
53
+
52
54
  this._parent.onceReady().then(() => {
53
55
  this._onPicChange(this._parent.psv.getPictureMetadata());
54
56
  this._parent.psv.addEventListener("picture-loaded", () => {
@@ -63,15 +65,21 @@ export default class PictureLegend extends LitElement {
63
65
  this._caption = picMeta?.caption;
64
66
 
65
67
  if(picMeta) {
66
- this._addrTimer1 = setTimeout(() => {
67
- this._addrTimer2 = setTimeout(() => this._addr = "", 500);
68
-
69
- reverseGeocodingNominatim(picMeta.gps[1], picMeta.gps[0])
70
- .then(addr => {
71
- clearTimeout(this._addrTimer2);
72
- this._addr = addr;
73
- });
74
- }, 500);
68
+ const coordsHash = `${picMeta.gps[0]}/${picMeta.gps[1]}`;
69
+ if(this._prevSearches[coordsHash]) {
70
+ this._addr = this._prevSearches[coordsHash];
71
+ }
72
+ else {
73
+ this._addrTimer2 = setTimeout(() => this._addr = "", 250);
74
+ this._addrTimer1 = setTimeout(() => {
75
+ reverseGeocodingNominatim(picMeta.gps[1], picMeta.gps[0])
76
+ .then(addr => {
77
+ clearTimeout(this._addrTimer2);
78
+ this._addr = addr;
79
+ this._prevSearches[coordsHash] = addr;
80
+ });
81
+ }, 750);
82
+ }
75
83
  }
76
84
  else {
77
85
  this._addr = "";
@@ -246,7 +246,7 @@ export default class SearchBar extends LitElement {
246
246
  }
247
247
 
248
248
  /**
249
- * Limit search calls to every 250ms
249
+ * Limit search calls to every 500ms
250
250
  * @private
251
251
  */
252
252
  _throttledSearch() {
@@ -255,7 +255,7 @@ export default class SearchBar extends LitElement {
255
255
  delete this._throttler;
256
256
  }
257
257
 
258
- this._throttler = setTimeout(this._search.bind(this), 250);
258
+ this._throttler = setTimeout(this._search.bind(this), 500);
259
259
  }
260
260
 
261
261
  /**
@@ -277,6 +277,8 @@ export default class SearchBar extends LitElement {
277
277
  this._results = null;
278
278
 
279
279
  this.searcher(this.value).then(data => {
280
+ if(this._icon !== "loading") { return; }
281
+
280
282
  this._icon = "empty";
281
283
  if(!data || data.length == 0) {
282
284
  this._results = [];
@@ -18,6 +18,67 @@ function geocoderParamsToURLString(params) {
18
18
  return new URLSearchParams(p).toString();
19
19
  }
20
20
 
21
+ /**
22
+ * Transforms Nominatim search result into a nice-to-display address.
23
+ * @param {object} addr The Nominatim API "address" property
24
+ * @returns {string} The clean-up string for display
25
+ * @private
26
+ */
27
+ function nominatimAddressToPlaceName(addr) {
28
+ // API format @ https://nominatim.org/release-docs/develop/api/Output/#addressdetails
29
+ if(!addr || typeof addr != "object") { return ""; }
30
+
31
+ let res = "";
32
+
33
+ // House n°-like
34
+ if(addr.house_number) { res = addr.house_number; }
35
+ else if(addr.house_name) { res = addr.house_name; }
36
+ else {
37
+ const potentialNames = [
38
+ "emergency", "historic", "military", "natural", "landuse", "place", "railway", "man_made",
39
+ "aerialway", "boundary", "amenity", "aeroway", "club", "craft", "leisure", "office",
40
+ "mountain_pass", "shop", "tourism", "bridge", "tunnel", "waterway", "park"
41
+ ];
42
+ for(let pn of potentialNames) {
43
+ if(addr[pn]) {
44
+ res = addr[pn];
45
+ break;
46
+ }
47
+ }
48
+ }
49
+
50
+ // Street-like
51
+ let street;
52
+ if(addr.road && addr.road.length > 6) { street = addr.road; }
53
+ else {
54
+ const potentialNames = [
55
+ // Hamlet-like
56
+ "hamlet", "croft", "isolated_dwelling",
57
+ // Zone Indus-like
58
+ "farm", "farmyard", "industrial", "commercial", "retail", "city_block", "residential",
59
+ // Quarter-like
60
+ "neighbourhood", "allotments", "quarter"
61
+ ];
62
+ for(let pn of potentialNames) {
63
+ if(addr[pn]) {
64
+ street = addr[pn];
65
+ break;
66
+ }
67
+ }
68
+ }
69
+
70
+ if(street && res.length > 0) { res += (addr.house_number ? " " : ", ")+street; }
71
+ else if(street) { res = street; }
72
+
73
+ // City
74
+ if(addr.village || addr.town || addr.city || addr.municipality) {
75
+ if(res.length > 0) { res += ", "; }
76
+ res += addr.village || addr.town || addr.city || addr.municipality;
77
+ }
78
+
79
+ return res;
80
+ }
81
+
21
82
  /**
22
83
  * Nominatim (OSM) geocoder, ready to use for our Map
23
84
  * @private
@@ -37,13 +98,14 @@ export function forwardGeocodingNominatim(config) {
37
98
  const finalRes = { features: [] };
38
99
  const listedNames = [];
39
100
  res.features.forEach(f => {
40
- if(!listedNames.includes(f.properties.display_name)) {
101
+ const plname = nominatimAddressToPlaceName(f.properties.address) || f.properties.display_name;
102
+ if(!listedNames.includes(plname)) {
41
103
  finalRes.features.push({
42
104
  place_type: ["place"],
43
- place_name: f.properties.display_name,
105
+ place_name: plname,
44
106
  bounds: new maplibregl.LngLatBounds(f.bbox),
45
107
  });
46
- listedNames.push(f.properties.display_name);
108
+ listedNames.push(plname);
47
109
  }
48
110
  });
49
111
  return finalRes;
@@ -53,35 +115,7 @@ export function forwardGeocodingNominatim(config) {
53
115
  export function reverseGeocodingNominatim(lat, lon) {
54
116
  return fetch(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&zoom=18&format=jsonv2`)
55
117
  .then(res => res.json())
56
- .then(res => {
57
- let addr = "";
58
-
59
- if(res?.address) {
60
- if(res.address.house_number) { addr = res.address.house_number; }
61
-
62
- // Street/place/hamlet
63
- let street;
64
- if(res.address.road && res.address.road.length > 6) {
65
- street = res.address.road;
66
- }
67
- else if(res.address.hamlet) {
68
- street = res.address.hamlet;
69
- }
70
- else if(res.address.isolated_dwelling) {
71
- street = res.address.isolated_dwelling;
72
- }
73
- if(street && addr.length > 0) { addr += " "+street; }
74
- else if(street) { addr = street; }
75
-
76
- // City
77
- if(res.address.village || res.address.town || res.address.city) {
78
- if(addr.length > 0) { addr += ", "; }
79
- addr += res.address.village || res.address.town || res.address.city;
80
- }
81
- }
82
-
83
- return addr;
84
- });
118
+ .then(res => nominatimAddressToPlaceName(res?.address));
85
119
  }
86
120
 
87
121
  /**
@@ -38,7 +38,7 @@ Object {
38
38
  "lng": -1.7,
39
39
  },
40
40
  },
41
- "place_name": "Paris, Île-de-France, France métropolitaine, France",
41
+ "place_name": "Paris",
42
42
  "place_type": Array [
43
43
  "place",
44
44
  ],