forked from hans/Nominatim
move localization into add_result_details
This means that the locale now needs to be handed in into the search functions already. At least search needs them for reranking.
This commit is contained in:
@@ -292,12 +292,6 @@ class SearchResults(List[SearchResult]):
|
||||
May be empty when no result was found.
|
||||
"""
|
||||
|
||||
def localize(self, locales: Locales) -> None:
|
||||
""" Apply the given locales to all results.
|
||||
"""
|
||||
for result in self:
|
||||
result.localize(locales)
|
||||
|
||||
|
||||
def _filter_geometries(row: SaRow) -> Dict[str, str]:
|
||||
return {k[9:]: v for k, v in row._mapping.items() # pylint: disable=W0212
|
||||
@@ -459,6 +453,8 @@ async def add_result_details(conn: SearchConnection, results: List[BaseResultT],
|
||||
log().comment('Query keywords')
|
||||
for result in results:
|
||||
await complete_keywords(conn, result)
|
||||
for result in results:
|
||||
result.localize(details.locales)
|
||||
|
||||
|
||||
def _result_row_to_address_row(row: SaRow) -> AddressLine:
|
||||
|
||||
@@ -17,6 +17,7 @@ from struct import unpack
|
||||
from binascii import unhexlify
|
||||
|
||||
from nominatim.errors import UsageError
|
||||
from nominatim.api.localization import Locales
|
||||
|
||||
# pylint: disable=no-member,too-many-boolean-expressions,too-many-instance-attributes
|
||||
|
||||
@@ -386,7 +387,7 @@ TParam = TypeVar('TParam', bound='LookupDetails') # pylint: disable=invalid-name
|
||||
|
||||
@dataclasses.dataclass
|
||||
class LookupDetails:
|
||||
""" Collection of parameters that define the amount of details
|
||||
""" Collection of parameters that define which kind of details are
|
||||
returned with a lookup or details result.
|
||||
"""
|
||||
geometry_output: GeometryFormat = GeometryFormat.NONE
|
||||
@@ -413,6 +414,9 @@ class LookupDetails:
|
||||
0.0 means the original geometry is kept. The higher the value, the
|
||||
more the geometry gets simplified.
|
||||
"""
|
||||
locales: Locales = Locales()
|
||||
""" Prefered languages for localization of results.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_kwargs(cls: Type[TParam], kwargs: Dict[str, Any]) -> TParam:
|
||||
|
||||
@@ -308,7 +308,8 @@ async def details_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
|
||||
keywords=params.get_bool('keywords', False),
|
||||
geometry_output = napi.GeometryFormat.GEOJSON
|
||||
if params.get_bool('polygon_geojson', False)
|
||||
else napi.GeometryFormat.NONE
|
||||
else napi.GeometryFormat.NONE,
|
||||
locales=locales
|
||||
)
|
||||
|
||||
if debug:
|
||||
@@ -317,8 +318,6 @@ async def details_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
|
||||
if result is None:
|
||||
params.raise_error('No place with that OSM ID found.', status=404)
|
||||
|
||||
result.localize(locales)
|
||||
|
||||
output = formatting.format_result(result, fmt,
|
||||
{'locales': locales,
|
||||
'group_hierarchy': params.get_bool('group_hierarchy', False),
|
||||
@@ -337,6 +336,7 @@ async def reverse_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
|
||||
details = params.parse_geometry_details(fmt)
|
||||
details['max_rank'] = helpers.zoom_to_rank(params.get_int('zoom', 18))
|
||||
details['layers'] = params.get_layers()
|
||||
details['locales'] = napi.Locales.from_accept_languages(params.get_accepted_languages())
|
||||
|
||||
result = await api.reverse(coord, **details)
|
||||
|
||||
@@ -357,9 +357,6 @@ async def reverse_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) ->
|
||||
'namedetails': params.get_bool('namedetails', False),
|
||||
'addressdetails': params.get_bool('addressdetails', True)}
|
||||
|
||||
if result:
|
||||
result.localize(napi.Locales.from_accept_languages(params.get_accepted_languages()))
|
||||
|
||||
output = formatting.format_result(napi.ReverseResults([result] if result else []),
|
||||
fmt, fmt_options)
|
||||
|
||||
@@ -372,6 +369,7 @@ async def lookup_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
|
||||
fmt = params.parse_format(napi.SearchResults, 'xml')
|
||||
debug = params.setup_debugging()
|
||||
details = params.parse_geometry_details(fmt)
|
||||
details['locales'] = napi.Locales.from_accept_languages(params.get_accepted_languages())
|
||||
|
||||
places = []
|
||||
for oid in (params.get('osm_ids') or '').split(','):
|
||||
@@ -394,8 +392,6 @@ async def lookup_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
|
||||
'namedetails': params.get_bool('namedetails', False),
|
||||
'addressdetails': params.get_bool('addressdetails', True)}
|
||||
|
||||
results.localize(napi.Locales.from_accept_languages(params.get_accepted_languages()))
|
||||
|
||||
output = formatting.format_result(results, fmt, fmt_options)
|
||||
|
||||
return params.build_response(output, num_results=len(results))
|
||||
@@ -456,6 +452,8 @@ async def search_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
|
||||
else:
|
||||
details['layers'] = params.get_layers()
|
||||
|
||||
details['locales'] = napi.Locales.from_accept_languages(params.get_accepted_languages())
|
||||
|
||||
# unstructured query parameters
|
||||
query = params.get('q', None)
|
||||
# structured query parameters
|
||||
@@ -480,8 +478,6 @@ async def search_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> A
|
||||
except UsageError as err:
|
||||
params.raise_error(str(err))
|
||||
|
||||
results.localize(napi.Locales.from_accept_languages(params.get_accepted_languages()))
|
||||
|
||||
if details['dedupe'] and len(results) > 1:
|
||||
results = helpers.deduplicate_results(results, max_results)
|
||||
|
||||
|
||||
@@ -109,7 +109,8 @@ class APISearch:
|
||||
'countries': args.countrycodes,
|
||||
'excluded': args.exclude_place_ids,
|
||||
'viewbox': args.viewbox,
|
||||
'bounded_viewbox': args.bounded
|
||||
'bounded_viewbox': args.bounded,
|
||||
'locales': args.get_locales(api.config.DEFAULT_LANGUAGE)
|
||||
}
|
||||
|
||||
if args.query:
|
||||
@@ -124,9 +125,6 @@ class APISearch:
|
||||
country=args.country,
|
||||
**params)
|
||||
|
||||
for result in results:
|
||||
result.localize(args.get_locales(api.config.DEFAULT_LANGUAGE))
|
||||
|
||||
if args.dedupe and len(results) > 1:
|
||||
results = deduplicate_results(results, args.limit)
|
||||
|
||||
@@ -187,14 +185,14 @@ class APIReverse:
|
||||
layers=args.get_layers(napi.DataLayer.ADDRESS | napi.DataLayer.POI),
|
||||
address_details=True, # needed for display name
|
||||
geometry_output=args.get_geometry_output(),
|
||||
geometry_simplification=args.polygon_threshold)
|
||||
geometry_simplification=args.polygon_threshold,
|
||||
locales=args.get_locales(api.config.DEFAULT_LANGUAGE))
|
||||
|
||||
if args.format == 'debug':
|
||||
print(loglib.get_and_disable())
|
||||
return 0
|
||||
|
||||
if result:
|
||||
result.localize(args.get_locales(api.config.DEFAULT_LANGUAGE))
|
||||
output = api_output.format_result(
|
||||
napi.ReverseResults([result]),
|
||||
args.format,
|
||||
@@ -249,10 +247,8 @@ class APILookup:
|
||||
results = api.lookup(places,
|
||||
address_details=True, # needed for display name
|
||||
geometry_output=args.get_geometry_output(),
|
||||
geometry_simplification=args.polygon_threshold or 0.0)
|
||||
|
||||
for result in results:
|
||||
result.localize(args.get_locales(api.config.DEFAULT_LANGUAGE))
|
||||
geometry_simplification=args.polygon_threshold or 0.0,
|
||||
locales=args.get_locales(api.config.DEFAULT_LANGUAGE))
|
||||
|
||||
output = api_output.format_result(
|
||||
results,
|
||||
@@ -326,6 +322,7 @@ class APIDetails:
|
||||
|
||||
api = napi.NominatimAPI(args.project_dir)
|
||||
|
||||
locales = args.get_locales(api.config.DEFAULT_LANGUAGE)
|
||||
result = api.details(place,
|
||||
address_details=args.addressdetails,
|
||||
linked_places=args.linkedplaces,
|
||||
@@ -333,13 +330,11 @@ class APIDetails:
|
||||
keywords=args.keywords,
|
||||
geometry_output=napi.GeometryFormat.GEOJSON
|
||||
if args.polygon_geojson
|
||||
else napi.GeometryFormat.NONE)
|
||||
else napi.GeometryFormat.NONE,
|
||||
locales=locales)
|
||||
|
||||
|
||||
if result:
|
||||
locales = args.get_locales(api.config.DEFAULT_LANGUAGE)
|
||||
result.localize(locales)
|
||||
|
||||
output = api_output.format_result(
|
||||
result,
|
||||
'json',
|
||||
|
||||
@@ -150,17 +150,20 @@ def test_lookup_placex_with_address_details(apiobj):
|
||||
category=('highway', 'residential'),
|
||||
names={'name': 'Street'}, extratags={},
|
||||
admin_level=15, fromarea=True, isaddress=True,
|
||||
rank_address=26, distance=0.0),
|
||||
rank_address=26, distance=0.0,
|
||||
local_name='Street'),
|
||||
napi.AddressLine(place_id=1000, osm_object=('N', 3333),
|
||||
category=('place', 'suburb'),
|
||||
names={'name': 'Smallplace'}, extratags={},
|
||||
admin_level=13, fromarea=False, isaddress=True,
|
||||
rank_address=23, distance=0.0034),
|
||||
rank_address=23, distance=0.0034,
|
||||
local_name='Smallplace'),
|
||||
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),
|
||||
rank_address=16, distance=0.0,
|
||||
local_name='Bigplace'),
|
||||
napi.AddressLine(place_id=None, osm_object=None,
|
||||
category=('place', 'country_code'),
|
||||
names={'ref': 'pl'}, extratags={},
|
||||
@@ -341,22 +344,26 @@ def test_lookup_osmline_with_address_details(apiobj):
|
||||
category=('place', 'house_number'),
|
||||
names={'ref': '2'}, extratags={},
|
||||
admin_level=None, fromarea=True, isaddress=True,
|
||||
rank_address=28, distance=0.0),
|
||||
rank_address=28, distance=0.0,
|
||||
local_name='2'),
|
||||
napi.AddressLine(place_id=332, osm_object=('W', 4),
|
||||
category=('highway', 'residential'),
|
||||
names={'name': 'Street'}, extratags={},
|
||||
admin_level=15, fromarea=True, isaddress=True,
|
||||
rank_address=26, distance=0.0),
|
||||
rank_address=26, distance=0.0,
|
||||
local_name='Street'),
|
||||
napi.AddressLine(place_id=1000, osm_object=('N', 3333),
|
||||
category=('place', 'suburb'),
|
||||
names={'name': 'Smallplace'}, extratags={},
|
||||
admin_level=13, fromarea=False, isaddress=True,
|
||||
rank_address=23, distance=0.0034),
|
||||
rank_address=23, distance=0.0034,
|
||||
local_name='Smallplace'),
|
||||
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),
|
||||
rank_address=16, distance=0.0,
|
||||
local_name='Bigplace'),
|
||||
napi.AddressLine(place_id=None, osm_object=None,
|
||||
category=('place', 'country_code'),
|
||||
names={'ref': 'pl'}, extratags={},
|
||||
@@ -441,22 +448,26 @@ def test_lookup_tiger_with_address_details(apiobj):
|
||||
category=('place', 'house_number'),
|
||||
names={'ref': '2'}, extratags={},
|
||||
admin_level=None, fromarea=True, isaddress=True,
|
||||
rank_address=28, distance=0.0),
|
||||
rank_address=28, distance=0.0,
|
||||
local_name='2'),
|
||||
napi.AddressLine(place_id=332, osm_object=('W', 4),
|
||||
category=('highway', 'residential'),
|
||||
names={'name': 'Street'}, extratags={},
|
||||
admin_level=15, fromarea=True, isaddress=True,
|
||||
rank_address=26, distance=0.0),
|
||||
rank_address=26, distance=0.0,
|
||||
local_name='Street'),
|
||||
napi.AddressLine(place_id=1000, osm_object=('N', 3333),
|
||||
category=('place', 'suburb'),
|
||||
names={'name': 'Smallplace'}, extratags={},
|
||||
admin_level=13, fromarea=False, isaddress=True,
|
||||
rank_address=23, distance=0.0034),
|
||||
rank_address=23, distance=0.0034,
|
||||
local_name='Smallplace'),
|
||||
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),
|
||||
rank_address=16, distance=0.0,
|
||||
local_name='Bigplace'),
|
||||
napi.AddressLine(place_id=None, osm_object=None,
|
||||
category=('place', 'country_code'),
|
||||
names={'ref': 'us'}, extratags={},
|
||||
@@ -536,17 +547,20 @@ def test_lookup_postcode_with_address_details(apiobj):
|
||||
category=('place', 'suburb'),
|
||||
names={'name': 'Smallplace'}, extratags={},
|
||||
admin_level=13, fromarea=True, isaddress=True,
|
||||
rank_address=23, distance=0.0),
|
||||
rank_address=23, distance=0.0,
|
||||
local_name='Smallplace'),
|
||||
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),
|
||||
rank_address=16, distance=0.0,
|
||||
local_name='Bigplace'),
|
||||
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),
|
||||
rank_address=5, distance=0.0,
|
||||
local_name='34 425'),
|
||||
napi.AddressLine(place_id=None, osm_object=None,
|
||||
category=('place', 'country_code'),
|
||||
names={'ref': 'gb'}, extratags={},
|
||||
|
||||
@@ -67,7 +67,9 @@ class TestCliReverseCall:
|
||||
result = napi.ReverseResult(napi.SourceTable.PLACEX, ('place', 'thing'),
|
||||
napi.Point(1.0, -3.0),
|
||||
names={'name':'Name', 'name:fr': 'Nom'},
|
||||
extratags={'extra':'Extra'})
|
||||
extratags={'extra':'Extra'},
|
||||
locale_name='Name',
|
||||
display_name='Name')
|
||||
|
||||
monkeypatch.setattr(napi.NominatimAPI, 'reverse',
|
||||
lambda *args, **kwargs: result)
|
||||
@@ -109,16 +111,6 @@ class TestCliReverseCall:
|
||||
assert out['type'] == 'FeatureCollection'
|
||||
|
||||
|
||||
def test_reverse_language(self, cli_call, tmp_path, capsys):
|
||||
result = cli_call('reverse', '--project-dir', str(tmp_path),
|
||||
'--lat', '34', '--lon', '34', '--lang', 'fr')
|
||||
|
||||
assert result == 0
|
||||
|
||||
out = json.loads(capsys.readouterr().out)
|
||||
assert out['name'] == 'Nom'
|
||||
|
||||
|
||||
class TestCliLookupCall:
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@@ -126,7 +118,9 @@ class TestCliLookupCall:
|
||||
result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
|
||||
napi.Point(1.0, -3.0),
|
||||
names={'name':'Name', 'name:fr': 'Nom'},
|
||||
extratags={'extra':'Extra'})
|
||||
extratags={'extra':'Extra'},
|
||||
locale_name='Name',
|
||||
display_name='Name')
|
||||
|
||||
monkeypatch.setattr(napi.NominatimAPI, 'lookup',
|
||||
lambda *args, **kwargs: napi.SearchResults([result]))
|
||||
@@ -150,9 +144,11 @@ class TestCliLookupCall:
|
||||
])
|
||||
def test_search(cli_call, tmp_path, capsys, monkeypatch, endpoint, params):
|
||||
result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
|
||||
napi.Point(1.0, -3.0),
|
||||
names={'name':'Name', 'name:fr': 'Nom'},
|
||||
extratags={'extra':'Extra'})
|
||||
napi.Point(1.0, -3.0),
|
||||
names={'name':'Name', 'name:fr': 'Nom'},
|
||||
extratags={'extra':'Extra'},
|
||||
locale_name='Name',
|
||||
display_name='Name')
|
||||
|
||||
monkeypatch.setattr(napi.NominatimAPI, endpoint,
|
||||
lambda *args, **kwargs: napi.SearchResults([result]))
|
||||
|
||||
Reference in New Issue
Block a user