X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/9d8ee885918f41557094413bb7758e9adee2aa6d..8d96e87b930c835ffc4c7f1cbf9ebee7283c4129:/website/search.php diff --git a/website/search.php b/website/search.php index 69f6a666..c7171f98 100755 --- a/website/search.php +++ b/website/search.php @@ -17,10 +17,11 @@ $sSuggestion = $sSuggestionURL = false; $bDeDupe = isset($_GET['dedupe'])?(bool)$_GET['dedupe']:true; $bReverseInPlan = false; - $iLimit = isset($_GET['limit'])?(int)$_GET['limit']:10; + $iFinalLimit = isset($_GET['limit'])?(int)$_GET['limit']:10; $iOffset = isset($_GET['offset'])?(int)$_GET['offset']:0; $iMaxRank = 20; - if ($iLimit > 100) $iLimit = 100; + if ($iFinalLimit > 50) $iFinalLimit = 50; + $iLimit = $iFinalLimit + min($iFinalLimit, 10); $iMinAddressRank = 0; $iMaxAddressRank = 30; @@ -32,22 +33,30 @@ // Show / use polygons $bShowPolygons = (boolean)isset($_GET['polygon']) && $_GET['polygon']; - $bAsGeoJSON = (boolean)isset($_GET['polygon_geojson']) && $_GET['polygon_geojson']; - $bAsKML = (boolean)isset($_GET['polygon_kml']) && $_GET['polygon_kml']; - $bAsSVG = (boolean)isset($_GET['polygon_svg']) && $_GET['polygon_svg']; - $bAsText = (boolean)isset($_GET['polygon_text']) && $_GET['polygon_text']; - if ((($bShowPolygons?1:0) - + ($bAsGeoJSON?1:0) - + ($bAsKML?1:0) - + ($bAsSVG?1:0) - + ($bAsTEXT?1:0) - ) > CONST_PolygonOutput_MaximumTypes) { - if (CONST_PolygonOutput_MaximumTypes) { - echo "Select only ".CONST_PolygonOutput_MaximumTypes." polgyon output option"; - } else { - echo "Polygon output is disabled"; + if ($sOutputFormat == 'html') { + $bAsText = $bShowPolygons; + $bShowPolygons = false; + $bAsGeoJSON = false; + $bAsKML = false; + $bAsSVG = false; + } else { + $bAsGeoJSON = (boolean)isset($_GET['polygon_geojson']) && $_GET['polygon_geojson']; + $bAsKML = (boolean)isset($_GET['polygon_kml']) && $_GET['polygon_kml']; + $bAsSVG = (boolean)isset($_GET['polygon_svg']) && $_GET['polygon_svg']; + $bAsText = (boolean)isset($_GET['polygon_text']) && $_GET['polygon_text']; + if ((($bShowPolygons?1:0) + + ($bAsGeoJSON?1:0) + + ($bAsKML?1:0) + + ($bAsSVG?1:0) + + ($bAsText?1:0) + ) > CONST_PolygonOutput_MaximumTypes) { + if (CONST_PolygonOutput_MaximumTypes) { + userError("Select only ".CONST_PolygonOutput_MaximumTypes." polgyon output option"); + } else { + userError("Polygon output is disabled"); + } + exit; } - exit; } // Show address breakdown @@ -191,7 +200,7 @@ $aPoints = explode(',',$_GET['route']); if (sizeof($aPoints) % 2 != 0) { - echo "Uneven number of points"; + userError("Uneven number of points"); exit; } $sViewboxCentreSQL = "ST_SetSRID('LINESTRING("; @@ -225,6 +234,7 @@ failInternalError("Could not get large viewbox.", $sSQL, $sViewboxLargeSQL); } $sViewboxLargeSQL = "'".$sViewboxLargeSQL."'::geometry"; + $bBoundingBoxSearch = true; } // Do we have anything that looks like a lat/lon pair? @@ -351,7 +361,7 @@ $aPhrase = $oDB->getRow("select make_standard_name('".pg_escape_string($sPhrase)."') as string"); if (PEAR::isError($aPhrase)) { - echo "Illegal query string (not an UTF-8 string): ".$sPhrase; + userError("Illegal query string (not an UTF-8 string): ".$sPhrase); if (CONST_Debug) var_dump($aPhrase); exit; } @@ -767,13 +777,12 @@ if (!$aSearch['sClass']) continue; if (CONST_Debug) var_dump('
',$aSearch); if (CONST_Debug) _debugDumpGroupedSearches(array($iGroupedRank => array($aSearch)), $aValidTokens); - $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_".$aSearch['sClass']."_".$aSearch['sType']."'"; if ($oDB->getOne($sSQL)) { $sSQL = "select place_id from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct"; if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)"; - $sSQL .= " where st_contains($sViewboxSmallSQL, ct.centroid) and linked_place_id is null"; + $sSQL .= " where st_contains($sViewboxSmallSQL, ct.centroid)"; if ($sCountryCodesSQL) $sSQL .= " and country_code in ($sCountryCodesSQL)"; if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc"; $sSQL .= " limit $iLimit"; @@ -784,7 +793,7 @@ { $sSQL = "select place_id from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct"; if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)"; - $sSQL .= " where st_contains($sViewboxLargeSQL, ct.centroid) and linked_place_id is null"; + $sSQL .= " where st_contains($sViewboxLargeSQL, ct.centroid)"; if ($sCountryCodesSQL) $sSQL .= " and country_code in ($sCountryCodesSQL)"; if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc"; $sSQL .= " limit $iLimit"; @@ -856,7 +865,7 @@ else $sSQL .= " limit ".$iLimit; - if (CONST_Debug) var_dump($sSQL); + if (CONST_Debug) { var_dump($sSQL); } $aViewBoxPlaceIDs = $oDB->getAll($sSQL); if (PEAR::IsError($aViewBoxPlaceIDs)) { @@ -931,15 +940,17 @@ { $sPlaceIDs = join(',',$aPlaceIDs); + $aClassPlaceIDs = array(); + if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'name') { // If they were searching for a named class (i.e. 'Kings Head pub') then we might have an extra match $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and class='".$aSearch['sClass']."' and type='".$aSearch['sType']."'"; - $sSQL = " and linked_place_id is null"; + $sSQL .= " and linked_place_id is null"; if ($sCountryCodesSQL) $sSQL .= " and country_code in ($sCountryCodesSQL)"; $sSQL .= " order by rank_search asc limit $iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $oDB->getCol($sSQL); + $aClassPlaceIDs = $oDB->getCol($sSQL); } if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'near') // & in @@ -957,9 +968,9 @@ if ($iMaxRank < 9 && $bCacheTable) { // Try and get a polygon to search in instead - $sSQL = "select geometry from placex where place_id in ($sPlaceIDs) and rank_search < $iMaxRank + 5 and st_geometrytype(geometry) in ('ST_Polygon','ST_MultiPolygon') order by rank_search asc limit 1"; - if (CONST_Debug) var_dump($sSQL); - $sPlaceGeom = $oDB->getOne($sSQL); + $sSQL = "select geometry from placex where place_id in ($sPlaceIDs) and rank_search < $iMaxRank + 5 and st_geometrytype(geometry) in ('ST_Polygon','ST_MultiPolygon') order by rank_search asc limit 1"; + if (CONST_Debug) var_dump($sSQL); + $sPlaceGeom = $oDB->getOne($sSQL); } if ($sPlaceGeom) @@ -969,10 +980,10 @@ else { $iMaxRank += 5; - $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and rank_search < $iMaxRank"; - if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $oDB->getCol($sSQL); - $sPlaceIDs = join(',',$aPlaceIDs); + $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and rank_search < $iMaxRank"; + if (CONST_Debug) var_dump($sSQL); + $aPlaceIDs = $oDB->getCol($sSQL); + $sPlaceIDs = join(',',$aPlaceIDs); } if ($sPlaceIDs || $sPlaceGeom) @@ -989,7 +1000,7 @@ else if ($sPlaceIDs) $sOrderBySQL = "ST_Distance(l.centroid, f.geometry)"; else if ($sPlaceGeom) $sOrderBysSQL = "ST_Distance(st_centroid('".$sPlaceGeom."'), l.centroid)"; - $sSQL = "select distinct l.place_id".($sOrderBysSQL?','.$sOrderBysSQL:'')." from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." as l"; + $sSQL = "select distinct l.place_id".($sOrderBySQL?','.$sOrderBySQL:'')." from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." as l"; if ($sCountryCodesSQL) $sSQL .= " join placex as lp using (place_id)"; if ($sPlaceIDs) { @@ -1006,11 +1017,11 @@ $sSQL .= " and l.place_id not in (".join(',',$aExcludePlaceIDs).")"; } if ($sCountryCodesSQL) $sSQL .= " and lp.country_code in ($sCountryCodesSQL)"; - if ($sOrderBy) $sSQL .= "order by ".$OrderBysSQL." asc"; + if ($sOrderBySQL) $sSQL .= "order by ".$sOrderBySQL." asc"; if ($iOffset) $sSQL .= " offset $iOffset"; $sSQL .= " limit $iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $oDB->getCol($sSQL); + $aClassPlaceIDs = array_merge($aClassPlaceIDs, $oDB->getCol($sSQL)); } else { @@ -1032,10 +1043,13 @@ if ($iOffset) $sSQL .= " offset $iOffset"; $sSQL .= " limit $iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $oDB->getCol($sSQL); + $aClassPlaceIDs = array_merge($aClassPlaceIDs, $oDB->getCol($sSQL)); } } } + + $aPlaceIDs = $aClassPlaceIDs; + } } @@ -1053,14 +1067,15 @@ } if ($iQueryLoop > 20) break; } + //exit; - if (sizeof($aResultPlaceIDs)) break; + if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs)) break; if ($iGroupLoop > 4) break; if ($iQueryLoop > 30) break; } //exit; // Did we find anything? - if (sizeof($aResultPlaceIDs)) + if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs)) { //var_Dump($aResultPlaceIDs);exit; // Get the details for display (is this a redundant extra step?) @@ -1223,8 +1238,7 @@ if ($bAsGeoJSON) $sSQL .= ",ST_AsGeoJSON(geometry) as asgeojson"; if ($bAsKML) $sSQL .= ",ST_AsKML(geometry) as askml"; if ($bAsSVG) $sSQL .= ",ST_AsSVG(geometry) as assvg"; - if ($bAsText) $sSQL .= ",ST_AsText(geometry) as astext"; - if ($bShowPolygons) $sSQL .= ",ST_AsText(geometry) as outlinestring"; + if ($bAsText || $bShowPolygons) $sSQL .= ",ST_AsText(geometry) as astext"; $sSQL .= " from placex where place_id = ".$aResult['place_id'].' and st_geometrytype(Box2D(geometry)) = \'ST_Polygon\''; $aPointPolygon = $oDB->getRow($sSQL); if (PEAR::IsError($aPointPolygon)) @@ -1245,15 +1259,15 @@ if ($bShowPolygons) { // Translate geometary string to point array - if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#',$aPointPolygon['outlinestring'],$aMatch)) + if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#',$aPointPolygon['astext'],$aMatch)) { preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER); } - elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#',$aPointPolygon['outlinestring'],$aMatch)) + elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#',$aPointPolygon['astext'],$aMatch)) { preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER); } - elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#',$aPointPolygon['outlinestring'],$aMatch)) + elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#',$aPointPolygon['astext'],$aMatch)) { $fRadius = 0.01; $iSteps = ($fRadius * 40000)^2; @@ -1405,7 +1419,7 @@ } // Absolute limit on number of results - if (sizeof($aSearchResults) >= $iLimit) break; + if (sizeof($aSearchResults) >= $iFinalLimit) break; } $sDataDate = $oDB->getOne("select TO_CHAR(lastimportdate - '1 day'::interval,'YYYY/MM/DD') from import_status limit 1");