Merge pull request #504 from lonvia/parameter-parser-class

factor out parameter parsing into its own class
This commit is contained in:
Sarah Hoffmann 2016-08-23 21:57:06 +02:00 committed by GitHub
commit d7c469d94e
13 changed files with 426 additions and 393 deletions

View File

@ -33,9 +33,9 @@
protected $bBoundedSearch = false;
protected $aViewBox = false;
protected $sViewboxCentreSQL = false;
protected $sViewboxSmallSQL = false;
protected $sViewboxLargeSQL = false;
protected $aRoutePoints = false;
protected $iMaxRank = 20;
protected $iMinAddressRank = 0;
@ -114,7 +114,7 @@
if ($iLimit < 1) $iLimit = 1;
$this->iFinalLimit = $iLimit;
$this->iLimit = $this->iFinalLimit + min($this->iFinalLimit, 10);
$this->iLimit = $iLimit + min($iLimit, 10);
}
function getExcludedPlaceIDs()
@ -122,11 +122,6 @@
return $this->aExcludePlaceIDs;
}
function setViewBox($fLeft, $fBottom, $fRight, $fTop)
{
$this->aViewBox = array($fLeft, $fBottom, $fRight, $fTop);
}
function getViewBoxString()
{
if (!$this->aViewBox) return null;
@ -158,6 +153,43 @@
$this->iMaxAddressRank = $iMax;
}
function setRoute($aRoutePoints, $fRouteWidth)
{
$this->aViewBox = false;
$this->sViewboxCentreSQL = "ST_SetSRID('LINESTRING(";
$sSep = '';
foreach($this->aRoutePoints as $aPoint)
{
$fPoint = (float)$aPoint;
$this->sViewboxCentreSQL .= $sSep.$fPoint;
$sSep = ($sSep == ' ') ? ',' : ' ';
}
$this->sViewboxCentreSQL .= ")'::geometry,4326)";
$this->sViewboxSmallSQL = 'st_buffer('.$this->sViewboxCentreSQL;
$this->sViewboxSmallSQL .= ','.($fRouteWidth/69).')';
$this->sViewboxLargeSQL = 'st_buffer('.$this->sViewboxCentreSQL;
$this->sViewboxLargeSQL .= ','.($fRouteWidth/30).')';
}
function setViewbox($aViewbox)
{
$this->aViewBox = array_map('floatval', $aViewbox);
$fHeight = $this->aViewBox[0] - $this->aViewBox[2];
$fWidth = $this->aViewBox[1] - $this->aViewBox[3];
$aBigViewBox[0] = $this->aViewBox[0] + $fHeight;
$aBigViewBox[2] = $this->aViewBox[2] - $fHeight;
$aBigViewBox[1] = $this->aViewBox[1] + $fWidth;
$aBigViewBox[3] = $this->aViewBox[3] - $fWidth;
$this->sViewboxCentreSQL = false;
$this->sViewboxSmallSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$this->aViewBox[0].",".$this->aViewBox[1]."),ST_Point(".$this->aViewBox[2].",".$this->aViewBox[3].")),4326)";
$this->sViewboxLargeSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$aBigViewBox[0].",".$aBigViewBox[1]."),ST_Point(".$aBigViewBox[2].",".$aBigViewBox[3].")),4326)";
}
function setNearPoint($aNearPoint, $fRadiusDeg = 0.1)
{
$this->aNearPoint = array((float)$aNearPoint[0], (float)$aNearPoint[1], (float)$fRadiusDeg);
@ -175,24 +207,28 @@
}
function loadParamArray($aParams)
function loadParamArray($oParams)
{
if (isset($aParams['addressdetails'])) $this->bIncludeAddressDetails = (bool)$aParams['addressdetails'];
if (isset($aParams['extratags'])) $this->bIncludeExtraTags = (bool)$aParams['extratags'];
if (isset($aParams['namedetails'])) $this->bIncludeNameDetails = (bool)$aParams['namedetails'];
$this->bIncludeAddressDetails = $oParams->getBool('addressdetails',
$this->bIncludeAddressDetails);
$this->bIncludeExtraTags = $oParams->getBool('extratags',
$this->bIncludeExtraTags);
$this->bIncludeNameDetails = $oParams->getBool('namedetails',
$this->bIncludeNameDetails);
if (isset($aParams['bounded'])) $this->bBoundedSearch = (bool)$aParams['bounded'];
if (isset($aParams['dedupe'])) $this->bDeDupe = (bool)$aParams['dedupe'];
$this->bBoundedSearch = $oParams->getBool('bounded', $this->bBoundedSearch);
$this->bDeDupe = $oParams->getBool('dedupe', $this->bDeDupe);
if (isset($aParams['limit'])) $this->setLimit((int)$aParams['limit']);
if (isset($aParams['offset'])) $this->iOffset = (int)$aParams['offset'];
$this->setLimit($oParams->getInt('limit', $this->iFinalLimit));
$this->iOffset = $oParams->getInt('offset', $this->iOffset);
if (isset($aParams['fallback'])) $this->bFallback = (bool)$aParams['fallback'];
$this->bFallback = $oParams->getBool('fallback', $this->bFallback);
// List of excluded Place IDs - used for more acurate pageing
if (isset($aParams['exclude_place_ids']) && $aParams['exclude_place_ids'])
$sExcluded = $oParams->getStringList('exclude_place_ids');
if ($sExcluded)
{
foreach(explode(',',$aParams['exclude_place_ids']) as $iExcludedPlaceID)
foreach($sExcluded as $iExcludedPlaceID)
{
$iExcludedPlaceID = (int)$iExcludedPlaceID;
if ($iExcludedPlaceID)
@ -204,66 +240,63 @@
}
// Only certain ranks of feature
if (isset($aParams['featureType'])) $this->setFeatureType($aParams['featureType']);
if (isset($aParams['featuretype'])) $this->setFeatureType($aParams['featuretype']);
$sFeatureType = $oParams->getString('featureType');
if (!$sFeatureType) $sFeatureType = $oParams->getString('featuretype');
if ($sFeatureType) $this->setFeatureType($sFeatureType);
// Country code list
if (isset($aParams['countrycodes']))
$sCountries = $oParams->getStringList('countrycodes');
if ($sCountries)
{
$aCountryCodes = array();
foreach(explode(',',$aParams['countrycodes']) as $sCountryCode)
foreach($sCountries as $sCountryCode)
{
if (preg_match('/^[a-zA-Z][a-zA-Z]$/', $sCountryCode))
{
$aCountryCodes[] = strtolower($sCountryCode);
$aCountries[] = strtolower($sCountryCode);
}
}
$this->aCountryCodes = $aCountryCodes;
if (isset($aCountryCodes))
$this->aCountryCodes = $aCountries;
}
if (isset($aParams['viewboxlbrt']) && $aParams['viewboxlbrt'])
$aViewbox = $oParams->getStringList('viewboxlbrt');
if ($aViewbox)
{
$aCoOrdinatesLBRT = explode(',',$aParams['viewboxlbrt']);
$this->setViewBox($aCoOrdinatesLBRT[0], $aCoOrdinatesLBRT[1], $aCoOrdinatesLBRT[2], $aCoOrdinatesLBRT[3]);
$this->setViewbox($aViewbox);
}
else if (isset($aParams['viewbox']) && $aParams['viewbox'])
else
{
$aCoOrdinatesLTRB = explode(',',$aParams['viewbox']);
$this->setViewBox($aCoOrdinatesLTRB[0], $aCoOrdinatesLTRB[3], $aCoOrdinatesLTRB[2], $aCoOrdinatesLTRB[1]);
}
if (isset($aParams['route']) && $aParams['route'] && isset($aParams['routewidth']) && $aParams['routewidth'])
{
$aPoints = explode(',',$aParams['route']);
if (sizeof($aPoints) % 2 != 0)
$aViewbox = $oParams->getStringList('viewbox');
if ($aViewbox)
{
userError("Uneven number of points");
exit;
$this->setViewBox(array($aViewbox[0], $aViewbox[3],
$aViewbox[2], $aViewbox[1]));
}
$fPrevCoord = false;
$aRoute = array();
foreach($aPoints as $i => $fPoint)
else
{
if ($i%2)
$aRoute = $oParams->getStringList('route');
$fRouteWidth = $oParams->getFloat('routewidth');
if ($aRoute && $fRouteWidth)
{
$aRoute[] = array((float)$fPoint, $fPrevCoord);
}
else
{
$fPrevCoord = (float)$fPoint;
$this->setRoute($aRoute, $fRouteWidth);
}
}
$this->aRoutePoints = $aRoute;
}
}
function setQueryFromParams($aParams)
function setQueryFromParams($oParams)
{
// Search query
$sQuery = (isset($aParams['q'])?trim($aParams['q']):'');
$sQuery = $oParams->getString('q');
if (!$sQuery)
{
$this->setStructuredQuery(@$aParams['amenity'], @$aParams['street'], @$aParams['city'], @$aParams['county'], @$aParams['state'], @$aParams['country'], @$aParams['postalcode']);
$this->setStructuredQuery($oParams->getString('amenity'),
$oParams->getString('street'),
$oParams->getString('city'),
$oParams->getString('county'),
$oParams->getString('state'),
$oParams->getString('country'),
$oParams->getString('postalcode'));
$this->setReverseInPlan(false);
}
else
@ -783,7 +816,7 @@
$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
$sCountryCodesSQL = false;
if ($this->aCountryCodes && sizeof($this->aCountryCodes))
if ($this->aCountryCodes)
{
$sCountryCodesSQL = join(',', array_map('addQuotes', $this->aCountryCodes));
}
@ -798,46 +831,17 @@
$sQuery = preg_replace('/(^|,)\s*la\s*(,|$)/','\1louisiana\2', $sQuery);
}
// View Box SQL
$sViewboxCentreSQL = false;
$bBoundingBoxSearch = false;
if ($this->aViewBox)
$bBoundingBoxSearch = $this->bBoundedSearch && $this->sViewboxSmallSQL;
if ($this->sViewboxCentreSQL)
{
$fHeight = $this->aViewBox[0]-$this->aViewBox[2];
$fWidth = $this->aViewBox[1]-$this->aViewBox[3];
$aBigViewBox[0] = $this->aViewBox[0] + $fHeight;
$aBigViewBox[2] = $this->aViewBox[2] - $fHeight;
$aBigViewBox[1] = $this->aViewBox[1] + $fWidth;
$aBigViewBox[3] = $this->aViewBox[3] - $fWidth;
// For complex viewboxes (routes) precompute the bounding geometry
$sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxSmallSQL),
"Could not get small viewbox");
$this->sViewboxSmallSQL = "'".$sGeom."'::geometry";
$this->sViewboxSmallSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".(float)$this->aViewBox[0].",".(float)$this->aViewBox[1]."),ST_Point(".(float)$this->aViewBox[2].",".(float)$this->aViewBox[3].")),4326)";
$this->sViewboxLargeSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".(float)$aBigViewBox[0].",".(float)$aBigViewBox[1]."),ST_Point(".(float)$aBigViewBox[2].",".(float)$aBigViewBox[3].")),4326)";
$bBoundingBoxSearch = $this->bBoundedSearch;
}
// Route SQL
if ($this->aRoutePoints)
{
$sViewboxCentreSQL = "ST_SetSRID('LINESTRING(";
$bFirst = true;
foreach($this->aRoutePoints as $aPoint)
{
if (!$bFirst) $sViewboxCentreSQL .= ",";
$sViewboxCentreSQL .= $aPoint[0].' '.$aPoint[1];
$bFirst = false;
}
$sViewboxCentreSQL .= ")'::geometry,4326)";
$sSQL = "select st_buffer(".$sViewboxCentreSQL.",".(float)($_GET['routewidth']/69).")";
$this->sViewboxSmallSQL = chksql($this->oDB->getOne($sSQL),
"Could not get small viewbox.");
$this->sViewboxSmallSQL = "'".$this->sViewboxSmallSQL."'::geometry";
$sSQL = "select st_buffer(".$sViewboxCentreSQL.",".(float)($_GET['routewidth']/30).")";
$this->sViewboxLargeSQL = chksql($this->oDB->getOne($sSQL),
"Could not get large viewbox.");
$this->sViewboxLargeSQL = "'".$this->sViewboxLargeSQL."'::geometry";
$bBoundingBoxSearch = $this->bBoundedSearch;
$sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxLargeSQL),
"Could not get large viewbox");
$this->sViewboxLargeSQL = "'".$sGeom."'::geometry";
}
// Do we have anything that looks like a lat/lon pair?
@ -1224,7 +1228,7 @@
{
$sSQL .= " and place_id not in (".join(',',$this->aExcludePlaceIDs).")";
}
if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc";
if ($this->sViewboxCentreSQL) $sSQL .= " order by st_distance($this->sViewboxCentreSQL, ct.centroid) asc";
$sSQL .= " limit $this->iLimit";
if (CONST_Debug) var_dump($sSQL);
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
@ -1239,7 +1243,7 @@
if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)";
$sSQL .= " where st_contains($this->sViewboxLargeSQL, ct.centroid)";
if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc";
if ($this->sViewboxCentreSQL) $sSQL .= " order by st_distance($this->sViewboxCentreSQL, ct.centroid) asc";
$sSQL .= " limit $this->iLimit";
if (CONST_Debug) var_dump($sSQL);
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
@ -1250,7 +1254,7 @@
$sSQL = "select place_id from placex where class='".$aSearch['sClass']."' and type='".$aSearch['sType']."'";
$sSQL .= " and st_contains($this->sViewboxSmallSQL, geometry) and linked_place_id is null";
if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, centroid) asc";
if ($this->sViewboxCentreSQL) $sSQL .= " order by st_distance($this->sViewboxCentreSQL, centroid) asc";
$sSQL .= " limit $this->iLimit";
if (CONST_Debug) var_dump($sSQL);
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));

