X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/f8bca4fbcb739daa6a89dd52c219713dd1173287..05eb1d5f4295b00dd630c68b0ec27d1daaf87a42:/nominatim/api/v1/format.py diff --git a/nominatim/api/v1/format.py b/nominatim/api/v1/format.py index 47d2af4d..53156fdd 100644 --- a/nominatim/api/v1/format.py +++ b/nominatim/api/v1/format.py @@ -7,8 +7,9 @@ """ Output formatters for API version v1. """ -from typing import Mapping, Any +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 @@ -16,6 +17,10 @@ from nominatim.api.v1.classtypes import ICONS from nominatim.api.v1 import format_json, format_xml from nominatim.utils.json_writer import JsonWriter +class RawDataList(List[Dict[str, Any]]): + """ Data type for formatting raw data lists 'as is' in json. + """ + dispatch = FormatDispatcher() @dispatch.format_func(napi.StatusResult, 'text') @@ -111,16 +116,16 @@ def _format_details_json(result: napi.DetailedResult, options: Mapping[str, Any] out.keyval('category', result.category[0])\ .keyval('type', result.category[1])\ .keyval('admin_level', result.admin_level)\ - .keyval('localname', locales.display_name(result.names))\ - .keyval_not_none('names', result.names or None)\ - .keyval_not_none('addresstags', result.address or None)\ + .keyval('localname', result.locale_name or '')\ + .keyval('names', result.names or {})\ + .keyval('addresstags', result.address or {})\ .keyval_not_none('housenumber', result.housenumber)\ .keyval_not_none('calculated_postcode', result.postcode)\ .keyval_not_none('country_code', result.country_code)\ .keyval_not_none('indexed_date', result.indexed_date, lambda v: v.isoformat())\ .keyval_not_none('importance', result.importance)\ .keyval('calculated_importance', result.calculated_importance())\ - .keyval_not_none('extratags', result.extratags or None)\ + .keyval('extratags', result.extratags or {})\ .keyval_not_none('calculated_wikipedia', result.wikipedia)\ .keyval('rank_address', result.rank_address)\ .keyval('rank_search', result.rank_search)\ @@ -136,7 +141,7 @@ def _format_details_json(result: napi.DetailedResult, options: Mapping[str, Any] if result.address_rows is not None: _add_address_rows(out, 'address', result.address_rows, locales) - if result.linked_rows is not None: + if result.linked_rows: _add_address_rows(out, 'linked_places', result.linked_rows, locales) if result.name_keywords is not None or result.address_keywords is not None: @@ -168,7 +173,7 @@ def _format_details_json(result: napi.DetailedResult, options: Mapping[str, Any] def _format_reverse_xml(results: napi.ReverseResults, options: Mapping[str, Any]) -> str: return format_xml.format_base_xml(results, options, True, 'reversegeocode', - {'querystring': 'TODO'}) + {'querystring': options.get('query', '')}) @dispatch.format_func(napi.ReverseResults, 'geojson') @@ -195,3 +200,57 @@ def _format_reverse_jsonv2(results: napi.ReverseResults, options: Mapping[str, Any]) -> str: return format_json.format_base_json(results, options, True, class_label='category') + + +@dispatch.format_func(napi.SearchResults, 'xml') +def _format_search_xml(results: napi.SearchResults, options: Mapping[str, Any]) -> str: + extra = {'querystring': options.get('query', '')} + for attr in ('more_url', 'exclude_place_ids', 'viewbox'): + if options.get(attr): + extra[attr] = options[attr] + return format_xml.format_base_xml(results, options, False, 'searchresults', + extra) + + + +@dispatch.format_func(napi.SearchResults, 'geojson') +def _format_search_geojson(results: napi.SearchResults, + options: Mapping[str, Any]) -> str: + return format_json.format_base_geojson(results, options, False) + + +@dispatch.format_func(napi.SearchResults, 'geocodejson') +def _format_search_geocodejson(results: napi.SearchResults, + options: Mapping[str, Any]) -> str: + return format_json.format_base_geocodejson(results, options, False) + + +@dispatch.format_func(napi.SearchResults, 'json') +def _format_search_json(results: napi.SearchResults, + options: Mapping[str, Any]) -> str: + return format_json.format_base_json(results, options, False, + class_label='class') + + +@dispatch.format_func(napi.SearchResults, 'jsonv2') +def _format_search_jsonv2(results: napi.SearchResults, + options: Mapping[str, Any]) -> str: + return format_json.format_base_json(results, options, False, + class_label='category') + +@dispatch.format_func(RawDataList, 'json') +def _format_raw_data_json(results: RawDataList, _: Mapping[str, Any]) -> str: + out = JsonWriter() + out.start_array() + for res in results: + out.start_object() + for k, v in res.items(): + 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() + + return out()