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)
 
  37     napi.Locales().localize_results([result])
 
  39     assert result is not None
 
  41     assert result.source_table.name == 'PLACEX'
 
  42     assert result.category == ('highway', 'residential')
 
  43     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.0))
 
  45     assert result.place_id == 332
 
  46     assert result.parent_place_id == 34
 
  47     assert result.linked_place_id == 55
 
  48     assert result.osm_object == ('W', 4)
 
  49     assert result.admin_level == 15
 
  51     assert result.names == {'name': 'Road'}
 
  52     assert result.address == {'city': 'Barrow'}
 
  53     assert result.extratags == {'surface': 'paved'}
 
  55     assert result.housenumber == '4'
 
  56     assert result.postcode == '34425'
 
  57     assert result.wikipedia == 'en:Faa'
 
  59     assert result.rank_search == 27
 
  60     assert result.rank_address == 26
 
  61     assert result.importance == pytest.approx(0.01)
 
  63     assert result.country_code == 'gb'
 
  64     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
  66     assert result.address_rows is None
 
  67     assert result.linked_rows is None
 
  68     assert result.parented_rows is None
 
  69     assert result.name_keywords is None
 
  70     assert result.address_keywords is None
 
  72     assert result.geometry == {'type': 'ST_LineString'}
 
  75 def test_lookup_in_placex_minimal_info(apiobj, frontend):
 
  76     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
  77     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
  78                       class_='highway', type='residential',
 
  80                       rank_search=27, rank_address=26,
 
  82                       indexed_date=import_date,
 
  83                       geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
  85     api = frontend(apiobj, options={'details'})
 
  86     result = api.details(napi.PlaceID(332))
 
  87     napi.Locales().localize_results([result])
 
  89     assert result is not None
 
  91     assert result.source_table.name == 'PLACEX'
 
  92     assert result.category == ('highway', 'residential')
 
  93     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.0))
 
  95     assert result.place_id == 332
 
  96     assert result.parent_place_id is None
 
  97     assert result.linked_place_id is None
 
  98     assert result.osm_object == ('W', 4)
 
  99     assert result.admin_level == 15
 
 101     assert result.names is None
 
 102     assert result.address is None
 
 103     assert result.extratags is None
 
 105     assert result.housenumber is None
 
 106     assert result.postcode is None
 
 107     assert result.wikipedia is None
 
 109     assert result.rank_search == 27
 
 110     assert result.rank_address == 26
 
 111     assert result.importance is None
 
 113     assert result.country_code is None
 
 114     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 116     assert result.address_rows is None
 
 117     assert result.linked_rows is None
 
 118     assert result.parented_rows is None
 
 119     assert result.name_keywords is None
 
 120     assert result.address_keywords is None
 
 122     assert result.geometry == {'type': 'ST_LineString'}
 
 125 def test_lookup_in_placex_with_geometry(apiobj, frontend):
 
 126     apiobj.add_placex(place_id=332,
 
 127                       geometry='LINESTRING(23 34, 23.1 34)')
 
 129     api = frontend(apiobj, options={'details'})
 
 130     result = api.details(napi.PlaceID(332), geometry_output=napi.GeometryFormat.GEOJSON)
 
 132     assert result.geometry == {'geojson': '{"type":"LineString","coordinates":[[23,34],[23.1,34]]}'}
 
 135 def test_lookup_placex_with_address_details(apiobj, frontend):
 
 136     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 137                       class_='highway', type='residential',  name='Street',
 
 139                       rank_search=27, rank_address=26)
 
 140     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 142                               place_id=1000, osm_type='N', osm_id=3333,
 
 143                               class_='place', type='suburb', name='Smallplace',
 
 144                               country_code='pl', admin_level=13,
 
 145                               rank_search=24, rank_address=23)
 
 146     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 147                               place_id=1001, osm_type='N', osm_id=3334,
 
 148                               class_='place', type='city', name='Bigplace',
 
 150                               rank_search=17, rank_address=16)
 
 152     api = frontend(apiobj, options={'details'})
 
 153     result = api.details(napi.PlaceID(332), address_details=True)
 
 154     napi.Locales().localize_results([result])
 
 156     assert result.address_rows == [
 
 157                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 158                                 category=('highway', 'residential'),
 
 159                                 names={'name': 'Street'}, extratags={},
 
 160                                 admin_level=15, fromarea=True, isaddress=True,
 
 161                                 rank_address=26, distance=0.0,
 
 162                                 local_name='Street'),
 
 163                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 164                                 category=('place', 'suburb'),
 
 165                                 names={'name': 'Smallplace'}, extratags={},
 
 166                                 admin_level=13, fromarea=False, isaddress=True,
 
 167                                 rank_address=23, distance=0.0034,
 
 168                                 local_name='Smallplace'),
 
 169                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 170                                 category=('place', 'city'),
 
 171                                 names={'name': 'Bigplace'}, extratags={},
 
 172                                 admin_level=15, fromarea=True, isaddress=True,
 
 173                                 rank_address=16, distance=0.0,
 
 174                                 local_name='Bigplace'),
 
 175                napi.AddressLine(place_id=None, osm_object=None,
 
 176                                 category=('place', 'country_code'),
 
 177                                 names={'ref': 'pl'}, extratags={},
 
 178                                 admin_level=None, fromarea=True, isaddress=False,
 
 179                                 rank_address=4, distance=0.0)
 
 183 def test_lookup_place_with_linked_places_none_existing(apiobj, frontend):
 
 184     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 185                       class_='highway', type='residential',  name='Street',
 
 186                       country_code='pl', linked_place_id=45,
 
 187                       rank_search=27, rank_address=26)
 
 189     api = frontend(apiobj, options={'details'})
 
 190     result = api.details(napi.PlaceID(332), linked_places=True)
 
 192     assert result.linked_rows == []
 
 195 def test_lookup_place_with_linked_places_existing(apiobj, frontend):
 
 196     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 197                       class_='highway', type='residential',  name='Street',
 
 198                       country_code='pl', linked_place_id=45,
 
 199                       rank_search=27, rank_address=26)
 
 200     apiobj.add_placex(place_id=1001, osm_type='W', osm_id=5,
 
 201                       class_='highway', type='residential',  name='Street',
 
 202                       country_code='pl', linked_place_id=332,
 
 203                       rank_search=27, rank_address=26)
 
 204     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
 
 205                       class_='highway', type='residential',  name='Street',
 
 206                       country_code='pl', linked_place_id=332,
 
 207                       rank_search=27, rank_address=26)
 
 209     api = frontend(apiobj, options={'details'})
 
 210     result = api.details(napi.PlaceID(332), linked_places=True)
 
 212     assert result.linked_rows == [
 
 213                napi.AddressLine(place_id=1001, osm_object=('W', 5),
 
 214                                 category=('highway', 'residential'),
 
 215                                 names={'name': 'Street'}, extratags={},
 
 216                                 admin_level=15, fromarea=False, isaddress=True,
 
 217                                 rank_address=26, distance=0.0),
 
 218                napi.AddressLine(place_id=1002, osm_object=('W', 6),
 
 219                                 category=('highway', 'residential'),
 
 220                                 names={'name': 'Street'}, extratags={},
 
 221                                 admin_level=15, fromarea=False, isaddress=True,
 
 222                                 rank_address=26, distance=0.0),
 
 226 def test_lookup_place_with_parented_places_not_existing(apiobj, frontend):
 
 227     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 228                       class_='highway', type='residential',  name='Street',
 
 229                       country_code='pl', parent_place_id=45,
 
 230                       rank_search=27, rank_address=26)
 
 232     api = frontend(apiobj, options={'details'})
 
 233     result = api.details(napi.PlaceID(332), parented_places=True)
 
 235     assert result.parented_rows == []
 
 238 def test_lookup_place_with_parented_places_existing(apiobj, frontend):
 
 239     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 240                       class_='highway', type='residential',  name='Street',
 
 241                       country_code='pl', parent_place_id=45,
 
 242                       rank_search=27, rank_address=26)
 
 243     apiobj.add_placex(place_id=1001, osm_type='N', osm_id=5,
 
 244                       class_='place', type='house', housenumber='23',
 
 245                       country_code='pl', parent_place_id=332,
 
 246                       rank_search=30, rank_address=30)
 
 247     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
 
 248                       class_='highway', type='residential',  name='Street',
 
 249                       country_code='pl', parent_place_id=332,
 
 250                       rank_search=27, rank_address=26)
 
 252     api = frontend(apiobj, options={'details'})
 
 253     result = api.details(napi.PlaceID(332), parented_places=True)
 
 255     assert result.parented_rows == [
 
 256                napi.AddressLine(place_id=1001, osm_object=('N', 5),
 
 257                                 category=('place', 'house'),
 
 258                                 names={'housenumber': '23'}, extratags={},
 
 259                                 admin_level=15, fromarea=False, isaddress=True,
 
 260                                 rank_address=30, distance=0.0),
 
 264 @pytest.mark.parametrize('idobj', (napi.PlaceID(4924), napi.OsmID('W', 9928)))
 
 265 def test_lookup_in_osmline(apiobj, frontend, idobj):
 
 266     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
 267     apiobj.add_osmline(place_id=4924, osm_id=9928,
 
 269                        startnumber=1, endnumber=4, step=1,
 
 270                        country_code='gb', postcode='34425',
 
 271                        address={'city': 'Big'},
 
 272                        indexed_date=import_date,
 
 273                        geometry='LINESTRING(23 34, 23 35)')
 
 275     api = frontend(apiobj, options={'details'})
 
 276     result = api.details(idobj)
 
 278     assert result is not None
 
 280     assert result.source_table.name == 'OSMLINE'
 
 281     assert result.category == ('place', 'houses')
 
 282     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.5))
 
 284     assert result.place_id == 4924
 
 285     assert result.parent_place_id == 12
 
 286     assert result.linked_place_id is None
 
 287     assert result.osm_object == ('W', 9928)
 
 288     assert result.admin_level == 15
 
 290     assert result.names is None
 
 291     assert result.address == {'city': 'Big'}
 
 292     assert result.extratags == {'startnumber': '1', 'endnumber': '4', 'step': '1'}
 
 294     assert result.housenumber is None
 
 295     assert result.postcode == '34425'
 
 296     assert result.wikipedia is None
 
 298     assert result.rank_search == 30
 
 299     assert result.rank_address == 30
 
 300     assert result.importance is None
 
 302     assert result.country_code == 'gb'
 
 303     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 305     assert result.address_rows is None
 
 306     assert result.linked_rows is None
 
 307     assert result.parented_rows is None
 
 308     assert result.name_keywords is None
 
 309     assert result.address_keywords is None
 
 311     assert result.geometry == {'type': 'ST_LineString'}
 
 314 def test_lookup_in_osmline_split_interpolation(apiobj, frontend):
 
 315     apiobj.add_osmline(place_id=1000, osm_id=9,
 
 316                        startnumber=2, endnumber=4, step=1)
 
 317     apiobj.add_osmline(place_id=1001, osm_id=9,
 
 318                        startnumber=6, endnumber=9, step=1)
 
 319     apiobj.add_osmline(place_id=1002, osm_id=9,
 
 320                        startnumber=11, endnumber=20, step=1)
 
 322     api = frontend(apiobj, options={'details'})
 
 323     for i in range(1, 6):
 
 324         result = api.details(napi.OsmID('W', 9, str(i)))
 
 325         assert result.place_id == 1000
 
 326     for i in range(7, 11):
 
 327         result = api.details(napi.OsmID('W', 9, str(i)))
 
 328         assert result.place_id == 1001
 
 329     for i in range(12, 22):
 
 330         result = api.details(napi.OsmID('W', 9, str(i)))
 
 331         assert result.place_id == 1002
 
 334 def test_lookup_osmline_with_address_details(apiobj, frontend):
 
 335     apiobj.add_osmline(place_id=9000, osm_id=9,
 
 336                        startnumber=2, endnumber=4, step=1,
 
 338     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 339                       class_='highway', type='residential',  name='Street',
 
 341                       rank_search=27, rank_address=26)
 
 342     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 344                               place_id=1000, osm_type='N', osm_id=3333,
 
 345                               class_='place', type='suburb', name='Smallplace',
 
 346                               country_code='pl', admin_level=13,
 
 347                               rank_search=24, rank_address=23)
 
 348     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 349                               place_id=1001, osm_type='N', osm_id=3334,
 
 350                               class_='place', type='city', name='Bigplace',
 
 352                               rank_search=17, rank_address=16)
 
 354     api = frontend(apiobj, options={'details'})
 
 355     result = api.details(napi.PlaceID(9000), address_details=True)
 
 356     napi.Locales().localize_results([result])
 
 358     assert result.address_rows == [
 
 359                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 360                                 category=('highway', 'residential'),
 
 361                                 names={'name': 'Street'}, extratags={},
 
 362                                 admin_level=15, fromarea=True, isaddress=True,
 
 363                                 rank_address=26, distance=0.0,
 
 364                                 local_name='Street'),
 
 365                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 366                                 category=('place', 'suburb'),
 
 367                                 names={'name': 'Smallplace'}, extratags={},
 
 368                                 admin_level=13, fromarea=False, isaddress=True,
 
 369                                 rank_address=23, distance=0.0034,
 
 370                                 local_name='Smallplace'),
 
 371                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 372                                 category=('place', 'city'),
 
 373                                 names={'name': 'Bigplace'}, extratags={},
 
 374                                 admin_level=15, fromarea=True, isaddress=True,
 
 375                                 rank_address=16, distance=0.0,
 
 376                                 local_name='Bigplace'),
 
 377                napi.AddressLine(place_id=None, osm_object=None,
 
 378                                 category=('place', 'country_code'),
 
 379                                 names={'ref': 'pl'}, extratags={},
 
 380                                 admin_level=None, fromarea=True, isaddress=False,
 
 381                                 rank_address=4, distance=0.0)
 
 385 def test_lookup_in_tiger(apiobj, frontend):
 
 386     apiobj.add_tiger(place_id=4924,
 
 388                      startnumber=1, endnumber=4, step=1,
 
 390                      geometry='LINESTRING(23 34, 23 35)')
 
 391     apiobj.add_placex(place_id=12,
 
 392                       category=('highway', 'residential'),
 
 393                       osm_type='W', osm_id=6601223,
 
 394                       geometry='LINESTRING(23 34, 23 35)')
 
 396     api = frontend(apiobj, options={'details'})
 
 397     result = api.details(napi.PlaceID(4924))
 
 399     assert result is not None
 
 401     assert result.source_table.name == 'TIGER'
 
 402     assert result.category == ('place', 'houses')
 
 403     assert result.centroid == (pytest.approx(23.0), pytest.approx(34.5))
 
 405     assert result.place_id == 4924
 
 406     assert result.parent_place_id == 12
 
 407     assert result.linked_place_id is None
 
 408     assert result.osm_object == ('W', 6601223)
 
 409     assert result.admin_level == 15
 
 411     assert result.names is None
 
 412     assert result.address is None
 
 413     assert result.extratags == {'startnumber': '1', 'endnumber': '4', 'step': '1'}
 
 415     assert result.housenumber is None
 
 416     assert result.postcode == '34425'
 
 417     assert result.wikipedia is None
 
 419     assert result.rank_search == 30
 
 420     assert result.rank_address == 30
 
 421     assert result.importance is None
 
 423     assert result.country_code == 'us'
 
 424     assert result.indexed_date is None
 
 426     assert result.address_rows is None
 
 427     assert result.linked_rows is None
 
 428     assert result.parented_rows is None
 
 429     assert result.name_keywords is None
 
 430     assert result.address_keywords is None
 
 432     assert result.geometry == {'type': 'ST_LineString'}
 
 435 def test_lookup_tiger_with_address_details(apiobj, frontend):
 
 436     apiobj.add_tiger(place_id=9000,
 
 437                      startnumber=2, endnumber=4, step=1,
 
 439     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 440                       class_='highway', type='residential',  name='Street',
 
 442                       rank_search=27, rank_address=26)
 
 443     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
 
 445                               place_id=1000, osm_type='N', osm_id=3333,
 
 446                               class_='place', type='suburb', name='Smallplace',
 
 447                               country_code='us', admin_level=13,
 
 448                               rank_search=24, rank_address=23)
 
 449     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 450                               place_id=1001, osm_type='N', osm_id=3334,
 
 451                               class_='place', type='city', name='Bigplace',
 
 453                               rank_search=17, rank_address=16)
 
 455     api = frontend(apiobj, options={'details'})
 
 456     result = api.details(napi.PlaceID(9000), address_details=True)
 
 457     napi.Locales().localize_results([result])
 
 459     assert result.address_rows == [
 
 460                napi.AddressLine(place_id=332, osm_object=('W', 4),
 
 461                                 category=('highway', 'residential'),
 
 462                                 names={'name': 'Street'}, extratags={},
 
 463                                 admin_level=15, fromarea=True, isaddress=True,
 
 464                                 rank_address=26, distance=0.0,
 
 465                                 local_name='Street'),
 
 466                napi.AddressLine(place_id=1000, osm_object=('N', 3333),
 
 467                                 category=('place', 'suburb'),
 
 468                                 names={'name': 'Smallplace'}, extratags={},
 
 469                                 admin_level=13, fromarea=False, isaddress=True,
 
 470                                 rank_address=23, distance=0.0034,
 
 471                                 local_name='Smallplace'),
 
 472                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 473                                 category=('place', 'city'),
 
 474                                 names={'name': 'Bigplace'}, extratags={},
 
 475                                 admin_level=15, fromarea=True, isaddress=True,
 
 476                                 rank_address=16, distance=0.0,
 
 477                                 local_name='Bigplace'),
 
 478                napi.AddressLine(place_id=None, osm_object=None,
 
 479                                 category=('place', 'country_code'),
 
 480                                 names={'ref': 'us'}, extratags={},
 
 481                                 admin_level=None, fromarea=True, isaddress=False,
 
 482                                 rank_address=4, distance=0.0)
 
 486 def test_lookup_in_postcode(apiobj, frontend):
 
 487     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
 
 488     apiobj.add_postcode(place_id=554,
 
 492                         rank_search=20, rank_address=22,
 
 493                         indexed_date=import_date,
 
 494                         geometry='POINT(-9.45 5.6)')
 
 496     api = frontend(apiobj, options={'details'})
 
 497     result = api.details(napi.PlaceID(554))
 
 499     assert result is not None
 
 501     assert result.source_table.name == 'POSTCODE'
 
 502     assert result.category == ('place', 'postcode')
 
 503     assert result.centroid == (pytest.approx(-9.45), pytest.approx(5.6))
 
 505     assert result.place_id == 554
 
 506     assert result.parent_place_id == 152
 
 507     assert result.linked_place_id is None
 
 508     assert result.osm_object is None
 
 509     assert result.admin_level == 15
 
 511     assert result.names == {'ref': '34 425'}
 
 512     assert result.address is None
 
 513     assert result.extratags is None
 
 515     assert result.housenumber is None
 
 516     assert result.postcode is None
 
 517     assert result.wikipedia is None
 
 519     assert result.rank_search == 20
 
 520     assert result.rank_address == 22
 
 521     assert result.importance is None
 
 523     assert result.country_code == 'gb'
 
 524     assert result.indexed_date == import_date.replace(tzinfo=dt.timezone.utc)
 
 526     assert result.address_rows is None
 
 527     assert result.linked_rows is None
 
 528     assert result.parented_rows is None
 
 529     assert result.name_keywords is None
 
 530     assert result.address_keywords is None
 
 532     assert result.geometry == {'type': 'ST_Point'}
 
 535 def test_lookup_postcode_with_address_details(apiobj, frontend):
 
 536     apiobj.add_postcode(place_id=9000,
 
 540                         rank_search=25, rank_address=25)
 
 541     apiobj.add_placex(place_id=332, osm_type='N', osm_id=3333,
 
 542                       class_='place', type='suburb',  name='Smallplace',
 
 543                       country_code='gb', admin_level=13,
 
 544                       rank_search=24, rank_address=23)
 
 545     apiobj.add_address_placex(332, fromarea=True, isaddress=True,
 
 546                               place_id=1001, osm_type='N', osm_id=3334,
 
 547                               class_='place', type='city', name='Bigplace',
 
 549                               rank_search=17, rank_address=16)
 
 551     api = frontend(apiobj, options={'details'})
 
 552     result = api.details(napi.PlaceID(9000), address_details=True)
 
 553     napi.Locales().localize_results([result])
 
 555     assert result.address_rows == [
 
 556                napi.AddressLine(place_id=9000, osm_object=None,
 
 557                                 category=('place', 'postcode'),
 
 558                                 names={'ref': '34 425'}, extratags={},
 
 559                                 admin_level=15, fromarea=True, isaddress=True,
 
 560                                 rank_address=25, distance=0.0,
 
 561                                 local_name='34 425'),
 
 562                napi.AddressLine(place_id=332, osm_object=('N', 3333),
 
 563                                 category=('place', 'suburb'),
 
 564                                 names={'name': 'Smallplace'}, extratags={},
 
 565                                 admin_level=13, fromarea=True, isaddress=True,
 
 566                                 rank_address=23, distance=0.0,
 
 567                                 local_name='Smallplace'),
 
 568                napi.AddressLine(place_id=1001, osm_object=('N', 3334),
 
 569                                 category=('place', 'city'),
 
 570                                 names={'name': 'Bigplace'}, extratags={},
 
 571                                 admin_level=15, fromarea=True, isaddress=True,
 
 572                                 rank_address=16, distance=0.0,
 
 573                                 local_name='Bigplace'),
 
 574                napi.AddressLine(place_id=None, osm_object=None,
 
 575                                 category=('place', 'country_code'),
 
 576                                 names={'ref': 'gb'}, extratags={},
 
 577                                 admin_level=None, fromarea=True, isaddress=False,
 
 578                                 rank_address=4, distance=0.0)
 
 582 @pytest.mark.parametrize('objid', [napi.PlaceID(1736),
 
 584                                    napi.OsmID('N', 55, 'amenity')])
 
 585 def test_lookup_missing_object(apiobj, frontend, objid):
 
 586     apiobj.add_placex(place_id=1, osm_type='N', osm_id=55,
 
 587                       class_='place', type='suburb')
 
 589     api = frontend(apiobj, options={'details'})
 
 590     assert api.details(objid) is None
 
 593 @pytest.mark.parametrize('gtype', (napi.GeometryFormat.KML,
 
 594                                    napi.GeometryFormat.SVG,
 
 595                                    napi.GeometryFormat.TEXT))
 
 596 def test_lookup_unsupported_geometry(apiobj, frontend, gtype):
 
 597     apiobj.add_placex(place_id=332)
 
 599     api = frontend(apiobj, options={'details'})
 
 600     with pytest.raises(ValueError):
 
 601         api.details(napi.PlaceID(332), geometry_output=gtype)