133
lib/ParameterParser.php Normal file
View File

@ -0,0 +1,133 @@
<?php
class ParameterParser
{
private $aParams;
function __construct($aParams=NULL)
{
$this->aParams = ($aParams === NULL) ? $_GET : $aParams;
}
function getBool($sName, $bDefault=false)
{
if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
{
return $bDefault;
}
return (bool) $this->aParams[$sName];
}
function getInt($sName, $bDefault=false)
{
if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
{
return $bDefault;
}
if (!preg_match('/^[+-]?[0-9]+$/', $this->aParams[$sName]))
{
userError("Integer number expected for parameter '$sName'");
}
return (int) $this->aParams[$sName];
}
function getFloat($sName, $bDefault=false)
{
if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
{
return $bDefault;
}
if (!preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $this->aParams[$sName]))
{
userError("Floating-point number expected for parameter '$sName'");
}
return (float) $this->aParams[$sName];
}
function getString($sName, $bDefault=false)
{
if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
{
return $bDefault;
}
return $this->aParams[$sName];
}
function getSet($sName, $aValues, $sDefault=false)
{
if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
{
return $sDefault;
}
if (!in_array($this->aParams[$sName], $aValues))
{
userError("Parameter '$sName' must be one of: ".join(', ', $aValues));
}
return $this->aParams[$sName];
}
function getStringList($sName, $aDefault=false)
{
$sValue = $this->getString($sName);
if ($sValue)
{
return explode(',', $sValue);
}
return $aDefault;
}
function getPreferredLanguages($sFallback=NULL)
{
if ($sFallback === NULL && isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
{
$sFallback = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
}
$aLanguages = array();
$sLangString = $this->getString('accept-language', $sFallback);
if ($sLangString)
{
if (preg_match_all('/(([a-z]{1,8})(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $sLangString, $aLanguagesParse, PREG_SET_ORDER))
{
foreach($aLanguagesParse as $iLang => $aLanguage)
{
$aLanguages[$aLanguage[1]] = isset($aLanguage[5])?(float)$aLanguage[5]:1 - ($iLang/100);
if (!isset($aLanguages[$aLanguage[2]])) $aLanguages[$aLanguage[2]] = $aLanguages[$aLanguage[1]]/10;
}
arsort($aLanguages);
}
}
if (!sizeof($aLanguages) && CONST_Default_Language)
{
$aLanguages[CONST_Default_Language] = 1;
}
foreach($aLanguages as $sLanguage => $fLanguagePref)
{
$aLangPrefOrder['short_name:'.$sLanguage] = 'short_name:'.$sLanguage;
$aLangPrefOrder['name:'.$sLanguage] = 'name:'.$sLanguage;
}
$aLangPrefOrder['short_name'] = 'short_name';
$aLangPrefOrder['name'] = 'name';
$aLangPrefOrder['brand'] = 'brand';
foreach($aLanguages as $sLanguage => $fLanguagePref)
{
$aLangPrefOrder['official_name:'.$sLanguage] = 'official_name:'.$sLanguage;
}
$aLangPrefOrder['official_name'] = 'official_name';
$aLangPrefOrder['ref'] = 'ref';
$aLangPrefOrder['type'] = 'type';
return $aLangPrefOrder;
}
}

View File

@ -1,6 +1,93 @@
<?php
require_once('init.php');
require_once('website.php');
require_once('ParameterParser.php');
/***************************************************************************
*
* Error handling functions
*
*/
function chksql($oSql, $sMsg = "Database request failed")
{
if (!PEAR::isError($oSql)) return $oSql;
header('HTTP/1.0 500 Internal Server Error');
header('Content-type: text/html; charset=utf-8');
$sSqlError = $oSql->getMessage();
echo <<<INTERNALFAIL
<html>
<head><title>Internal Server Error</title></head>
<body>
<h1>Internal Server Error</h1>
<p>Nominatim has encountered an internal error while accessing the database.
This may happen because the database is broken or because of a bug in
the software. If you think it is a bug, feel free to report
it over on <a href="https://github.com/twain47/Nominatim/issues">
Github</a>. Please include the URL that caused the problem and the
complete error details below.</p>
<p><b>Message:</b> $sMsg</p>
<p><b>SQL Error:</b> $sSqlError</p>
<p><b>Details:</b> <pre>
INTERNALFAIL;
if (CONST_Debug)
{
var_dump($oSql);
}
else
{
echo "<pre>\n".$oSql->getUserInfo()."</pre>";
}
echo "</pre></p></body></html>";
exit;
}
function failInternalError($sError, $sSQL = false, $vDumpVar = false)
{
header('HTTP/1.0 500 Internal Server Error');
header('Content-type: text/html; charset=utf-8');
echo "<html><body><h1>Internal Server Error</h1>";
echo '<p>Nominatim has encountered an internal error while processing your request. This is most likely because of a bug in the software.</p>';
echo "<p><b>Details:</b> ".$sError,"</p>";
echo '<p>Feel free to file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
if (CONST_Debug)
{
echo "<hr><h2>Debugging Information</h2><br>";
if ($sSQL)
{
echo "<h3>SQL query</h3><code>".$sSQL."</code>";
}
if ($vDumpVar)
{
echo "<h3>Result</h3> <code>";
var_dump($vDumpVar);
echo "</code>";
}
}
echo "\n</body></html>\n";
exit;
}
function userError($sError)
{
header('HTTP/1.0 400 Bad Request');
header('Content-type: text/html; charset=utf-8');
echo "<html><body><h1>Bad Request</h1>";
echo '<p>Nominatim has encountered an error with your request.</p>';
echo "<p><b>Details:</b> ".$sError."</p>";
echo '<p>If you feel this error is incorrect feel file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
echo "\n</body></html>\n";
exit;
}
/***************************************************************************
* HTTP Reply header setup
*/
if (CONST_NoAccessControl)
{
@ -13,5 +100,5 @@
}
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') exit;
header('Content-type: text/html; charset=utf-8');
if (CONST_Debug) header('Content-type: text/html; charset=utf-8');

View File

@ -50,62 +50,6 @@
}
function getPreferredLanguages($sLangString=false)
{
if (!$sLangString)
{
// If we have been provided the value in $_GET it overrides browser value
if (isset($_GET['accept-language']) && $_GET['accept-language'])
{
$_SERVER["HTTP_ACCEPT_LANGUAGE"] = $_GET['accept-language'];
$sLangString = $_GET['accept-language'];
}
else if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
{
$sLangString = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
}
}
$aLanguages = array();
if ($sLangString)
{
if (preg_match_all('/(([a-z]{1,8})(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $sLangString, $aLanguagesParse, PREG_SET_ORDER))
{
foreach($aLanguagesParse as $iLang => $aLanguage)
{
$aLanguages[$aLanguage[1]] = isset($aLanguage[5])?(float)$aLanguage[5]:1 - ($iLang/100);
if (!isset($aLanguages[$aLanguage[2]])) $aLanguages[$aLanguage[2]] = $aLanguages[$aLanguage[1]]/10;
}
arsort($aLanguages);
}
}
if (!sizeof($aLanguages) && CONST_Default_Language) $aLanguages = array(CONST_Default_Language=>1);
foreach($aLanguages as $sLangauge => $fLangauagePref)
{
$aLangPrefOrder['short_name:'.$sLangauge] = 'short_name:'.$sLangauge;
}
foreach($aLanguages as $sLangauge => $fLangauagePref)
{
$aLangPrefOrder['name:'.$sLangauge] = 'name:'.$sLangauge;
}
foreach($aLanguages as $sLangauge => $fLangauagePref)
{
$aLangPrefOrder['place_name:'.$sLangauge] = 'place_name:'.$sLangauge;
}
foreach($aLanguages as $sLangauge => $fLangauagePref)
{
$aLangPrefOrder['official_name:'.$sLangauge] = 'official_name:'.$sLangauge;
}
$aLangPrefOrder['short_name'] = 'short_name';
$aLangPrefOrder['name'] = 'name';
$aLangPrefOrder['place_name'] = 'place_name';
$aLangPrefOrder['official_name'] = 'official_name';
$aLangPrefOrder['ref'] = 'ref';
$aLangPrefOrder['type'] = 'type';
return $aLangPrefOrder;
}
function getWordSets($aWords, $iDepth)
{
$aResult = array(array(join(' ',$aWords)));

View File

@ -1,140 +0,0 @@
<?php
/***************************************************************************
*
* Error handling functions
*
*/
function chksql($oSql, $sMsg = "Database request failed")
{
if (!PEAR::isError($oSql)) return $oSql;
header('HTTP/1.0 500 Internal Server Error');
header('Content-type: text/html; charset=utf-8');
$sSqlError = $oSql->getMessage();
echo <<<INTERNALFAIL
<html>
<head><title>Internal Server Error</title></head>
<body>
<h1>Internal Server Error</h1>
<p>Nominatim has encountered an internal error while accessing the database.
This may happen because the database is broken or because of a bug in
the software. If you think it is a bug, feel free to report
it over on <a href="https://github.com/twain47/Nominatim/issues">
Github</a>. Please include the URL that caused the problem and the
complete error details below.</p>
<p><b>Message:</b> $sMsg</p>
<p><b>SQL Error:</b> $sSqlError</p>
<p><b>Details:</b> <pre>
INTERNALFAIL;
if (CONST_Debug)
{
var_dump($oSql);
}
else
{
echo "<pre>\n".$oSql->getUserInfo()."</pre>";
}
echo "</pre></p></body></html>";
exit;
}
function failInternalError($sError, $sSQL = false, $vDumpVar = false)
{
header('HTTP/1.0 500 Internal Server Error');
header('Content-type: text/html; charset=utf-8');
echo "<html><body><h1>Internal Server Error</h1>";
echo '<p>Nominatim has encountered an internal error while processing your request. This is most likely because of a bug in the software.</p>';
echo "<p><b>Details:</b> ".$sError,"</p>";
echo '<p>Feel free to file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
if (CONST_Debug)
{
echo "<hr><h2>Debugging Information</h2><br>";
if ($sSQL)
{
echo "<h3>SQL query</h3><code>".$sSQL."</code>";
}
if ($vDumpVar)
{
echo "<h3>Result</h3> <code>";
var_dump($vDumpVar);
echo "</code>";
}
}
echo "\n</body></html>\n";
exit;
}
function userError($sError)
{
header('HTTP/1.0 400 Bad Request');
header('Content-type: text/html; charset=utf-8');
echo "<html><body><h1>Bad Request</h1>";
echo '<p>Nominatim has encountered an error with your request.</p>';
echo "<p><b>Details:</b> ".$sError."</p>";
echo '<p>If you feel this error is incorrect feel file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
echo "\n</body></html>\n";
exit;
}
/***************************************************************************
*
* Functions for parsing URL parameters
*
*/
function getParamBool($sName, $bDefault=false)
{
if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault;
return (bool) $_GET[$sName];
}
function getParamInt($sName, $bDefault=false)
{
if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault;
if (!preg_match('/^[+-]?[0-9]+$/', $_GET[$sName]))
{
userError("Integer number expected for parameter '$sName'");
}
return (int) $_GET[$sName];
}
function getParamFloat($sName, $bDefault=false)
{
if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault;
if (!preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $_GET[$sName]))
{
userError("Floating-point number expected for parameter '$sName'");
}
return (float) $_GET[$sName];
}
function getParamString($sName, $bDefault=false)
{
if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault;
return $_GET[$sName];
}
function getParamSet($sName, $aValues, $sDefault=false)
{
if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $sDefault;
if (!in_array($_GET[$sName], $aValues))
{
userError("Parameter '$sName' must be one of: ".join(', ', $aValues));
}
return $_GET[$sName];
}

View File

@ -4,6 +4,7 @@
require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
require_once(CONST_BasePath.'/lib/init-cmd.php');
require_once(CONST_BasePath.'/lib/Geocode.php');
require_once(CONST_BasePath.'/lib/ParameterParser.php');
ini_set('memory_limit', '800M');
$aCMDOptions = array(
@ -12,45 +13,43 @@
array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
array('search', '', 0, 1, 1, 1, 'string', 'Search for given term or coordinate'),
array('search', '', 0, 1, 1, 1, 'string', 'Search for given term or coordinate'),
array('accept-language', '', 0, 1, 1, 1, 'string', 'Preferred language order for showing search results'),
array('bounded', '', 0, 1, 0, 0, 'bool', 'Restrict results to given viewbox'),
array('nodedupe', '', 0, 1, 0, 0, 'bool', 'Do not remove duplicate results'),
array('limit', '', 0, 1, 1, 1, 'int', 'Maximum number of results returned (default: 10)'),
array('exclude_place_ids', '', 0, 1, 1, 1, 'string', 'Comma-separated list of place ids to exclude from results'),
array('featureType', '', 0, 1, 1, 1, 'string', 'Restrict results to certain features (country, state,city,settlement)'),
array('countrycodes', '', 0, 1, 1, 1, 'string', 'Comma-separated list of countries to restrict search to'),
array('viewbox', '', 0, 1, 1, 1, 'string', 'Prefer results in given view box')
);
getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
array('accept-language', '', 0, 1, 1, 1, 'string', 'Preferred language order for showing search results'),
array('bounded', '', 0, 1, 0, 0, 'bool', 'Restrict results to given viewbox'),
array('nodedupe', '', 0, 1, 0, 0, 'bool', 'Do not remove duplicate results'),
array('limit', '', 0, 1, 1, 1, 'int', 'Maximum number of results returned (default: 10)'),
array('exclude_place_ids', '', 0, 1, 1, 1, 'string', 'Comma-separated list of place ids to exclude from results'),
array('featureType', '', 0, 1, 1, 1, 'string', 'Restrict results to certain features (country, state,city,settlement)'),
array('countrycodes', '', 0, 1, 1, 1, 'string', 'Comma-separated list of countries to restrict search to'),
array('viewbox', '', 0, 1, 1, 1, 'string', 'Prefer results in given view box')
);
getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
$oDB =& getDB();
$oDB =& getDB();
$oParams = new ParameterParser($aCMDResult);
if (isset($aCMDResult['search']) && $aCMDResult['search'])
{
if (isset($aCMDResult['bounded'])) $aCMDResult['bounded'] = 'true';
if (isset($aCMDResult['nodedupe'])) $aCMDResult['dedupe'] = 'false';
if ($oParams->getBool('search'))
{
if (isset($aCMDResult['nodedupe'])) $aCMDResult['dedupe'] = 'false';
$oGeocode = new Geocode($oDB);
if (isset($aCMDResult['accept-language']) && $aCMDResult['accept-language'])
$oGeocode->setLanguagePreference(getPreferredLanguages($aCMDResult['accept-language']));
else
$oGeocode->setLanguagePreference(getPreferredLanguages());
$oGeocode->loadParamArray($aCMDResult);
$oGeocode->setQuery($aCMDResult['search']);
$oGeocode = new Geocode($oDB);
$aSearchResults = $oGeocode->lookup();
$oGeocode->setLanguagePreference($oParams->getPreferredLanguages(false));
$oGeocode->loadParamArray($oParams);
$oGeocode->setQuery($aCMDResult['search']);
$aSearchResults = $oGeocode->lookup();
if (version_compare(phpversion(), "5.4.0", '<'))
echo json_encode($aSearchResults);
else
echo json_encode($aSearchResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)."\n";
}
else
{
showUsage($aCMDOptions, true);
}
if (version_compare(phpversion(), "5.4.0", '<'))
echo json_encode($aSearchResults);
else
echo json_encode($aSearchResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)."\n";
}
else
{
showUsage($aCMDOptions, true);
}

View File

@ -3,9 +3,9 @@
require_once(CONST_BasePath.'/lib/init-website.php');
require_once(CONST_BasePath.'/lib/log.php');
require_once(CONST_BasePath.'/lib/output.php');
ini_set('memory_limit', '200M');
$sOutputFormat = 'html';
ini_set('memory_limit', '200M');
$oDB =& getDB();

View File

@ -5,19 +5,20 @@
require_once(CONST_BasePath.'/lib/init-website.php');
require_once(CONST_BasePath.'/lib/log.php');
require_once(CONST_BasePath.'/lib/output.php');
ini_set('memory_limit', '200M');
$oParams = new ParameterParser();
$sOutputFormat = 'html';
$aLangPrefOrder = $oParams->getPreferredLanguages();
$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]";
ini_set('memory_limit', '200M');
$sPlaceId = $oParams->getString('place_id');
$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
$iOsmId = $oParams->getInt('osmid', -1);
$oDB =& getDB();
$aLangPrefOrder = getPreferredLanguages();
$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]";
$sPlaceId = getParamString('place_id');
$sOsmType = getParamSet('osmtype', array('N', 'W', 'R'));
$iOsmId = getParamInt('osmid', -1);
if ($sOsmType && $iOsmId > 0)
{
$sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc"));
@ -125,7 +126,7 @@
$aPlaceSearchNameKeywords = false;
$aPlaceSearchAddressKeywords = false;
if (getParamBool('keywords'))
if ($oParams->getBool('keywords'))
{
$sSQL = "select * from search_name where place_id = $iPlaceID";
$aPlaceSearchName = $oDB->getRow($sSQL);

View File

@ -8,16 +8,18 @@
require_once(CONST_BasePath.'/lib/output.php');
ini_set('memory_limit', '200M');
$oDB =& getDB();
$oParams = new ParameterParser();
$sOutputFormat = getParamSet('format', array('html', 'json'), 'html');
$aLangPrefOrder = getPreferredLanguages();
$sOutputFormat = $oParams->getSet('format', array('html', 'json'), 'html');
$aLangPrefOrder = $oParams->getPreferredLanguages();
$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]";
$sPlaceId = getParamString('place_id');
$sOsmType = getParamSet('osmtype', array('N', 'W', 'R'));
$iOsmId = getParamInt('osmid', -1);
$sPlaceId = $oParams->getString('place_id');
$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
$iOsmId = $oParams->getInt('osmid', -1);
$oDB =& getDB();
if ($sOsmType && $iOsmId > 0)
{
$sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc"));

View File

@ -6,15 +6,17 @@
require_once(CONST_BasePath.'/lib/log.php');
require_once(CONST_BasePath.'/lib/PlaceLookup.php');
require_once(CONST_BasePath.'/lib/output.php');
$oDB =& getDB();
ini_set('memory_limit', '200M');
$oParams = new ParameterParser();
// Format for output
$sOutputFormat = getParamSet('format', array('xml', 'json'), 'xml');
$sOutputFormat = $oParams->getSet('format', array('xml', 'json'), 'xml');
// Preferred language
$aLangPrefOrder = getPreferredLanguages();
$aLangPrefOrder = $oParams->getPreferredLanguages();
$oDB =& getDB();
$hLog = logStart($oDB, 'place', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
@ -23,11 +25,11 @@
$oPlaceLookup = new PlaceLookup($oDB);
$oPlaceLookup->setLanguagePreference($aLangPrefOrder);
$oPlaceLookup->setIncludeAddressDetails(getParamBool('addressdetails', true));
$oPlaceLookup->setIncludeExtraTags(getParamBool('extratags', false));
$oPlaceLookup->setIncludeNameDetails(getParamBool('namedetails', false));
$oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
$oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false));
$oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false));
$aOsmIds = explode(',', getParamString('osm_ids', ''));
$aOsmIds = explode(',', $oParams->getString('osm_ids', ''));
if (count($aOsmIds) > CONST_Places_Max_ID_count)
{

View File

@ -5,12 +5,14 @@
require_once(CONST_BasePath.'/lib/output.php');
ini_set('memory_limit', '200M');
$oDB =& getDB();
$oParams = new ParameterParser();
$sOutputFormat = 'html';
$iDays = getParamInt('days', 1);
$bReduced = getParamBool('reduced', false);
$sClass = getParamString('class', false);
$iDays = $oParams->getInt('days', 1);
$bReduced = $oParams->getBool('reduced', false);
$sClass = $oParams->getString('class', false);
$oDB =& getDB();
$iTotalBroken = (int) chksql($oDB->getOne('select count(*) from import_polygon_error'));

View File

@ -7,11 +7,14 @@
require_once(CONST_BasePath.'/lib/PlaceLookup.php');
require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
require_once(CONST_BasePath.'/lib/output.php');
ini_set('memory_limit', '200M');
$bAsGeoJSON = getParamBool('polygon_geojson');
$bAsKML = getParamBool('polygon_kml');
$bAsSVG = getParamBool('polygon_svg');
$bAsText = getParamBool('polygon_text');
$oParams = new ParameterParser();
$bAsGeoJSON = $oParams->getBool('polygon_geojson');
$bAsKML = $oParams->getBool('polygon_kml');
$bAsSVG = $oParams->getBool('polygon_svg');
$bAsText = $oParams->getBool('polygon_text');
if ((($bAsGeoJSON?1:0) + ($bAsKML?1:0) + ($bAsSVG?1:0)
+ ($bAsText?1:0)) > CONST_PolygonOutput_MaximumTypes)
{
@ -23,36 +26,32 @@
{
userError("Polygon output is disabled");
}
exit;
}
// Polygon simplification threshold (optional)
$fThreshold = getParamFloat('polygon_threshold', 0.0);
$oDB =& getDB();
ini_set('memory_limit', '200M');
$fThreshold = $oParams->getFloat('polygon_threshold', 0.0);
// Format for output
$sOutputFormat = getParamSet('format', array('html', 'xml', 'json', 'jsonv2'), 'xml');
$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'xml');
// Preferred language
$aLangPrefOrder = getPreferredLanguages();
$aLangPrefOrder = $oParams->getPreferredLanguages();
$oDB =& getDB();
$hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
$oPlaceLookup = new PlaceLookup($oDB);
$oPlaceLookup->setLanguagePreference($aLangPrefOrder);
$oPlaceLookup->setIncludeAddressDetails(getParamBool('addressdetails', true));
$oPlaceLookup->setIncludeExtraTags(getParamBool('extratags', false));
$oPlaceLookup->setIncludeNameDetails(getParamBool('namedetails', false));
$oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
$oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false));
$oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false));
$sOsmType = getParamSet('osm_type', array('N', 'W', 'R'));
$iOsmId = getParamInt('osm_id', -1);
$fLat = getParamFloat('lat');
$fLon = getParamFloat('lon');
$sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R'));
$iOsmId = $oParams->getInt('osm_id', -1);
$fLat = $oParams->getFloat('lat');
$fLon = $oParams->getFloat('lon');
if ($sOsmType && $iOsmId > 0)
{
$aPlace = $oPlaceLookup->lookupOSMID($sOsmType, $iOsmId);
@ -60,7 +59,7 @@
else if ($fLat !== false && $fLon !== false)
{
$oReverseGeocode = new ReverseGeocode($oDB);
$oReverseGeocode->setZoom(getParamInt('zoom', 18));
$oReverseGeocode->setZoom($oParams->getInt('zoom', 18));
$aLookup = $oReverseGeocode->lookup($fLat, $fLon);
if (CONST_Debug) var_dump($aLookup);

View File

@ -6,14 +6,14 @@
require_once(CONST_BasePath.'/lib/log.php');
require_once(CONST_BasePath.'/lib/Geocode.php');
require_once(CONST_BasePath.'/lib/output.php');
ini_set('memory_limit', '200M');
$oDB =& getDB();
$oParams = new ParameterParser();
$oGeocode = new Geocode($oDB);
$aLangPrefOrder = getPreferredLanguages();
$aLangPrefOrder = $oParams->getPreferredLanguages();
$oGeocode->setLanguagePreference($aLangPrefOrder);
if (CONST_Search_ReversePlanForAll
@ -26,21 +26,21 @@
}
// Format for output
$sOutputFormat = getParamSet('format', array('html', 'xml', 'json', 'jsonv2'), 'html');
$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'html');
// Show / use polygons
if ($sOutputFormat == 'html')
{
$oGeocode->setIncludePolygonAsText(getParamBool('polygon'));
$oGeocode->setIncludePolygonAsText($oParams->getBool('polygon'));
$bAsText = false;
}
else
{
$bAsPoints = getParamBool('polygon');
$bAsGeoJSON = getParamBool('polygon_geojson');
$bAsKML = getParamBool('polygon_kml');
$bAsSVG = getParamBool('polygon_svg');
$bAsText = getParamBool('polygon_text');
$bAsPoints = $oParams->getBool('polygon');
$bAsGeoJSON = $oParams->getBool('polygon_geojson');
$bAsKML = $oParams->getBool('polygon_kml');
$bAsSVG = $oParams->getBool('polygon_svg');
$bAsText = $oParams->getBool('polygon_text');
if ( ( ($bAsGeoJSON?1:0)
+ ($bAsKML?1:0)
+ ($bAsSVG?1:0)
@ -66,9 +66,9 @@
}
// Polygon simplification threshold (optional)
$oGeocode->setPolygonSimplificationThreshold(getParamFloat('polygon_threshold', 0.0));
$oGeocode->setPolygonSimplificationThreshold($oParams->getFloat('polygon_threshold', 0.0));
$oGeocode->loadParamArray($_GET);
$oGeocode->loadParamArray($oParams);
if (CONST_Search_BatchMode && isset($_GET['batch']))
{
@ -77,8 +77,9 @@
foreach($aBatch as $aBatchParams)
{
$oBatchGeocode = clone $oGeocode;
$oBatchGeocode->loadParamArray($aBatchParams);
$oBatchGeocode->setQueryFromParams($aBatchParams);
$oBatchParams = new ParameterParser($aBatchParams);
$oBatchGeocode->loadParamArray($oBatchParams);
$oBatchGeocode->setQueryFromParams($oBatchParams);
$aSearchResults = $oBatchGeocode->lookup();
$aBatchResults[] = $aSearchResults;
}
@ -86,7 +87,10 @@
exit;
}
if (!getParamString('q') && isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'][0] == '/')
$oGeocode->setQueryFromParams($oParams);
if (!$oGeocode->getQueryString()
&& isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'][0] == '/')
{
$sQuery = substr(rawurldecode($_SERVER['PATH_INFO']), 1);
@ -96,10 +100,6 @@
$sQuery = join(', ',$aPhrases);
$oGeocode->setQuery($sQuery);
}
else
{
$oGeocode->setQueryFromParams($_GET);
}
$hLog = logStart($oDB, 'search', $oGeocode->getQueryString(), $aLangPrefOrder);