Skip to content

Commit 9746629

Browse files
committed
during reverse geocode lookup we also check the (optional) Tiger data for house numbers
1 parent 5eb56c1 commit 9746629

File tree

5 files changed

+97
-2
lines changed

5 files changed

+97
-2
lines changed

AUTHORS

+3
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ Nominatim was written by:
1515
Kurt Roeckx
1616
Rodolphe Quiédeville
1717
Marc Tobias Metten
18+
19+
Reverse geocoding using Tiger data sponsored by
20+
Linux training company, Guru Labs (https://www.gurulabs.com)

ChangeLog

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
* reverse geocoding looking includes looking up Tiger data
2+
3+
14
2.4
25

36
* drop support for postgres 8.4

lib/PlaceLookup.php

+25
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ class PlaceLookup
55

66
protected $iPlaceID;
77

8+
protected $bIsTiger = false;
9+
810
protected $aLangPrefOrder = array();
911

1012
protected $bAddressDetails = false;
@@ -35,6 +37,11 @@ function setOSMID($sType, $iID)
3537
$this->iPlaceID = $this->oDB->getOne($sSQL);
3638
}
3739

40+
function setIsTiger($b = false)
41+
{
42+
$this->bIsTiger = $b;
43+
}
44+
3845
function lookup()
3946
{
4047
if (!$this->iPlaceID) return null;
@@ -49,12 +56,29 @@ function lookup()
4956
$sSQL .= " (case when centroid is null then st_y(st_centroid(geometry)) else st_y(centroid) end) as lat,";
5057
$sSQL .= " (case when centroid is null then st_x(st_centroid(geometry)) else st_x(centroid) end) as lon";
5158
$sSQL .= " from placex where place_id = ".(int)$this->iPlaceID;
59+
60+
61+
if ($this->bIsTiger)
62+
{
63+
$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,";
64+
$sSQL .= " 'us' as country_code, null as extratags, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,";
65+
$sSQL .= " coalesce(0,0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, 'us' as calculated_country_code, ";
66+
$sSQL .= " get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
67+
$sSQL .= " null as placename,";
68+
$sSQL .= " null as ref,";
69+
$sSQL .= " st_y(centroid) as lat,";
70+
$sSQL .= " st_x(centroid) as lon";
71+
$sSQL .= " from location_property_tiger where place_id = ".(int)$this->iPlaceID;
72+
}
73+
5274
$aPlace = $this->oDB->getRow($sSQL);
5375

76+
5477
if (PEAR::IsError($aPlace))
5578
{
5679
failInternalError("Could not lookup place.", $sSQL, $aPlace);
5780
}
81+
5882
if (!$aPlace['place_id']) return null;
5983

6084
if ($this->bAddressDetails)
@@ -63,6 +87,7 @@ function lookup()
6387
$aPlace['aAddress'] = $aAddress;
6488
}
6589

90+
6691
$aClassType = getClassTypes();
6792
$sAddressType = '';
6893
$sClassType = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];

lib/ReverseGeocode.php

