mirror of
https://github.com/osm-search/Nominatim.git
synced 2024-11-23 13:44:36 +03:00
433017b990
Instead of creating the website wrapper scripts with cmake, they are now created when --setup-website is called. The setup of the configuration constants is directly embedded into the scripts. This means we can get rid of the separate settings-frontend.php. More importantly however, it means that it is now possible to set up multiple website directories from the same build directory.
283 lines
9.5 KiB
PHP
283 lines
9.5 KiB
PHP
<?php
|
||
|
||
require('Symfony/Component/Dotenv/autoload.php');
|
||
|
||
function loadSettings($sProjectDir)
|
||
{
|
||
@define('CONST_InstallDir', $sProjectDir);
|
||
|
||
$dotenv = new \Symfony\Component\Dotenv\Dotenv();
|
||
$dotenv->load(CONST_DataDir.'/settings/env.defaults');
|
||
|
||
if (file_exists($sProjectDir.'/.env')) {
|
||
$dotenv->load($sProjectDir.'/.env');
|
||
}
|
||
}
|
||
|
||
function getSetting($sConfName, $sDefault = null)
|
||
{
|
||
$sValue = $_SERVER['NOMINATIM_'.$sConfName];
|
||
|
||
if ($sDefault !== null && !$sValue) {
|
||
return $sDefault;
|
||
}
|
||
|
||
return $sValue;
|
||
}
|
||
|
||
function getSettingBool($sConfName)
|
||
{
|
||
$sVal = strtolower(getSetting($sConfName));
|
||
|
||
return strcmp($sVal, 'yes') == 0
|
||
|| strcmp($sVal, 'true') == 0
|
||
|| strcmp($sVal, '1') == 0;
|
||
}
|
||
|
||
function getSettingConfig($sConfName, $sSystemConfig)
|
||
{
|
||
$sValue = $_ENV['NOMINATIM_'.$sConfName];
|
||
|
||
if (!$sValue) {
|
||
return CONST_DataDir.'/settings/'.$sSystemConfig;
|
||
}
|
||
|
||
return $sValue;
|
||
}
|
||
|
||
function fail($sError, $sUserError = false)
|
||
{
|
||
if (!$sUserError) $sUserError = $sError;
|
||
error_log('ERROR: '.$sError);
|
||
var_dump($sUserError)."\n";
|
||
exit(-1);
|
||
}
|
||
|
||
|
||
function getProcessorCount()
|
||
{
|
||
$sCPU = file_get_contents('/proc/cpuinfo');
|
||
preg_match_all('#processor\s+: [0-9]+#', $sCPU, $aMatches);
|
||
return count($aMatches[0]);
|
||
}
|
||
|
||
|
||
function getTotalMemoryMB()
|
||
{
|
||
$sCPU = file_get_contents('/proc/meminfo');
|
||
preg_match('#MemTotal: +([0-9]+) kB#', $sCPU, $aMatches);
|
||
return (int)($aMatches[1]/1024);
|
||
}
|
||
|
||
|
||
function getCacheMemoryMB()
|
||
{
|
||
$sCPU = file_get_contents('/proc/meminfo');
|
||
preg_match('#Cached: +([0-9]+) kB#', $sCPU, $aMatches);
|
||
return (int)($aMatches[1]/1024);
|
||
}
|
||
|
||
function getDatabaseDate(&$oDB)
|
||
{
|
||
// Find the newest node in the DB
|
||
$iLastOSMID = $oDB->getOne("select max(osm_id) from place where osm_type = 'N'");
|
||
// Lookup the timestamp that node was created
|
||
$sLastNodeURL = 'https://www.openstreetmap.org/api/0.6/node/'.$iLastOSMID.'/1';
|
||
$sLastNodeXML = file_get_contents($sLastNodeURL);
|
||
|
||
if ($sLastNodeXML === false) {
|
||
return false;
|
||
}
|
||
|
||
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);
|
||
|
||
return $aLastNodeDate[1];
|
||
}
|
||
|
||
|
||
function byImportance($a, $b)
|
||
{
|
||
if ($a['importance'] != $b['importance'])
|
||
return ($a['importance'] > $b['importance']?-1:1);
|
||
|
||
return $a['foundorder'] <=> $b['foundorder'];
|
||
}
|
||
|
||
|
||
function javascript_renderData($xVal, $iOptions = 0)
|
||
{
|
||
$sCallback = isset($_GET['json_callback']) ? $_GET['json_callback'] : '';
|
||
if ($sCallback && !preg_match('/^[$_\p{L}][$_\p{L}\p{Nd}.[\]]*$/u', $sCallback)) {
|
||
// Unset, we call javascript_renderData again during exception handling
|
||
unset($_GET['json_callback']);
|
||
throw new Exception('Invalid json_callback value', 400);
|
||
}
|
||
|
||
$iOptions |= JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
|
||
if (isset($_GET['pretty']) && in_array(strtolower($_GET['pretty']), array('1', 'true'))) {
|
||
$iOptions |= JSON_PRETTY_PRINT;
|
||
}
|
||
|
||
$jsonout = json_encode($xVal, $iOptions);
|
||
|
||
if ($sCallback) {
|
||
header('Content-Type: application/javascript; charset=UTF-8');
|
||
echo $_GET['json_callback'].'('.$jsonout.')';
|
||
} else {
|
||
header('Content-Type: application/json; charset=UTF-8');
|
||
echo $jsonout;
|
||
}
|
||
}
|
||
|
||
function addQuotes($s)
|
||
{
|
||
return "'".$s."'";
|
||
}
|
||
|
||
function fwriteConstDef($rFile, $sConstName, $value)
|
||
{
|
||
$sEscapedValue;
|
||
|
||
if (is_bool($value)) {
|
||
$sEscapedValue = $value ? 'true' : 'false';
|
||
} elseif (is_numeric($value)) {
|
||
$sEscapedValue = strval($value);
|
||
} elseif (!$value) {
|
||
$sEscapedValue = 'false';
|
||
} else {
|
||
$sEscapedValue = addQuotes(str_replace("'", "\\'", (string)$value));
|
||
}
|
||
|
||
fwrite($rFile, "@define('CONST_$sConstName', $sEscapedValue);\n");
|
||
}
|
||
|
||
|
||
function parseLatLon($sQuery)
|
||
{
|
||
$sFound = null;
|
||
$fQueryLat = null;
|
||
$fQueryLon = null;
|
||
|
||
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)) {
|
||
/* 1 2 3 4 5 6
|
||
* degrees decimal minutes
|
||
* N 40 26.767, W 79 58.933
|
||
* N 40°26.767′, W 79°58.933′
|
||
*/
|
||
$sFound = $aData[0];
|
||
$fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60);
|
||
$fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60);
|
||
} 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)) {
|
||
/* 1 2 3 4 5 6
|
||
* degrees decimal minutes
|
||
* 40 26.767 N, 79 58.933 W
|
||
* 40° 26.767′ N 79° 58.933′ W
|
||
*/
|
||
$sFound = $aData[0];
|
||
$fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60);
|
||
$fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60);
|
||
} 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)) {
|
||
/* 1 2 3 4 5 6 7 8
|
||
* degrees decimal seconds
|
||
* N 40 26 46 W 79 58 56
|
||
* N 40° 26′ 46″, W 79° 58′ 56″
|
||
*/
|
||
$sFound = $aData[0];
|
||
$fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60 + $aData[4]/3600);
|
||
$fQueryLon = ($aData[5]=='E'?1:-1) * ($aData[6] + $aData[7]/60 + $aData[8]/3600);
|
||
} 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)) {
|
||
/* 1 2 3 4 5 6 7 8
|
||
* degrees decimal seconds
|
||
* 40 26 46 N 79 58 56 W
|
||
* 40° 26′ 46″ N, 79° 58′ 56″ W
|
||
* 40° 26′ 46.78″ N, 79° 58′ 56.89″ W
|
||
*/
|
||
$sFound = $aData[0];
|
||
$fQueryLat = ($aData[4]=='N'?1:-1) * ($aData[1] + $aData[2]/60 + $aData[3]/3600);
|
||
$fQueryLon = ($aData[8]=='E'?1:-1) * ($aData[5] + $aData[6]/60 + $aData[7]/3600);
|
||
} elseif (preg_match('/\\s*([NS])[\s]+([0-9]+[0-9]*\\.[0-9]+)[°]*[,\s]+([EW])[\s]+([0-9]+[0-9]*\\.[0-9]+)[°]*\\s*/', $sQuery, $aData)) {
|
||
/* 1 2 3 4
|
||
* degrees decimal
|
||
* N 40.446° W 79.982°
|
||
*/
|
||
$sFound = $aData[0];
|
||
$fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2]);
|
||
$fQueryLon = ($aData[3]=='E'?1:-1) * ($aData[4]);
|
||
} elseif (preg_match('/\\s*([0-9]+[0-9]*\\.[0-9]+)[°\s]+([NS])[,\s]+([0-9]+[0-9]*\\.[0-9]+)[°\s]+([EW])\\s*/', $sQuery, $aData)) {
|
||
/* 1 2 3 4
|
||
* degrees decimal
|
||
* 40.446° N 79.982° W
|
||
*/
|
||
$sFound = $aData[0];
|
||
$fQueryLat = ($aData[2]=='N'?1:-1) * ($aData[1]);
|
||
$fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[3]);
|
||
} elseif (preg_match('/(\\s*\\[|^\\s*|\\s*)(-?[0-9]+[0-9]*\\.[0-9]+)[,\s]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]\\s*|\\s*$|\\s*)/', $sQuery, $aData)) {
|
||
/* 1 2 3 4
|
||
* degrees decimal
|
||
* 12.34, 56.78
|
||
* 12.34 56.78
|
||
* [12.456,-78.90]
|
||
*/
|
||
$sFound = $aData[0];
|
||
$fQueryLat = $aData[2];
|
||
$fQueryLon = $aData[3];
|
||
} else {
|
||
return false;
|
||
}
|
||
|
||
return array($sFound, $fQueryLat, $fQueryLon);
|
||
}
|
||
|
||
function createPointsAroundCenter($fLon, $fLat, $fRadius)
|
||
{
|
||
$iSteps = max(8, min(100, ($fRadius * 40000)^2));
|
||
$fStepSize = (2*pi())/$iSteps;
|
||
$aPolyPoints = array();
|
||
for ($f = 0; $f < 2*pi(); $f += $fStepSize) {
|
||
$aPolyPoints[] = array('', $fLon+($fRadius*sin($f)), $fLat+($fRadius*cos($f)) );
|
||
}
|
||
return $aPolyPoints;
|
||
}
|
||
|
||
function closestHouseNumber($aRow)
|
||
{
|
||
$fHouse = $aRow['startnumber']
|
||
+ ($aRow['endnumber'] - $aRow['startnumber']) * $aRow['fraction'];
|
||
|
||
switch ($aRow['interpolationtype']) {
|
||
case 'odd':
|
||
$iHn = (int)($fHouse/2) * 2 + 1;
|
||
break;
|
||
case 'even':
|
||
$iHn = (int)(round($fHouse/2)) * 2;
|
||
break;
|
||
default:
|
||
$iHn = (int)(round($fHouse));
|
||
break;
|
||
}
|
||
|
||
return max(min($aRow['endnumber'], $iHn), $aRow['startnumber']);
|
||
}
|
||
|
||
function getSearchRankLabel($iRank)
|
||
{
|
||
if (!isset($iRank)) return 'unknown';
|
||
if ($iRank < 2) return 'continent';
|
||
if ($iRank < 4) return 'sea';
|
||
if ($iRank < 8) return 'country';
|
||
if ($iRank < 12) return 'state';
|
||
if ($iRank < 16) return 'county';
|
||
if ($iRank == 16) return 'city';
|
||
if ($iRank == 17) return 'town / island';
|
||
if ($iRank == 18) return 'village / hamlet';
|
||
if ($iRank == 20) return 'suburb';
|
||
if ($iRank == 21) return 'postcode area';
|
||
if ($iRank == 22) return 'croft / farm / locality / islet';
|
||
if ($iRank == 23) return 'postcode area';
|
||
if ($iRank == 25) return 'postcode point';
|
||
if ($iRank == 26) return 'street / major landmark';
|
||
if ($iRank == 27) return 'minory street / path';
|
||
if ($iRank == 28) return 'house / building';
|
||
return 'other: ' . $iRank;
|
||
}
|