]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorSarah Hoffmann <lonvia@denofr.de>
Tue, 11 Aug 2015 21:19:51 +0000 (23:19 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Tue, 11 Aug 2015 21:19:51 +0000 (23:19 +0200)
Conflicts:
website/reverse.php
website/search.php

1  2 
lib/Geocode.php
lib/lib.php
settings/settings.php
tests/features/api/search_params.feature
tests/features/api/search_simple.feature
utils/setup.php
website/reverse.php

diff --combined lib/Geocode.php
index 38f7614233ea3313c3e67a84aa550fa09afc6f25,8b94e54938cf6ccc5fc623e9752e83765e3de3d3..a3ac4f0ecb0fe73060723aa1ec4e7719937d132f
@@@ -6,6 -6,8 +6,8 @@@
                protected $aLangPrefOrder = array();
  
                protected $bIncludeAddressDetails = false;
+               protected $bIncludeExtraTags = false;
+               protected $bIncludeNameDetails = false;
  
                protected $bIncludePolygonAsPoints = false;
                protected $bIncludePolygonAsText = false;
@@@ -16,7 -18,7 +18,7 @@@
  
                protected $aExcludePlaceIDs = array();
                protected $bDeDupe = true;
 -              protected $bReverseInPlan = false;
 +              protected $bReverseInPlan = true;
  
                protected $iLimit = 20;
                protected $iFinalLimit = 10;
                        return $this->bIncludeAddressDetails;
                }
  
+               function getIncludeExtraTags()
+               {
+                       return $this->bIncludeExtraTags;
+               }
+               function getIncludeNameDetails()
+               {
+                       return $this->bIncludeNameDetails;
+               }
                function setIncludePolygonAsPoints($b = true)
                {
                        $this->bIncludePolygonAsPoints = $b;
                function loadParamArray($aParams)
                {
                        if (isset($aParams['addressdetails'])) $this->bIncludeAddressDetails = (bool)$aParams['addressdetails'];
+                       if ((float) CONST_Postgresql_Version > 9.2)
+                       {
+                               if (isset($aParams['extratags'])) $this->bIncludeExtraTags = (bool)$aParams['extratags'];
+                               if (isset($aParams['namedetails'])) $this->bIncludeNameDetails = (bool)$aParams['namedetails'];
+                       }
                        if (isset($aParams['bounded'])) $this->bBoundedSearch = (bool)$aParams['bounded'];
                        if (isset($aParams['dedupe'])) $this->bDeDupe = (bool)$aParams['dedupe'];
  
                        $sSQL .= "get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
                        $sSQL .= "get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
                        $sSQL .= "get_name_by_language(name, ARRAY['ref']) as ref,";
+                       if ($this->bIncludeExtraTags) $sSQL .= "hstore_to_json(extratags)::text as extra,";
+                       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 .= ",langaddress ";
                        $sSQL .= ",placename ";
                        $sSQL .= ",ref ";
+                       if ($this->bIncludeExtraTags) $sSQL .= ",extratags";
+                       if ($this->bIncludeNameDetails) $sSQL .= ",name";
                        $sSQL .= ",extratags->'place' ";
  
                        if (30 >= $this->iMinAddressRank && 30 <= $this->iMaxAddressRank)
                                $sSQL .= "get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
                                $sSQL .= "null as placename,";
                                $sSQL .= "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(location_property_tiger.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
                                $sSQL .= "and 30 between $this->iMinAddressRank and $this->iMaxAddressRank ";
                                $sSQL .= "group by place_id";
                                if (!$this->bDeDupe) $sSQL .= ",place_id ";
 +                              /*
                                $sSQL .= " union ";
                                $sSQL .= "select 'L' 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, $sLanguagePrefArraySQL) as langaddress,";
                                $sSQL .= "null as placename,";
                                $sSQL .= "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.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 .= "group by place_id";
                                if (!$this->bDeDupe) $sSQL .= ",place_id";
                                $sSQL .= ",get_address_by_language(place_id, $sLanguagePrefArraySQL) ";
 +                              */
                        }
  
                        $sSQL .= " order by importance desc";
                                                        // 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
                                                                                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'])."'";
                                                                $aPlaceIDs = $this->oDB->getCol($sSQL);
  
                                                                // If not try the aux fallback table
 +                                                              /*
                                                                if (!sizeof($aPlaceIDs))
                                                                {
                                                                        $sSQL = "select place_id from location_property_aux where parent_place_id in (".$sPlaceIDs.") and housenumber = '".pg_escape_string($aSearch['sHouseNumber'])."'";
                                                                        if (CONST_Debug) var_dump($sSQL);
                                                                        $aPlaceIDs = $this->oDB->getCol($sSQL);
                                                                }
 +                                                              */
  
                                                                if (!sizeof($aPlaceIDs))
                                                                {
                                                        {
                                                                preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
                                                        }
 +                            /*
                                                        elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#',$aPointPolygon['astext'],$aMatch))
                                                        {
                                                                preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
                                                        }
 +                            */
                                                        elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#',$aPointPolygon['astext'],$aMatch))
                                                        {
                                                                $iSteps = max(8, min(100, ($fRadius * 40000)^2));
                                        }
                                }
  
+                               if ($this->bIncludeExtraTags)
+                               {
+                                       if ($aResult['extra'])
+                                       {
+                                               $aResult['sExtraTags'] = json_decode($aResult['extra']);
+                                       }
+                                       else
+                                       {
+                                               $aResult['sExtraTags'] = array();
+                                       }
+                               }
+                               if ($this->bIncludeNameDetails)
+                               {
+                                       if ($aResult['names'])
+                                       {
+                                               $aResult['sNameDetails'] = json_decode($aResult['names']);
+                                       }
+                                       else
+                                       {
+                                               $aResult['sNameDetails'] = array();
+                                       }
+                               }
                                // Adjust importance for the number of exact string matches in the result
                                $aResult['importance'] = max(0.001,$aResult['importance']);
                                $iCountWords = 0;
                                {
                                        $aResult['foundorder'] += 0.01;
                                }
+                               if (CONST_Debug) { var_dump($aResult); }
                                $aSearchResults[$iResNum] = $aResult;
                        }
                        uasort($aSearchResults, 'byImportance');
