mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-16 15:47:58 +00:00
Update entrances schema
This commit is contained in:
@@ -23,7 +23,7 @@ import sqlalchemy as sa
|
||||
|
||||
from .typing import SaSelect, SaRow
|
||||
from .sql.sqlalchemy_types import Geometry
|
||||
from .types import Point, Bbox, LookupDetails
|
||||
from .types import Point, Bbox, LookupDetails, EntranceDetails
|
||||
from .connection import SearchConnection
|
||||
from .logging import log
|
||||
|
||||
@@ -206,6 +206,8 @@ class BaseResult:
|
||||
name_keywords: Optional[WordInfos] = None
|
||||
address_keywords: Optional[WordInfos] = None
|
||||
|
||||
entrances: Optional[List[EntranceDetails]] = None
|
||||
|
||||
geometry: Dict[str, str] = dataclasses.field(default_factory=dict)
|
||||
|
||||
@property
|
||||
@@ -466,6 +468,10 @@ async def add_result_details(conn: SearchConnection, results: List[BaseResultT],
|
||||
log().comment('Query parent places')
|
||||
for result in results:
|
||||
await complete_parented_places(conn, result)
|
||||
if details.entrances:
|
||||
log().comment('Query entrances details')
|
||||
for result in results:
|
||||
await complete_entrances_details(conn, result)
|
||||
if details.keywords:
|
||||
log().comment('Query keywords')
|
||||
for result in results:
|
||||
@@ -717,6 +723,19 @@ async def complete_linked_places(conn: SearchConnection, result: BaseResult) ->
|
||||
result.linked_rows.append(_result_row_to_address_row(row))
|
||||
|
||||
|
||||
async def complete_entrances_details(conn: SearchConnection, result: BaseResult) -> None:
|
||||
""" Retrieve information about tagged entrances for this place.
|
||||
"""
|
||||
if result.source_table != SourceTable.PLACEX:
|
||||
return
|
||||
|
||||
t = conn.t.place_entrance
|
||||
sql = sa.select(t.c.entrances).where(t.c.place_id == result.place_id)
|
||||
|
||||
for results in await conn.execute(sql):
|
||||
result.entrances = [EntranceDetails(**r) for r in results[0]]
|
||||
|
||||
|
||||
async def complete_keywords(conn: SearchConnection, result: BaseResult) -> None:
|
||||
""" Retrieve information about the search terms used for this place.
|
||||
|
||||
|
||||
@@ -127,3 +127,8 @@ class SearchTables:
|
||||
sa.Column('step', sa.SmallInteger),
|
||||
sa.Column('linegeo', Geometry),
|
||||
sa.Column('postcode', sa.Text))
|
||||
|
||||
self.place_entrance = sa.Table(
|
||||
'place_entrance', meta,
|
||||
sa.Column('place_id', sa.BigInteger),
|
||||
sa.Column('entrances', KeyValueStore))
|
||||
|
||||
@@ -401,6 +401,9 @@ class LookupDetails:
|
||||
for, i.e. all places for which it provides the address details.
|
||||
Only POI places can have parents.
|
||||
"""
|
||||
entrances: bool = False
|
||||
""" Get detailed information about the tagged entrances for the result.
|
||||
"""
|
||||
keywords: bool = False
|
||||
""" Add information about the search terms used for this place.
|
||||
"""
|
||||
@@ -548,3 +551,27 @@ class SearchDetails(LookupDetails):
|
||||
true when layer restriction has been disabled completely.
|
||||
"""
|
||||
return self.layers is None or bool(self.layers & layer)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class EntranceDetails:
|
||||
""" Reference a place by its OSM ID and potentially the basic category.
|
||||
|
||||
The OSM ID may refer to places in the main table placex and OSM
|
||||
interpolation lines.
|
||||
"""
|
||||
osm_id: int
|
||||
""" The OSM ID of the object.
|
||||
"""
|
||||
type: str
|
||||
""" The value of the OSM entrance tag (i.e. yes, main, secondary, etc.).
|
||||
"""
|
||||
lat: float
|
||||
""" The latitude of the entrance node.
|
||||
"""
|
||||
lon: float
|
||||
""" The longitude of the entrance node.
|
||||
"""
|
||||
extratags: Dict[str, str]
|
||||
""" The longitude of the entrance node.
|
||||
"""
|
||||
|
||||
@@ -196,6 +196,9 @@ def _format_details_json(result: DetailedResult, options: Mapping[str, Any]) ->
|
||||
else:
|
||||
_add_address_rows(out, 'hierarchy', result.parented_rows, locales)
|
||||
|
||||
if result.entrances is not None:
|
||||
out.keyval('entrances', result.entrances)
|
||||
|
||||
out.end_object()
|
||||
|
||||
return out()
|
||||
|
||||
@@ -107,6 +107,9 @@ def format_base_json(results: Union[ReverseResults, SearchResults],
|
||||
_write_typed_address(out, result.address_rows, result.country_code)
|
||||
out.end_object().next()
|
||||
|
||||
if options.get('entrances', False) and result.entrances:
|
||||
out.keyval('entrances', result.entrances)
|
||||
|
||||
if options.get('extratags', False):
|
||||
out.keyval('extratags', result.extratags)
|
||||
|
||||
@@ -180,6 +183,9 @@ def format_base_geojson(results: Union[ReverseResults, SearchResults],
|
||||
_write_typed_address(out, result.address_rows, result.country_code)
|
||||
out.end_object().next()
|
||||
|
||||
if options.get('entrances', False):
|
||||
out.keyval('entrances', result.entrances)
|
||||
|
||||
if options.get('extratags', False):
|
||||
out.keyval('extratags', result.extratags)
|
||||
|
||||
@@ -251,6 +257,9 @@ def format_base_geocodejson(results: Union[ReverseResults, SearchResults],
|
||||
out.keyval(f"level{line.admin_level}", line.local_name)
|
||||
out.end_object().next()
|
||||
|
||||
if options.get('entrances', False):
|
||||
out.keyval('entrances', result.entrances)
|
||||
|
||||
if options.get('extratags', False):
|
||||
out.keyval('extra', result.extratags)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
Helper functions for output of results in XML format.
|
||||
"""
|
||||
from typing import Mapping, Any, Optional, Union
|
||||
import dataclasses
|
||||
import datetime as dt
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
@@ -122,4 +123,10 @@ def format_base_xml(results: Union[ReverseResults, SearchResults],
|
||||
for k, v in result.names.items():
|
||||
ET.SubElement(eroot, 'name', attrib={'desc': k}).text = v
|
||||
|
||||
if options.get('entrances', False):
|
||||
eroot = ET.SubElement(root if simple else place, 'entrances')
|
||||
if result.entrances:
|
||||
for entrance_detail in result.entrances:
|
||||
ET.SubElement(eroot, 'entrance', attrib=dataclasses.asdict(entrance_detail))
|
||||
|
||||
return '<?xml version="1.0" encoding="UTF-8" ?>\n' + ET.tostring(root, encoding='unicode')
|
||||
|
||||
@@ -72,6 +72,8 @@ def extend_query_parts(queryparts: Dict[str, Any], details: Dict[str, Any],
|
||||
queryparts['polygon_text'] = '1'
|
||||
if parsed.address_details:
|
||||
queryparts['addressdetails'] = '1'
|
||||
if parsed.entrances:
|
||||
queryparts['entrances'] = '1'
|
||||
if namedetails:
|
||||
queryparts['namedetails'] = '1'
|
||||
if extratags:
|
||||
|
||||
@@ -158,6 +158,7 @@ async def details_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
||||
|
||||
result = await api.details(place,
|
||||
address_details=params.get_bool('addressdetails', False),
|
||||
entrances=params.get_bool('entrances', False),
|
||||
linked_places=params.get_bool('linkedplaces', True),
|
||||
parented_places=params.get_bool('hierarchy', False),
|
||||
keywords=params.get_bool('keywords', False),
|
||||
@@ -216,6 +217,7 @@ async def reverse_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
||||
fmt_options = {'query': query,
|
||||
'extratags': params.get_bool('extratags', False),
|
||||
'namedetails': params.get_bool('namedetails', False),
|
||||
'entrances': params.get_bool('entrances', False),
|
||||
'addressdetails': params.get_bool('addressdetails', True)}
|
||||
|
||||
output = params.formatting().format_result(ReverseResults([result] if result else []),
|
||||
@@ -252,6 +254,7 @@ async def lookup_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
||||
|
||||
fmt_options = {'extratags': params.get_bool('extratags', False),
|
||||
'namedetails': params.get_bool('namedetails', False),
|
||||
'entrances': params.get_bool('entrances', False),
|
||||
'addressdetails': params.get_bool('addressdetails', True)}
|
||||
|
||||
output = params.formatting().format_result(results, fmt, fmt_options)
|
||||
@@ -298,6 +301,7 @@ async def search_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
||||
details = parse_geometry_details(params, fmt)
|
||||
|
||||
details['countries'] = params.get('countrycodes', None)
|
||||
details['entrances'] = params.get_bool('entrances', False)
|
||||
details['excluded'] = params.get('exclude_place_ids', None)
|
||||
details['viewbox'] = params.get('viewbox', None) or params.get('viewboxlbrt', None)
|
||||
details['bounded_viewbox'] = params.get_bool('bounded', False)
|
||||
@@ -363,6 +367,7 @@ async def search_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
||||
'viewbox': queryparts.get('viewbox'),
|
||||
'extratags': params.get_bool('extratags', False),
|
||||
'namedetails': params.get_bool('namedetails', False),
|
||||
'entrances': params.get_bool('entrances', False),
|
||||
'addressdetails': params.get_bool('addressdetails', False)}
|
||||
|
||||
output = params.formatting().format_result(results, fmt, fmt_options)
|
||||
|
||||
Reference in New Issue
Block a user