]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorSarah Hoffmann <lonvia@denofr.de>
Sun, 3 May 2015 07:19:23 +0000 (09:19 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Sun, 3 May 2015 07:19:23 +0000 (09:19 +0200)
AUTHORS
ChangeLog
configure.ac
lib/Geocode.php
lib/PlaceLookup.php
lib/ReverseGeocode.php
settings/settings.php
tests/features/api/reverse.feature
tests/features/api/search.feature
tests/features/api/search_params.feature
website/search.php

diff --git a/AUTHORS b/AUTHORS
index ea48a49c67d7e7c758efd6ec14d926c09479d370..b90e705714e4702a4714845c05fdd55a8551e73c 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -15,3 +15,5 @@ Nominatim was written by:
   Kurt Roeckx
   Rodolphe QuiĆ©deville
   Marc Tobias Metten
+
+Reverse geocoding using Tiger data feature made possible with support from Guru Labs
index ae45f6ca5bef4bde8ef40e1b7776973d18559716..d6002d4389cbce9d74ff4af4de006b4df7ae9667 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,48 @@
-2.0.1
+ * reverse geocoding looking includes looking up Tiger data
 
- * delete outdated entries from location_area_country
- * remove remaining uses of INTEGER, to allow node ids larger than 2^31
+
+2.4
+
+ * drop support for postgres 8.4
+ * rewrite address interpolation
+ * switch to C++ version of osm2pgsql and rewrite tag filtering
+ * support for bridge:name and tunnel:name, man_made, junction
+ * drop way-node index (reduces database size by about 15%)
+ * add support for configuring tablespaces and webserver user
+ * better evaluation of search queries in right-to-left notation
+ * improve house number search for streets with many duplicate entries
+ * code cleanup (remove unused functions and tables)
+
+2.3
+
+ * further improve ordering of results
+ * support for more lat/lon formats in search-as-reverse
+ * fix handling of GB postcodes
+ * new functional test suite
+ * support for waterway relations
+ * inherit postcodes from street to poi
+ * fix housenumber normalisation to find non-latin house numbers
+ * take viewbox into account for ordering of results
+ * pois may now inherit address tags from surrounding buildings
+ * improve what objects may participate in an address
+ * clean up handled class/type combinations to current OSM usage
+ * lots of bug fixes
+
+2.2
+
+ * correct database rights for www-data
+ * add timestamps for update output
+ * load postgis via extension for postgis >= 2.0
+ * remove non-admin boundaries from addresses
+ * further improve ordering of results with same importance
+ * merge addr:postcode tags into object addresses
+ * include rank and importance in reverse geocode output
+ * replace ST_Line_Interpolate_Point with ST_LineInterpolatePoint
+  (for postgis >= 2.1)
+ * update osm2pgsql to latest version
+ * properly detect changes of admin_level
+ * remove landuses when name is removed
+ * smaller fixes
 
 2.1
 
  * refactoring of front-end PHP code
  * lots of smaller bug fixes
 
-2.2
-
- * correct database rights for www-data
- * add timestamps for update output
- * load postgis via extension for postgis >= 2.0
- * remove non-admin boundaries from addresses
- * further improve ordering of results with same importance
- * merge addr:postcode tags into object addresses
- * include rank and importance in reverse geocode output
- * replace ST_Line_Interpolate_Point with ST_LineInterpolatePoint
-  (for postgis >= 2.1)
- * update osm2pgsql to latest version
- * properly detect changes of admin_level
- * remove landuses when name is removed
- * smaller fixes
-
-2.3
+2.0.1
 
- * further improve ordering of results
- * support for more lat/lon formats in search-as-reverse
- * fix handling of GB postcodes
- * new functional test suite
- * support for waterway relations
- * inherit postcodes from street to poi
- * fix housenumber normalisation to find non-latin house numbers
- * take viewbox into account for ordering of results
- * pois may now inherit address tags from surrounding buildings
- * improve what objects may participate in an address
- * clean up handled class/type combinations to current OSM usage
- * lots of bug fixes
+ * delete outdated entries from location_area_country
+ * remove remaining uses of INTEGER, to allow node ids larger than 2^31
index cc77d333ae4cb32b53f04b4cfe3f2f91e5ca0f00..badcb5b224258b4ef2754775a9ba53d86db8302f 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT(Nominatim,2.4)
+AC_INIT(Nominatim,2.5)
 if git rev-parse HEAD 2>/dev/null >/dev/null; then
     AC_SUBST([PACKAGE_VERSION], [$PACKAGE_VERSION-git-`git rev-parse --short HEAD`])
 fi
index ed618aec874cc05243dbd9bf98d1c86d19189a5d..5464c386b21631aee1a67f8fcd45990ea2be41a4 100644 (file)
@@ -12,6 +12,7 @@
                protected $bIncludePolygonAsGeoJSON = false;
                protected $bIncludePolygonAsKML = false;
                protected $bIncludePolygonAsSVG = false;
+               protected $fPolygonSimplificationThreshold = 0.0;
 
                protected $aExcludePlaceIDs = array();
                protected $bDeDupe = true;
                        $this->bIncludePolygonAsSVG = $b;
                }
 
