]> git.openstreetmap.org Git - nominatim-ui.git/blob - src/lib/helpers.js
make LastUpdated a Svelte component (#56)
[nominatim-ui.git] / src / lib / helpers.js
1 module.exports.formatOSMType = formatOSMType;
2 module.exports.formatShortOSMType = formatShortOSMType;
3 module.exports.osmLink = osmLink;
4 module.exports.formatLabel = formatLabel;
5 module.exports.detailsURL = detailsURL;
6 module.exports.wikipediaLink = wikipediaLink;
7 module.exports.coverageType = coverageType;
8 module.exports.isAdminBoundary = isAdminBoundary;
9 module.exports.formatAddressRank = formatAddressRank;
10 module.exports.formatPlaceType = formatPlaceType;
11 module.exports.formatAdminLevel = formatAdminLevel;
12 module.exports.formatDistance = formatDistance;
13 module.exports.formatKeywordToken = formatKeywordToken;
14 module.exports.zoomLevels = zoomLevels;
15
16 const escapeHtml = require('escape-html');
17
18 function formatOSMType(sType, bExcludeExternal) {
19   if (sType === 'N') return 'node';
20   if (sType === 'W') return 'way';
21   if (sType === 'R') return 'relation';
22
23   if (!bExcludeExternal) return '';
24
25   if (sType === 'T') return 'way';
26   if (sType === 'I') return 'way';
27
28   return '';
29 }
30
31 function formatShortOSMType(sType) {
32   if (sType === 'node') return 'N';
33   if (sType === 'way') return 'W';
34   if (sType === 'relation') return 'R';
35   return '';
36 }
37
38 function osmLink(aPlace) {
39   if (!aPlace.osm_type) return '';
40   var sOSMType = formatOSMType(aPlace.osm_type, false);
41   if (!sOSMType) return '';
42
43   return '<a href="https://www.openstreetmap.org/' + sOSMType + '/' + aPlace.osm_id + '">' + sOSMType + ' ' + aPlace.osm_id + '</a>';
44 }
45
46 function formatLabel(aPlace) {
47   if (aPlace.label) return aPlace.label;
48
49   function capitalize(s) {
50     return s && s[0].toUpperCase() + s.slice(1);
51   }
52
53   if (aPlace.type && aPlace.type === 'yes' && aPlace.class) {
54     return capitalize(aPlace.class.replace(/_/g, ' '));
55   }
56   if (aPlace.type) {
57     return capitalize(aPlace.type.replace(/_/g, ' '));
58   }
59   return '';
60 }
61
62 // 'details.html?osmtype=R&osmid=2181874&class=boundary'
63 function detailsURL(aFeature) {
64   if (!aFeature) return '';
65
66   var sOSMType = aFeature.osm_type;
67   if (sOSMType && sOSMType.length !== 1) {
68     sOSMType = formatShortOSMType(aFeature.osm_type, false); // node => N
69   }
70   if (!sOSMType) return '';
71
72   var sURL = 'details.html?osmtype=' + sOSMType + '&osmid=' + aFeature.osm_id;
73   if (aFeature.class) {
74     sURL = sURL + '&class=' + encodeURIComponent(aFeature.class);
75   } else if (aFeature.category) {
76     sURL = sURL + '&class=' + encodeURIComponent(aFeature.category);
77   }
78   return sURL;
79 }
80
81 /* en:London_Borough_of_Redbridge => https://en.wikipedia.org/wiki/London_Borough_of_Redbridge */
82 function wikipediaLink(aPlace) {
83   if (!aPlace.calculated_wikipedia) return '';
84
85   var parts = aPlace.calculated_wikipedia.split(':', 2);
86
87   var sTitle = escapeHtml(aPlace.calculated_wikipedia);
88   var sLanguage = escapeHtml(parts[0]);
89   var sArticle = escapeHtml(parts[1]);
90
91   return '<a href="https://' + sLanguage + '.wikipedia.org/wiki/' + sArticle + '" target="_blank">' + sTitle + '</a>';
92 }
93
94 function coverageType(aPlace) {
95   return (aPlace.isarea ? 'Polygon' : 'Point');
96 }
97
98 function isAdminBoundary(aPlace) {
99   return aPlace.category === 'boundary' && aPlace.type === 'administrative';
100 }
101
102 function formatAddressRank(iRank) {
103   if (iRank < 4) return 'other';
104   if (iRank < 6) return 'country';
105   if (iRank < 8) return 'region';
106   if (iRank < 10) return 'state';
107   if (iRank < 12) return 'state district';
108   if (iRank < 14) return 'county';
109   if (iRank < 16) return 'municipality';
110   if (iRank < 18) return 'city / town / village';
111   if (iRank < 20) return 'city / village district';
112   if (iRank < 22) return 'suburb / hamlet';
113   if (iRank < 24) return 'neighbourhood';
114   if (iRank < 26) return 'city block / square';
115   if (iRank === 26) return 'major street';
116   if (iRank === 27) return 'minory street / path';
117   if (iRank <= 30) return 'house / building';
118   return 'other';
119 }
120
121 function formatPlaceType(aPlace) {
122   var sOut = aPlace.class + ':' + aPlace.type;
123   if (aPlace.type && aPlace.type === 'administrative' && aPlace.place_type) {
124     sOut = sOut + ' (' + aPlace.place_type + ')';
125   }
126   return escapeHtml(sOut);
127 }
128
129 // Any over 15 are invalid data in OSM anyway
130 function formatAdminLevel(iLevel) {
131   return (iLevel < 15 ? iLevel : '');
132 }
133
134 function formatDistance(fDistance, bInMeters) {
135   if (bInMeters) {
136     if (fDistance < 1) return '0';
137     var sFormatted = (fDistance >= 1000)
138       ? Math.round(fDistance / 1000, 1) + ' km'
139       : Math.round(fDistance, 0) + ' m';
140
141     return '<abbr class="distance" title="' + fDistance + ' meters">~' + sFormatted + '</abbr>';
142   }
143
144   // spheric distance, http://postgis.net/docs/ST_Distance_Spheroid.html
145   if (fDistance === 0) return '0';
146
147   return '<abbr class="distance" title="spheric distance ' + fDistance + '">~'
148       + (Math.round(fDistance * 1000, 4) / 1000)
149       + '</abbr>';
150 }
151
152 // mark partial tokens (those starting with a space) with a star for readability
153 function formatKeywordToken(sToken) {
154   return (sToken[0] === ' ' ? '*' : '') + escapeHtml(sToken);
155 }
156
157 function zoomLevels() {
158   const aZoomLevels = [
159     /*  0 */ 'Continent / Sea',
160     /*  1 */ '',
161     /*  2 */ '',
162     /*  3 */ 'Country',
163     /*  4 */ '',
164     /*  5 */ 'State',
165     /*  6 */ 'Region',
166     /*  7 */ '',
167     /*  8 */ 'County',
168     /*  9 */ '',
169     /* 10 */ 'City',
170     /* 11 */ '',
171     /* 12 */ 'Town / Village',
172     /* 13 */ '',
173     /* 14 */ 'Suburb',
174     /* 15 */ '',
175     /* 16 */ 'Street',
176     /* 17 */ '',
177     /* 18 */ 'Building',
178     /* 19 */ '',
179     /* 20 */ '',
180     /* 21 */ ''
181   ];
182   return aZoomLevels;
183 }