]> git.openstreetmap.org Git - nominatim.git/blob - lib-php/lib.php
ICU: additional ranking by matching of normalised term
[nominatim.git] / lib-php / lib.php
1 <?php
2
3 function loadSettings($sProjectDir)
4 {
5     @define('CONST_InstallDir', $sProjectDir);
6     // Temporary hack to set the direcory via environment instead of
7     // the installed scripts. Neither setting is part of the official
8     // set of settings.
9     defined('CONST_ConfigDir') or define('CONST_ConfigDir', $_SERVER['NOMINATIM_CONFIGDIR']);
10 }
11
12 function getSetting($sConfName, $sDefault = null)
13 {
14     $sValue = $_SERVER['NOMINATIM_'.$sConfName];
15
16     if ($sDefault !== null && !$sValue) {
17         return $sDefault;
18     }
19
20     return $sValue;
21 }
22
23 function getSettingBool($sConfName)
24 {
25     $sVal = strtolower(getSetting($sConfName));
26
27     return strcmp($sVal, 'yes') == 0
28            || strcmp($sVal, 'true') == 0
29            || strcmp($sVal, '1') == 0;
30 }
31
32 function fail($sError, $sUserError = false)
33 {
34     if (!$sUserError) {
35         $sUserError = $sError;
36     }
37     error_log('ERROR: '.$sError);
38     var_dump($sUserError);
39     echo "\n";
40     exit(-1);
41 }
42
43
44 function getProcessorCount()
45 {
46     $sCPU = file_get_contents('/proc/cpuinfo');
47     preg_match_all('#processor\s+: [0-9]+#', $sCPU, $aMatches);
48     return count($aMatches[0]);
49 }
50
51
52 function getTotalMemoryMB()
53 {
54     $sCPU = file_get_contents('/proc/meminfo');
55     preg_match('#MemTotal: +([0-9]+) kB#', $sCPU, $aMatches);
56     return (int)($aMatches[1]/1024);
57 }
58
59
60 function getCacheMemoryMB()
61 {
62     $sCPU = file_get_contents('/proc/meminfo');
63     preg_match('#Cached: +([0-9]+) kB#', $sCPU, $aMatches);
64     return (int)($aMatches[1]/1024);
65 }
66
67 function getDatabaseDate(&$oDB)
68 {
69     // Find the newest node in the DB
70     $iLastOSMID = $oDB->getOne("select max(osm_id) from place where osm_type = 'N'");
71     // Lookup the timestamp that node was created
72     $sLastNodeURL = 'https://www.openstreetmap.org/api/0.6/node/'.$iLastOSMID.'/1';
73     $sLastNodeXML = file_get_contents($sLastNodeURL);
74
75     if ($sLastNodeXML === false) {
76         return false;
77     }
78
79     preg_match('#timestamp="(([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z)"#', $sLastNodeXML, $aLastNodeDate);
80
81     return $aLastNodeDate[1];
82 }
83
84
85 function byImportance($a, $b)
86 {
87     if ($a['importance'] != $b['importance']) {
88         return ($a['importance'] > $b['importance']?-1:1);
89     }
90
91     return $a['foundorder'] <=> $b['foundorder'];
92 }
93
94
95 function javascript_renderData($xVal, $iOptions = 0)
96 {
97     $sCallback = isset($_GET['json_callback']) ? $_GET['json_callback'] : '';
98     if ($sCallback && !preg_match('/^[$_\p{L}][$_\p{L}\p{Nd}.[\]]*$/u', $sCallback)) {
99         // Unset, we call javascript_renderData again during exception handling
100         unset($_GET['json_callback']);
101         throw new Exception('Invalid json_callback value', 400);
102     }
103
104     $iOptions |= JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
105     if (isset($_GET['pretty']) && in_array(strtolower($_GET['pretty']), array('1', 'true'))) {
106         $iOptions |= JSON_PRETTY_PRINT;
107     }
108
109     $jsonout = json_encode($xVal, $iOptions);
110
111     if ($sCallback) {
112         header('Content-Type: application/javascript; charset=UTF-8');
113         echo $_GET['json_callback'].'('.$jsonout.')';
114     } else {
115         header('Content-Type: application/json; charset=UTF-8');
116         echo $jsonout;
117     }
118 }
119
120 function addQuotes($s)
121 {
122     return "'".$s."'";
123 }
124
125 function parseLatLon($sQuery)
126 {
127     $sFound    = null;
128     $fQueryLat = null;
129     $fQueryLon = null;
130
131     if (preg_match('/\\s*([NS])[\s]+([0-9]+[0-9.]*)[°\s]+([0-9.]+)?[′\']*[,\s]+([EW])[\s]+([0-9]+)[°\s]+([0-9]+[0-9.]*)[′\']*\\s*/', $sQuery, $aData)) {
132         /*               1          2                    3                     4          5             6
133          * degrees decimal minutes
134          * N 40 26.767, W 79 58.933
135          * N 40°26.767′, W 79°58.933′
136          */
137         $sFound    = $aData[0];
138         $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60);
139         $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60);
140     } elseif (preg_match('/\\s*([0-9]+)[°\s]+([0-9]+[0-9.]*)?[′\']*[\s]+([NS])[,\s]+([0-9]+)[°\s]+([0-9]+[0-9.]*)?[′\'\s]+([EW])\\s*/', $sQuery, $aData)) {
141         /*                     1             2                          3           4             5                       6
142          * degrees decimal minutes
143          * 40 26.767 N, 79 58.933 W
144          * 40° 26.767′ N 79° 58.933′ W
145          */
146         $sFound    = $aData[0];
147         $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60);
148         $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60);
149     } elseif (preg_match('/\\s*([NS])[\s]+([0-9]+)[°\s]+([0-9]+)[′\'\s]+([0-9]+)[″"]*[,\s]+([EW])[\s]+([0-9]+)[°\s]+([0-9]+)[′\'\s]+([0-9]+)[″"]*\\s*/', $sQuery, $aData)) {
150         /*                     1          2             3               4                  5          6             7               8
151          * degrees decimal seconds
152          * N 40 26 46 W 79 58 56
153          * N 40° 26′ 46″, W 79° 58′ 56″
154          */
155         $sFound    = $aData[0];
156         $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60 + $aData[4]/3600);
157         $fQueryLon = ($aData[5]=='E'?1:-1) * ($aData[6] + $aData[7]/60 + $aData[8]/3600);
158     } elseif (preg_match('/\\s*([0-9]+)[°\s]+([0-9]+)[′\'\s]+([0-9]+[0-9.]*)[″"\s]+([NS])[,\s]+([0-9]+)[°\s]+([0-9]+)[′\'\s]+([0-9]+[0-9.]*)[″"\s]+([EW])\\s*/', $sQuery, $aData)) {
159         /*                     1             2               3                     4           5             6               7                     8
160          * degrees decimal seconds
161          * 40 26 46 N 79 58 56 W
162          * 40° 26′ 46″ N, 79° 58′ 56″ W
163          * 40° 26′ 46.78″ N, 79° 58′ 56.89″ W
164          */
165         $sFound    = $aData[0];
166         $fQueryLat = ($aData[4]=='N'?1:-1) * ($aData[1] + $aData[2]/60 + $aData[3]/3600);
167         $fQueryLon = ($aData[8]=='E'?1:-1) * ($aData[5] + $aData[6]/60 + $aData[7]/3600);
168     } elseif (preg_match('/\\s*([NS])[\s]+([0-9]+[0-9]*\\.[0-9]+)[°]*[,\s]+([EW])[\s]+([0-9]+[0-9]*\\.[0-9]+)[°]*\\s*/', $sQuery, $aData)) {
169         /*                     1          2                                3          4
170          * degrees decimal
171          * N 40.446° W 79.982°
172          */
173         $sFound    = $aData[0];
174         $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2]);
175         $fQueryLon = ($aData[3]=='E'?1:-1) * ($aData[4]);
176     } elseif (preg_match('/\\s*([0-9]+[0-9]*\\.[0-9]+)[°\s]+([NS])[,\s]+([0-9]+[0-9]*\\.[0-9]+)[°\s]+([EW])\\s*/', $sQuery, $aData)) {
177         /*                     1                            2           3                            4
178          * degrees decimal
179          * 40.446° N 79.982° W
180          */
181         $sFound    = $aData[0];
182         $fQueryLat = ($aData[2]=='N'?1:-1) * ($aData[1]);
183         $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[3]);
184     } elseif (preg_match('/(\\s*\\[|^\\s*|\\s*)(-?[0-9]+[0-9]*\\.[0-9]+)[,\s]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]\\s*|\\s*$|\\s*)/', $sQuery, $aData)) {
185         /*                 1                   2                              3                        4
186          * degrees decimal
187          * 12.34, 56.78
188          * 12.34 56.78
189          * [12.456,-78.90]
190          */
191         $sFound    = $aData[0];
192         $fQueryLat = $aData[2];
193         $fQueryLon = $aData[3];
194     } else {
195         return false;
196     }
197
198     return array($sFound, $fQueryLat, $fQueryLon);
199 }
200
201 function closestHouseNumber($aRow)
202 {
203     $fHouse = $aRow['startnumber']
204                 + ($aRow['endnumber'] - $aRow['startnumber']) * $aRow['fraction'];
205
206     switch ($aRow['interpolationtype']) {
207         case 'odd':
208             $iHn = (int)($fHouse/2) * 2 + 1;
209             break;
210         case 'even':
211             $iHn = (int)(round($fHouse/2)) * 2;
212             break;
213         default:
214             $iHn = (int)(round($fHouse));
215             break;
216     }
217
218     return max(min($aRow['endnumber'], $iHn), $aRow['startnumber']);
219 }
220
221 if (!function_exists('array_key_last')) {
222     function array_key_last(array $array)
223     {
224         if (!empty($array)) {
225             return key(array_slice($array, -1, 1, true));
226         }
227     }
228 }