+               function setPolygonSimplificationThreshold($f)
+               {
+                       $this->fPolygonSimplificationThreshold = $f;
+               }
+
                function setDeDupe($bDeDupe = true)
                {
                        $this->bDeDupe = (bool)$bDeDupe;
                                                                                        else $aSearch['sOperator'] = 'near'; // near = in for the moment
                                                                                        if (strlen($aSearchTerm['operator']) == 0) $aSearch['iSearchRank'] += 1;
 
-                                                                                       // Do we have a shortcut id?
-                                                                                       if ($aSearch['sOperator'] == 'name')
-                                                                                       {
-                                                                                               $sSQL = "select get_tagpair('".$aSearch['sClass']."', '".$aSearch['sType']."')";
-                                                                                               if ($iAmenityID = $this->oDB->getOne($sSQL))
-                                                                                               {
-                                                                                                       $aValidTokens[$aSearch['sClass'].':'.$aSearch['sType']] = array('word_id' => $iAmenityID);
-                                                                                                       $aSearch['aName'][$iAmenityID] = $iAmenityID;
-                                                                                                       $aSearch['sClass'] = '';
-                                                                                                       $aSearch['sType'] = '';
-                                                                                               }
-                                                                                       }
                                                                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
                                                                                }
                                                                        }
                        if (!$this->sQuery && !$this->aStructuredQuery) return false;
 
                        $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
-
                        $sCountryCodesSQL = false;
                        if ($this->aCountryCodes && sizeof($this->aCountryCodes))
                        {
                                        if ($this->bIncludePolygonAsKML) $sSQL .= ",ST_AsKML(geometry) as askml";
                                        if ($this->bIncludePolygonAsSVG) $sSQL .= ",ST_AsSVG(geometry) as assvg";
                                        if ($this->bIncludePolygonAsText || $this->bIncludePolygonAsPoints) $sSQL .= ",ST_AsText(geometry) as astext";
-                                       $sSQL .= " from placex where place_id = ".$aResult['place_id'];
+                                       $sFrom = " from placex where place_id = ".$aResult['place_id'];
+                                       if ($this->fPolygonSimplificationThreshold > 0)
+                                       {
+                                               $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry".$sFrom.") as plx";
+                                       }
+                                       else
+                                       {
+                                               $sSQL .= $sFrom;
+                                       }
+
                                        $aPointPolygon = $this->oDB->getRow($sSQL);
                                        if (PEAR::IsError($aPointPolygon))
                                        {
index 6da82fd8225bd9cdb31366f22f8724262926fe61..84c68a99d8f503e89cf772524fa58553c38c405a 100644 (file)
@@ -5,6 +5,8 @@
 
                protected $iPlaceID;
 
+               protected $bIsTiger = false;
+
                protected $aLangPrefOrder = array();
 
                protected $bAddressDetails = false;
                        $this->iPlaceID = $this->oDB->getOne($sSQL);
                }
 
+               function setIsTiger($b = false)
+               {
+                       $this->bIsTiger = $b;
+               }
+
                function lookup()
                {
                        if (!$this->iPlaceID) return null;
                        $sSQL .= " (case when centroid is null then st_y(st_centroid(geometry)) else st_y(centroid) end) as lat,";
                        $sSQL .= " (case when centroid is null then st_x(st_centroid(geometry)) else st_x(centroid) end) as lon";
                        $sSQL .= " from placex where place_id = ".(int)$this->iPlaceID;
+
+
+                       if ($this->bIsTiger)
+                       {
+                               $sSQL = "select place_id,partition, 'T' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, housenumber, null as street, null as isin, postcode,";
+                               $sSQL .= " 'us' as country_code, null as extratags, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,";
+                               $sSQL .= " coalesce(null,0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, 'us' as calculated_country_code, ";
+                               $sSQL .= " get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
+                               $sSQL .= " null as placename,";
+                               $sSQL .= " null as ref,";
+                               $sSQL .= " st_y(centroid) as lat,";
+                               $sSQL .= " st_x(centroid) as lon";
+                               $sSQL .= " from location_property_tiger where place_id = ".(int)$this->iPlaceID;
+                       }
+
                        $aPlace = $this->oDB->getRow($sSQL);
 
+
                        if (PEAR::IsError($aPlace))
                        {
                                failInternalError("Could not lookup place.", $sSQL, $aPlace);
                        }
+
                        if (!$aPlace['place_id']) return null;
 
                        if ($this->bAddressDetails)
@@ -63,6 +87,7 @@
                                $aPlace['aAddress'] = $aAddress;
                        }
 