diff --combined lib/lib.php
index e548dc3af3abe35fd82efc1e6df040ab63632e23,57bd4723cdc2a284875770f9f39f8f0e449e4324..dfd7008d82ae4e9e2b82dbc311819819b96263a9
                exit;
        }
  
+       function getParamBool($name, $default=false)
+       {
+               if (!isset($_GET[$name])) return $default;
+               return (bool) $_GET[$name];
+       }
  
        function fail($sError, $sUserError = false)
        {
        {
                $aResult = array(array(join(' ',$aWords)));
                $sFirstToken = '';
 -              if ($iDepth < 8) {
 +              if ($iDepth < 7) {
                        while(sizeof($aWords) > 1)
                        {
                                $sWord = array_shift($aWords);
        }
  
  
-       function javascript_renderData($xVal)
+       function javascript_renderData($xVal, $iOptions = 0)
        {
                header("Access-Control-Allow-Origin: *");
-               $iOptions = 0;
                if (defined('PHP_VERSION_ID') && PHP_VERSION_ID > 50400)
-                       $iOptions = JSON_UNESCAPED_UNICODE;
+                       $iOptions |= JSON_UNESCAPED_UNICODE;
                $jsonout = json_encode($xVal, $iOptions);
  
                if( ! isset($_GET['json_callback']))
diff --combined settings/settings.php
index 62892ed5dc828c190e67c910f433283283e261bb,cc81e7a90967f1b6c73a084bdab7b15c85439324..3deda462fc5f94e61a8e360a0219e40cebeefa2a
  
        // Website settings
        @define('CONST_NoAccessControl', true);
 -      @define('CONST_ClosedForIndexing', false);
 -      @define('CONST_ClosedForIndexingExceptionIPs', '');
        @define('CONST_BlockedIPs', '');
 +      @define('CONST_IPBanFile', CONST_BasePath.'/settings/ip_blocks');
 +      @define('CONST_WhitelistedIPs', '');
 +      @define('CONST_BlockedUserAgents', '');
 +      @define('CONST_BlockReverseMaxLoad', 15);
        @define('CONST_BulkUserIPs', '');
        @define('CONST_BlockMessage', ''); // additional info to show for blocked IPs
  
 -      @define('CONST_Website_BaseURL', 'http://'.php_uname('n').'/');
 +      @define('CONST_Website_BaseURL', 'http://nominatim.openstreetmap.org/');
        @define('CONST_Tile_Default', 'Mapnik');
  
        @define('CONST_Default_Language', false);
  
        @define('CONST_Search_TryDroppedAddressTerms', false);
        @define('CONST_Search_NameOnlySearchFrequencyThreshold', 500);
+       // If set to true, then reverse order of queries will be tried by default.
+       // When set to false only selected languages alloow reverse search.
+       @define('CONST_Search_ReversePlanForAll', true);
  
        @define('CONST_Places_Max_ID_count', 50); 
  
index 92ca8c398b7d812cba013a6514ed3fa222135d9f,7099c72fe4d9f0e4c7fa4b75253f8529093aa441..a4885a1577933fcdfbb3ef80cb928a99acaf5320
@@@ -70,7 -70,7 +70,7 @@@ Feature: Search querie
          Then result addresses contain
            | ID | city
            | 0  | Chicago
-     
      Scenario: No POI search with unbounded viewbox
          Given the request parameters
            | viewbox
@@@ -83,7 -83,7 +83,7 @@@
      Scenario: bounded search remains within viewbox, even with no results
          Given the request parameters
           | bounded | viewbox
 -         | 1       | 43.54285,-5.662003,43.5403125,-5.6563282
 +         | 1       | 43.5403125,-5.6563282,43.54285,-5.662003
           When sending json search query "restaurant"
          Then less than 1 result is returned
  
          | 0.5
          | 999
          | nan
+     Scenario Outline: Search with extratags
+         Given the request parameters
+           | extratags
+           | 1
+         When sending <format> search query "Hauptstr"
+         Then result 0 has attributes extratags
+         And result 1 has attributes extratags
+     Examples:
+         | format
+         | xml
+         | json
+         | jsonv2
+     Scenario Outline: Search with namedetails
+         Given the request parameters
+           | namedetails
+           | 1
+         When sending <format> search query "Hauptstr"
+         Then result 0 has attributes namedetails
+         And result 1 has attributes namedetails
+     Examples:
+         | format
+         | xml
+         | json
+         | jsonv2
index 747d4004d9c008c711a9bdff10f9860841dc59c1,2cb27b7cf61be0c3237f23220d804bf876374d18..43f460980da073be5f479963a47b2c9cc829b9a1
@@@ -51,6 -51,10 +51,10 @@@ Feature: Simple Test
       | limit            | 1000
       | dedupe           | 1
       | dedupe           | 0
+      | extratags        | 1
+      | extratags        | 0
+      | namedetails      | 1
+      | namedetails      | 0
  
      Scenario: Search with invalid output format
          Given the request parameters
      Scenario: Empty XML search with viewbox
          Given the request parameters
            | viewbox
 -          | 12,45.13,77,33
 +          | 12,45.13,13,44
          When sending xml search query "xnznxvcx"
          Then result header contains
            | attr        | value
            | querystring | xnznxvcx
            | polygon     | false
 -          | viewbox     | 12,45.13,77,33
 +          | viewbox     | 12,45.13,13,44
  
      Scenario: Empty XML search with viewboxlbrt
          Given the request parameters
            | viewboxlbrt
 -          | 12,34.13,77,45
 +          | 12,34.13,13,35
          When sending xml search query "xnznxvcx"
          Then result header contains
            | attr        | value
            | querystring | xnznxvcx
            | polygon     | false
 -          | viewbox     | 12,45.13,77,33
 +          | viewbox     | 12,34.13,13,35
  
      Scenario: Empty XML search with viewboxlbrt and viewbox
          Given the request parameters
 -          | viewbox        | viewboxblrt
 -          | 12,45.13,77,33 | 1,2,3,4
 +          | viewbox          | viewboxblrt
 +          | 12,45.13,13.5,44 | 1,0,2,1
          When sending xml search query "pub"
          Then result header contains
            | attr        | value
            | querystring | pub
            | polygon     | false
 -          | viewbox     | 12,45.13,77,33
 +          | viewbox     | 12,45.13,13.5,44
  
  
      Scenario Outline: Empty XML search with polygon values
diff --combined utils/setup.php
index 3bbe18d4231c6c4974023b8f89d5dac18a1d1e10,14fe675e9c2173b79a6298fc673b44c53739a4df..be422949b6b1e8945d988d97a20f5224d92d7b2a
        }
  
        // Assume we can steal all the cache memory in the box (unless told otherwise)
-       $iCacheMemory = (isset($aCMDResult['osm2pgsql-cache'])?$aCMDResult['osm2pgsql-cache']:getCacheMemoryMB());
-       if ($iCacheMemory > getTotalMemoryMB())
+       if (isset($aCMDResult['osm2pgsql-cache']))
+       {
+               $iCacheMemory = $aCMDResult['osm2pgsql-cache'];
+       }
+       else
        {
                $iCacheMemory = getCacheMemoryMB();
-               echo "WARNING: resetting cache memory to $iCacheMemory\n";
        }
  
        $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
                if (CONST_Tablespace_Place_Index)
                        $osm2pgsql .= ' --tablespace-main-index '.CONST_Tablespace_Place_Index;
                $osm2pgsql .= ' -lsc -O gazetteer --hstore';
 -              $osm2pgsql .= ' -C '.$iCacheMemory;
 +              $osm2pgsql .= ' -C 25000';
                $osm2pgsql .= ' -P '.$aDSNInfo['port'];
                $osm2pgsql .= ' -d '.$aDSNInfo['database'].' '.$aCMDResult['osm-file'];
                passthruCheckReturn($osm2pgsql);
                $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,calculated_country_code,";
                $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from (select calculated_country_code,postcode,";
                $sSQL .= "avg(st_x(st_centroid(geometry))) as x,avg(st_y(st_centroid(geometry))) as y ";
 -              $sSQL .= "from placex where postcode is not null group by calculated_country_code,postcode) as x";
 +              $sSQL .= "from placex where postcode is not null and calculated_country_code not in ('ie') group by calculated_country_code,postcode) as x";
                if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection));
  
                $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,calculated_country_code,geometry) ";
diff --combined website/reverse.php
index d70a11e9e2a1a0f3639711f9522273a5865bab5a,abc33a09ed297e382cc1d3862fc8147badc63e6f..ee2fa475a308380f616cf0aa92117eeb1ad5f902
@@@ -6,6 -6,18 +6,6 @@@
        require_once(CONST_BasePath.'/lib/PlaceLookup.php');
        require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
  
 -      if (strpos(CONST_BulkUserIPs, ','.$_SERVER["REMOTE_ADDR"].',') !== false)
 -      {
 -              $fLoadAvg = getLoadAverage();
 -              if ($fLoadAvg > 2) sleep(60);
 -              if ($fLoadAvg > 4) sleep(120);
 -              if ($fLoadAvg > 6)
 -              {
 -                      echo "Bulk User: Temporary block due to high server load\n";
 -                      exit;
 -              }
 -      }
 -
        $oDB =& getDB();
        ini_set('memory_limit', '200M');
  
                $sOutputFormat = $_GET['format'];
        }
  
-       // Show address breakdown
-       $bShowAddressDetails = true;
-       if (isset($_GET['addressdetails'])) $bShowAddressDetails = (bool)$_GET['addressdetails'];
        // Preferred language
        $aLangPrefOrder = getPreferredLanguages();
  
        $hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
  
        if (isset($_GET['osm_type']) && isset($_GET['osm_id']) && (int)$_GET['osm_id'] && ($_GET['osm_type'] == 'N' || $_GET['osm_type'] == 'W' || $_GET['osm_type'] == 'R'))
        {
-               $oPlaceLookup = new PlaceLookup($oDB);
-               $oPlaceLookup->setLanguagePreference($aLangPrefOrder);
-               $oPlaceLookup->setIncludeAddressDetails($bShowAddressDetails);
-               $oPlaceLookup->setOSMID($_GET['osm_type'], $_GET['osm_id']);
-               $aPlace = $oPlaceLookup->lookup();
+               $aLookup = array('osm_type' => $_GET['osm_type'], 'osm_id' => $_GET['osm_id']);
        }
        else if (isset($_GET['lat']) && isset($_GET['lon']) && preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $_GET['lat']) && preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $_GET['lon']))
        {
                $oReverseGeocode = new ReverseGeocode($oDB);
                $oReverseGeocode->setLanguagePreference($aLangPrefOrder);
-               $oReverseGeocode->setIncludeAddressDetails($bShowAddressDetails);
  
                $oReverseGeocode->setLatLon($_GET['lat'], $_GET['lon']);
                $oReverseGeocode->setZoom(@$_GET['zoom']);
  
-               $aPlace = $oReverseGeocode->lookup();
+               $aLookup = $oReverseGeocode->lookup();
+               if (CONST_Debug) var_dump($aLookup);
+       }
+       else
+       {
+               $aLookup = null;
+       }
+       if ($aLookup)
+       {
+               $oPlaceLookup = new PlaceLookup($oDB);
+               $oPlaceLookup->setLanguagePreference($aLangPrefOrder);
+               $oPlaceLookup->setIncludeAddressDetails(getParamBool('addressdetails', true));
+               $oPlaceLookup->setIncludeExtraTags(getParamBool('extratags', false));
+               $oPlaceLookup->setIncludeNameDetails(getParamBool('namedetails', false));
+               $aPlace = $oPlaceLookup->lookupPlace($aLookup);
        }
        else
        {
                $aPlace = null;
        }
  
 +      logEnd($oDB, $hLog, sizeof($aPlace)?1:0);
  
-       if (CONST_Debug) exit;
+       if (CONST_Debug)
+       {
+               var_dump($aPlace);
+               exit;
+       }
  
        include(CONST_BasePath.'/lib/template/address-'.$sOutputFormat.'.php');