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