X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/eb0b3bfa4cd74ee9e425c54868a30d8859e694cd..bb1c3f23abe70a618851bdda27e8410b59ab7faf:/lib/Geocode.php diff --git a/lib/Geocode.php b/lib/Geocode.php index 48683e64..0f79eae5 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -1,4 +1,7 @@ oDB =& $oDB; } - function setReverseInPlan($bReverse) + public function setReverseInPlan($bReverse) { $this->bReverseInPlan = $bReverse; } - function setLanguagePreference($aLangPref) + public function setLanguagePreference($aLangPref) { $this->aLangPrefOrder = $aLangPref; } - function getIncludeAddressDetails() + public function getIncludeAddressDetails() { return $this->bIncludeAddressDetails; } - function getIncludeExtraTags() + public function getIncludeExtraTags() { return $this->bIncludeExtraTags; } - function getIncludeNameDetails() + public function getIncludeNameDetails() { return $this->bIncludeNameDetails; } - function setIncludePolygonAsPoints($b = true) + public function setIncludePolygonAsPoints($b = true) { $this->bIncludePolygonAsPoints = $b; } - function setIncludePolygonAsText($b = true) + public function setIncludePolygonAsText($b = true) { $this->bIncludePolygonAsText = $b; } - function setIncludePolygonAsGeoJSON($b = true) + public function setIncludePolygonAsGeoJSON($b = true) { $this->bIncludePolygonAsGeoJSON = $b; } - function setIncludePolygonAsKML($b = true) + public function setIncludePolygonAsKML($b = true) { $this->bIncludePolygonAsKML = $b; } - function setIncludePolygonAsSVG($b = true) + public function setIncludePolygonAsSVG($b = true) { $this->bIncludePolygonAsSVG = $b; } - function setPolygonSimplificationThreshold($f) + public function setPolygonSimplificationThreshold($f) { $this->fPolygonSimplificationThreshold = $f; } - function setLimit($iLimit = 10) + public function setLimit($iLimit = 10) { if ($iLimit > 50) $iLimit = 50; if ($iLimit < 1) $iLimit = 1; @@ -117,48 +121,48 @@ class Geocode $this->iLimit = $iLimit + min($iLimit, 10); } - function getExcludedPlaceIDs() + public function getExcludedPlaceIDs() { return $this->aExcludePlaceIDs; } - function getViewBoxString() + public function getViewBoxString() { if (!$this->aViewBox) return null; return $this->aViewBox[0].','.$this->aViewBox[3].','.$this->aViewBox[2].','.$this->aViewBox[1]; } - function setFeatureType($sFeatureType) + public function setFeatureType($sFeatureType) { switch ($sFeatureType) { - case 'country': - $this->setRankRange(4, 4); - break; - case 'state': - $this->setRankRange(8, 8); - break; - case 'city': - $this->setRankRange(14, 16); - break; - case 'settlement': - $this->setRankRange(8, 20); - break; + case 'country': + $this->setRankRange(4, 4); + break; + case 'state': + $this->setRankRange(8, 8); + break; + case 'city': + $this->setRankRange(14, 16); + break; + case 'settlement': + $this->setRankRange(8, 20); + break; } } - function setRankRange($iMin, $iMax) + public function setRankRange($iMin, $iMax) { $this->iMinAddressRank = $iMin; $this->iMaxAddressRank = $iMax; } - function setRoute($aRoutePoints, $fRouteWidth) + public function setRoute($aRoutePoints, $fRouteWidth) { $this->aViewBox = false; $this->sViewboxCentreSQL = "ST_SetSRID('LINESTRING("; $sSep = ''; - foreach ($this->aRoutePoints as $aPoint) { + foreach ($aRoutePoints as $aPoint) { $fPoint = (float)$aPoint; $this->sViewboxCentreSQL .= $sSep.$fPoint; $sSep = ($sSep == ' ') ? ',' : ' '; @@ -172,10 +176,20 @@ class Geocode $this->sViewboxLargeSQL .= ','.($fRouteWidth/30).')'; } - function setViewbox($aViewbox) + public function setViewbox($aViewbox) { $this->aViewBox = array_map('floatval', $aViewbox); + if ($this->aViewBox[0] < -180 + || $this->aViewBox[2] > 180 + || $this->aViewBox[0] >= $this->aViewBox[2] + || $this->aViewBox[1] < -90 + || $this->aViewBox[3] > 90 + || $this->aViewBox[1] >= $this->aViewBox[3] + ) { + userError("Bad parameter 'viewbox'. Out of range."); + } + $fHeight = $this->aViewBox[0] - $this->aViewBox[2]; $fWidth = $this->aViewBox[1] - $this->aViewBox[3]; $aBigViewBox[0] = $this->aViewBox[0] + $fHeight; @@ -188,24 +202,24 @@ class Geocode $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) + public function setNearPoint($aNearPoint, $fRadiusDeg = 0.1) { $this->aNearPoint = array((float)$aNearPoint[0], (float)$aNearPoint[1], (float)$fRadiusDeg); } - function setQuery($sQueryString) + public function setQuery($sQueryString) { $this->sQuery = $sQueryString; $this->aStructuredQuery = false; } - function getQueryString() + public function getQueryString() { return $this->sQuery; } - function loadParamArray($oParams) + public function loadParamArray($oParams) { $this->bIncludeAddressDetails = $oParams->getBool('addressdetails', $this->bIncludeAddressDetails); @@ -248,16 +262,22 @@ class Geocode $aCountries[] = strtolower($sCountryCode); } } - if (isset($aCountryCodes)) + if (isset($aCountries)) $this->aCountryCodes = $aCountries; } $aViewbox = $oParams->getStringList('viewboxlbrt'); if ($aViewbox) { + if (count($aViewbox) != 4) { + userError("Bad parmater 'viewbox'. Expected 4 coordinates."); + } $this->setViewbox($aViewbox); } else { $aViewbox = $oParams->getStringList('viewbox'); if ($aViewbox) { + if (count($aViewbox) != 4) { + userError("Bad parmater 'viewbox'. Expected 4 coordinates."); + } $this->setViewBox(array( $aViewbox[0], $aViewbox[3], @@ -274,7 +294,7 @@ class Geocode } } - function setQueryFromParams($oParams) + public function setQueryFromParams($oParams) { // Search query $sQuery = $oParams->getString('q'); @@ -294,7 +314,7 @@ class Geocode } } - function loadStructuredAddressElement($sValue, $sKey, $iNewMinAddressRank, $iNewMaxAddressRank, $aItemListValues) + public function loadStructuredAddressElement($sValue, $sKey, $iNewMinAddressRank, $iNewMaxAddressRank, $aItemListValues) { $sValue = trim($sValue); if (!$sValue) return false; @@ -307,7 +327,7 @@ class Geocode return true; } - function setStructuredQuery($sAmentiy = false, $sStreet = false, $sCity = false, $sCounty = false, $sState = false, $sCountry = false, $sPostalCode = false) + public function setStructuredQuery($sAmentiy = false, $sStreet = false, $sCity = false, $sCounty = false, $sState = false, $sCountry = false, $sPostalCode = false) { $this->sQuery = false; @@ -335,7 +355,7 @@ class Geocode } } - function fallbackStructuredQuery() + public function fallbackStructuredQuery() { if (!$this->aStructuredQuery) return false; @@ -356,7 +376,7 @@ class Geocode return false; } - function getDetails($aPlaceIDs) + public function getDetails($aPlaceIDs) { //$aPlaceIDs is an array with key: placeID and value: tiger-housenumber, if found, else -1 if (sizeof($aPlaceIDs) == 0) return array(); @@ -378,7 +398,10 @@ class Geocode if ($this->bIncludeNameDetails) $sSQL .= "hstore_to_json(name)::text as names,"; $sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, "; $sSQL .= $sImportanceSQL."coalesce(importance,0.75-(rank_search::float/40)) as importance, "; - $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(CASE WHEN placex.rank_search < 28 THEN placex.place_id ELSE placex.parent_place_id END) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, "; + $sSQL .= "(select max(p.importance*(p.rank_address+2))"; + $sSQL .= " from place_addressline s, placex p"; + $sSQL .= " where s.place_id = min(CASE WHEN placex.rank_search < 28 THEN placex.place_id ELSE placex.parent_place_id END)"; + $sSQL .= " and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, "; $sSQL .= "(extratags->'place') as extra_place "; $sSQL .= "from placex where place_id in ($sPlaceIDs) "; $sSQL .= "and (placex.rank_address between $this->iMinAddressRank and $this->iMaxAddressRank "; @@ -397,7 +420,7 @@ class Geocode $sSQL .= ",extratags->'place' "; if (30 >= $this->iMinAddressRank && 30 <= $this->iMaxAddressRank) { - //only Tiger housenumbers and interpolation lines need to be interpolated, because they are saved as lines + // only Tiger housenumbers and interpolation lines need to be interpolated, because they are saved as lines // with start- and endnumber, the common osm housenumbers are usually saved as points $sHousenumbers = ""; $i = 0; @@ -408,20 +431,26 @@ class Geocode 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) + // 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 'T' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, 30 as rank_search, 30 as rank_address, min(place_id) as place_id, min(parent_place_id) as parent_place_id, 'us' as country_code"; - $sSQL .= ", get_address_by_language(place_id, housenumber_for_place, $sLanguagePrefArraySQL) as langaddress "; - $sSQL .= ", null as placename"; - $sSQL .= ", null as ref"; + $sSQL .= " select 'T' as osm_type, place_id as osm_id, 'place' as class,"; + $sSQL .= " 'house' as type, null as admin_level, 30 as rank_search,"; + $sSQL .= " 30 as rank_address, min(place_id) as place_id,"; + $sSQL .= " min(parent_place_id) as parent_place_id, 'us' as country_code,"; + $sSQL .= " get_address_by_language(place_id, housenumber_for_place, $sLanguagePrefArraySQL) as langaddress,"; + $sSQL .= " null as placename, null as ref"; if ($this->bIncludeExtraTags) $sSQL .= ", null as extra"; if ($this->bIncludeNameDetails) $sSQL .= ", null as names"; $sSQL .= ", avg(st_x(centroid)) as lon, avg(st_y(centroid)) as lat,"; $sSQL .= $sImportanceSQL."-1.15 as importance "; - $sSQL .= ", (select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(blub.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance "; + $sSQL .= ", (select max(p.importance*(p.rank_address+2))"; + $sSQL .= " from place_addressline s, placex p"; + $sSQL .= " where s.place_id = min(blub.parent_place_id)"; + $sSQL .= " and p.place_id = s.address_place_id and s.isaddress"; + $sSQL .= " and p.importance is not null) as addressimportance "; $sSQL .= ", null as extra_place "; $sSQL .= " from (select place_id"; - //interpolate the Tiger housenumbers here + // interpolate the Tiger housenumbers here $sSQL .= ", ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) as centroid, parent_place_id, housenumber_for_place"; $sSQL .= " from (location_property_tiger "; $sSQL .= " join (values ".$sHousenumbers.") as housenumbers(place_id, housenumber_for_place) using(place_id)) "; @@ -432,7 +461,10 @@ class Geocode // osmline // interpolation line 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 'W' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, 30 as rank_search, 30 as rank_address, min(place_id) as place_id, min(parent_place_id) as parent_place_id, calculated_country_code as country_code, "; + $sSQL .= "select 'W' as osm_type, place_id as osm_id, 'place' as class,"; + $sSQL .= " 'house' as type, null as admin_level, 30 as rank_search,"; + $sSQL .= " 30 as rank_address, min(place_id) as place_id,"; + $sSQL .= " min(parent_place_id) as parent_place_id, calculated_country_code as country_code, "; $sSQL .= "get_address_by_language(place_id, housenumber_for_place, $sLanguagePrefArraySQL) as langaddress, "; $sSQL .= "null as placename, "; $sSQL .= "null as ref, "; @@ -444,7 +476,7 @@ class Geocode $sSQL .= " where s.place_id = min(blub.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance,"; $sSQL .= " null as extra_place "; $sSQL .= " from (select place_id, calculated_country_code "; - //interpolate the housenumbers here + // interpolate the housenumbers here $sSQL .= ", CASE WHEN startnumber != endnumber THEN ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) "; $sSQL .= " ELSE ST_LineInterpolatePoint(linegeo, 0.5) END as centroid"; $sSQL .= ", parent_place_id, housenumber_for_place "; @@ -456,7 +488,10 @@ class Geocode if (CONST_Use_Aux_Location_data) { $sSQL .= " union "; - $sSQL .= "select 'L' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, 0 as rank_search, 0 as rank_address, min(place_id) as place_id, min(parent_place_id) as parent_place_id, 'us' as country_code, "; + $sSQL .= "select 'L' as osm_type, place_id as osm_id, 'place' as class,"; + $sSQL .= " 'house' as type, null as admin_level, 0 as rank_search,"; + $sSQL .= " 0 as rank_address, min(place_id) as place_id,"; + $sSQL .= " min(parent_place_id) as parent_place_id, 'us' as country_code, "; $sSQL .= "get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) as langaddress, "; $sSQL .= "null as placename, "; $sSQL .= "null as ref, "; @@ -464,7 +499,11 @@ class Geocode if ($this->bIncludeNameDetails) $sSQL .= "null as names, "; $sSQL .= "avg(ST_X(centroid)) as lon, avg(ST_Y(centroid)) as lat, "; $sSQL .= $sImportanceSQL."-1.10 as importance, "; - $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(location_property_aux.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, "; + $sSQL .= "(select max(p.importance*(p.rank_address+2))"; + $sSQL .= " from place_addressline s, placex p"; + $sSQL .= " where s.place_id = min(location_property_aux.parent_place_id)"; + $sSQL .= " and p.place_id = s.address_place_id and s.isaddress"; + $sSQL .= " and p.importance is not null) as addressimportance, "; $sSQL .= "null as extra_place "; $sSQL .= "from location_property_aux where place_id in ($sPlaceIDs) "; $sSQL .= "and 30 between $this->iMinAddressRank and $this->iMaxAddressRank "; @@ -476,7 +515,8 @@ class Geocode $sSQL .= " order by importance desc"; if (CONST_Debug) { - echo "