]> git.openstreetmap.org Git - nominatim.git/commitdiff
add /polygons endpoint to Python v1 API
authorSarah Hoffmann <lonvia@denofr.de>
Sat, 22 Jul 2023 18:59:13 +0000 (20:59 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Sat, 22 Jul 2023 18:59:13 +0000 (20:59 +0200)
nominatim/api/v1/format.py
nominatim/api/v1/server_glue.py

index 2442bb76a74aac562e867296782164b3386e394a..1e37b4c7a6fe191aec67413428aa2ad34b9d27dc 100644 (file)
@@ -9,6 +9,7 @@ Output formatters for API version v1.
 """
 from typing import List, Dict, Mapping, Any
 import collections
+import datetime as dt
 
 import nominatim.api as napi
 from nominatim.api.result_formatting import FormatDispatcher
@@ -244,7 +245,10 @@ def _format_raw_data_json(results: RawDataList,  _: Mapping[str, Any]) -> str:
     for res in results:
         out.start_object()
         for k, v in res.items():
-            out.keyval(k, v)
+            if isinstance(v, dt.datetime):
+                out.keyval(k, v.isoformat(sep= ' ', timespec='seconds'))
+            else:
+                out.keyval(k, v)
         out.end_object().next()
 
     out.end_array()
index b40d4e9ad3cab214329492d06137d91def30dabe..5ebdb55e967a29e94966213dc9613df7d1180d08 100644 (file)
@@ -514,10 +514,40 @@ async def deletable_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -
                       """)
         results = RawDataList(r._asdict() for r in await conn.execute(sql))
 
-
     return params.build_response(formatting.format_result(results, fmt, {}))
 
 
+async def polygons_endpoint(api: napi.NominatimAPIAsync, params: ASGIAdaptor) -> Any:
+    """ Server glue for /polygons endpoint.
+        This is a special endpoint that shows polygons that have changed
+        thier size but are kept in the Nominatim database with their
+        old area to minimize disruption.
+    """
+    fmt = params.parse_format(RawDataList, 'json')
+    sql_params: Dict[str, Any] = {
+        'days': params.get_int('days', -1),
+        'cls': params.get('class')
+    }
+    reduced = params.get_bool('reduced', False)
+
+    async with api.begin() as conn:
+        sql = sa.select(sa.text("""osm_type, osm_id, class, type,
+                                   name->'name' as name,
+                                   country_code, errormessage, updated"""))\
+                .select_from(sa.text('import_polygon_error'))
+        if sql_params['days'] > 0:
+            sql = sql.where(sa.text("updated > 'now'::timestamp - make_interval(days => :days)"))
+        if reduced:
+            sql = sql.where(sa.text("errormessage like 'Area reduced%'"))
+        if sql_params['cls'] is not None:
+            sql = sql.where(sa.text("class = :cls"))
+
+        sql = sql.order_by(sa.literal_column('updated').desc()).limit(1000)
+
+        results = RawDataList(r._asdict() for r in await conn.execute(sql, sql_params))
+
+    return params.build_response(formatting.format_result(results, fmt, {}))
+
 
 EndpointFunc = Callable[[napi.NominatimAPIAsync, ASGIAdaptor], Any]
 
@@ -528,4 +558,5 @@ ROUTES = [
     ('lookup', lookup_endpoint),
     ('search', search_endpoint),
     ('deletable', deletable_endpoint),
+    ('polygons', polygons_endpoint),
 ]