]> git.openstreetmap.org Git - nominatim.git/blobdiff - nominatim/api/results.py
Merge pull request #2986 from mtmail/add-more-languages-from-osm-wiki
[nominatim.git] / nominatim / api / results.py
index 779911e97a1cada25fd50b56985539a8da733d37..10f03393416b33b36f2969e012c0e678d064998a 100644 (file)
@@ -21,6 +21,7 @@ import sqlalchemy as sa
 from nominatim.typing import SaSelect, SaRow
 from nominatim.api.types import Point, LookupDetails
 from nominatim.api.connection import SearchConnection
+from nominatim.api.logging import log
 
 # This file defines complex result data classes.
 # pylint: disable=too-many-instance-attributes
@@ -105,6 +106,9 @@ class SearchResult:
 
     geometry: Dict[str, str] = dataclasses.field(default_factory=dict)
 
+    def __post_init__(self) -> None:
+        if self.indexed_date is not None and self.indexed_date.tzinfo is None:
+            self.indexed_date = self.indexed_date.replace(tzinfo=dt.timezone.utc)
 
     @property
     def lat(self) -> float:
@@ -128,41 +132,89 @@ class SearchResult:
         return self.importance or (0.7500001 - (self.rank_search/40.0))
 
 
-    # pylint: disable=consider-using-f-string
-    def centroid_as_geojson(self) -> str:
-        """ Get the centroid in GeoJSON format.
-        """
-        return '{"type": "Point","coordinates": [%f, %f]}' % self.centroid
+def _filter_geometries(row: SaRow) -> Dict[str, str]:
+    return {k[9:]: v for k, v in row._mapping.items() # pylint: disable=W0212
+            if k.startswith('geometry_')}
 
 
 def create_from_placex_row(row: SaRow) -> SearchResult:
     """ Construct a new SearchResult and add the data from the result row
         from the placex table.
     """
-    result = SearchResult(source_table=SourceTable.PLACEX,
-                          place_id=row.place_id,
-                          parent_place_id=row.parent_place_id,
-                          linked_place_id=row.linked_place_id,
-                          osm_object=(row.osm_type, row.osm_id),
-                          category=(row.class_, row.type),
-                          admin_level=row.admin_level,
-                          names=row.name,
-                          address=row.address,
-                          extratags=row.extratags,
-                          housenumber=row.housenumber,
-                          postcode=row.postcode,
-                          wikipedia=row.wikipedia,
-                          rank_address=row.rank_address,
-                          rank_search=row.rank_search,
-                          importance=row.importance,
-                          country_code=row.country_code,
-                          indexed_date=getattr(row, 'indexed_date'),
-                          centroid=Point(row.x, row.y))
-
-    result.geometry = {k[9:]: v for k, v in row._mapping.items() # pylint: disable=W0212
-                       if k.startswith('geometry_')}
-
-    return result
+    return SearchResult(source_table=SourceTable.PLACEX,
+                        place_id=row.place_id,
+                        parent_place_id=row.parent_place_id,
+                        linked_place_id=row.linked_place_id,
+                        osm_object=(row.osm_type, row.osm_id),
+                        category=(row.class_, row.type),
+                        admin_level=row.admin_level,
+                        names=row.name,
+                        address=row.address,
+                        extratags=row.extratags,
+                        housenumber=row.housenumber,
+                        postcode=row.postcode,
+                        wikipedia=row.wikipedia,
+                        rank_address=row.rank_address,
+                        rank_search=row.rank_search,
+                        importance=row.importance,
+                        country_code=row.country_code,
+                        indexed_date=getattr(row, 'indexed_date'),
+                        centroid=Point.from_wkb(row.centroid.data),
+                        geometry=_filter_geometries(row))
+
+
+def create_from_osmline_row(row: SaRow) -> SearchResult:
+    """ Construct a new SearchResult and add the data from the result row
+        from the osmline table.
+    """
+    return SearchResult(source_table=SourceTable.OSMLINE,
+                        place_id=row.place_id,
+                        parent_place_id=row.parent_place_id,
+                        osm_object=('W', row.osm_id),
+                        category=('place', 'houses'),
+                        address=row.address,
+                        postcode=row.postcode,
+                        extratags={'startnumber': str(row.startnumber),
+                                   'endnumber': str(row.endnumber),
+                                   'step': str(row.step)},
+                        country_code=row.country_code,
+                        indexed_date=getattr(row, 'indexed_date'),
+                        centroid=Point.from_wkb(row.centroid.data),
+                        geometry=_filter_geometries(row))
+
+
+def create_from_tiger_row(row: SaRow) -> SearchResult:
+    """ Construct a new SearchResult and add the data from the result row
+        from the Tiger table.
+    """
+    return SearchResult(source_table=SourceTable.TIGER,
+                        place_id=row.place_id,
+                        parent_place_id=row.parent_place_id,
+                        category=('place', 'houses'),
+                        postcode=row.postcode,
+                        extratags={'startnumber': str(row.startnumber),
+                                   'endnumber': str(row.endnumber),
+                                   'step': str(row.step)},
+                        country_code='us',
+                        centroid=Point.from_wkb(row.centroid.data),
+                        geometry=_filter_geometries(row))
+
+
+def create_from_postcode_row(row: SaRow) -> SearchResult:
+    """ Construct a new SearchResult and add the data from the result row
+        from the postcode centroid table.
+    """
+    return SearchResult(source_table=SourceTable.POSTCODE,
+                        place_id=row.place_id,
+                        parent_place_id=row.parent_place_id,
+                        category=('place', 'postcode'),
+                        names={'ref': row.postcode},
+                        rank_search=row.rank_search,
+                        rank_address=row.rank_address,
+                        country_code=row.country_code,
+                        centroid=Point.from_wkb(row.centroid.data),
+                        indexed_date=row.indexed_date,
+                        geometry=_filter_geometries(row))
 
 
 async def add_result_details(conn: SearchConnection, result: SearchResult,
@@ -170,13 +222,18 @@ async def add_result_details(conn: SearchConnection, result: SearchResult,
     """ Retrieve more details from the database according to the
         parameters specified in 'details'.
     """
+    log().section('Query details for result')
     if details.address_details:
+        log().comment('Query address details')
         await complete_address_details(conn, result)
     if details.linked_places:
+        log().comment('Query linked places')
         await complete_linked_places(conn, result)
     if details.parented_places:
+        log().comment('Query parent places')
         await complete_parented_places(conn, result)
     if details.keywords:
+        log().comment('Query keywords')
         await complete_keywords(conn, result)