+
                        $aClassType = getClassTypes();
                        $sAddressType = '';
                        $sClassType = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];
index cb8c0c6bcf84b7febe7b17a053b12ab1cfd9fe8f..ae83af1e90a710aa0341cbd427210c781d70205d 100644 (file)
                {
                        $sPointSQL = 'ST_SetSRID(ST_Point('.$this->fLon.','.$this->fLat.'),4326)';
                        $iMaxRank = $this->iMaxRank;
+                       $iMaxRank_orig = $this->iMaxRank;
 
                        // Find the nearest point
                        $fSearchDiam = 0.0004;
                        $iPlaceID = null;
                        $aArea = false;
                        $fMaxAreaDistance = 1;
+                       $bIsInUnitedStates = false;
+                       $bPlaceIsTiger = false;
                        while(!$iPlaceID && $fSearchDiam < $fMaxAreaDistance)
                        {
                                $fSearchDiam = $fSearchDiam * 2;
@@ -90,7 +93,7 @@
                                if ($fSearchDiam > 0.008 && $iMaxRank > 22) $iMaxRank = 22;
                                if ($fSearchDiam > 0.001 && $iMaxRank > 26) $iMaxRank = 26;
 
-                               $sSQL = 'select place_id,parent_place_id,rank_search from placex';
+                               $sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code from placex';
                                $sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')';
                                $sSQL .= ' and rank_search != 28 and rank_search >= '.$iMaxRank;
                                $sSQL .= ' and (name is not null or housenumber is not null)';
                                }
                                $iPlaceID = $aPlace['place_id'];
                                $iParentPlaceID = $aPlace['parent_place_id'];
+                               $bIsInUnitedStates = ($aPlace['calculated_country_code'] == 'us');
+                       }
+
+                       // Only street found? If it's in the US we can check TIGER data for nearest housenumber
+                       if ($bIsInUnitedStates && $iMaxRank_orig >= 28 && $iPlaceID && ($aPlace['rank_search'] == 26 || $aPlace['rank_search'] == 27 )) 
+                       {
+                               $fSearchDiam = 0.001;
+                               $sSQL = 'SELECT place_id,parent_place_id,30 as rank_search ';
+                               if (CONST_Debug) { $sSQL .= ', housenumber, ST_distance('.$sPointSQL.', centroid) as distance, st_y(centroid) as lat, st_x(centroid) as lon'; }
+                               $sSQL .= ' FROM location_property_tiger WHERE parent_place_id = '.$iPlaceID;
+                               $sSQL .= ' AND ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.')';
+                               $sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', centroid) ASC limit 1';
+
+
+                               // print all house numbers in the parent (street)
+                               if (CONST_Debug)
+                               {
+                                       $sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
+                                       var_dump($sSQL);
+
+                                       $aAllHouses = $this->oDB->getAll($sSQL);
+                                       foreach($aAllHouses as $i)
+                                       {
+                                               echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon']. ' | '. "<br>\n";
+                                       }
+                               }
+
+                               $aPlaceTiger = $this->oDB->getRow($sSQL);
+                               if (PEAR::IsError($aPlace))
+                               {
+                                       failInternalError("Could not determine closest Tiger place.", $sSQL, $aPlaceTiger);
+                               }
+                               if ($aPlaceTiger)
+                               {
+                                       if (CONST_Debug) var_dump('found Tiger place', $aPlaceTiger);
+                                       $bPlaceIsTiger = true;
+                                       $aPlace = $aPlaceTiger;
+                                       $iPlaceID = $aPlaceTiger['place_id'];
+                                       $iParentPlaceID = $aPlaceTiger['parent_place_id']; // the street
+                               }
                        }
 
                        // The point we found might be too small - use the address to find what it is a child of
                        if ($iPlaceID && $iMaxRank < 28)
                        {
-                               if ($aPlace['rank_search'] > 28 && $iParentPlaceID)
+                               if ($aPlace['rank_search'] > 28 && $iParentPlaceID && !$bPlaceIsTiger)
                                {
                                        $iPlaceID = $iParentPlaceID;
                                }
                        $oPlaceLookup->setLanguagePreference($this->aLangPrefOrder);
                        $oPlaceLookup->setIncludeAddressDetails($this->bAddressDetails);
                        $oPlaceLookup->setPlaceId($iPlaceID);
+                       $oPlaceLookup->setIsTiger($bPlaceIsTiger);
 
                        return $oPlaceLookup->lookup();
                }
