X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/190a72cab52efe0a094395b052735e3d590817ad..42a06c6bab36c357210fddfced2223ae2c0b191d:/lib/Geocode.php?ds=inline diff --git a/lib/Geocode.php b/lib/Geocode.php index e6e6e3eb..bdc8226e 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -1,5 +1,6 @@ aLangPrefOrder = $aLangPref; } - function setIncludeAddressDetails($bAddressDetails = true) - { - $this->bIncludeAddressDetails = (bool)$bAddressDetails; - } - function getIncludeAddressDetails() { return $this->bIncludeAddressDetails; @@ -87,21 +83,11 @@ $this->bIncludePolygonAsPoints = $b; } - function getIncludePolygonAsPoints() - { - return $this->bIncludePolygonAsPoints; - } - function setIncludePolygonAsText($b = true) { $this->bIncludePolygonAsText = $b; } - function getIncludePolygonAsText() - { - return $this->bIncludePolygonAsText; - } - function setIncludePolygonAsGeoJSON($b = true) { $this->bIncludePolygonAsGeoJSON = $b; @@ -122,11 +108,6 @@ $this->fPolygonSimplificationThreshold = $f; } - function setDeDupe($bDeDupe = true) - { - $this->bDeDupe = (bool)$bDeDupe; - } - function setLimit($iLimit = 10) { if ($iLimit > 50) $iLimit = 50; @@ -136,32 +117,11 @@ $this->iLimit = $this->iFinalLimit + min($this->iFinalLimit, 10); } - function setOffset($iOffset = 0) - { - $this->iOffset = $iOffset; - } - - function setFallback($bFallback = true) - { - $this->bFallback = (bool)$bFallback; - } - - function setExcludedPlaceIDs($a) - { - // TODO: force to int - $this->aExcludePlaceIDs = $a; - } - function getExcludedPlaceIDs() { return $this->aExcludePlaceIDs; } - function setBounded($bBoundedSearch = true) - { - $this->bBoundedSearch = (bool)$bBoundedSearch; - } - function setViewBox($fLeft, $fBottom, $fRight, $fTop) { $this->aViewBox = array($fLeft, $fBottom, $fRight, $fTop); @@ -173,11 +133,6 @@ return $this->aViewBox[0].','.$this->aViewBox[3].','.$this->aViewBox[2].','.$this->aViewBox[1]; } - function setRoute($aRoutePoints) - { - $this->aRoutePoints = $aRoutePoints; - } - function setFeatureType($sFeatureType) { switch($sFeatureType) @@ -199,8 +154,8 @@ function setRankRange($iMin, $iMax) { - $this->iMinAddressRank = (int)$iMin; - $this->iMaxAddressRank = (int)$iMax; + $this->iMinAddressRank = $iMin; + $this->iMaxAddressRank = $iMax; } function setNearPoint($aNearPoint, $fRadiusDeg = 0.1) @@ -208,11 +163,6 @@ $this->aNearPoint = array((float)$aNearPoint[0], (float)$aNearPoint[1], (float)$fRadiusDeg); } - function setCountryCodesList($aCountryCodes) - { - $this->aCountryCodes = $aCountryCodes; - } - function setQuery($sQueryString) { $this->sQuery = $sQueryString; @@ -514,12 +464,8 @@ $sSQL .= " order by importance desc"; if (CONST_Debug) { echo "
"; var_dump($sSQL); } - $aSearchResults = $this->oDB->getAll($sSQL); - - if (PEAR::IsError($aSearchResults)) - { - failInternalError("Could not get details for place.", $sSQL, $aSearchResults); - } + $aSearchResults = chksql($this->oDB->getAll($sSQL), + "Could not get details for place."); return $aSearchResults; } @@ -883,19 +829,13 @@ $sViewboxCentreSQL .= ")'::geometry,4326)"; $sSQL = "select st_buffer(".$sViewboxCentreSQL.",".(float)($_GET['routewidth']/69).")"; - $this->sViewboxSmallSQL = $this->oDB->getOne($sSQL); - if (PEAR::isError($this->sViewboxSmallSQL)) - { - failInternalError("Could not get small viewbox.", $sSQL, $this->sViewboxSmallSQL); - } + $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 = $this->oDB->getOne($sSQL); - if (PEAR::isError($this->sViewboxLargeSQL)) - { - failInternalError("Could not get large viewbox.", $sSQL, $this->sViewboxLargeSQL); - } + $this->sViewboxLargeSQL = chksql($this->oDB->getOne($sSQL), + "Could not get large viewbox."); $this->sViewboxLargeSQL = "'".$this->sViewboxLargeSQL."'::geometry"; $bBoundingBoxSearch = $this->bBoundedSearch; } @@ -961,11 +901,11 @@ foreach($aSpecialTermsRaw as $aSpecialTerm) { $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery); - $sToken = $this->oDB->getOne("select make_standard_name('".$aSpecialTerm[1]."') as string"); + $sToken = chksql($this->oDB->getOne("select make_standard_name('".$aSpecialTerm[1]."') as string")); $sSQL = 'select * from (select word_id,word_token, word, class, type, country_code, operator'; $sSQL .= ' from word where word_token in (\' '.$sToken.'\')) as x where (class is not null and class not in (\'place\')) or country_code is not null'; if (CONST_Debug) var_Dump($sSQL); - $aSearchWords = $this->oDB->getAll($sSQL); + $aSearchWords = chksql($this->oDB->getAll($sSQL)); $aNewSearches = array(); foreach($aSearches as $aSearch) { @@ -1010,13 +950,8 @@ $aTokens = array(); foreach($aPhrases as $iPhrase => $sPhrase) { - $aPhrase = $this->oDB->getRow("select make_standard_name('".pg_escape_string($sPhrase)."') as string"); - if (PEAR::isError($aPhrase)) - { - userError("Illegal query string (not an UTF-8 string): ".$sPhrase); - if (CONST_Debug) var_dump($aPhrase); - exit; - } + $aPhrase = chksql($this->oDB->getRow("select make_standard_name('".pg_escape_string($sPhrase)."') as string"), + "Cannot nomralize query string (is it an UTF-8 string?)"); if (trim($aPhrase['string'])) { $aPhrases[$iPhrase] = $aPhrase; @@ -1043,11 +978,14 @@ if (CONST_Debug) var_Dump($sSQL); $aValidTokens = array(); - if (sizeof($aTokens)) $aDatabaseWords = $this->oDB->getAll($sSQL); - else $aDatabaseWords = array(); - if (PEAR::IsError($aDatabaseWords)) + if (sizeof($aTokens)) + { + $aDatabaseWords = chksql($this->oDB->getAll($sSQL), + "Could not get word tokens."); + } + else { - failInternalError("Could not get word tokens.", $sSQL, $aDatabaseWords); + $aDatabaseWords = array(); } $aPossibleMainWordIDs = array(); $aWordFrequencyScores = array(); @@ -1264,7 +1202,7 @@ $sSQL .= " and _st_intersects($this->sViewboxSmallSQL, geometry)"; $sSQL .= " order by st_area(geometry) desc limit 1"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $this->oDB->getCol($sSQL); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); } else { @@ -1276,7 +1214,7 @@ if (!$bBoundingBoxSearch && !$aSearch['fLon']) continue; if (!$aSearch['sClass']) continue; $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_".$aSearch['sClass']."_".$aSearch['sType']."'"; - if ($this->oDB->getOne($sSQL)) + if (chksql($this->oDB->getOne($sSQL))) { $sSQL = "select place_id from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct"; if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)"; @@ -1289,7 +1227,7 @@ if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $this->oDB->getCol($sSQL); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); // If excluded place IDs are given, it is fair to assume that // there have been results in the small box, so no further @@ -1304,7 +1242,7 @@ if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $this->oDB->getCol($sSQL); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); } } else @@ -1315,10 +1253,16 @@ if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, centroid) asc"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $this->oDB->getCol($sSQL); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); } } } + // If a coordinate is given, the search must either + // be for a name or a special search. Ignore everythin else. + else if ($aSearch['fLon'] && !sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['sClass']) + { + $aPlaceIDs = array(); + } else { $aPlaceIDs = array(); @@ -1342,7 +1286,7 @@ // TODO: filter out the pointless search terms (2 letter name tokens and less) // they might be right - but they are just too darned expensive to run if (sizeof($aSearch['aName'])) $aTerms[] = "name_vector @> ARRAY[".join($aSearch['aName'],",")."]"; - if (sizeof($aSearch['aNameNonSearch'])) $aTerms[] = "array_cat(name_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aNameNonSearch'],",")."]"; + //if (sizeof($aSearch['aNameNonSearch'])) $aTerms[] = "array_cat(name_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aNameNonSearch'],",")."]"; if (sizeof($aSearch['aAddress']) && $aSearch['aName'] != $aSearch['aAddress']) { // For infrequent name terms disable index usage for address @@ -1350,12 +1294,13 @@ sizeof($aSearch['aName']) == 1 && $aWordFrequencyScores[$aSearch['aName'][reset($aSearch['aName'])]] < CONST_Search_NameOnlySearchFrequencyThreshold) { - $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join(array_merge($aSearch['aAddress'],$aSearch['aAddressNonSearch']),",")."]"; + //$aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join(array_merge($aSearch['aAddress'],$aSearch['aAddressNonSearch']),",")."]"; + $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aAddress'],",")."]"; } else { $aTerms[] = "nameaddress_vector @> ARRAY[".join($aSearch['aAddress'],",")."]"; - if (sizeof($aSearch['aAddressNonSearch'])) $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aAddressNonSearch'],",")."]"; + //if (sizeof($aSearch['aAddressNonSearch'])) $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aAddressNonSearch'],",")."]"; } } if ($aSearch['sCountryCode']) $aTerms[] = "country_code = '".pg_escape_string($aSearch['sCountryCode'])."'"; @@ -1426,11 +1371,8 @@ $sSQL .= " limit ".$this->iLimit; if (CONST_Debug) { var_dump($sSQL); } - $aViewBoxPlaceIDs = $this->oDB->getAll($sSQL); - if (PEAR::IsError($aViewBoxPlaceIDs)) - { - failInternalError("Could not get places for search terms.", $sSQL, $aViewBoxPlaceIDs); - } + $aViewBoxPlaceIDs = chksql($this->oDB->getAll($sSQL), + "Could not get places for search terms."); //var_dump($aViewBoxPlaceIDs); // Did we have an viewbox matches? $aPlaceIDs = array(); @@ -1464,7 +1406,7 @@ } $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $this->oDB->getCol($sSQL); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); // if nothing found, search in the interpolation line table if(!sizeof($aPlaceIDs)) @@ -1481,12 +1423,12 @@ if (sizeof($this->aExcludePlaceIDs)) { - $sSQL .= " and parent_place_id not in (".join(',', $this->aExcludePlaceIDs).")"; + $sSQL .= " and place_id not in (".join(',', $this->aExcludePlaceIDs).")"; } //$sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); //get place IDs - $aPlaceIDs = $this->oDB->getCol($sSQL, 0); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL, 0)); } // If nothing found try the aux fallback table @@ -1499,7 +1441,7 @@ } //$sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $this->oDB->getCol($sSQL); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); } //if nothing was found in placex or location_property_aux, then search in Tiger data for this housenumber(location_property_tiger) @@ -1521,7 +1463,7 @@ //$sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); //get place IDs - $aPlaceIDs = $this->oDB->getCol($sSQL, 0); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL, 0)); } // Fallback to the road (if no housenumber was found) @@ -1548,18 +1490,18 @@ if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)"; $sSQL .= " order by rank_search asc limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aClassPlaceIDs = $this->oDB->getCol($sSQL); + $aClassPlaceIDs = chksql($this->oDB->getCol($sSQL)); } if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'near') // & in { $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_".$aSearch['sClass']."_".$aSearch['sType']."'"; - $bCacheTable = $this->oDB->getOne($sSQL); + $bCacheTable = chksql($this->oDB->getOne($sSQL)); $sSQL = "select min(rank_search) from placex where place_id in ($sPlaceIDs)"; if (CONST_Debug) var_dump($sSQL); - $this->iMaxRank = ((int)$this->oDB->getOne($sSQL)); + $this->iMaxRank = ((int)chksql($this->oDB->getOne($sSQL))); // For state / country level searches the normal radius search doesn't work very well $sPlaceGeom = false; @@ -1568,7 +1510,7 @@ // Try and get a polygon to search in instead $sSQL = "select geometry from placex where place_id in ($sPlaceIDs) and rank_search < $this->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 = $this->oDB->getOne($sSQL); + $sPlaceGeom = chksql($this->oDB->getOne($sSQL)); } if ($sPlaceGeom) @@ -1580,7 +1522,7 @@ $this->iMaxRank += 5; $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and rank_search < $this->iMaxRank"; if (CONST_Debug) var_dump($sSQL); - $aPlaceIDs = $this->oDB->getCol($sSQL); + $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); $sPlaceIDs = join(',',$aPlaceIDs); } @@ -1619,7 +1561,7 @@ if ($this->iOffset) $sSQL .= " offset $this->iOffset"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aClassPlaceIDs = array_merge($aClassPlaceIDs, $this->oDB->getCol($sSQL)); + $aClassPlaceIDs = array_merge($aClassPlaceIDs, chksql($this->oDB->getCol($sSQL))); } else { @@ -1641,7 +1583,7 @@ if ($this->iOffset) $sSQL .= " offset $this->iOffset"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); - $aClassPlaceIDs = array_merge($aClassPlaceIDs, $this->oDB->getCol($sSQL)); + $aClassPlaceIDs = array_merge($aClassPlaceIDs, chksql($this->oDB->getCol($sSQL))); } } } @@ -1652,11 +1594,6 @@ } - if (PEAR::IsError($aPlaceIDs)) - { - failInternalError("Could not get place IDs from tokens." ,$sSQL, $aPlaceIDs); - } - if (CONST_Debug) { echo "
Place IDs: "; var_Dump($aPlaceIDs); } foreach($aPlaceIDs as $iPlaceID) @@ -1685,7 +1622,7 @@ $sSQL .= ") UNION select place_id from location_property_osmline where place_id in (".join(',',array_keys($aResultPlaceIDs)).")"; $sSQL .= " and (30 between $this->iMinAddressRank and $this->iMaxAddressRank)"; if (CONST_Debug) var_dump($sSQL); - $aFilteredPlaceIDs = $this->oDB->getCol($sSQL); + $aFilteredPlaceIDs = chksql($this->oDB->getCol($sSQL)); $tempIDs = array(); foreach($aFilteredPlaceIDs as $placeID) { @@ -1710,9 +1647,17 @@ else { // Just interpret as a reverse geocode - $iPlaceID = geocodeReverse((float)$this->aNearPoint[0], (float)$this->aNearPoint[1]); - if ($iPlaceID) - $aSearchResults = $this->getDetails(array($iPlaceID)); + $oReverse = new ReverseGeocode($this->oDB); + $oReverse->setZoom(18); + + $aLookup = $oReverse->lookup((float)$this->aNearPoint[0], + (float)$this->aNearPoint[1], + false); + + if (CONST_Debug) var_dump("Reverse search", $aLookup); + + if ($aLookup['place_id']) + $aSearchResults = $this->getDetails(array($aLookup['place_id'] => -1)); else $aSearchResults = array(); } @@ -1740,19 +1685,19 @@ if (CONST_Debug) { echo 'Recheck words:<\i>'; var_dump($aRecheckWords); } + $oPlaceLookup = new PlaceLookup($this->oDB); + $oPlaceLookup->setIncludePolygonAsPoints($this->bIncludePolygonAsPoints); + $oPlaceLookup->setIncludePolygonAsText($this->bIncludePolygonAsText); + $oPlaceLookup->setIncludePolygonAsGeoJSON($this->bIncludePolygonAsGeoJSON); + $oPlaceLookup->setIncludePolygonAsKML($this->bIncludePolygonAsKML); + $oPlaceLookup->setIncludePolygonAsSVG($this->bIncludePolygonAsSVG); + $oPlaceLookup->setPolygonSimplificationThreshold($this->fPolygonSimplificationThreshold); + foreach($aSearchResults as $iResNum => $aResult) { // Default $fDiameter = getResultDiameter($aResult); - $oPlaceLookup = new PlaceLookup($this->oDB); - $oPlaceLookup->setIncludePolygonAsPoints($this->bIncludePolygonAsPoints); - $oPlaceLookup->setIncludePolygonAsText($this->bIncludePolygonAsText); - $oPlaceLookup->setIncludePolygonAsGeoJSON($this->bIncludePolygonAsGeoJSON); - $oPlaceLookup->setIncludePolygonAsKML($this->bIncludePolygonAsKML); - $oPlaceLookup->setIncludePolygonAsSVG($this->bIncludePolygonAsSVG); - $oPlaceLookup->setPolygonSimplificationThreshold($this->fPolygonSimplificationThreshold); - $aOutlineResult = $oPlaceLookup->getOutlines($aResult['place_id'], $aResult['lon'], $aResult['lat'], $fDiameter/2); if ($aOutlineResult) {