add lookup of postcdoe data

This commit is contained in:
Sarah Hoffmann
2023-02-02 16:22:18 +01:00
parent 70f6f9a711
commit 1924beeb20
4 changed files with 151 additions and 2 deletions

View File

@@ -95,8 +95,8 @@ async def find_in_osmline(conn: SearchConnection, place: ntyp.PlaceRef,
async def find_in_tiger(conn: SearchConnection, place: ntyp.PlaceRef, async def find_in_tiger(conn: SearchConnection, place: ntyp.PlaceRef,
details: ntyp.LookupDetails) -> Optional[SaRow]: details: ntyp.LookupDetails) -> Optional[SaRow]:
""" Search for the given place in table of Tiger addresses and return the """ Search for the given place in the table of Tiger addresses and return
base information. the base information. Only lookup by place ID is supported.
""" """
t = conn.t.tiger t = conn.t.tiger
sql = sa.select(t.c.place_id, t.c.parent_place_id, sql = sa.select(t.c.place_id, t.c.parent_place_id,
@@ -114,6 +114,27 @@ async def find_in_tiger(conn: SearchConnection, place: ntyp.PlaceRef,
return (await conn.execute(sql)).one_or_none() return (await conn.execute(sql)).one_or_none()
async def find_in_postcode(conn: SearchConnection, place: ntyp.PlaceRef,
details: ntyp.LookupDetails) -> Optional[SaRow]:
""" Search for the given place in the postcode table and return the
base information. Only lookup by place ID is supported.
"""
t = conn.t.postcode
sql = sa.select(t.c.place_id, t.c.parent_place_id,
t.c.rank_search, t.c.rank_address,
t.c.indexed_date, t.c.postcode, t.c.country_code,
sa.func.ST_X(t.c.geometry).label('x'),
sa.func.ST_Y(t.c.geometry).label('y'),
_select_column_geometry(t.c.geometry, details.geometry_output))
if isinstance(place, ntyp.PlaceID):
sql = sql.where(t.c.place_id == place.place_id)
else:
return None
return (await conn.execute(sql)).one_or_none()
async def get_place_by_id(conn: SearchConnection, place: ntyp.PlaceRef, async def get_place_by_id(conn: SearchConnection, place: ntyp.PlaceRef,
details: ntyp.LookupDetails) -> Optional[nres.SearchResult]: details: ntyp.LookupDetails) -> Optional[nres.SearchResult]:
""" Retrieve a place with additional details from the database. """ Retrieve a place with additional details from the database.
@@ -133,6 +154,12 @@ async def get_place_by_id(conn: SearchConnection, place: ntyp.PlaceRef,
await nres.add_result_details(conn, result, details) await nres.add_result_details(conn, result, details)
return result return result
row = await find_in_postcode(conn, place, details)
if row is not None:
result = nres.create_from_postcode_row(row)
await nres.add_result_details(conn, result, details)
return result
row = await find_in_tiger(conn, place, details) row = await find_in_tiger(conn, place, details)
if row is not None: if row is not None:
result = nres.create_from_tiger_row(row) result = nres.create_from_tiger_row(row)

View File

@@ -203,6 +203,23 @@ def create_from_tiger_row(row: SaRow) -> SearchResult:
geometry=_filter_geometries(row)) geometry=_filter_geometries(row))
def create_from_postcode_row(row: SaRow) -> SearchResult:
""" Construct a new SearchResult and add the data from the result row
from the postcode centroid table.
"""
return SearchResult(source_table=SourceTable.POSTCODE,
place_id=row.place_id,
parent_place_id=row.parent_place_id,
category=('place', 'postcode'),
names={'ref': row.postcode},
rank_search=row.rank_search,
rank_address=row.rank_address,
country_code=row.country_code,
centroid=Point(row.x, row.y),
indexed_date=row.indexed_date,
geometry=_filter_geometries(row))
async def add_result_details(conn: SearchConnection, result: SearchResult, async def add_result_details(conn: SearchConnection, result: SearchResult,
details: LookupDetails) -> None: details: LookupDetails) -> None:
""" Retrieve more details from the database according to the """ Retrieve more details from the database according to the

View File

@@ -103,6 +103,20 @@ class APITester:
'postcode': kw.get('postcode'), 'postcode': kw.get('postcode'),
'linegeo': 'SRID=4326;' + kw.get('geometry', 'LINESTRING(1.1 -0.2, 1.09 -0.22)')}) 'linegeo': 'SRID=4326;' + kw.get('geometry', 'LINESTRING(1.1 -0.2, 1.09 -0.22)')})
def add_postcode(self, **kw):
self.add_data('postcode',
{'place_id': kw.get('place_id', 1000),
'parent_place_id': kw.get('parent_place_id'),
'country_code': kw.get('country_code'),
'postcode': kw.get('postcode'),
'rank_search': kw.get('rank_search', 20),
'rank_address': kw.get('rank_address', 22),
'indexed_date': kw.get('indexed_date',
dt.datetime(2022, 12, 7, 14, 14, 46, 0)),
'geometry': 'SRID=4326;' + kw.get('geometry', 'POINT(23 34)')})
async def exec_async(self, sql, *args, **kwargs): async def exec_async(self, sql, *args, **kwargs):
async with self.api._async_api.begin() as conn: async with self.api._async_api.begin() as conn:
return await conn.execute(sql, *args, **kwargs) return await conn.execute(sql, *args, **kwargs)

