1 # SPDX-License-Identifier: GPL-3.0-or-later
 
   3 # This file is part of Nominatim. (https://nominatim.org)
 
   5 # Copyright (C) 2024 by the Nominatim developer community.
 
   6 # For a full list of authors see the git log.
 
   8 Tests for details API call.
 
  14 import nominatim_api as napi
 
  16 @pytest.mark.parametrize('idobj', (napi.PlaceID(332), napi.OsmID('W', 4),
 
  17                                    napi.OsmID('W', 4, 'highway')))
 
  18 def test_lookup_in_placex(apiobj, frontend, idobj):
 
  19     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
  20     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
  21                      class_='highway', type='residential',
 
  22                      name={'name': 'Road'}, address={'city': 'Barrow'},
 
  23                      extratags={'surface': 'paved'},
 
  24                      parent_place_id=34, linked_place_id=55,
 
  25                      admin_level=15, country_code='gb',
 
  27                      postcode='34425', wikipedia='en:Faa',
 
  28                      rank_search=27, rank_address=26,
 
  31                      indexed_date=import_date,
 
  32                      geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
  34     api = frontend(apiobj, options={'details'})
 
  35     result = api.details(idobj)
 
  37     assert result is not None
 
  39     assert result.source_table.name == 'PLACEX'
 
  40     assert result.category == ('highway', 'residential')
 
  41     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.0))
 
  43     assert result.place_id == 332
 
  44     assert result.parent_place_id == 34
 
  45     assert result.linked_place_id == 55
 
  46     assert result.osm_object == ('W', 4)
 
  47     assert result.admin_level == 15
 
  49     assert result.names == {'name': 'Road'}
 
  50     assert result.address == {'city': 'Barrow'}
 
  51     assert result.extratags == {'surface': 'paved'}
 
  53     assert result.housenumber == '4'
 
  54     assert result.postcode == '34425'
 
  55     assert result.wikipedia == 'en:Faa'
 
  57     assert result.rank_search == 27
 
  58     assert result.rank_address == 26
 
  59     assert result.importance == pytest.approx(0.01)
 
  61     assert result.country_code == 'gb'
 
  62     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
  64     assert result.address_rows is None
 
  65     assert result.linked_rows is None
 
  66     assert result.parented_rows is None
 
  67     assert result.name_keywords is None
 
  68     assert result.address_keywords is None
 
  70     assert result.geometry == {'type': 'ST_LineString'}
 
  73 def test_lookup_in_placex_minimal_info(apiobj, frontend):
 
  74     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
  75     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
  76                      class_='highway', type='residential',
 
  78                      rank_search=27, rank_address=26,
 
  80                      indexed_date=import_date,
 
  81                      geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
  83     api = frontend(apiobj, options={'details'})
 
  84     result = api.details(napi.PlaceID(332))
 
  86     assert result is not None
 
  88     assert result.source_table.name == 'PLACEX'
 
  89     assert result.category == ('highway', 'residential')
 
  90     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.0))
 
  92     assert result.place_id == 332
 
  93     assert result.parent_place_id is None
 
  94     assert result.linked_place_id is None
 
  95     assert result.osm_object == ('W', 4)
 
  96     assert result.admin_level == 15
 
  98     assert result.names is None
 
  99     assert result.address is None
 
 100     assert result.extratags is None
 
 102     assert result.housenumber is None
 
 103     assert result.postcode is None
 
 104     assert result.wikipedia is None
 
 106     assert result.rank_search == 27
 
 107     assert result.rank_address == 26
 
 108     assert result.importance is None
 
 110     assert result.country_code is None
 
 111     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 113     assert result.address_rows is None
 
 114     assert result.linked_rows is None
 
 115     assert result.parented_rows is None
 
 116     assert result.name_keywords is None
 
 117     assert result.address_keywords is None
 
 119     assert result.geometry == {'type': 'ST_LineString'}
 
 122 def test_lookup_in_placex_with_geometry(apiobj, frontend):
 
 123     apiobj.add_placex(place_id=332,
 
 124                       geometry='LINESTRING(23 34, 23.1 34)')
 
 126     api = frontend(apiobj, options={'details'})
 
 127     result = api.details(napi.PlaceID(332), geometry_output=napi.GeometryFormat.GEOJSON)
 
 129     assert result.geometry == {'geojson': '{"type":"LineString","coordinates":[[23,34],[23.1,34]]}'}
 
 132 def test_lookup_placex_with_address_details(apiobj, frontend):
 
 133     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 134                      class_='highway', type='residential',  name='Street',
 
 136                      rank_search=27, rank_address=26)
 
 137     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 139                               place_id=1000, osm_type='N', osm_id=3333,
 
 140                               class_='place', type='suburb', name='Smallplace',
 
 141                               country_code='pl', admin_level=13,
 
 142                               rank_search=24, rank_address=23)
 
 143     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 144                               place_id=1001, osm_type='N', osm_id=3334,
 
 145                               class_='place', type='city', name='Bigplace',
 
 147                               rank_search=17, rank_address=16)
 
 149     api = frontend(apiobj, options={'details'})
 
 150     result = api.details(napi.PlaceID(332), address_details=True)
 
 152     assert result.address_rows == [
 
 153                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 154                                 category=('highway', 'residential'),
 
 155                                 names={'name': 'Street'}, extratags={},
 
 156                                 admin_level=15, fromarea=True, isaddress=True,
 
 157                                 rank_address=26, distance=0.0,
 
 158                                 local_name='Street'),
 
 159                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 160                                 category=('place', 'suburb'),
 
 161                                 names={'name': 'Smallplace'}, extratags={},
 
 162                                 admin_level=13, fromarea=False, isaddress=True,
 
 163                                 rank_address=23, distance=0.0034,
 
 164                                 local_name='Smallplace'),
 
 165                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 166                                 category=('place', 'city'),
 
 167                                 names={'name': 'Bigplace'}, extratags={},
 
 168                                 admin_level=15, fromarea=True, isaddress=True,
 
 169                                 rank_address=16, distance=0.0,
 
 170                                 local_name='Bigplace'),
 
 171                napi.AddressLine(place_id=None, osm_object=None,
 
 172                                 category=('place', 'country_code'),
 
 173                                 names={'ref': 'pl'}, extratags={},
 
 174                                 admin_level=None, fromarea=True, isaddress=False,
 
 175                                 rank_address=4, distance=0.0)
 
 179 def test_lookup_place_with_linked_places_none_existing(apiobj, frontend):
 
 180     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 181                      class_='highway', type='residential',  name='Street',
 
 182                      country_code='pl', linked_place_id=45,
 
 183                      rank_search=27, rank_address=26)
 
 185     api = frontend(apiobj, options={'details'})
 
 186     result = api.details(napi.PlaceID(332), linked_places=True)
 
 188     assert result.linked_rows == []
 
 191 def test_lookup_place_with_linked_places_existing(apiobj, frontend):
 
 192     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 193                      class_='highway', type='residential',  name='Street',
 
 194                      country_code='pl', linked_place_id=45,
 
 195                      rank_search=27, rank_address=26)
 
 196     apiobj.add_placex(place_id=1001, osm_type='W', osm_id=5,
 
 197                      class_='highway', type='residential',  name='Street',
 
 198                      country_code='pl', linked_place_id=332,
 
 199                      rank_search=27, rank_address=26)
 
 200     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
 
 201                      class_='highway', type='residential',  name='Street',
 
 202                      country_code='pl', linked_place_id=332,
 
 203                      rank_search=27, rank_address=26)
 
 205     api = frontend(apiobj, options={'details'})
 
 206     result = api.details(napi.PlaceID(332), linked_places=True)
 
 208     assert result.linked_rows == [
 
 209                napi.AddressLine(place_id=1001, osm_object=('W', 5),
 
 210                                 category=('highway', 'residential'),
 
 211                                 names={'name': 'Street'}, extratags={},
 
 212                                 admin_level=15, fromarea=False, isaddress=True,
 
 213                                 rank_address=26, distance=0.0),
 
 214                napi.AddressLine(place_id=1002, osm_object=('W', 6),
 
 215                                 category=('highway', 'residential'),
 
 216                                 names={'name': 'Street'}, extratags={},
 
 217                                 admin_level=15, fromarea=False, isaddress=True,
 
 218                                 rank_address=26, distance=0.0),
 
 222 def test_lookup_place_with_parented_places_not_existing(apiobj, frontend):
 
 223     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 224                      class_='highway', type='residential',  name='Street',
 
 225                      country_code='pl', parent_place_id=45,
 
 226                      rank_search=27, rank_address=26)
 
 228     api = frontend(apiobj, options={'details'})
 
 229     result = api.details(napi.PlaceID(332), parented_places=True)
 
 231     assert result.parented_rows == []
 
 234 def test_lookup_place_with_parented_places_existing(apiobj, frontend):
 
 235     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 236                      class_='highway', type='residential',  name='Street',
 
 237                      country_code='pl', parent_place_id=45,
 
 238                      rank_search=27, rank_address=26)
 
 239     apiobj.add_placex(place_id=1001, osm_type='N', osm_id=5,
 
 240                      class_='place', type='house', housenumber='23',
 
 241                      country_code='pl', parent_place_id=332,
 
 242                      rank_search=30, rank_address=30)
 
 243     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
 
 244                      class_='highway', type='residential',  name='Street',
 
 245                      country_code='pl', parent_place_id=332,
 
 246                      rank_search=27, rank_address=26)
 
 248     api = frontend(apiobj, options={'details'})
 
 249     result = api.details(napi.PlaceID(332), parented_places=True)
 
 251     assert result.parented_rows == [
 
 252                napi.AddressLine(place_id=1001, osm_object=('N', 5),
 
 253                                 category=('place', 'house'),
 
 254                                 names={'housenumber': '23'}, extratags={},
 
 255                                 admin_level=15, fromarea=False, isaddress=True,
 
 256                                 rank_address=30, distance=0.0),
 
 260 @pytest.mark.parametrize('idobj', (napi.PlaceID(4924), napi.OsmID('W', 9928)))
 
 261 def test_lookup_in_osmline(apiobj, frontend, idobj):
 
 262     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
 263     apiobj.add_osmline(place_id=4924, osm_id=9928,
 
 265                        startnumber=1, endnumber=4, step=1,
 
 266                        country_code='gb', postcode='34425',
 
 267                        address={'city': 'Big'},
 
 268                        indexed_date=import_date,
 
 269                        geometry='LINESTRING(23 34, 23 35)')
 
 271     api = frontend(apiobj, options={'details'})
 
 272     result = api.details(idobj)
 
 274     assert result is not None
 
 276     assert result.source_table.name == 'OSMLINE'
 
 277     assert result.category == ('place', 'houses')
 
 278     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.5))
 
 280     assert result.place_id == 4924
 
 281     assert result.parent_place_id == 12
 
 282     assert result.linked_place_id is None
 
 283     assert result.osm_object == ('W', 9928)
 
 284     assert result.admin_level == 15
 
 286     assert result.names is None
 
 287     assert result.address == {'city': 'Big'}
 
 288     assert result.extratags == {'startnumber': '1', 'endnumber': '4', 'step': '1'}
 
 290     assert result.housenumber is None
 
 291     assert result.postcode == '34425'
 
 292     assert result.wikipedia is None
 
 294     assert result.rank_search == 30
 
 295     assert result.rank_address == 30
 
 296     assert result.importance is None
 
 298     assert result.country_code == 'gb'
 
 299     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 301     assert result.address_rows is None
 
 302     assert result.linked_rows is None
 
 303     assert result.parented_rows is None
 
 304     assert result.name_keywords is None
 
 305     assert result.address_keywords is None
 
 307     assert result.geometry == {'type': 'ST_LineString'}
 
 310 def test_lookup_in_osmline_split_interpolation(apiobj, frontend):
 
 311     apiobj.add_osmline(place_id=1000, osm_id=9,
 
 312                        startnumber=2, endnumber=4, step=1)
 
 313     apiobj.add_osmline(place_id=1001, osm_id=9,
 
 314                        startnumber=6, endnumber=9, step=1)
 
 315     apiobj.add_osmline(place_id=1002, osm_id=9,
 
 316                        startnumber=11, endnumber=20, step=1)
 
 318     api = frontend(apiobj, options={'details'})
 
 319     for i in range(1, 6):
 
 320         result = api.details(napi.OsmID('W', 9, str(i)))
 
 321         assert result.place_id == 1000
 
 322     for i in range(7, 11):
 
 323         result = api.details(napi.OsmID('W', 9, str(i)))
 
 324         assert result.place_id == 1001
 
 325     for i in range(12, 22):
 
 326         result = api.details(napi.OsmID('W', 9, str(i)))
 
 327         assert result.place_id == 1002
 
 330 def test_lookup_osmline_with_address_details(apiobj, frontend):
 
 331     apiobj.add_osmline(place_id=9000, osm_id=9,
 
 332                        startnumber=2, endnumber=4, step=1,
 
 334     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 335                      class_='highway', type='residential',  name='Street',
 
 337                      rank_search=27, rank_address=26)
 
 338     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 340                               place_id=1000, osm_type='N', osm_id=3333,
 
 341                               class_='place', type='suburb', name='Smallplace',
 
 342                               country_code='pl', admin_level=13,
 
 343                               rank_search=24, rank_address=23)
 
 344     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 345                               place_id=1001, osm_type='N', osm_id=3334,
 
 346                               class_='place', type='city', name='Bigplace',
 
 348                               rank_search=17, rank_address=16)
 
 350     api = frontend(apiobj, options={'details'})
 
 351     result = api.details(napi.PlaceID(9000), address_details=True)
 
 353     assert result.address_rows == [
 
 354                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 355                                 category=('highway', 'residential'),
 
 356                                 names={'name': 'Street'}, extratags={},
 
 357                                 admin_level=15, fromarea=True, isaddress=True,
 
 358                                 rank_address=26, distance=0.0,
 
 359                                 local_name='Street'),
 
 360                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 361                                 category=('place', 'suburb'),
 
 362                                 names={'name': 'Smallplace'}, extratags={},
 
 363                                 admin_level=13, fromarea=False, isaddress=True,
 
 364                                 rank_address=23, distance=0.0034,
 
 365                                 local_name='Smallplace'),
 
 366                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 367                                 category=('place', 'city'),
 
 368                                 names={'name': 'Bigplace'}, extratags={},
 
 369                                 admin_level=15, fromarea=True, isaddress=True,
 
 370                                 rank_address=16, distance=0.0,
 
 371                                 local_name='Bigplace'),
 
 372                napi.AddressLine(place_id=None, osm_object=None,
 
 373                                 category=('place', 'country_code'),
 
 374                                 names={'ref': 'pl'}, extratags={},
 
 375                                 admin_level=None, fromarea=True, isaddress=False,
 
 376                                 rank_address=4, distance=0.0)
 
 380 def test_lookup_in_tiger(apiobj, frontend):
 
 381     apiobj.add_tiger(place_id=4924,
 
 383                      startnumber=1, endnumber=4, step=1,
 
 385                      geometry='LINESTRING(23 34, 23 35)')
 
 386     apiobj.add_placex(place_id=12,
 
 387                       category=('highway', 'residential'),
 
 388                       osm_type='W', osm_id=6601223,
 
 389                       geometry='LINESTRING(23 34, 23 35)')
 
 391     api = frontend(apiobj, options={'details'})
 
 392     result = api.details(napi.PlaceID(4924))
 
 394     assert result is not None
 
 396     assert result.source_table.name == 'TIGER'
 
 397     assert result.category == ('place', 'houses')
 
 398     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.5))
 
 400     assert result.place_id == 4924
 
 401     assert result.parent_place_id == 12
 
 402     assert result.linked_place_id is None
 
 403     assert result.osm_object == ('W', 6601223)
 
 404     assert result.admin_level == 15
 
 406     assert result.names is None
 
 407     assert result.address is None
 
 408     assert result.extratags == {'startnumber': '1', 'endnumber': '4', 'step': '1'}
 
 410     assert result.housenumber is None
 
 411     assert result.postcode == '34425'
 
 412     assert result.wikipedia is None
 
 414     assert result.rank_search == 30
 
 415     assert result.rank_address == 30
 
 416     assert result.importance is None
 
 418     assert result.country_code == 'us'
 
 419     assert result.indexed_date is None
 
 421     assert result.address_rows is None
 
 422     assert result.linked_rows is None
 
 423     assert result.parented_rows is None
 
 424     assert result.name_keywords is None
 
 425     assert result.address_keywords is None
 
 427     assert result.geometry == {'type': 'ST_LineString'}
 
 430 def test_lookup_tiger_with_address_details(apiobj, frontend):
 
 431     apiobj.add_tiger(place_id=9000,
 
 432                      startnumber=2, endnumber=4, step=1,
 
 434     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 435                      class_='highway', type='residential',  name='Street',
 
 437                      rank_search=27, rank_address=26)
 
 438     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 440                               place_id=1000, osm_type='N', osm_id=3333,
 
 441                               class_='place', type='suburb', name='Smallplace',
 
 442                               country_code='us', admin_level=13,
 
 443                               rank_search=24, rank_address=23)
 
 444     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 445                               place_id=1001, osm_type='N', osm_id=3334,
 
 446                               class_='place', type='city', name='Bigplace',
 
 448                               rank_search=17, rank_address=16)
 
 450     api = frontend(apiobj, options={'details'})
 
 451     result = api.details(napi.PlaceID(9000), address_details=True)
 
 453     assert result.address_rows == [
 
 454                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 455                                 category=('highway', 'residential'),
 
 456                                 names={'name': 'Street'}, extratags={},
 
 457                                 admin_level=15, fromarea=True, isaddress=True,
 
 458                                 rank_address=26, distance=0.0,
 
 459                                 local_name='Street'),
 
 460                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 461                                 category=('place', 'suburb'),
 
 462                                 names={'name': 'Smallplace'}, extratags={},
 
 463                                 admin_level=13, fromarea=False, isaddress=True,
 
 464                                 rank_address=23, distance=0.0034,
 
 465                                 local_name='Smallplace'),
 
 466                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 467                                 category=('place', 'city'),
 
 468                                 names={'name': 'Bigplace'}, extratags={},
 
 469                                 admin_level=15, fromarea=True, isaddress=True,
 
 470                                 rank_address=16, distance=0.0,
 
 471                                 local_name='Bigplace'),
 
 472                napi.AddressLine(place_id=None, osm_object=None,
 
 473                                 category=('place', 'country_code'),
 
 474                                 names={'ref': 'us'}, extratags={},
 
 475                                 admin_level=None, fromarea=True, isaddress=False,
 
 476                                 rank_address=4, distance=0.0)
 
 480 def test_lookup_in_postcode(apiobj, frontend):
 
 481     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
 482     apiobj.add_postcode(place_id=554,
 
 486                         rank_search=20, rank_address=22,
 
 487                         indexed_date=import_date,
 
 488                         geometry='POINT(-9.45 5.6)')
 
 490     api = frontend(apiobj, options={'details'})
 
 491     result = api.details(napi.PlaceID(554))
 
 493     assert result is not None
 
 495     assert result.source_table.name == 'POSTCODE'
 
 496     assert result.category == ('place', 'postcode')
 
 497     assert result.centroid == (pytest.approx(-9.45), pytest.approx(5.6))
 
 499     assert result.place_id == 554
 
 500     assert result.parent_place_id == 152
 
 501     assert result.linked_place_id is None
 
 502     assert result.osm_object is None
 
 503     assert result.admin_level == 15
 
 505     assert result.names == {'ref': '34 425'}
 
 506     assert result.address is None
 
 507     assert result.extratags is None
 
 509     assert result.housenumber is None
 
 510     assert result.postcode is None
 
 511     assert result.wikipedia is None
 
 513     assert result.rank_search == 20
 
 514     assert result.rank_address == 22
 
 515     assert result.importance is None
 
 517     assert result.country_code == 'gb'
 
 518     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 520     assert result.address_rows is None
 
 521     assert result.linked_rows is None
 
 522     assert result.parented_rows is None
 
 523     assert result.name_keywords is None
 
 524     assert result.address_keywords is None
 
 526     assert result.geometry == {'type': 'ST_Point'}
 
 529 def test_lookup_postcode_with_address_details(apiobj, frontend):
 
 530     apiobj.add_postcode(place_id=9000,
 
 534                         rank_search=25, rank_address=25)
 
 535     apiobj.add_placex(place_id=332, osm_type='N', osm_id=3333,
 
 536                       class_='place', type='suburb',  name='Smallplace',
 
 537                       country_code='gb', admin_level=13,
 
 538                       rank_search=24, rank_address=23)
 
 539     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 540                               place_id=1001, osm_type='N', osm_id=3334,
 
 541                               class_='place', type='city', name='Bigplace',
 
 543                               rank_search=17, rank_address=16)
 
 545     api = frontend(apiobj, options={'details'})
 
 546     result = api.details(napi.PlaceID(9000), address_details=True)
 
 548     assert result.address_rows == [
 
 549                napi.AddressLine(place_id=9000, osm_object=None,
 
 550                                 category=('place', 'postcode'),
 
 551                                 names={'ref': '34 425'}, extratags={},
 
 552                                 admin_level=15, fromarea=True, isaddress=True,
 
 553                                 rank_address=25, distance=0.0,
 
 554                                 local_name='34 425'),
 
 555                napi.AddressLine(place_id=332, osm_object=('N', 3333),
 
 556                                 category=('place', 'suburb'),
 
 557                                 names={'name': 'Smallplace'}, extratags={},
 
 558                                 admin_level=13, fromarea=True, isaddress=True,
 
 559                                 rank_address=23, distance=0.0,
 
 560                                 local_name='Smallplace'),
 
 561                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 562                                 category=('place', 'city'),
 
 563                                 names={'name': 'Bigplace'}, extratags={},
 
 564                                 admin_level=15, fromarea=True, isaddress=True,
 
 565                                 rank_address=16, distance=0.0,
 
 566                                 local_name='Bigplace'),
 
 567                napi.AddressLine(place_id=None, osm_object=None,
 
 568                                 category=('place', 'country_code'),
 
 569                                 names={'ref': 'gb'}, extratags={},
 
 570                                 admin_level=None, fromarea=True, isaddress=False,
 
 571                                 rank_address=4, distance=0.0)
 
 574 @pytest.mark.parametrize('objid', [napi.PlaceID(1736),
 
 576                                    napi.OsmID('N', 55, 'amenity')])
 
 577 def test_lookup_missing_object(apiobj, frontend, objid):
 
 578     apiobj.add_placex(place_id=1, osm_type='N', osm_id=55,
 
 579                       class_='place', type='suburb')
 
 581     api = frontend(apiobj, options={'details'})
 
 582     assert api.details(objid) is None
 
 585 @pytest.mark.parametrize('gtype', (napi.GeometryFormat.KML,
 
 586                                     napi.GeometryFormat.SVG,
 
 587                                     napi.GeometryFormat.TEXT))
 
 588 def test_lookup_unsupported_geometry(apiobj, frontend, gtype):
 
 589     apiobj.add_placex(place_id=332)
 
 591     api = frontend(apiobj, options={'details'})
 
 592     with pytest.raises(ValueError):
 
 593         api.details(napi.PlaceID(332), geometry_output=gtype)