1 # SPDX-License-Identifier: GPL-3.0-or-later
 
   3 # This file is part of Nominatim. (https://nominatim.org)
 
   5 # Copyright (C) 2025 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
 
  17 @pytest.mark.parametrize('idobj', (napi.PlaceID(332), napi.OsmID('W', 4),
 
  18                                    napi.OsmID('W', 4, 'highway')))
 
  19 def test_lookup_in_placex(apiobj, frontend, idobj):
 
  20     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
  21     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
  22                       class_='highway', type='residential',
 
  23                       name={'name': 'Road'}, address={'city': 'Barrow'},
 
  24                       extratags={'surface': 'paved'},
 
  25                       parent_place_id=34, linked_place_id=55,
 
  26                       admin_level=15, country_code='gb',
 
  28                       postcode='34425', wikipedia='en:Faa',
 
  29                       rank_search=27, rank_address=26,
 
  32                       indexed_date=import_date,
 
  33                       geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
  35     api = frontend(apiobj, options={'details'})
 
  36     result = api.details(idobj)
 
  38     assert result is not None
 
  40     assert result.source_table.name == 'PLACEX'
 
  41     assert result.category == ('highway', 'residential')
 
  42     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.0))
 
  44     assert result.place_id == 332
 
  45     assert result.parent_place_id == 34
 
  46     assert result.linked_place_id == 55
 
  47     assert result.osm_object == ('W', 4)
 
  48     assert result.admin_level == 15
 
  50     assert result.names == {'name': 'Road'}
 
  51     assert result.address == {'city': 'Barrow'}
 
  52     assert result.extratags == {'surface': 'paved'}
 
  54     assert result.housenumber == '4'
 
  55     assert result.postcode == '34425'
 
  56     assert result.wikipedia == 'en:Faa'
 
  58     assert result.rank_search == 27
 
  59     assert result.rank_address == 26
 
  60     assert result.importance == pytest.approx(0.01)
 
  62     assert result.country_code == 'gb'
 
  63     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
  65     assert result.address_rows is None
 
  66     assert result.linked_rows is None
 
  67     assert result.parented_rows is None
 
  68     assert result.name_keywords is None
 
  69     assert result.address_keywords is None
 
  71     assert result.geometry == {'type': 'ST_LineString'}
 
  74 def test_lookup_in_placex_minimal_info(apiobj, frontend):
 
  75     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
  76     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
  77                       class_='highway', type='residential',
 
  79                       rank_search=27, rank_address=26,
 
  81                       indexed_date=import_date,
 
  82                       geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
  84     api = frontend(apiobj, options={'details'})
 
  85     result = api.details(napi.PlaceID(332))
 
  87     assert result is not None
 
  89     assert result.source_table.name == 'PLACEX'
 
  90     assert result.category == ('highway', 'residential')
 
  91     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.0))
 
  93     assert result.place_id == 332
 
  94     assert result.parent_place_id is None
 
  95     assert result.linked_place_id is None
 
  96     assert result.osm_object == ('W', 4)
 
  97     assert result.admin_level == 15
 
  99     assert result.names is None
 
 100     assert result.address is None
 
 101     assert result.extratags is None
 
 103     assert result.housenumber is None
 
 104     assert result.postcode is None
 
 105     assert result.wikipedia is None
 
 107     assert result.rank_search == 27
 
 108     assert result.rank_address == 26
 
 109     assert result.importance is None
 
 111     assert result.country_code is None
 
 112     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 114     assert result.address_rows is None
 
 115     assert result.linked_rows is None
 
 116     assert result.parented_rows is None
 
 117     assert result.name_keywords is None
 
 118     assert result.address_keywords is None
 
 120     assert result.geometry == {'type': 'ST_LineString'}
 
 123 def test_lookup_in_placex_with_geometry(apiobj, frontend):
 
 124     apiobj.add_placex(place_id=332,
 
 125                       geometry='LINESTRING(23 34, 23.1 34)')
 
 127     api = frontend(apiobj, options={'details'})
 
 128     result = api.details(napi.PlaceID(332), geometry_output=napi.GeometryFormat.GEOJSON)
 
 130     assert result.geometry == {'geojson': '{"type":"LineString","coordinates":[[23,34],[23.1,34]]}'}
 
 133 def test_lookup_placex_with_address_details(apiobj, frontend):
 
 134     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 135                       class_='highway', type='residential',  name='Street',
 
 137                       rank_search=27, rank_address=26)
 
 138     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 140                               place_id=1000, osm_type='N', osm_id=3333,
 
 141                               class_='place', type='suburb', name='Smallplace',
 
 142                               country_code='pl', admin_level=13,
 
 143                               rank_search=24, rank_address=23)
 
 144     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 145                               place_id=1001, osm_type='N', osm_id=3334,
 
 146                               class_='place', type='city', name='Bigplace',
 
 148                               rank_search=17, rank_address=16)
 
 150     api = frontend(apiobj, options={'details'})
 
 151     result = api.details(napi.PlaceID(332), address_details=True)
 
 153     assert result.address_rows == [
 
 154                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 155                                 category=('highway', 'residential'),
 
 156                                 names={'name': 'Street'}, extratags={},
 
 157                                 admin_level=15, fromarea=True, isaddress=True,
 
 158                                 rank_address=26, distance=0.0,
 
 159                                 local_name='Street'),
 
 160                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 161                                 category=('place', 'suburb'),
 
 162                                 names={'name': 'Smallplace'}, extratags={},
 
 163                                 admin_level=13, fromarea=False, isaddress=True,
 
 164                                 rank_address=23, distance=0.0034,
 
 165                                 local_name='Smallplace'),
 
 166                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 167                                 category=('place', 'city'),
 
 168                                 names={'name': 'Bigplace'}, extratags={},
 
 169                                 admin_level=15, fromarea=True, isaddress=True,
 
 170                                 rank_address=16, distance=0.0,
 
 171                                 local_name='Bigplace'),
 
 172                napi.AddressLine(place_id=None, osm_object=None,
 
 173                                 category=('place', 'country_code'),
 
 174                                 names={'ref': 'pl'}, extratags={},
 
 175                                 admin_level=None, fromarea=True, isaddress=False,
 
 176                                 rank_address=4, distance=0.0)
 
 180 def test_lookup_place_with_linked_places_none_existing(apiobj, frontend):
 
 181     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 182                       class_='highway', type='residential',  name='Street',
 
 183                       country_code='pl', linked_place_id=45,
 
 184                       rank_search=27, rank_address=26)
 
 186     api = frontend(apiobj, options={'details'})
 
 187     result = api.details(napi.PlaceID(332), linked_places=True)
 
 189     assert result.linked_rows == []
 
 192 def test_lookup_place_with_linked_places_existing(apiobj, frontend):
 
 193     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 194                       class_='highway', type='residential',  name='Street',
 
 195                       country_code='pl', linked_place_id=45,
 
 196                       rank_search=27, rank_address=26)
 
 197     apiobj.add_placex(place_id=1001, osm_type='W', osm_id=5,
 
 198                       class_='highway', type='residential',  name='Street',
 
 199                       country_code='pl', linked_place_id=332,
 
 200                       rank_search=27, rank_address=26)
 
 201     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
 
 202                       class_='highway', type='residential',  name='Street',
 
 203                       country_code='pl', linked_place_id=332,
 
 204                       rank_search=27, rank_address=26)
 
 206     api = frontend(apiobj, options={'details'})
 
 207     result = api.details(napi.PlaceID(332), linked_places=True)
 
 209     assert result.linked_rows == [
 
 210                napi.AddressLine(place_id=1001, osm_object=('W', 5),
 
 211                                 category=('highway', 'residential'),
 
 212                                 names={'name': 'Street'}, extratags={},
 
 213                                 admin_level=15, fromarea=False, isaddress=True,
 
 214                                 rank_address=26, distance=0.0),
 
 215                napi.AddressLine(place_id=1002, osm_object=('W', 6),
 
 216                                 category=('highway', 'residential'),
 
 217                                 names={'name': 'Street'}, extratags={},
 
 218                                 admin_level=15, fromarea=False, isaddress=True,
 
 219                                 rank_address=26, distance=0.0),
 
 223 def test_lookup_place_with_parented_places_not_existing(apiobj, frontend):
 
 224     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 225                       class_='highway', type='residential',  name='Street',
 
 226                       country_code='pl', parent_place_id=45,
 
 227                       rank_search=27, rank_address=26)
 
 229     api = frontend(apiobj, options={'details'})
 
 230     result = api.details(napi.PlaceID(332), parented_places=True)
 
 232     assert result.parented_rows == []
 
 235 def test_lookup_place_with_parented_places_existing(apiobj, frontend):
 
 236     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 237                       class_='highway', type='residential',  name='Street',
 
 238                       country_code='pl', parent_place_id=45,
 
 239                       rank_search=27, rank_address=26)
 
 240     apiobj.add_placex(place_id=1001, osm_type='N', osm_id=5,
 
 241                       class_='place', type='house', housenumber='23',
 
 242                       country_code='pl', parent_place_id=332,
 
 243                       rank_search=30, rank_address=30)
 
 244     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
 
 245                       class_='highway', type='residential',  name='Street',
 
 246                       country_code='pl', parent_place_id=332,
 
 247                       rank_search=27, rank_address=26)
 
 249     api = frontend(apiobj, options={'details'})
 
 250     result = api.details(napi.PlaceID(332), parented_places=True)
 
 252     assert result.parented_rows == [
 
 253                napi.AddressLine(place_id=1001, osm_object=('N', 5),
 
 254                                 category=('place', 'house'),
 
 255                                 names={'housenumber': '23'}, extratags={},
 
 256                                 admin_level=15, fromarea=False, isaddress=True,
 
 257                                 rank_address=30, distance=0.0),
 
 261 @pytest.mark.parametrize('idobj', (napi.PlaceID(4924), napi.OsmID('W', 9928)))
 
 262 def test_lookup_in_osmline(apiobj, frontend, idobj):
 
 263     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
 264     apiobj.add_osmline(place_id=4924, osm_id=9928,
 
 266                        startnumber=1, endnumber=4, step=1,
 
 267                        country_code='gb', postcode='34425',
 
 268                        address={'city': 'Big'},
 
 269                        indexed_date=import_date,
 
 270                        geometry='LINESTRING(23 34, 23 35)')
 
 272     api = frontend(apiobj, options={'details'})
 
 273     result = api.details(idobj)
 
 275     assert result is not None
 
 277     assert result.source_table.name == 'OSMLINE'
 
 278     assert result.category == ('place', 'houses')
 
 279     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.5))
 
 281     assert result.place_id == 4924
 
 282     assert result.parent_place_id == 12
 
 283     assert result.linked_place_id is None
 
 284     assert result.osm_object == ('W', 9928)
 
 285     assert result.admin_level == 15
 
 287     assert result.names is None
 
 288     assert result.address == {'city': 'Big'}
 
 289     assert result.extratags == {'startnumber': '1', 'endnumber': '4', 'step': '1'}
 
 291     assert result.housenumber is None
 
 292     assert result.postcode == '34425'
 
 293     assert result.wikipedia is None
 
 295     assert result.rank_search == 30
 
 296     assert result.rank_address == 30
 
 297     assert result.importance is None
 
 299     assert result.country_code == 'gb'
 
 300     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 302     assert result.address_rows is None
 
 303     assert result.linked_rows is None
 
 304     assert result.parented_rows is None
 
 305     assert result.name_keywords is None
 
 306     assert result.address_keywords is None
 
 308     assert result.geometry == {'type': 'ST_LineString'}
 
 311 def test_lookup_in_osmline_split_interpolation(apiobj, frontend):
 
 312     apiobj.add_osmline(place_id=1000, osm_id=9,
 
 313                        startnumber=2, endnumber=4, step=1)
 
 314     apiobj.add_osmline(place_id=1001, osm_id=9,
 
 315                        startnumber=6, endnumber=9, step=1)
 
 316     apiobj.add_osmline(place_id=1002, osm_id=9,
 
 317                        startnumber=11, endnumber=20, step=1)
 
 319     api = frontend(apiobj, options={'details'})
 
 320     for i in range(1, 6):
 
 321         result = api.details(napi.OsmID('W', 9, str(i)))
 
 322         assert result.place_id == 1000
 
 323     for i in range(7, 11):
 
 324         result = api.details(napi.OsmID('W', 9, str(i)))
 
 325         assert result.place_id == 1001
 
 326     for i in range(12, 22):
 
 327         result = api.details(napi.OsmID('W', 9, str(i)))
 
 328         assert result.place_id == 1002
 
 331 def test_lookup_osmline_with_address_details(apiobj, frontend):
 
 332     apiobj.add_osmline(place_id=9000, osm_id=9,
 
 333                        startnumber=2, endnumber=4, step=1,
 
 335     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 336                       class_='highway', type='residential',  name='Street',
 
 338                       rank_search=27, rank_address=26)
 
 339     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 341                               place_id=1000, osm_type='N', osm_id=3333,
 
 342                               class_='place', type='suburb', name='Smallplace',
 
 343                               country_code='pl', admin_level=13,
 
 344                               rank_search=24, rank_address=23)
 
 345     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 346                               place_id=1001, osm_type='N', osm_id=3334,
 
 347                               class_='place', type='city', name='Bigplace',
 
 349                               rank_search=17, rank_address=16)
 
 351     api = frontend(apiobj, options={'details'})
 
 352     result = api.details(napi.PlaceID(9000), address_details=True)
 
 354     assert result.address_rows == [
 
 355                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 356                                 category=('highway', 'residential'),
 
 357                                 names={'name': 'Street'}, extratags={},
 
 358                                 admin_level=15, fromarea=True, isaddress=True,
 
 359                                 rank_address=26, distance=0.0,
 
 360                                 local_name='Street'),
 
 361                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 362                                 category=('place', 'suburb'),
 
 363                                 names={'name': 'Smallplace'}, extratags={},
 
 364                                 admin_level=13, fromarea=False, isaddress=True,
 
 365                                 rank_address=23, distance=0.0034,
 
 366                                 local_name='Smallplace'),
 
 367                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 368                                 category=('place', 'city'),
 
 369                                 names={'name': 'Bigplace'}, extratags={},
 
 370                                 admin_level=15, fromarea=True, isaddress=True,
 
 371                                 rank_address=16, distance=0.0,
 
 372                                 local_name='Bigplace'),
 
 373                napi.AddressLine(place_id=None, osm_object=None,
 
 374                                 category=('place', 'country_code'),
 
 375                                 names={'ref': 'pl'}, extratags={},
 
 376                                 admin_level=None, fromarea=True, isaddress=False,
 
 377                                 rank_address=4, distance=0.0)
 
 381 def test_lookup_in_tiger(apiobj, frontend):
 
 382     apiobj.add_tiger(place_id=4924,
 
 384                      startnumber=1, endnumber=4, step=1,
 
 386                      geometry='LINESTRING(23 34, 23 35)')
 
 387     apiobj.add_placex(place_id=12,
 
 388                       category=('highway', 'residential'),
 
 389                       osm_type='W', osm_id=6601223,
 
 390                       geometry='LINESTRING(23 34, 23 35)')
 
 392     api = frontend(apiobj, options={'details'})
 
 393     result = api.details(napi.PlaceID(4924))
 
 395     assert result is not None
 
 397     assert result.source_table.name == 'TIGER'
 
 398     assert result.category == ('place', 'houses')
 
 399     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.5))
 
 401     assert result.place_id == 4924
 
 402     assert result.parent_place_id == 12
 
 403     assert result.linked_place_id is None
 
 404     assert result.osm_object == ('W', 6601223)
 
 405     assert result.admin_level == 15
 
 407     assert result.names is None
 
 408     assert result.address is None
 
 409     assert result.extratags == {'startnumber': '1', 'endnumber': '4', 'step': '1'}
 
 411     assert result.housenumber is None
 
 412     assert result.postcode == '34425'
 
 413     assert result.wikipedia is None
 
 415     assert result.rank_search == 30
 
 416     assert result.rank_address == 30
 
 417     assert result.importance is None
 
 419     assert result.country_code == 'us'
 
 420     assert result.indexed_date is None
 
 422     assert result.address_rows is None
 
 423     assert result.linked_rows is None
 
 424     assert result.parented_rows is None
 
 425     assert result.name_keywords is None
 
 426     assert result.address_keywords is None
 
 428     assert result.geometry == {'type': 'ST_LineString'}
 
 431 def test_lookup_tiger_with_address_details(apiobj, frontend):
 
 432     apiobj.add_tiger(place_id=9000,
 
 433                      startnumber=2, endnumber=4, step=1,
 
 435     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 436                       class_='highway', type='residential',  name='Street',
 
 438                       rank_search=27, rank_address=26)
 
 439     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 441                               place_id=1000, osm_type='N', osm_id=3333,
 
 442                               class_='place', type='suburb', name='Smallplace',
 
 443                               country_code='us', admin_level=13,
 
 444                               rank_search=24, rank_address=23)
 
 445     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 446                               place_id=1001, osm_type='N', osm_id=3334,
 
 447                               class_='place', type='city', name='Bigplace',
 
 449                               rank_search=17, rank_address=16)
 
 451     api = frontend(apiobj, options={'details'})
 
 452     result = api.details(napi.PlaceID(9000), address_details=True)
 
 454     assert result.address_rows == [
 
 455                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 456                                 category=('highway', 'residential'),
 
 457                                 names={'name': 'Street'}, extratags={},
 
 458                                 admin_level=15, fromarea=True, isaddress=True,
 
 459                                 rank_address=26, distance=0.0,
 
 460                                 local_name='Street'),
 
 461                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 462                                 category=('place', 'suburb'),
 
 463                                 names={'name': 'Smallplace'}, extratags={},
 
 464                                 admin_level=13, fromarea=False, isaddress=True,
 
 465                                 rank_address=23, distance=0.0034,
 
 466                                 local_name='Smallplace'),
 
 467                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 468                                 category=('place', 'city'),
 
 469                                 names={'name': 'Bigplace'}, extratags={},
 
 470                                 admin_level=15, fromarea=True, isaddress=True,
 
 471                                 rank_address=16, distance=0.0,
 
 472                                 local_name='Bigplace'),
 
 473                napi.AddressLine(place_id=None, osm_object=None,
 
 474                                 category=('place', 'country_code'),
 
 475                                 names={'ref': 'us'}, extratags={},
 
 476                                 admin_level=None, fromarea=True, isaddress=False,
 
 477                                 rank_address=4, distance=0.0)
 
 481 def test_lookup_in_postcode(apiobj, frontend):
 
 482     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
 483     apiobj.add_postcode(place_id=554,
 
 487                         rank_search=20, rank_address=22,
 
 488                         indexed_date=import_date,
 
 489                         geometry='POINT(-9.45 5.6)')
 
 491     api = frontend(apiobj, options={'details'})
 
 492     result = api.details(napi.PlaceID(554))
 
 494     assert result is not None
 
 496     assert result.source_table.name == 'POSTCODE'
 
 497     assert result.category == ('place', 'postcode')
 
 498     assert result.centroid == (pytest.approx(-9.45), pytest.approx(5.6))
 
 500     assert result.place_id == 554
 
 501     assert result.parent_place_id == 152
 
 502     assert result.linked_place_id is None
 
 503     assert result.osm_object is None
 
 504     assert result.admin_level == 15
 
 506     assert result.names == {'ref': '34 425'}
 
 507     assert result.address is None
 
 508     assert result.extratags is None
 
 510     assert result.housenumber is None
 
 511     assert result.postcode is None
 
 512     assert result.wikipedia is None
 
 514     assert result.rank_search == 20
 
 515     assert result.rank_address == 22
 
 516     assert result.importance is None
 
 518     assert result.country_code == 'gb'
 
 519     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 521     assert result.address_rows is None
 
 522     assert result.linked_rows is None
 
 523     assert result.parented_rows is None
 
 524     assert result.name_keywords is None
 
 525     assert result.address_keywords is None
 
 527     assert result.geometry == {'type': 'ST_Point'}
 
 530 def test_lookup_postcode_with_address_details(apiobj, frontend):
 
 531     apiobj.add_postcode(place_id=9000,
 
 535                         rank_search=25, rank_address=25)
 
 536     apiobj.add_placex(place_id=332, osm_type='N', osm_id=3333,
 
 537                       class_='place', type='suburb',  name='Smallplace',
 
 538                       country_code='gb', admin_level=13,
 
 539                       rank_search=24, rank_address=23)
 
 540     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 541                               place_id=1001, osm_type='N', osm_id=3334,
 
 542                               class_='place', type='city', name='Bigplace',
 
 544                               rank_search=17, rank_address=16)
 
 546     api = frontend(apiobj, options={'details'})
 
 547     result = api.details(napi.PlaceID(9000), address_details=True)
 
 549     assert result.address_rows == [
 
 550                napi.AddressLine(place_id=9000, osm_object=None,
 
 551                                 category=('place', 'postcode'),
 
 552                                 names={'ref': '34 425'}, extratags={},
 
 553                                 admin_level=15, fromarea=True, isaddress=True,
 
 554                                 rank_address=25, distance=0.0,
 
 555                                 local_name='34 425'),
 
 556                napi.AddressLine(place_id=332, osm_object=('N', 3333),
 
 557                                 category=('place', 'suburb'),
 
 558                                 names={'name': 'Smallplace'}, extratags={},
 
 559                                 admin_level=13, fromarea=True, isaddress=True,
 
 560                                 rank_address=23, distance=0.0,
 
 561                                 local_name='Smallplace'),
 
 562                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 563                                 category=('place', 'city'),
 
 564                                 names={'name': 'Bigplace'}, extratags={},
 
 565                                 admin_level=15, fromarea=True, isaddress=True,
 
 566                                 rank_address=16, distance=0.0,
 
 567                                 local_name='Bigplace'),
 
 568                napi.AddressLine(place_id=None, osm_object=None,
 
 569                                 category=('place', 'country_code'),
 
 570                                 names={'ref': 'gb'}, extratags={},
 
 571                                 admin_level=None, fromarea=True, isaddress=False,
 
 572                                 rank_address=4, distance=0.0)
 
 576 @pytest.mark.parametrize('objid', [napi.PlaceID(1736),
 
 578                                    napi.OsmID('N', 55, 'amenity')])
 
 579 def test_lookup_missing_object(apiobj, frontend, objid):
 
 580     apiobj.add_placex(place_id=1, osm_type='N', osm_id=55,
 
 581                       class_='place', type='suburb')
 
 583     api = frontend(apiobj, options={'details'})
 
 584     assert api.details(objid) is None
 
 587 @pytest.mark.parametrize('gtype', (napi.GeometryFormat.KML,
 
 588                                    napi.GeometryFormat.SVG,
 
 589                                    napi.GeometryFormat.TEXT))
 
 590 def test_lookup_unsupported_geometry(apiobj, frontend, gtype):
 
 591     apiobj.add_placex(place_id=332)
 
 593     api = frontend(apiobj, options={'details'})
 
 594     with pytest.raises(ValueError):
 
 595         api.details(napi.PlaceID(332), geometry_output=gtype)