View File

@@ -469,6 +469,97 @@ def test_lookup_tiger_with_address_details(apiobj):
] ]
def test_lookup_in_postcode(apiobj):
import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
apiobj.add_postcode(place_id=554,
parent_place_id=152,
postcode='34 425',
country_code='gb',
rank_search=20, rank_address=22,
indexed_date=import_date,
geometry='POINT(-9.45 5.6)')
result = apiobj.api.lookup(napi.PlaceID(554), napi.LookupDetails())
assert result is not None
assert result.source_table.name == 'POSTCODE'
assert result.category == ('place', 'postcode')
assert result.centroid == (pytest.approx(-9.45), pytest.approx(5.6))
assert result.place_id == 554
assert result.parent_place_id == 152
assert result.linked_place_id is None
assert result.osm_object is None
assert result.admin_level == 15
assert result.names == {'ref': '34 425'}
assert result.address is None
assert result.extratags is None
assert result.housenumber is None
assert result.postcode is None
assert result.wikipedia is None
assert result.rank_search == 20
assert result.rank_address == 22
assert result.importance is None
assert result.country_code == 'gb'
assert result.indexed_date == import_date
assert result.address_rows is None
assert result.linked_rows is None
assert result.parented_rows is None
assert result.name_keywords is None
assert result.address_keywords is None
assert result.geometry == {'type': 'ST_Point'}
def test_lookup_postcode_with_address_details(apiobj):
apiobj.add_postcode(place_id=9000,
parent_place_id=332,
postcode='34 425',
country_code='gb',
rank_search=25, rank_address=25)
apiobj.add_placex(place_id=332, osm_type='N', osm_id=3333,
class_='place', type='suburb', name='Smallplace',
country_code='gb', admin_level=13,
rank_search=24, rank_address=23)
apiobj.add_address_placex(332, fromarea=True, isaddress=True,
place_id=1001, osm_type='N', osm_id=3334,
class_='place', type='city', name='Bigplace',
country_code='gb',
rank_search=17, rank_address=16)
result = apiobj.api.lookup(napi.PlaceID(9000),
napi.LookupDetails(address_details=True))
assert result.address_rows == [
napi.AddressLine(place_id=332, osm_object=('N', 3333),
category=('place', 'suburb'),
names={'name': 'Smallplace'}, extratags={},
admin_level=13, fromarea=True, isaddress=True,
rank_address=23, distance=0.0),
napi.AddressLine(place_id=1001, osm_object=('N', 3334),
category=('place', 'city'),
names={'name': 'Bigplace'}, extratags={},
admin_level=15, fromarea=True, isaddress=True,
rank_address=16, distance=0.0),
napi.AddressLine(place_id=None, osm_object=None,
category=('place', 'postcode'),
names={'ref': '34 425'}, extratags={},
admin_level=None, fromarea=False, isaddress=True,
rank_address=5, distance=0.0),
napi.AddressLine(place_id=None, osm_object=None,
category=('place', 'country_code'),
names={'ref': 'gb'}, extratags={},
admin_level=None, fromarea=True, isaddress=False,
rank_address=4, distance=0.0)
]
@pytest.mark.parametrize('gtype', (napi.GeometryFormat.KML, @pytest.mark.parametrize('gtype', (napi.GeometryFormat.KML,
napi.GeometryFormat.SVG, napi.GeometryFormat.SVG,
napi.GeometryFormat.TEXT)) napi.GeometryFormat.TEXT))