+46-2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ function lookup()
7575
$iPlaceID = null;
7676
$aArea = false;
7777
$fMaxAreaDistance = 1;
78+
$bIsInUnitedStates = false;
79+
$bPlaceIsTiger = false;
7880
while(!$iPlaceID && $fSearchDiam < $fMaxAreaDistance)
7981
{
8082
$fSearchDiam = $fSearchDiam * 2;
@@ -90,7 +92,7 @@ function lookup()
9092
if ($fSearchDiam > 0.008 && $iMaxRank > 22) $iMaxRank = 22;
9193
if ($fSearchDiam > 0.001 && $iMaxRank > 26) $iMaxRank = 26;
9294

93-
$sSQL = 'select place_id,parent_place_id,rank_search from placex';
95+
$sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code from placex';
9496
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')';
9597
$sSQL .= ' and rank_search != 28 and rank_search >= '.$iMaxRank;
9698
$sSQL .= ' and (name is not null or housenumber is not null)';
@@ -107,12 +109,53 @@ function lookup()
107109
}
108110
$iPlaceID = $aPlace['place_id'];
109111
$iParentPlaceID = $aPlace['parent_place_id'];
112+
$bIsInUnitedStates = ($aPlace['calculated_country_code'] == 'us');
113+
}
114+
115+
116+
// Only street found? If it's in the US we can check TIGER data for nearest housenumber
117+
if ($bIsInUnitedStates && $iPlaceID && $aPlace['rank_search'] == 26)
118+
{
119+
$fSearchDiam = 0.001;
120+
$sSQL = 'SELECT place_id,parent_place_id,30 as rank_search ';
121+
if (CONST_Debug) { $sSQL .= ', housenumber, ST_distance('.$sPointSQL.', centroid) as distance, st_y(centroid) as lat, st_x(centroid) as lon'; }
122+
$sSQL .= ' FROM location_property_tiger WHERE parent_place_id = '.$iPlaceID;
123+
$sSQL .= ' AND ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.')';
124+
$sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', centroid) ASC limit 1';
125+
126+
127+
// print all house numbers in the parent (street)
128+
if (CONST_Debug)
129+
{
130+
$sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
131+
var_dump($sSQL);
132+
133+
$aAllHouses = $this->oDB->getAll($sSQL);
134+
foreach($aAllHouses as $i)
135+
{
136+
echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon']. ' | '. "<br>\n";
137+
}
138+
}
139+
140+
$aPlaceTiger = $this->oDB->getRow($sSQL);
141+
if (PEAR::IsError($aPlace))
142+
{
143+
failInternalError("Could not determine closest Tiger place.", $sSQL, $aPlaceTiger);
144+
}
145+
if ($aPlaceTiger)
146+
{
147+
if (CONST_Debug) var_dump('found Tiger place', $aPlaceTiger);
148+
$bPlaceIsTiger = true;
149+
$aPlace = $aPlaceTiger;
150+
$iPlaceID = $aPlaceTiger['place_id'];
151+
$iParentPlaceID = $aPlaceTiger['parent_place_id']; // the street
152+
}
110153
}
111154

112155
// The point we found might be too small - use the address to find what it is a child of
113156
if ($iPlaceID && $iMaxRank < 28)
114157
{
115-
if ($aPlace['rank_search'] > 28 && $iParentPlaceID)
158+
if ($aPlace['rank_search'] > 28 && $iParentPlaceID && !$bPlaceIsTiger)
116159
{
117160
$iPlaceID = $iParentPlaceID;
118161
}
@@ -132,6 +175,7 @@ function lookup()
132175
$oPlaceLookup->setLanguagePreference($this->aLangPrefOrder);
133176
$oPlaceLookup->setIncludeAddressDetails($this->bAddressDetails);
134177
$oPlaceLookup->setPlaceId($iPlaceID);
178+
$oPlaceLookup->setIsTiger($bPlaceIsTiger);
135179

136180
return $oPlaceLookup->lookup();
137181
}

tests/features/api/reverse.feature

+20
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,23 @@ Feature: Reverse geocoding
1111
| ID | country
1212
| 0 | Deutschland
1313
14+
@Tiger
15+
Scenario: TIGER house number
16+
Given the request parameters
17+
| addressdetails
18+
| 1
19+
When looking up jsonv2 coordinates 40.6863624710666,-112.060005720023
20+
# Then exactly 1 result is returned
21+
# Then result addresses contain
22+
# | ID | house_number | road | postcode | country_code
23+
# | 0 | 7094 | Kings Estate Drive | 84128 | us
24+
Then results contain
25+
| type | house
26+
And results contain
27+
| addresstype | place
28+
And results contain
29+
| road | Kings Estate Drive
30+
And results contain
31+
| house_number | 7094
32+
And results contain
33+
| postcode | 84128

0 commit comments

Comments
 (0)