Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat-3416: configurable-output-name-tags #3486

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/customize/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,25 @@ results gathered so far.
Note that under high load you may observe that users receive different results
than usual without seeing an error. This may cause some confusion.


#### NOMINATIM_OUTPUT_NAMES

| Summary | |
| -------------- | --------------------------------------------------- |
| **Description:** | Determines which name tags is chosen for a place |
| **Format:** | string |
| **Default:** | name:XX,name,brand,official_name:XX,short_name:XX,official_name,short_name,ref |
| **Comment:** | Python frontend only |


Accepts Coma separated values, `:XX` at the end identifies language specific tags
else value is identified as general tag. Tags will be added based on the given order.

Take `name:XX,name,brand` for example:
first name will added as language tag for given languages,
then name and brand will added as place name tags


### Logging Settings

#### NOMINATIM_LOG_DB
Expand Down
6 changes: 6 additions & 0 deletions settings/env.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ NOMINATIM_REQUEST_TIMEOUT=60
# to geocode" instead.
NOMINATIM_SEARCH_WITHIN_COUNTRIES=False

# Determines which name tags is chosen for a place.
# Accepts Coma separated values, `:XX` at the end identifies
# language specific tags else value is identified as general tag.
# Tags will be added based on the given order.
NOMINATIM_OUTPUT_NAMES=name:XX,name,brand,official_name:XX,short_name:XX,official_name,short_name,ref

### Log settings
#
# The following options allow to enable logging of API requests.
Expand Down
49 changes: 41 additions & 8 deletions src/nominatim_api/localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,55 @@

import re


class Locales:
""" Helper class for localization of names.

It takes a list of language prefixes in their order of preferred
usage.
Keyword arguments:
langs: List[str] -- list of language prefixes in
their order of preferred usage.
output_name_tags_config: str -- string object
containing output name tags in their order of preferred usage.
default --
`name:XX,name,brand,official_name:XX,short_name:XX,official_name,short_name,ref`
"""

def __init__(self, langs: Optional[List[str]] = None):
def __init__(
self,
langs: Optional[List[str]] = None,
output_name_tags_config: str = (
"name:XX,name,brand,official_name:XX,short_name:XX,official_name,short_name,ref"
)
):
self.languages = langs or []
self.name_tags: List[str] = []

# Build the list of supported tags. It is currently hard-coded.
self._add_lang_tags('name')
self._add_tags('name', 'brand')
self._add_lang_tags('official_name', 'short_name')
self._add_tags('official_name', 'short_name', 'ref')
# Build the list of supported tags
self._build_output_name_tags(output_name_tags_config)


def _build_output_name_tags(self, nominatim_output_names: str) -> None:
"""
Build the list of supported tags. Dynamic implementation.
"""
nominatim_output_names: List[str] = nominatim_output_names.split(",")
lang_tags: List[str] = []
tags: List[str] = []
for name in nominatim_output_names:
if name.endswith(":XX"): # Identifies Lang Tag
lang_tags.append(name[:-3])
if tags:# Determines tags batch is over, lang tag batch begins
self._add_tags(*tags)
tags = []
else: # Identifies Tag
tags.append(name)
if lang_tags: # Determines lang tags batch is over, tag batch begins
self._add_lang_tags(*lang_tags)
lang_tags = []
if lang_tags: # Adds lefover lang tags
self._add_lang_tags(*lang_tags)
if tags: # Adds lefover tags
self._add_tags(*tags)


def __bool__(self) -> bool:
Expand Down
51 changes: 51 additions & 0 deletions test/python/api/test_localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,54 @@ def test_display_name_preference():
('en,fr;garbage,de', ['en', 'de'])])
def test_from_language_preferences(langstr, langlist):
assert Locales.from_accept_languages(langstr).languages == langlist


def test_configurable_output_name_tags():
"""
tests the output name tags when environment config is provided
"""
name_tags = [
"name:en",
"_place_name:en",
"name",
"_place_name",
"brand",
"_place_brand",
"official_name:en",
"_place_official_name:en",
"shirt_name:en",
"_place_shirt_name:en",
"official_name",
"_place_official_name",
"shirt_name",
"_place_shirt_name",
"ref",
"_place_ref",
]
l = Locales(
['en'],
output_name_tags_config=(
"name:XX,name,brand,official_name:XX,shirt_name:XX,official_name,shirt_name,ref"
)
)
assert l.name_tags == name_tags


def test_default_output_name_tags():
"""
tests the default setting (previously hardcoded) in case environment config is not provided
"""
name_tags = [
"name",
"_place_name",
"brand",
"_place_brand",
"official_name",
"_place_official_name",
"short_name",
"_place_short_name",
"ref",
"_place_ref",
]
l = Locales()
assert l.name_tags == name_tags