index 598ce86e7fe823d9f83c51434ba97df510d5e24d..e99b6173b91ad75e6d3bd9f2060b77c0fe76c817 100644 (file)
@@ -10,8 +10,8 @@
        @define('CONST_Limit_Reindexing', true);
 
        // Software versions
-       @define('CONST_Postgresql_Version', '9.1'); // values: 9.0, 9.1, 9.2
-       @define('CONST_Postgis_Version', '1.5'); // values: 1.5, 2.0
+       @define('CONST_Postgresql_Version', '9.3'); // values: 9.0, ... , 9.4
+       @define('CONST_Postgis_Version', '2.1'); // values: 1.5, 2.0, 2.1
 
        // Paths
        @define('CONST_Path_Postgresql_Contrib', '/usr/share/postgresql/'.CONST_Postgresql_Version.'/contrib');
index b46ab2cdce5bf0ca2744a5649542807ed0e926c1..f8c4f3883a7a6b4b6fb0bffb8ce70034e87421ee 100644 (file)
@@ -11,3 +11,28 @@ Feature: Reverse geocoding
          | ID | country
          | 0  | Deutschland
 
+    @Tiger
+    Scenario: TIGER house number
+        Given the request parameters
+          | addressdetails
+          | 1
+        When looking up coordinates 40.6863624710666,-112.060005720023
+        And exactly 1 result is returned
+        And result addresses contain
+          | ID | house_number | road               | postcode | country_code
+          | 0  | 7094         | Kings Estate Drive | 84128    | us
+        And result 0 has not attributes osm_id,osm_type
+
+
+    @Tiger
+    Scenario: No TIGER house number for zoom < 18
+        Given the request parameters
+          | addressdetails | zoom
+          | 1              | 17
+        When looking up coordinates 40.6863624710666,-112.060005720023
+        And exactly 1 result is returned
+        And result addresses contain
+          | ID | road               | postcode | country_code
+          | 0  | Kings Estate Drive | 84128    | us
+        And result 0 has attributes osm_id,osm_type
+
index ac378b0e0d6c137a71b13ea54bd0eb417504e9b4..859faa76f1256847d18e3eb703d6da8bbe026c02 100644 (file)
@@ -74,3 +74,9 @@ Feature: Search queries
         Then results contain
           | ID | display_name
           | 0  | Illinois.*
+
+    Scenario: Search with class-type feature
+        When sending jsonv2 search query "Hotel California"
+        Then results contain
+          | place_rank
+          | 30
index 23a6bf5938eb46690efdbd5de2ab2dd73f56d828..1062cd0277c3702a015e3a8bc64fe4f532f6dcc1 100644 (file)
@@ -170,3 +170,35 @@ Feature: Search queries
         Then results contain
           | ID | display_name
           | 0  | Everest.*
+
+    Scenario Outline: Search with polygon threshold (json)
+        Given the request parameters
+          | polygon_geojson | polygon_threshold
+          | 1               | <th>
+        When sending json search query "switzerland"
+        Then at least 1 result is returned
+        And result 0 has attributes geojson
+
+     Examples:
+        | th
+        | -1
+        | 0.0
+        | 0.5
+        | 999
+        | nan
+
+    Scenario Outline: Search with polygon threshold (xml)
+        Given the request parameters
+          | polygon_geojson | polygon_threshold
+          | 1               | <th>
+        When sending xml search query "switzerland"
+        Then at least 1 result is returned
+        And result 0 has attributes geojson
+
+     Examples:
+        | th
+        | -1
+        | 0.0
+        | 0.5
+        | 999
+        | nan
index cd522c5771c0fdd536b097d59aeec4b445881e22..18b47e1ddc5d1bcb2dd9a0a833ba4b660e91557e 100755 (executable)
                $oGeocode->setIncludePolygonAsSVG($bAsSVG);
        }
 
+       // Polygon simplification threshold (optional)
+       $fThreshold = 0.0;
+       if (isset($_GET['polygon_threshold'])) $fThreshold = (float)$_GET['polygon_threshold'];
+       $oGeocode->setPolygonSimplificationThreshold($fThreshold);
+
        $oGeocode->loadParamArray($_GET);
 
        if (CONST_Search_BatchMode && isset($_GET['batch']))