mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
Merge pull request #3686 from astridx/output_names
Output names as setting
This commit is contained in:
@@ -602,6 +602,43 @@ results gathered so far.
|
|||||||
Note that under high load you may observe that users receive different results
|
Note that under high load you may observe that users receive different results
|
||||||
than usual without seeing an error. This may cause some confusion.
|
than usual without seeing an error. This may cause some confusion.
|
||||||
|
|
||||||
|
#### NOMINATIM_OUTPUT_NAMES
|
||||||
|
|
||||||
|
| Summary | |
|
||||||
|
| -------------- | --------------------------------------------------- |
|
||||||
|
| **Description:** | Specifies order of name tags |
|
||||||
|
| **Format:** | string: comma-separated list of tag names |
|
||||||
|
| **Default:** | name:XX,name,brand,official_name:XX,short_name:XX,official_name,short_name,ref |
|
||||||
|
|
||||||
|
Specifies the order in which different name tags are used.
|
||||||
|
The values in this list determine the preferred order of name variants,
|
||||||
|
including language-specific names (in OSM: the name tag with and without any language suffix).
|
||||||
|
|
||||||
|
Comma-separated list, where :XX stands for language suffix
|
||||||
|
(e.g. name:en) and no :XX stands for general tags (e.g. name).
|
||||||
|
|
||||||
|
See also [NOMINATIM_DEFAULT_LANGUAGE](#nominatim_default_language).
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
If NOMINATIM_OUTPUT_NAMES = `name:XX,name,short_name:XX,short_name` the search follows
|
||||||
|
|
||||||
|
```
|
||||||
|
'name', 'short_name'
|
||||||
|
```
|
||||||
|
|
||||||
|
if we have no preferred language order for showing search results.
|
||||||
|
|
||||||
|
For languages ['en', 'es'] the search follows
|
||||||
|
|
||||||
|
```
|
||||||
|
'name:en', 'name:es',
|
||||||
|
'name',
|
||||||
|
'short_name:en', 'short_name:es',
|
||||||
|
'short_name'
|
||||||
|
```
|
||||||
|
|
||||||
|
For those familiar with the internal implementation, the `_place_*` expansion is added, but to simplify, it is not included in this example.
|
||||||
|
|
||||||
### Logging Settings
|
### Logging Settings
|
||||||
|
|
||||||
#### NOMINATIM_LOG_DB
|
#### NOMINATIM_LOG_DB
|
||||||
|
|||||||
@@ -192,6 +192,13 @@ NOMINATIM_REQUEST_TIMEOUT=60
|
|||||||
# to geocode" instead.
|
# to geocode" instead.
|
||||||
NOMINATIM_SEARCH_WITHIN_COUNTRIES=False
|
NOMINATIM_SEARCH_WITHIN_COUNTRIES=False
|
||||||
|
|
||||||
|
# Specifies the order in which different name tags are used.
|
||||||
|
# The values in this list determine the preferred order of name variants,
|
||||||
|
# including language-specific names.
|
||||||
|
# Comma-separated list, where :XX stands for language-specific tags
|
||||||
|
# (e.g. name:en) and no :XX stands for general tags (e.g. name).
|
||||||
|
NOMINATIM_OUTPUT_NAMES=name:XX,name,brand,official_name:XX,short_name:XX,official_name,short_name,ref
|
||||||
|
|
||||||
### Log settings
|
### Log settings
|
||||||
#
|
#
|
||||||
# The following options allow to enable logging of API requests.
|
# The following options allow to enable logging of API requests.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
Helper functions for localizing names of results.
|
Helper functions for localizing names of results.
|
||||||
"""
|
"""
|
||||||
from typing import Mapping, List, Optional
|
from typing import Mapping, List, Optional
|
||||||
|
from .config import Configuration
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@@ -20,14 +21,18 @@ class Locales:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, langs: Optional[List[str]] = None):
|
def __init__(self, langs: Optional[List[str]] = None):
|
||||||
|
self.config = Configuration(None)
|
||||||
self.languages = langs or []
|
self.languages = langs or []
|
||||||
self.name_tags: List[str] = []
|
self.name_tags: List[str] = []
|
||||||
|
|
||||||
# Build the list of supported tags. It is currently hard-coded.
|
parts = self.config.OUTPUT_NAMES.split(',')
|
||||||
self._add_lang_tags('name')
|
|
||||||
self._add_tags('name', 'brand')
|
for part in parts:
|
||||||
self._add_lang_tags('official_name', 'short_name')
|
part = part.strip()
|
||||||
self._add_tags('official_name', 'short_name', 'ref')
|
if part.endswith(":XX"):
|
||||||
|
self._add_lang_tags(part[:-3])
|
||||||
|
else:
|
||||||
|
self._add_tags(part)
|
||||||
|
|
||||||
def __bool__(self) -> bool:
|
def __bool__(self) -> bool:
|
||||||
return len(self.languages) > 0
|
return len(self.languages) > 0
|
||||||
|
|||||||
@@ -27,6 +27,62 @@ def test_display_name_none_localized():
|
|||||||
assert loc.display_name({'ref': '34', 'name:de': 'DE'}) == '34'
|
assert loc.display_name({'ref': '34', 'name:de': 'DE'}) == '34'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_none_localized():
|
||||||
|
loc = Locales()
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name', '_place_name', 'brand', '_place_brand', 'official_name', '_place_official_name',
|
||||||
|
'short_name', '_place_short_name', 'ref', '_place_ref'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_none_localized_and_custom_output_names(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,entrance:XX,name,brand,test_tag,'
|
||||||
|
'official_name:XX,short_name:XX,alt_name:XX'
|
||||||
|
)
|
||||||
|
loc = Locales()
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name', '_place_name', 'brand', '_place_brand', 'test_tag', '_place_test_tag'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_none_localized_and_custom_output_names_more_than_two_changes(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,brand,test_tag:XX,official_name,short_name:XX,'
|
||||||
|
'alt_name,another_tag_with:XX,another_tag_withoutXX'
|
||||||
|
)
|
||||||
|
loc = Locales()
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'brand', '_place_brand', 'official_name', '_place_official_name', 'alt_name',
|
||||||
|
'_place_alt_name', 'another_tag_withoutXX', '_place_another_tag_withoutXX'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_none_localized_and_custom_output_names_including_space(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,name ,short_name:XX, short_name'
|
||||||
|
)
|
||||||
|
loc = Locales()
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name', '_place_name', 'short_name', '_place_short_name'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
def test_display_name_localized():
|
def test_display_name_localized():
|
||||||
loc = Locales(['en', 'de'])
|
loc = Locales(['en', 'de'])
|
||||||
|
|
||||||
@@ -35,6 +91,146 @@ def test_display_name_localized():
|
|||||||
assert loc.display_name({'ref': '34', 'name:de': 'DE'}) == 'DE'
|
assert loc.display_name({'ref': '34', 'name:de': 'DE'}) == 'DE'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized():
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name:en', '_place_name:en', 'name:es', '_place_name:es', 'name', '_place_name', 'brand',
|
||||||
|
'_place_brand', 'official_name:en', '_place_official_name:en', 'official_name:es',
|
||||||
|
'_place_official_name:es', 'short_name:en', '_place_short_name:en', 'short_name:es',
|
||||||
|
'_place_short_name:es', 'official_name', '_place_official_name', 'short_name',
|
||||||
|
'_place_short_name', 'ref', '_place_ref'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized_and_custom_output_names_including_space(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,name ,short_name:XX, short_name'
|
||||||
|
)
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name:en', '_place_name:en', 'name:es', '_place_name:es',
|
||||||
|
'name', '_place_name',
|
||||||
|
'short_name:en', '_place_short_name:en', 'short_name:es', '_place_short_name:es',
|
||||||
|
'short_name', '_place_short_name'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized_and_custom_output_names(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,entrance:XX,name,brand,test_tag,official_name:XX,short_name:XX,alt_name:XX'
|
||||||
|
)
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name:en', '_place_name:en', 'name:es', '_place_name:es', 'entrance:en',
|
||||||
|
'_place_entrance:en', 'entrance:es', '_place_entrance:es', 'name', '_place_name',
|
||||||
|
'brand', '_place_brand', 'test_tag', '_place_test_tag', 'official_name:en',
|
||||||
|
'_place_official_name:en', 'official_name:es', '_place_official_name:es',
|
||||||
|
'short_name:en', '_place_short_name:en', 'short_name:es', '_place_short_name:es',
|
||||||
|
'alt_name:en', '_place_alt_name:en', 'alt_name:es', '_place_alt_name:es'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized_and_custom_output_names_start_with_tag_that_has_no_XX(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name,brand,test_tag,official_name:XX,short_name:XX,alt_name:XX'
|
||||||
|
)
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name', '_place_name', 'brand', '_place_brand', 'test_tag', '_place_test_tag',
|
||||||
|
'official_name:en', '_place_official_name:en', 'official_name:es',
|
||||||
|
'_place_official_name:es', 'short_name:en', '_place_short_name:en', 'short_name:es',
|
||||||
|
'_place_short_name:es', 'alt_name:en', '_place_alt_name:en', 'alt_name:es',
|
||||||
|
'_place_alt_name:es'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized_and_custom_output_names_no_named_tags(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name,brand,test_tag'
|
||||||
|
)
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name', '_place_name', 'brand', '_place_brand', 'test_tag', '_place_test_tag'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized_and_custom_output_names_only_named_tags(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,entrance:XX,official_name:XX,short_name:XX,alt_name:XX'
|
||||||
|
)
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name:en', '_place_name:en', 'name:es', '_place_name:es', 'entrance:en',
|
||||||
|
'_place_entrance:en', 'entrance:es', '_place_entrance:es', 'official_name:en',
|
||||||
|
'_place_official_name:en', 'official_name:es', '_place_official_name:es',
|
||||||
|
'short_name:en', '_place_short_name:en', 'short_name:es', '_place_short_name:es',
|
||||||
|
'alt_name:en', '_place_alt_name:en', 'alt_name:es', '_place_alt_name:es'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized_and_custom_output_names_more_than_two_changes(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,brand,test_tag:XX,official_name,short_name:XX,'
|
||||||
|
'alt_name,another_tag_with:XX,another_tag_withoutXX'
|
||||||
|
)
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name:en', '_place_name:en', 'name:es', '_place_name:es', 'brand', '_place_brand',
|
||||||
|
'test_tag:en', '_place_test_tag:en', 'test_tag:es', '_place_test_tag:es', 'official_name',
|
||||||
|
'_place_official_name', 'short_name:en', '_place_short_name:en', 'short_name:es',
|
||||||
|
'_place_short_name:es', 'alt_name', '_place_alt_name', 'another_tag_with:en',
|
||||||
|
'_place_another_tag_with:en', 'another_tag_with:es', '_place_another_tag_with:es',
|
||||||
|
'another_tag_withoutXX', '_place_another_tag_withoutXX'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_names_localized_and_custom_output_names_XX_in_the_middle(monkeypatch):
|
||||||
|
monkeypatch.setenv(
|
||||||
|
'NOMINATIM_OUTPUT_NAMES',
|
||||||
|
'name:XX,br:XXand,test_tag:XX,official_name,sh:XXort_name:XX,'
|
||||||
|
'alt_name,another_tag_with:XX,another_tag_withoutXX'
|
||||||
|
)
|
||||||
|
loc = Locales(['en', 'es'])
|
||||||
|
|
||||||
|
expected_tags = [
|
||||||
|
'name:en', '_place_name:en', 'name:es', '_place_name:es', 'br:XXand', '_place_br:XXand',
|
||||||
|
'test_tag:en', '_place_test_tag:en', 'test_tag:es', '_place_test_tag:es', 'official_name',
|
||||||
|
'_place_official_name', 'sh:XXort_name:en', '_place_sh:XXort_name:en', 'sh:XXort_name:es',
|
||||||
|
'_place_sh:XXort_name:es', 'alt_name', '_place_alt_name', 'another_tag_with:en',
|
||||||
|
'_place_another_tag_with:en', 'another_tag_with:es', '_place_another_tag_with:es',
|
||||||
|
'another_tag_withoutXX', '_place_another_tag_withoutXX'
|
||||||
|
]
|
||||||
|
|
||||||
|
assert loc.name_tags == expected_tags, f'Expected {expected_tags}, but got {loc.name_tags}'
|
||||||
|
|
||||||
|
|
||||||
def test_display_name_preference():
|
def test_display_name_preference():
|
||||||
loc = Locales(['en', 'de'])
|
loc = Locales(['en', 'de'])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user