@panoramax/web-viewer 3.2.3-develop-72318485 → 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/CHANGELOG.md +1 -0
- package/build/index.js +5 -5
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/core/Viewer.js +8 -3
- package/src/components/menus/PictureLegend.js +17 -9
- package/src/components/ui/SearchBar.js +4 -2
- package/src/translations/da.json +7 -3
- package/src/utils/geocoder.js +66 -32
- package/tests/utils/__snapshots__/geocoder.test.js.snap +1 -1
package/package.json
CHANGED
|
@@ -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(() =>
|
|
300
|
-
this.psv.
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
|
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),
|
|
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 = [];
|
package/src/translations/da.json
CHANGED
|
@@ -164,9 +164,11 @@
|
|
|
164
164
|
"qualityscore_title": "Om kvalitetsscoren",
|
|
165
165
|
"qualityscore_doc_2": "Bedømmelsen vises for brugerne som en A/B/C/D/E-score (A er den bedste, E den dårligste) og vises grafisk via denne skala:",
|
|
166
166
|
"qualityscore_doc_3": "Den beregnes ud fra GPS-præcision og billedopløsning. Et professionelt system vil have en A-rating, et 360° actionkamera vil have en B-rating, og en smartphone vil have en C/D/E-rating.",
|
|
167
|
-
"qualityscore_doc_link": "Yderligere oplysninger om
|
|
167
|
+
"qualityscore_doc_link": "Yderligere oplysninger om kvalitetsscoren",
|
|
168
168
|
"qualityscore_doc_1": "Panoramax tilbyder en kvalitetsscore for hvert billede. Det giver mulighed for nem kortfiltrering og overskuelig visning af tilgængelige billeder af høj kvalitet.",
|
|
169
|
-
"minimize_short": "Skjul"
|
|
169
|
+
"minimize_short": "Skjul",
|
|
170
|
+
"id": "iD",
|
|
171
|
+
"josm": "JOSM"
|
|
170
172
|
},
|
|
171
173
|
"psv": {
|
|
172
174
|
"loadError": "Panoramaet kan ikke indlæses",
|
|
@@ -177,6 +179,8 @@
|
|
|
177
179
|
"loading": "Indlæser…",
|
|
178
180
|
"thumbnail": "Miniature af billedet, der holdes",
|
|
179
181
|
"not_public": "Ikke offentligt synlig",
|
|
180
|
-
"slow_loading": "Kortet indlæses langsomt og kan virke defekt"
|
|
182
|
+
"slow_loading": "Kortet indlæses langsomt og kan virke defekt",
|
|
183
|
+
"map_data": "Kortdata:",
|
|
184
|
+
"more_panoramax": "Få mere at vide om Panoramax"
|
|
181
185
|
}
|
|
182
186
|
}
|
package/src/utils/geocoder.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
105
|
+
place_name: plname,
|
|
44
106
|
bounds: new maplibregl.LngLatBounds(f.bbox),
|
|
45
107
|
});
|
|
46
|
-
listedNames.push(
|
|
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
|
/**
|