X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/eb79e655e638a4345a130ceef6b0d31a1ab5b1f9..41fce277cd75f866365d4fc64fdbd16fa10e25ac:/lib/Geocode.php diff --git a/lib/Geocode.php b/lib/Geocode.php index a8e4083b..bb8ae651 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -2,6 +2,7 @@ namespace Nominatim; +require_once(CONST_BasePath.'/lib/NearPoint.php'); require_once(CONST_BasePath.'/lib/PlaceLookup.php'); require_once(CONST_BasePath.'/lib/ReverseGeocode.php'); @@ -32,7 +33,6 @@ class Geocode protected $bFallback = false; protected $aCountryCodes = false; - protected $aNearPoint = false; protected $bBoundedSearch = false; protected $aViewBox = false; @@ -126,6 +126,12 @@ class Geocode return $this->aExcludePlaceIDs; } + + public function getCountryCodes() + { + return $this->aCountryCodes; + } + public function getViewBoxString() { if (!$this->aViewBox) return null; @@ -215,11 +221,6 @@ class Geocode ); } - public function setNearPoint($aNearPoint, $fRadiusDeg = 0.1) - { - $this->aNearPoint = array((float)$aNearPoint[0], (float)$aNearPoint[1], (float)$fRadiusDeg); - } - public function setQuery($sQueryString) { $this->sQuery = $sQueryString; @@ -477,12 +478,13 @@ class Geocode $sHousenumbers .= "(".$placeID.", ".$housenumber.")"; if ($i<$length) $sHousenumbers .= ", "; } + if (CONST_Use_US_Tiger_Data) { // Tiger search only if a housenumber was searched and if it was found (i.e. aPlaceIDs[placeID] = housenumber != -1) (realized through a join) $sSQL .= " union"; $sSQL .= " SELECT "; $sSQL .= " 'T' AS osm_type, "; - $sSQL .= " place_id AS osm_id, "; + $sSQL .= " (SELECT osm_id from placex p WHERE p.place_id=min(blub.parent_place_id)) as osm_id, "; $sSQL .= " 'place' AS class, "; $sSQL .= " 'house' AS type, "; $sSQL .= " null AS admin_level, "; @@ -907,6 +909,9 @@ class Geocode } $sQuery = $this->sQuery; + if (!preg_match('//u', $sQuery)) { + userError("Query string is not UTF-8 encoded."); + } // Conflicts between US state abreviations and various words for 'the' in different languages if (isset($this->aLangPrefOrder['name:en'])) { @@ -932,8 +937,9 @@ class Geocode } // Do we have anything that looks like a lat/lon pair? - if ($aLooksLike = looksLikeLatLonPair($sQuery)) { - $this->setNearPoint(array($aLooksLike['lat'], $aLooksLike['lon'])); + $oNearPoint = false; + if ($aLooksLike = NearPoint::extractFromQuery($sQuery)) { + $oNearPoint = $aLooksLike['pt']; $sQuery = $aLooksLike['query']; } @@ -962,12 +968,10 @@ class Geocode ); // Do we have a radius search? - $sNearPointSQL = false; - if ($this->aNearPoint) { - $sNearPointSQL = "ST_SetSRID(ST_Point(".(float)$this->aNearPoint[1].",".(float)$this->aNearPoint[0]."),4326)"; - $aSearches[0]['fLat'] = (float)$this->aNearPoint[0]; - $aSearches[0]['fLon'] = (float)$this->aNearPoint[1]; - $aSearches[0]['fRadius'] = (float)$this->aNearPoint[2]; + if ($oNearPoint) { + $aSearches[0]['fLat'] = $oNearPoint->lat(); + $aSearches[0]['fLon'] = $oNearPoint->lon(); + $aSearches[0]['fRadius'] = $oNearPoint->radius(); } // Any 'special' terms in the search? @@ -1316,6 +1320,7 @@ class Geocode $aOrder[0] .= " SELECT place_id "; $aOrder[0] .= " FROM location_property_osmline "; $aOrder[0] .= " WHERE parent_place_id = search_name.place_id"; + $aOrder[0] .= " AND startnumber is not NULL"; $aOrder[0] .= " AND ".intval($aSearch['sHouseNumber']).">=startnumber "; $aOrder[0] .= " AND ".intval($aSearch['sHouseNumber'])."<=endnumber "; $aOrder[0] .= " LIMIT 1"; @@ -1371,7 +1376,9 @@ class Geocode } if ($bBoundingBoxSearch) $aTerms[] = "centroid && $this->sViewboxSmallSQL"; - if ($sNearPointSQL) $aOrder[] = "ST_Distance($sNearPointSQL, centroid) ASC"; + if ($oNearPoint) { + $aOrder[] = $oNearPoint->distanceSQL('centroid'); + } if ($aSearch['sHouseNumber']) { $sImportanceSQL = '- abs(26 - address_rank) + 3'; @@ -1452,7 +1459,7 @@ class Geocode // do we need to use transliteration and the regex for housenumbers??? //new query for lines, not housenumbers anymore $sSQL = "SELECT distinct place_id FROM location_property_osmline"; - $sSQL .= " WHERE parent_place_id in (".$sPlaceIDs.") and ("; + $sSQL .= " WHERE startnumber is not NULL and parent_place_id in (".$sPlaceIDs.") and ("; if ($searchedHousenumber%2 == 0) { //if housenumber is even, look for housenumber in streets with interpolationtype even or all $sSQL .= "interpolationtype='even'"; @@ -1579,9 +1586,13 @@ class Geocode $fRange = 0.05; $sOrderBySQL = ''; - if ($sNearPointSQL) $sOrderBySQL = "ST_Distance($sNearPointSQL, l.centroid)"; - elseif ($sPlaceIDs) $sOrderBySQL = "ST_Distance(l.centroid, f.geometry)"; - elseif ($sPlaceGeom) $sOrderBysSQL = "ST_Distance(st_centroid('".$sPlaceGeom."'), l.centroid)"; + if ($oNearPoint) { + $sOrderBySQL = $oNearPoint->distanceSQL('l.centroid'); + } elseif ($sPlaceIDs) { + $sOrderBySQL = "ST_Distance(l.centroid, f.geometry)"; + } elseif ($sPlaceGeom) { + $sOrderBysSQL = "ST_Distance(st_centroid('".$sPlaceGeom."'), l.centroid)"; + } $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)"; @@ -1606,8 +1617,11 @@ class Geocode if (isset($aSearch['fRadius']) && $aSearch['fRadius']) $fRange = $aSearch['fRadius']; $sOrderBySQL = ''; - if ($sNearPointSQL) $sOrderBySQL = "ST_Distance($sNearPointSQL, l.geometry)"; - else $sOrderBySQL = "ST_Distance(l.geometry, f.geometry)"; + if ($oNearPoint) { + $sOrderBySQL = $oNearPoint->distanceSQL('l.geometry'); + } else { + $sOrderBySQL = "ST_Distance(l.geometry, f.geometry)"; + } $sSQL = "SELECT distinct l.place_id".($sOrderBysSQL?','.$sOrderBysSQL:''); $sSQL .= " FROM placex as l, placex as f "; @@ -1671,7 +1685,7 @@ class Geocode $sSQL .= " SELECT place_id "; $sSQL .= " FROM location_property_osmline "; $sSQL .= " WHERE place_id in (".join(',', array_keys($aResultPlaceIDs)).")"; - $sSQL .= " AND (30 between $this->iMinAddressRank and $this->iMaxAddressRank)"; + $sSQL .= " AND startnumber is not NULL AND (30 between $this->iMinAddressRank and $this->iMaxAddressRank)"; if (CONST_Debug) var_dump($sSQL); $aFilteredPlaceIDs = chksql($this->oDB->getCol($sSQL)); $tempIDs = array(); @@ -1697,8 +1711,8 @@ class Geocode $oReverse->setZoom(18); $aLookup = $oReverse->lookup( - (float)$this->aNearPoint[0], - (float)$this->aNearPoint[1], + $oNearPoint->lat(), + $oNearPoint->lon(), false ); @@ -1726,7 +1740,7 @@ class Geocode $aClassType = getClassTypesWithImportance(); $aRecheckWords = preg_split('/\b[\s,\\-]*/u', $sQuery); foreach ($aRecheckWords as $i => $sWord) { - if (!preg_match('/\pL/', $sWord)) unset($aRecheckWords[$i]); + if (!preg_match('/[\pL\pN]/', $sWord)) unset($aRecheckWords[$i]); } if (CONST_Debug) {