]> git.openstreetmap.org Git - nominatim.git/blobdiff - lib/ReverseGeocode.php
new query if no polygon is found
[nominatim.git] / lib / ReverseGeocode.php
index a6d4b76f47e76c79a0f289ba6e8fbff0c3060605..422159311557ea5cb77edca281b68cb1ebbbe0d4 100644 (file)
@@ -69,36 +69,28 @@ class ReverseGeocode
         );
     }
     
-    protected function noPolygonfound($sPointSQL, $iMaxRank)
+    protected function noPolygonFound($sPointSQL, $iMaxRank)
     {
-        // search_rank => search diameter
-        $aRankDiam = array(
-            18 => 0.2,
-            17 => 0.6,
-            12 => 0.8,
-            10 => 1,
-            8 => 2,
-            4 => 3,
-        );
+        $sSQL = 'SELECT * FROM country_osm_grid';
+        $sSQL .= ' WHERE ST_CONTAINS (geometry, '.$sPointSQL.' )';
         
-        foreach ($aRankDiam as $key => $value) {
-            if ($key > $iMaxRank) continue;
-    
-            $sSQL = 'SELECT *';
-            $sSQL .= ' FROM (';
-            $sSQL .= ' SELECT place_id, rank_address,country_code, geometry,';
-            $sSQL .= ' ST_distance('.$sPointSQL.', geometry) as distance';
+        $aPoly = chksql(
+            $this->oDB->getRow($sSQL),
+            'Could not determine polygon containing the point.'
+        );
+        if ($aPoly) {
+            $sCountryCode = $aPoly['country_code'];
+            
+            $sSQL = 'SELECT *, ST_distance('.$sPointSQL.', geometry) as distance';
             $sSQL .= ' FROM placex';
             $sSQL .= ' WHERE osm_type = \'N\'';
+            $sSQL .= ' AND country_code = \''.$sCountryCode.'\'';
             $sSQL .= ' AND rank_address > 0';
-            $sSQL .= ' AND rank_address <= ' .$key;
+            $sSQL .= ' AND rank_address <= ' .Min(25, $iMaxRank);
             $sSQL .= ' AND type != \'postcode\'';
             $sSQL .= ' AND name IS NOT NULL ';
             $sSQL .= ' and indexed_status = 0 and linked_place_id is null';
-            $sSQL .= ' ORDER BY rank_address DESC, distance ASC';
-            $sSQL .= ' limit 500) as a';
-            $sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$value.')';
-            $sSQL .= ' ORDER BY rank_address DESC, distance ASC';
+            $sSQL .= ' ORDER BY distance ASC, rank_address DESC';
             $sSQL .= ' LIMIT 1';
             
             if (CONST_Debug) var_dump($sSQL);
@@ -108,7 +100,6 @@ class ReverseGeocode
             );
             if ($aPlacNode) {
                 return $aPlacNode;
-                break;
             }
         }
     }
@@ -171,8 +162,6 @@ class ReverseGeocode
                     return $aPlacNode;
                 }
             }
-        }else{
-            return $this->noPolygonfound ($sPointSQL, $iMaxRank);
         }
         return $aPoly;
     }
@@ -197,6 +186,22 @@ class ReverseGeocode
         $fMaxAreaDistance = 1;
         $bIsTigerStreet = false;
         
+        // try with interpolations before continuing
+        if ($bDoInterpolation && $iMaxRank >= 30) {
+            $aHouse = $this->lookupInterpolation($sPointSQL, $fSearchDiam/3);
+
+            if ($aHouse) {
+                $oResult = new Result($aHouse['place_id'], Result::TABLE_OSMLINE);
+                $oResult->iHouseNumber = closestHouseNumber($aHouse);
+
+                $aPlace = $aHouse;
+                $iParentPlaceID = $aHouse['parent_place_id']; // the street
+                $iMaxRank = 30;
+                
+                return $oResult;
+            }
+        }// no interpolation found, continue search
+        
         // for POI or street level
         if ($iMaxRank >= 26) {
             $sSQL = 'select place_id,parent_place_id,rank_address,country_code,';
@@ -261,6 +266,11 @@ class ReverseGeocode
                 $aPlace = $this->lookupPolygon($sPointSQL, $iMaxRank);
                 if ($aPlace) {
                     $oResult = new Result($aPlace['place_id']);
+                } else {
+                    $aPlace = $this->noPolygonFound($sPointSQL, $iMaxRank);
+                    if ($aPlace) {
+                        $oResult = new Result($aPlace['place_id']);
+                    }
                 }
             }
             // lower than street level ($iMaxRank < 26 )
@@ -268,6 +278,11 @@ class ReverseGeocode
             $aPlace = $this->lookupPolygon($sPointSQL, $iMaxRank);
             if ($aPlace) {
                 $oResult = new Result($aPlace['place_id']);
+            } else {
+                $aPlace = $this->noPolygonFound($sPointSQL, $iMaxRank);
+                if ($aPlace) {
+                    $oResult = new Result($aPlace['place_id']);
+                }
             }
         }
         return $oResult;