]> git.openstreetmap.org Git - nominatim.git/blobdiff - lib/Geocode.php
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / lib / Geocode.php
index 314d20bc88f0cf75e691a646ba8e472a99a7a8d3..20749fffe0e860cd74c363f3f5fc4692b401e841 100644 (file)
@@ -25,7 +25,7 @@ class Geocode
 
     protected $aExcludePlaceIDs = array();
     protected $bDeDupe = true;
-    protected $bReverseInPlan = false;
+    protected $bReverseInPlan = true;
 
     protected $iLimit = 20;
     protected $iFinalLimit = 10;
@@ -63,7 +63,7 @@ class Geocode
     private function normTerm($sTerm)
     {
         if ($this->oNormalizer === null) {
-            return null;
+            return $sTerm;
         }
 
         return $this->oNormalizer->transliterate($sTerm);
@@ -1274,8 +1274,8 @@ class Geocode
                     }
 
                     // No location term?
-                    if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['oNear']) {
-                        if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber']) {
+                    if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress'])) {
+                        if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber'] && !$aSearch['oNear']) {
                             // Just looking for a country by code - look it up
                             if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank) {
                                 $sSQL = "SELECT place_id FROM placex WHERE country_code='".$aSearch['sCountryCode']."' AND rank_search = 4";
@@ -1295,39 +1295,32 @@ class Geocode
                             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)";
-                                $sSQL .= " WHERE st_contains($this->sViewboxSmallSQL, ct.centroid)";
+                                if ($aSearch['oNear']) {
+                                    $sSQL .= " WHERE ".$aSearch['oNear']->withinSQL('ct.centroid');
+                                } else {
+                                    $sSQL .= " WHERE st_contains($this->sViewboxSmallSQL, ct.centroid)";
+                                }
                                 if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
                                 if (sizeof($this->aExcludePlaceIDs)) {
                                     $sSQL .= " AND place_id not in (".join(',', $this->aExcludePlaceIDs).")";
                                 }
-                                if ($this->sViewboxCentreSQL) $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, ct.centroid) ASC";
+                                if ($this->sViewboxCentreSQL) {
+                                    $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, ct.centroid) ASC";
+                                } elseif ($aSearch['oNear']) {
+                                    $sSQL .= " ORDER BY ".$aSearch['oNear']->distanceSQL('ct.centroid').' ASC';
+                                }
                                 $sSQL .= " limit $this->iLimit";
                                 if (CONST_Debug) var_dump($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
-                                // expansion in that case.
-                                // Also don't expand if bounded results were requested.
-                                if (!sizeof($aPlaceIDs) && !sizeof($this->aExcludePlaceIDs) && !$this->bBoundedSearch) {
-                                    $sSQL = "SELECT place_id FROM place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct";
-                                    if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)";
-                                    $sSQL .= " WHERE ST_Contains($this->sViewboxLargeSQL, ct.centroid)";
-                                    if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
-                                    if ($this->sViewboxCentreSQL) $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, ct.centroid) ASC";
-                                    $sSQL .= " LIMIT $this->iLimit";
-                                    if (CONST_Debug) var_dump($sSQL);
-                                    $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                }
-                            } else {
+                            } else if ($aSearch['oNear']) {
                                 $sSQL = "SELECT place_id ";
                                 $sSQL .= "FROM placex ";
                                 $sSQL .= "WHERE class='".$aSearch['sClass']."' ";
                                 $sSQL .= "  AND type='".$aSearch['sType']."'";
-                                $sSQL .= "  AND ST_Contains($this->sViewboxSmallSQL, geometry) ";
+                                $sSQL .= "  AND ".$aSearch['oNear']->withinSQL('geometry');
                                 $sSQL .= "  AND linked_place_id is null";
                                 if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
-                                if ($this->sViewboxCentreSQL)   $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, centroid) ASC";
+                                $sSQL .= " ORDER BY ".$aSearch['oNear']->distanceSQL('centroid')." ASC";
                                 $sSQL .= " LIMIT $this->iLimit";
                                 if (CONST_Debug) var_dump($sSQL);
                                 $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
@@ -1390,19 +1383,20 @@ class Geocode
                         // 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
                             if (CONST_Search_NameOnlySearchFrequencyThreshold
                                 && 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'])) {
+                                /*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'])."'";