mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
Update entrances schema
This commit is contained in:
@@ -818,6 +818,8 @@ DECLARE
|
|||||||
nameaddress_vector INTEGER[];
|
nameaddress_vector INTEGER[];
|
||||||
addr_nameaddress_vector INTEGER[];
|
addr_nameaddress_vector INTEGER[];
|
||||||
|
|
||||||
|
entrances JSONB;
|
||||||
|
|
||||||
linked_place BIGINT;
|
linked_place BIGINT;
|
||||||
|
|
||||||
linked_node_id BIGINT;
|
linked_node_id BIGINT;
|
||||||
@@ -880,12 +882,17 @@ BEGIN
|
|||||||
NEW.centroid := get_center_point(NEW.geometry);
|
NEW.centroid := get_center_point(NEW.geometry);
|
||||||
|
|
||||||
-- Record the entrance node locations
|
-- Record the entrance node locations
|
||||||
IF NEW.osm_type = 'W' THEN
|
IF NEW.osm_type = 'W' and (NEW.rank_search > 27 or NEW.class IN ('landuse', 'leisure')) THEN
|
||||||
DELETE FROM place_entrance WHERE place_id = NEW.place_id;
|
SELECT jsonb_agg(jsonb_build_object('osm_id', osm_id, 'type', type, 'lat', ST_Y(geometry), 'lon', ST_X(geometry), 'extratags', extratags))
|
||||||
INSERT INTO place_entrance (place_id, osm_node_id, type, geometry)
|
|
||||||
SELECT NEW.place_id, osm_id, type, geometry
|
|
||||||
FROM place
|
FROM place
|
||||||
WHERE osm_id IN (SELECT unnest(nodes) FROM planet_osm_ways WHERE id=NEW.osm_id) AND class IN ('routing:entrance', 'entrance');
|
WHERE osm_id IN (SELECT unnest(nodes) FROM planet_osm_ways WHERE id=NEW.osm_id) AND class IN ('routing:entrance', 'entrance')
|
||||||
|
INTO entrances;
|
||||||
|
IF entrances IS NOT NULL THEN
|
||||||
|
INSERT INTO place_entrance (place_id, entrances)
|
||||||
|
SELECT NEW.place_id, entrances
|
||||||
|
ON CONFLICT (place_id) DO UPDATE
|
||||||
|
SET entrances = excluded.entrances;
|
||||||
|
END IF;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- recalculate country and partition
|
-- recalculate country and partition
|
||||||
|
|||||||
@@ -248,11 +248,10 @@ GRANT SELECT ON location_postcode TO "{{config.DATABASE_WEBUSER}}" ;
|
|||||||
DROP TABLE IF EXISTS place_entrance;
|
DROP TABLE IF EXISTS place_entrance;
|
||||||
CREATE TABLE place_entrance (
|
CREATE TABLE place_entrance (
|
||||||
place_id BIGINT NOT NULL,
|
place_id BIGINT NOT NULL,
|
||||||
osm_node_id BIGINT NOT NULL,
|
entrances JSONB NOT NULL
|
||||||
type TEXT NOT NULL,
|
|
||||||
geometry GEOMETRY(Point, 4326) NOT NULL
|
|
||||||
);
|
);
|
||||||
CREATE UNIQUE INDEX idx_place_entrance_id ON place_entrance USING BTREE (place_id, osm_node_id) {{db.tablespace.search_index}};
|
CREATE UNIQUE INDEX idx_place_entrance_place_id ON place_entrance
|
||||||
|
USING BTREE (place_id) {{db.tablespace.search_index}};
|
||||||
GRANT SELECT ON place_entrance TO "{{config.DATABASE_WEBUSER}}" ;
|
GRANT SELECT ON place_entrance TO "{{config.DATABASE_WEBUSER}}" ;
|
||||||
|
|
||||||
-- Create an index on the place table for lookups to populate the entrance
|
-- Create an index on the place table for lookups to populate the entrance
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import sqlalchemy as sa
|
|||||||
|
|
||||||
from .typing import SaSelect, SaRow
|
from .typing import SaSelect, SaRow
|
||||||
from .sql.sqlalchemy_types import Geometry
|
from .sql.sqlalchemy_types import Geometry
|
||||||
from .types import Point, Bbox, LookupDetails
|
from .types import Point, Bbox, LookupDetails, EntranceDetails
|
||||||
from .connection import SearchConnection
|
from .connection import SearchConnection
|
||||||
from .logging import log
|
from .logging import log
|
||||||
|
|
||||||
@@ -206,6 +206,8 @@ class BaseResult:
|
|||||||
name_keywords: Optional[WordInfos] = None
|
name_keywords: Optional[WordInfos] = None
|
||||||
address_keywords: Optional[WordInfos] = None
|
address_keywords: Optional[WordInfos] = None
|
||||||
|
|
||||||
|
entrances: Optional[List[EntranceDetails]] = None
|
||||||
|
|
||||||
geometry: Dict[str, str] = dataclasses.field(default_factory=dict)
|
geometry: Dict[str, str] = dataclasses.field(default_factory=dict)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -466,6 +468,10 @@ async def add_result_details(conn: SearchConnection, results: List[BaseResultT],
|
|||||||
log().comment('Query parent places')
|
log().comment('Query parent places')
|
||||||
for result in results:
|
for result in results:
|
||||||
await complete_parented_places(conn, result)
|
await complete_parented_places(conn, result)
|
||||||
|
if details.entrances:
|
||||||
|
log().comment('Query entrances details')
|
||||||
|
for result in results:
|
||||||
|
await complete_entrances_details(conn, result)
|
||||||
if details.keywords:
|
if details.keywords:
|
||||||
log().comment('Query keywords')
|
log().comment('Query keywords')
|
||||||
for result in results:
|
for result in results:
|
||||||
@@ -717,6 +723,19 @@ async def complete_linked_places(conn: SearchConnection, result: BaseResult) ->
|
|||||||
result.linked_rows.append(_result_row_to_address_row(row))
|
result.linked_rows.append(_result_row_to_address_row(row))
|
||||||
|
|
||||||
|
|
||||||
|
async def complete_entrances_details(conn: SearchConnection, result: BaseResult) -> None:
|
||||||
|
""" Retrieve information about tagged entrances for this place.
|
||||||
|
"""
|
||||||
|
if result.source_table != SourceTable.PLACEX:
|
||||||
|
return
|
||||||
|
|
||||||
|
t = conn.t.place_entrance
|
||||||
|
sql = sa.select(t.c.entrances).where(t.c.place_id == result.place_id)
|
||||||
|
|
||||||
|
for results in await conn.execute(sql):
|
||||||
|
result.entrances = [EntranceDetails(**r) for r in results[0]]
|
||||||
|
|
||||||
|
|
||||||
async def complete_keywords(conn: SearchConnection, result: BaseResult) -> None:
|
async def complete_keywords(conn: SearchConnection, result: BaseResult) -> None:
|
||||||
""" Retrieve information about the search terms used for this place.
|
""" Retrieve information about the search terms used for this place.
|
||||||
|
|
||||||
|
|||||||
@@ -127,3 +127,8 @@ class SearchTables:
|
|||||||
sa.Column('step', sa.SmallInteger),
|
sa.Column('step', sa.SmallInteger),
|
||||||
sa.Column('linegeo', Geometry),
|
sa.Column('linegeo', Geometry),
|
||||||
sa.Column('postcode', sa.Text))
|
sa.Column('postcode', sa.Text))
|
||||||
|
|
||||||
|
self.place_entrance = sa.Table(
|
||||||
|
'place_entrance', meta,
|
||||||
|
sa.Column('place_id', sa.BigInteger),
|
||||||
|
sa.Column('entrances', KeyValueStore))
|
||||||
|
|||||||
@@ -401,6 +401,9 @@ class LookupDetails:
|
|||||||
for, i.e. all places for which it provides the address details.
|
for, i.e. all places for which it provides the address details.
|
||||||
Only POI places can have parents.
|
Only POI places can have parents.
|
||||||
"""
|
"""
|
||||||
|
entrances: bool = False
|
||||||
|
""" Get detailed information about the tagged entrances for the result.
|
||||||
|
"""
|
||||||
keywords: bool = False
|
keywords: bool = False
|
||||||
""" Add information about the search terms used for this place.
|
""" Add information about the search terms used for this place.
|
||||||
"""
|
"""
|
||||||
@@ -548,3 +551,27 @@ class SearchDetails(LookupDetails):
|
|||||||
true when layer restriction has been disabled completely.
|
true when layer restriction has been disabled completely.
|
||||||
"""
|
"""
|
||||||
return self.layers is None or bool(self.layers & layer)
|
return self.layers is None or bool(self.layers & layer)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class EntranceDetails:
|
||||||
|
""" Reference a place by its OSM ID and potentially the basic category.
|
||||||
|
|
||||||
|
The OSM ID may refer to places in the main table placex and OSM
|
||||||
|
interpolation lines.
|
||||||
|
"""
|
||||||
|
osm_id: int
|
||||||
|
""" The OSM ID of the object.
|
||||||
|
"""
|
||||||
|
type: str
|
||||||
|
""" The value of the OSM entrance tag (i.e. yes, main, secondary, etc.).
|
||||||
|
"""
|
||||||
|
lat: float
|
||||||
|
""" The latitude of the entrance node.
|
||||||
|
"""
|
||||||
|
lon: float
|
||||||
|
""" The longitude of the entrance node.
|
||||||
|
"""
|
||||||
|
extratags: Dict[str, str]
|
||||||
|
""" The longitude of the entrance node.
|
||||||
|
"""
|
||||||
|
|||||||
@@ -196,6 +196,9 @@ def _format_details_json(result: DetailedResult, options: Mapping[str, Any]) ->
|
|||||||
else:
|
else:
|
||||||
_add_address_rows(out, 'hierarchy', result.parented_rows, locales)
|
_add_address_rows(out, 'hierarchy', result.parented_rows, locales)
|
||||||
|
|
||||||
|
if result.entrances is not None:
|
||||||
|
out.keyval('entrances', result.entrances)
|
||||||
|
|
||||||
out.end_object()
|
out.end_object()
|
||||||
|
|
||||||
return out()
|
return out()
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ def format_base_json(results: Union[ReverseResults, SearchResults],
|
|||||||
_write_typed_address(out, result.address_rows, result.country_code)
|
_write_typed_address(out, result.address_rows, result.country_code)
|
||||||
out.end_object().next()
|
out.end_object().next()
|
||||||
|
|
||||||
|
if options.get('entrances', False) and result.entrances:
|
||||||
|
out.keyval('entrances', result.entrances)
|
||||||
|
|
||||||
if options.get('extratags', False):
|
if options.get('extratags', False):
|
||||||
out.keyval('extratags', result.extratags)
|
out.keyval('extratags', result.extratags)
|
||||||
|
|
||||||
@@ -180,6 +183,9 @@ def format_base_geojson(results: Union[ReverseResults, SearchResults],
|
|||||||
_write_typed_address(out, result.address_rows, result.country_code)
|
_write_typed_address(out, result.address_rows, result.country_code)
|
||||||
out.end_object().next()
|
out.end_object().next()
|
||||||
|
|
||||||
|
if options.get('entrances', False):
|
||||||
|
out.keyval('entrances', result.entrances)
|
||||||
|
|
||||||
if options.get('extratags', False):
|
if options.get('extratags', False):
|
||||||
out.keyval('extratags', result.extratags)
|
out.keyval('extratags', result.extratags)
|
||||||
|
|
||||||
@@ -251,6 +257,9 @@ def format_base_geocodejson(results: Union[ReverseResults, SearchResults],
|
|||||||
out.keyval(f"level{line.admin_level}", line.local_name)
|
out.keyval(f"level{line.admin_level}", line.local_name)
|
||||||
out.end_object().next()
|
out.end_object().next()
|
||||||
|
|
||||||
|
if options.get('entrances', False):
|
||||||
|
out.keyval('entrances', result.entrances)
|
||||||
|
|
||||||
if options.get('extratags', False):
|
if options.get('extratags', False):
|
||||||
out.keyval('extra', result.extratags)
|
out.keyval('extra', result.extratags)
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
Helper functions for output of results in XML format.
|
Helper functions for output of results in XML format.
|
||||||
"""
|
"""
|
||||||
from typing import Mapping, Any, Optional, Union
|
from typing import Mapping, Any, Optional, Union
|
||||||
|
import dataclasses
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
@@ -122,4 +123,10 @@ def format_base_xml(results: Union[ReverseResults, SearchResults],
|
|||||||
for k, v in result.names.items():
|
for k, v in result.names.items():
|
||||||
ET.SubElement(eroot, 'name', attrib={'desc': k}).text = v
|
ET.SubElement(eroot, 'name', attrib={'desc': k}).text = v
|
||||||
|
|
||||||
|
if options.get('entrances', False):
|
||||||
|
eroot = ET.SubElement(root if simple else place, 'entrances')
|
||||||
|
if result.entrances:
|
||||||
|
for entrance_detail in result.entrances:
|
||||||
|
ET.SubElement(eroot, 'entrance', attrib=dataclasses.asdict(entrance_detail))
|
||||||
|
|
||||||
return '<?xml version="1.0" encoding="UTF-8" ?>\n' + ET.tostring(root, encoding='unicode')
|
return '<?xml version="1.0" encoding="UTF-8" ?>\n' + ET.tostring(root, encoding='unicode')
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ def extend_query_parts(queryparts: Dict[str, Any], details: Dict[str, Any],
|
|||||||
queryparts['polygon_text'] = '1'
|
queryparts['polygon_text'] = '1'
|
||||||
if parsed.address_details:
|
if parsed.address_details:
|
||||||
queryparts['addressdetails'] = '1'
|
queryparts['addressdetails'] = '1'
|
||||||
|
if parsed.entrances:
|
||||||
|
queryparts['entrances'] = '1'
|
||||||
if namedetails:
|
if namedetails:
|
||||||
queryparts['namedetails'] = '1'
|
queryparts['namedetails'] = '1'
|
||||||
if extratags:
|
if extratags:
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ async def details_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
|||||||
|
|
||||||
result = await api.details(place,
|
result = await api.details(place,
|
||||||
address_details=params.get_bool('addressdetails', False),
|
address_details=params.get_bool('addressdetails', False),
|
||||||
|
entrances=params.get_bool('entrances', False),
|
||||||
linked_places=params.get_bool('linkedplaces', True),
|
linked_places=params.get_bool('linkedplaces', True),
|
||||||
parented_places=params.get_bool('hierarchy', False),
|
parented_places=params.get_bool('hierarchy', False),
|
||||||
keywords=params.get_bool('keywords', False),
|
keywords=params.get_bool('keywords', False),
|
||||||
@@ -216,6 +217,7 @@ async def reverse_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
|||||||
fmt_options = {'query': query,
|
fmt_options = {'query': query,
|
||||||
'extratags': params.get_bool('extratags', False),
|
'extratags': params.get_bool('extratags', False),
|
||||||
'namedetails': params.get_bool('namedetails', False),
|
'namedetails': params.get_bool('namedetails', False),
|
||||||
|
'entrances': params.get_bool('entrances', False),
|
||||||
'addressdetails': params.get_bool('addressdetails', True)}
|
'addressdetails': params.get_bool('addressdetails', True)}
|
||||||
|
|
||||||
output = params.formatting().format_result(ReverseResults([result] if result else []),
|
output = params.formatting().format_result(ReverseResults([result] if result else []),
|
||||||
@@ -252,6 +254,7 @@ async def lookup_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
|||||||
|
|
||||||
fmt_options = {'extratags': params.get_bool('extratags', False),
|
fmt_options = {'extratags': params.get_bool('extratags', False),
|
||||||
'namedetails': params.get_bool('namedetails', False),
|
'namedetails': params.get_bool('namedetails', False),
|
||||||
|
'entrances': params.get_bool('entrances', False),
|
||||||
'addressdetails': params.get_bool('addressdetails', True)}
|
'addressdetails': params.get_bool('addressdetails', True)}
|
||||||
|
|
||||||
output = params.formatting().format_result(results, fmt, fmt_options)
|
output = params.formatting().format_result(results, fmt, fmt_options)
|
||||||
@@ -298,6 +301,7 @@ async def search_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
|||||||
details = parse_geometry_details(params, fmt)
|
details = parse_geometry_details(params, fmt)
|
||||||
|
|
||||||
details['countries'] = params.get('countrycodes', None)
|
details['countries'] = params.get('countrycodes', None)
|
||||||
|
details['entrances'] = params.get_bool('entrances', False)
|
||||||
details['excluded'] = params.get('exclude_place_ids', None)
|
details['excluded'] = params.get('exclude_place_ids', None)
|
||||||
details['viewbox'] = params.get('viewbox', None) or params.get('viewboxlbrt', None)
|
details['viewbox'] = params.get('viewbox', None) or params.get('viewboxlbrt', None)
|
||||||
details['bounded_viewbox'] = params.get_bool('bounded', False)
|
details['bounded_viewbox'] = params.get_bool('bounded', False)
|
||||||
@@ -363,6 +367,7 @@ async def search_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
|
|||||||
'viewbox': queryparts.get('viewbox'),
|
'viewbox': queryparts.get('viewbox'),
|
||||||
'extratags': params.get_bool('extratags', False),
|
'extratags': params.get_bool('extratags', False),
|
||||||
'namedetails': params.get_bool('namedetails', False),
|
'namedetails': params.get_bool('namedetails', False),
|
||||||
|
'entrances': params.get_bool('entrances', False),
|
||||||
'addressdetails': params.get_bool('addressdetails', False)}
|
'addressdetails': params.get_bool('addressdetails', False)}
|
||||||
|
|
||||||
output = params.formatting().format_result(results, fmt, fmt_options)
|
output = params.formatting().format_result(results, fmt, fmt_options)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ EXTRADATA_PARAMS = (
|
|||||||
('addressdetails', 'Include a breakdown of the address into elements'),
|
('addressdetails', 'Include a breakdown of the address into elements'),
|
||||||
('extratags', ("Include additional information if available "
|
('extratags', ("Include additional information if available "
|
||||||
"(e.g. wikipedia link, opening hours)")),
|
"(e.g. wikipedia link, opening hours)")),
|
||||||
|
('entrances', 'Include a list of tagged entrance nodes'),
|
||||||
('namedetails', 'Include a list of alternative names')
|
('namedetails', 'Include a list of alternative names')
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -196,6 +197,7 @@ class APISearch:
|
|||||||
'excluded': args.exclude_place_ids,
|
'excluded': args.exclude_place_ids,
|
||||||
'viewbox': args.viewbox,
|
'viewbox': args.viewbox,
|
||||||
'bounded_viewbox': args.bounded,
|
'bounded_viewbox': args.bounded,
|
||||||
|
'entrances': args.entrances,
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.query:
|
if args.query:
|
||||||
@@ -225,6 +227,7 @@ class APISearch:
|
|||||||
_print_output(formatter, results, args.format,
|
_print_output(formatter, results, args.format,
|
||||||
{'extratags': args.extratags,
|
{'extratags': args.extratags,
|
||||||
'namedetails': args.namedetails,
|
'namedetails': args.namedetails,
|
||||||
|
'entrances': args.entrances,
|
||||||
'addressdetails': args.addressdetails})
|
'addressdetails': args.addressdetails})
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -295,6 +298,7 @@ class APIReverse:
|
|||||||
_print_output(formatter, napi.ReverseResults([result]), args.format,
|
_print_output(formatter, napi.ReverseResults([result]), args.format,
|
||||||
{'extratags': args.extratags,
|
{'extratags': args.extratags,
|
||||||
'namedetails': args.namedetails,
|
'namedetails': args.namedetails,
|
||||||
|
'entrances': args.entrances,
|
||||||
'addressdetails': args.addressdetails})
|
'addressdetails': args.addressdetails})
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@@ -358,6 +362,7 @@ class APILookup:
|
|||||||
_print_output(formatter, results, args.format,
|
_print_output(formatter, results, args.format,
|
||||||
{'extratags': args.extratags,
|
{'extratags': args.extratags,
|
||||||
'namedetails': args.namedetails,
|
'namedetails': args.namedetails,
|
||||||
|
'entrances': args.entrances,
|
||||||
'addressdetails': args.addressdetails})
|
'addressdetails': args.addressdetails})
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -395,6 +400,8 @@ class APIDetails:
|
|||||||
help='Include a list of name keywords and address keywords')
|
help='Include a list of name keywords and address keywords')
|
||||||
group.add_argument('--linkedplaces', action='store_true',
|
group.add_argument('--linkedplaces', action='store_true',
|
||||||
help='Include a details of places that are linked with this one')
|
help='Include a details of places that are linked with this one')
|
||||||
|
group.add_argument('--entrances', action='store_true',
|
||||||
|
help='Include a list of tagged entrance nodes')
|
||||||
group.add_argument('--hierarchy', action='store_true',
|
group.add_argument('--hierarchy', action='store_true',
|
||||||
help='Include details of places lower in the address hierarchy')
|
help='Include details of places lower in the address hierarchy')
|
||||||
group.add_argument('--group_hierarchy', action='store_true',
|
group.add_argument('--group_hierarchy', action='store_true',
|
||||||
@@ -434,6 +441,7 @@ class APIDetails:
|
|||||||
with napi.NominatimAPI(args.project_dir) as api:
|
with napi.NominatimAPI(args.project_dir) as api:
|
||||||
result = api.details(place,
|
result = api.details(place,
|
||||||
address_details=args.addressdetails,
|
address_details=args.addressdetails,
|
||||||
|
entrances=args.entrances,
|
||||||
linked_places=args.linkedplaces,
|
linked_places=args.linkedplaces,
|
||||||
parented_places=args.hierarchy,
|
parented_places=args.hierarchy,
|
||||||
keywords=args.keywords,
|
keywords=args.keywords,
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ class NominatimArgs:
|
|||||||
format: str
|
format: str
|
||||||
list_formats: bool
|
list_formats: bool
|
||||||
addressdetails: bool
|
addressdetails: bool
|
||||||
|
entrances: bool
|
||||||
extratags: bool
|
extratags: bool
|
||||||
namedetails: bool
|
namedetails: bool
|
||||||
lang: Optional[str]
|
lang: Optional[str]
|
||||||
|
|||||||
@@ -124,20 +124,19 @@ def create_place_entrance_table(conn: Connection, config: Configuration, **_: An
|
|||||||
"""
|
"""
|
||||||
sqlp = SQLPreprocessor(conn, config)
|
sqlp = SQLPreprocessor(conn, config)
|
||||||
sqlp.run_string(conn, """
|
sqlp.run_string(conn, """
|
||||||
-- Table to store location of entrance nodes
|
-- Table to store location of entrance nodes
|
||||||
CREATE TABLE IF NOT EXISTS place_entrance (
|
DROP TABLE IF EXISTS place_entrance;
|
||||||
place_id BIGINT NOT NULL,
|
CREATE TABLE place_entrance (
|
||||||
osm_node_id BIGINT NOT NULL,
|
place_id BIGINT NOT NULL,
|
||||||
type TEXT NOT NULL,
|
entrances JSONB NOT NULL
|
||||||
geometry GEOMETRY(Point, 4326) NOT NULL
|
);
|
||||||
);
|
CREATE UNIQUE INDEX idx_place_entrance_place_id ON place_entrance
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_place_entrance_id
|
USING BTREE (place_id) {{db.tablespace.search_index}};
|
||||||
ON place_entrance USING BTREE (place_id, osm_node_id) {{db.tablespace.search_index}};
|
GRANT SELECT ON place_entrance TO "{{config.DATABASE_WEBUSER}}" ;
|
||||||
GRANT SELECT ON place_entrance TO "{{config.DATABASE_WEBUSER}}" ;
|
|
||||||
|
|
||||||
-- Create an index on the place table for lookups to populate the entrance
|
-- Create an index on the place table for lookups to populate the entrance
|
||||||
-- table
|
-- table
|
||||||
CREATE INDEX IF NOT EXISTS idx_place_entrance_lookup ON place
|
CREATE INDEX IF NOT EXISTS idx_place_entrance_lookup ON place
|
||||||
USING BTREE (osm_id)
|
USING BTREE (osm_id)
|
||||||
WHERE class IN ('routing:entrance', 'entrance');
|
WHERE class IN ('routing:entrance', 'entrance');
|
||||||
""")
|
""")
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ Feature: Object details
|
|||||||
And the result is valid json
|
And the result is valid json
|
||||||
And the result has attributes address
|
And the result has attributes address
|
||||||
|
|
||||||
|
Scenario: Details with entrances
|
||||||
|
When sending v1/details
|
||||||
|
| osmtype | osmid | entrances |
|
||||||
|
| W | 429210603 | 1 |
|
||||||
|
Then a HTTP 200 is returned
|
||||||
|
And the result is valid json
|
||||||
|
And the result has attributes entrances
|
||||||
|
|
||||||
Scenario: Details with linkedplaces
|
Scenario: Details with linkedplaces
|
||||||
When sending v1/details
|
When sending v1/details
|
||||||
| osmtype | osmid | linkedplaces |
|
| osmtype | osmid | linkedplaces |
|
||||||
|
|||||||
@@ -63,6 +63,20 @@ Feature: Search queries
|
|||||||
| geojson | geojson |
|
| geojson | geojson |
|
||||||
| xml | xml |
|
| xml | xml |
|
||||||
|
|
||||||
|
Scenario Outline: Search with entrances
|
||||||
|
When sending v1/search with format <format>
|
||||||
|
| q | entrances |
|
||||||
|
| Saint Joseph Catholic Church | 1 |
|
||||||
|
Then a HTTP 200 is returned
|
||||||
|
And the result is valid <outformat>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
| format | outformat |
|
||||||
|
| json | json |
|
||||||
|
| jsonv2 | json |
|
||||||
|
| geojson | geojson |
|
||||||
|
| xml | xml |
|
||||||
|
|
||||||
Scenario: Coordinate search with addressdetails
|
Scenario: Coordinate search with addressdetails
|
||||||
When geocoding "47.12400621,9.6047552"
|
When geocoding "47.12400621,9.6047552"
|
||||||
| accept-language |
|
| accept-language |
|
||||||
|
|||||||
Reference in New Issue
Block a user