|
11 | 11 | internal use only. That's why they are implemented as free-standing functions |
12 | 12 | instead of member functions. |
13 | 13 | """ |
14 | | -from typing import Optional, Tuple, Dict, Sequence, TypeVar, Type, List, cast, Callable |
| 14 | +from typing import ( |
| 15 | + Optional, Tuple, Dict, Sequence, TypeVar, Type, List, |
| 16 | + cast, Callable |
| 17 | +) |
15 | 18 | import enum |
16 | 19 | import dataclasses |
17 | 20 | import datetime as dt |
|
23 | 26 | from .types import Point, Bbox, LookupDetails |
24 | 27 | from .connection import SearchConnection |
25 | 28 | from .logging import log |
26 | | -from .localization import Locales |
27 | 29 |
|
28 | 30 | # This file defines complex result data classes. |
29 | 31 |
|
@@ -130,27 +132,21 @@ class AddressLine: |
130 | 132 | [Localization](Result-Handling.md#localization) below. |
131 | 133 | """ |
132 | 134 |
|
133 | | - |
134 | | -class AddressLines(List[AddressLine]): |
135 | | - """ Sequence of address lines order in descending order by their rank. |
136 | | - """ |
137 | | - |
138 | | - def localize(self, locales: Locales) -> List[str]: |
139 | | - """ Set the local name of address parts according to the chosen |
140 | | - locale. Return the list of local names without duplicates. |
141 | | -
|
142 | | - Only address parts that are marked as isaddress are localized |
143 | | - and returned. |
| 135 | + @property |
| 136 | + def display_name(self) -> Optional[str]: |
| 137 | + """ Dynamically compute the display name for the Address Line component |
144 | 138 | """ |
145 | | - label_parts: List[str] = [] |
| 139 | + if self.local_name: |
| 140 | + return self.local_name |
| 141 | + elif 'name' in self.names: |
| 142 | + return self.names['name'] |
| 143 | + elif self.names: |
| 144 | + return next(iter(self.names.values()), None) |
| 145 | + return None |
146 | 146 |
|
147 | | - for line in self: |
148 | | - if line.isaddress and line.names: |
149 | | - line.local_name = locales.display_name(line.names) |
150 | | - if not label_parts or label_parts[-1] != line.local_name: |
151 | | - label_parts.append(line.local_name) |
152 | 147 |
|
153 | | - return label_parts |
| 148 | +class AddressLines(List[AddressLine]): |
| 149 | + """ A wrapper around a list of AddressLine objects.""" |
154 | 150 |
|
155 | 151 |
|
156 | 152 | @dataclasses.dataclass |
@@ -189,7 +185,6 @@ class BaseResult: |
189 | 185 | admin_level: int = 15 |
190 | 186 |
|
191 | 187 | locale_name: Optional[str] = None |
192 | | - display_name: Optional[str] = None |
193 | 188 |
|
194 | 189 | names: Optional[Dict[str, str]] = None |
195 | 190 | address: Optional[Dict[str, str]] = None |
@@ -225,23 +220,42 @@ def lon(self) -> float: |
225 | 220 | """ |
226 | 221 | return self.centroid[0] |
227 | 222 |
|
| 223 | + @property |
| 224 | + def display_name(self) -> Optional[str]: |
| 225 | + """ Dynamically compute the display name for the result place |
| 226 | + and, if available, its address information.. |
| 227 | + """ |
| 228 | + if self.address_rows: # if this is true we need additional processing |
| 229 | + label_parts: List[str] = [] |
| 230 | + |
| 231 | + for line in self.address_rows: # assume locale_name is set by external formatter |
| 232 | + if line.isaddress and line.names: |
| 233 | + address_name = line.display_name |
| 234 | + |
| 235 | + if address_name and (not label_parts or label_parts[-1] != address_name): |
| 236 | + label_parts.append(address_name) |
| 237 | + |
| 238 | + if label_parts: |
| 239 | + return ', '.join(label_parts) |
| 240 | + |
| 241 | + # Now adding additional information for reranking |
| 242 | + if self.locale_name: |
| 243 | + return self.locale_name |
| 244 | + elif self.names and 'name' in self.names: |
| 245 | + return self.names['name'] |
| 246 | + elif self.names: |
| 247 | + return next(iter(self.names.values())) |
| 248 | + elif self.housenumber: |
| 249 | + return self.housenumber |
| 250 | + return None |
| 251 | + |
228 | 252 | def calculated_importance(self) -> float: |
229 | 253 | """ Get a valid importance value. This is either the stored importance |
230 | 254 | of the value or an artificial value computed from the place's |
231 | 255 | search rank. |
232 | 256 | """ |
233 | 257 | return self.importance or (0.40001 - (self.rank_search/75.0)) |
234 | 258 |
|
235 | | - def localize(self, locales: Locales) -> None: |
236 | | - """ Fill the locale_name and the display_name field for the |
237 | | - place and, if available, its address information. |
238 | | - """ |
239 | | - self.locale_name = locales.display_name(self.names) |
240 | | - if self.address_rows: |
241 | | - self.display_name = ', '.join(self.address_rows.localize(locales)) |
242 | | - else: |
243 | | - self.display_name = self.locale_name |
244 | | - |
245 | 259 |
|
246 | 260 | BaseResultT = TypeVar('BaseResultT', bound=BaseResult) |
247 | 261 |
|
@@ -456,8 +470,6 @@ async def add_result_details(conn: SearchConnection, results: List[BaseResultT], |
456 | 470 | log().comment('Query keywords') |
457 | 471 | for result in results: |
458 | 472 | await complete_keywords(conn, result) |
459 | | - for result in results: |
460 | | - result.localize(details.locales) |
461 | 473 |
|
462 | 474 |
|
463 | 475 | def _result_row_to_address_row(row: SaRow, isaddress: Optional[bool] = None) -> AddressLine: |
|
0 commit comments