In [1]:
# Allow to import without installing
import sys
sys.path.insert(0, "..")

Buildings / Addresses

I want to understand how buildings and addresses are represented in OSM data.

Required reading: http://wiki.openstreetmap.org/wiki/Addresses


In [2]:
import osmdigest.digest as digest

Nodes tagged as buildings / with addresses

For the Isle of Wight dataset, there are rather few nodes tagged as buildings. There are quite a few more nodes which have address information, however.


In [3]:
import os
#filename = os.path.join("//media", "disk", "OSM_Data", "isle-of-wight-latest.osm.xz")
filename = os.path.join("..", "..", "..", "Data", "isle-of-wight-latest.osm.xz")

In [4]:
building_node_ids = []
addr_node_ids = []

for x in digest.parse(filename):
    if isinstance(x, digest.Node):
        if "building" in x.tags:
            building_node_ids.append(x)
        if any(key.startswith("addr:") for key in x.tags):
            addr_node_ids.append(x)

In [5]:
len(building_node_ids), building_node_ids[:5]


Out[5]:
(39,
 [Node(38921672 @ [50.6405824,-1.360434] {'name': 'Wolverton Manor', 'building': 'manor_house', 'historic': 'manor'}),
  Node(691207722 @ [50.6773251,-1.495855] {'name': 'Tollgate House', 'building': 'house', 'addr:city': 'Afton', 'addr:street': 'Wilmington Lane', 'addr:country': 'GB', 'addr:housename': 'Tollgate House'}),
  Node(718782298 @ [50.6829817,-1.418304] {'name': 'Freedom Farm', 'building': 'yes'}),
  Node(765755120 @ [50.6921583,-1.5315236] {'building': 'farmhouse', 'addr:housename': 'Bramble Farm'}),
  Node(829972519 @ [50.5856384,-1.2469082] {'name': 'St. Rhadagunds', 'email': 'info@strhads.co.uk', 'phone': '01983852160', 'tourism': 'hotel', 'website': 'strhads.co.uk', 'building': 'yes', 'internet_access': 'wlan'})])

In [6]:
len(addr_node_ids), addr_node_ids[:5]


Out[6]:
(1822,
 [Node(2383584 @ [50.7065062,-1.5006427] {'name': 'Yarmouth Quay', 'amenity': 'ferry_terminal', 'network': 'Car Ferry', 'operator': 'Wightlink', 'addr:city': 'Yarmouth', 'addr:street': 'Quay Street', 'addr:postcode': 'PO41 0PB'}),
  Node(2387351 @ [50.6833789,-1.0956959] {'name': 'Bembridge Windmill', 'tourism': 'attraction', 'website': 'https://www.nationaltrust.org.uk/bembridge-windmill', 'man_made': 'windmill', 'operator': 'National Trust', 'addr:city': 'Bembridge', 'addr:street': 'Mill Road', 'addr:postcode': 'PO35 5SQ', 'addr:housename': 'Bembridge Windmill'}),
  Node(2433320 @ [50.6717547,-1.5427212] {'name': 'High Down Inn', 'amenity': 'pub', 'tourism': 'bed_and_breakfast', 'website': 'http://www.highdowninn.com/', 'alt_name': 'Highdown Inn', 'addr:city': 'Totland', 'addr:street': 'Highdown Lane', 'addr:country': 'GB', 'addr:postcode': 'PO39 0HY'}),
  Node(7227760 @ [50.7054346,-1.2146592] {'name': 'Havenstreet', 'usage': 'tourism', 'railway': 'station', 'addr:city': 'Havenstreet, near Ryde', 'addr:street': 'Main Road'}),
  Node(8093989 @ [50.7302604,-1.1628019] {'addr:city': 'Ryde', 'addr:housenumber': '41', 'addr:postcode': 'PO33 2LF', 'addr:street': 'Union Street', 'amenity': 'pub', 'name': 'S. Fowler & Co.', 'owner': 'Wetherspoons', 'phone': '+44 1983 812112', 'source': 'survey', 'wifi': 'free'})])

Same for ways

We expected buildings to mostly have a polygonal outline, and so be "ways".

The situation here is reversed: lots of buildings, and fewer addresses. From eyeballing a few ways which have address information, but which are not buildings, we find that the "way" gives the total outline of, say, a school, which may contain a number of buildings, playing fields etc.


In [7]:
building_way_ids = []
addr_way_ids = []

for x in digest.parse(filename):
    if isinstance(x, digest.Way):
        if "building" in x.tags:
            building_way_ids.append(x)
        if any(key.startswith("addr:") for key in x.tags):
            addr_way_ids.append(x)

In [8]:
len(building_way_ids), building_way_ids[:5]


Out[8]:
(43644,
 [Way(3580387 ->  [17731291, 1812813868, 826100758, 17731290, 1812813848, 17731289, 826100762, 17731295, 1812813842, 17731294, 826100769, 17731293, 1812813861, 197678030, 826100761, 17731292, 1812813845, 17731291] {'alt_name': 'Spitsand Fort', 'alt_name:1': 'Spit Sand Fort', 'alt_name:2': 'Spit Fort', 'building': 'yes', 'castle_type': 'fortress', 'historic': 'castle', 'name': 'Spitbank Fort', 'natural': 'coastline', 'source': 'OS OpenData StreetView', 'start_date': '1867', 'tourism': 'hotel', 'wikidata': 'Q2311360', 'wikipedia': 'en:Spitbank Fort'}),
  Way(3580388 ->  [17731299, 17731297, 1812813839, 825993194, 1812813856, 17731305, 17731304, 825993180, 1812813854, 17731303, 17731302, 1812813864, 825993155, 17731301, 17731300, 1812813852, 825993118, 1812813850, 17731299] {'building': 'yes', 'historic': 'fort', 'man_made': 'pier', 'name': 'Horse Sand Fort', 'natural': 'coastline', 'source': 'OS OpenData StreetView', 'start_date': '1865', 'wikidata': 'Q1485267', 'wikipedia': 'en:Horse Sand Fort'}),
  Way(3580389 ->  [17731316, 3012280384, 825993175, 1812813838, 17731315, 1812813882, 17731314, 3012280382, 825993198, 3012280383, 17731312, 3012280385, 17731311, 3012280386, 825993127, 1812813833, 17731310, 1812813879, 17731308, 1812813835, 825993148, 3012280387, 17731306, 1812813840, 17731316] {'building': 'yes', 'historic': 'fort', 'name': "No Man's Land Fort", 'natural': 'coastline', 'source': 'OS OpenData StreetView', 'start_date': '1867', 'wikidata': 'Q7044423', 'wikipedia': "en:No Man's Land Fort"}),
  Way(5032385 ->  [33695388, 33625082, 33692427, 33695389, 33695388] {'name': 'Britten Norman Aircraft Factory', 'building': 'yes'}),
  Way(5241146 ->  [1086935675, 36882230, 36882227, 1086935597, 1086935675] {'building': 'glasshouse'})])

In [9]:
len(addr_way_ids), addr_way_ids[:5]


Out[9]:
(6963,
 [Way(5026852 ->  [1636613142, 1756154625, 2852765828, 1756154623, 4594616645, 4594616647, 1756154590, 1756154593, 1756154627, 2852765827, 1756154630, 1756154631, 33556615, 28837469, 2852765838, 28837470, 33556618, 33556619, 33556620, 1636613166, 2852765836, 2852774936, 1636613142] {'name': 'Christ The King College - Upper College', 'amenity': 'school', 'addr:city': 'Newport', 'addr:street': 'Wellington Road', 'addr:postcode': 'PO30 5QT'}),
  Way(5026862 ->  [4684759642, 4684759641, 4684827409, 4684827406, 4684827399, 4684827389, 4684759640, 4684759639, 4684824588, 4684759635, 33556692, 4684759633, 4684759634, 4684824584, 4684759636, 4684824587, 1382864717, 33556694, 33556695, 2852776705, 33556696, 33556697, 33556698, 33556699, 33556700, 33556701, 33556702, 33556703, 1662247222, 2852776708, 2852776721, 1662247194, 1662247197, 1662247191, 1662247189, 1662247187, 1662247185, 4684759642] {'addr:city': 'Newport', 'addr:postcode': 'PO30 5QU', 'addr:street': 'Mountbatten Drive', 'amenity': 'school', 'name': 'Carisbrooke College', 'old_name': 'Carisbrooke High School and Sports College', 'source:name': 'OS_OpenData_Streetview'}),
  Way(5028610 ->  [3849206039, 3849206040, 3849206041, 3234772928, 29185170, 3234772925, 33574498, 33574499, 33574500, 33574501, 33574502, 3234772953, 33574503, 33574504, 732375016, 732375014, 732375012, 3990224834, 33574532, 33574506, 3234772926, 3234772938, 3234772930, 3234772942, 3990224824, 33574507, 3990224825, 3990224822, 33574508, 33574510, 3990224813, 33574512, 1289004196, 3990228860, 3990224814, 1289004173, 3849206039] {'url': 'http://www.sandownbayacademy.org/', 'name': 'Sandown Bay Academy', 'amenity': 'school', 'addr:street': 'The Fairway', 'ref:edubase': '136751', 'addr:postcode': 'PO36 9JH'}),
  Way(5667125 ->  [42399086, 4130695753, 4130695755, 42399060, 4130695751, 4130695749, 42399063, 42399065, 42399066, 42399068, 3206216757, 4130730324, 4130730322, 3206216756, 42399071, 4793149153, 42399072, 42399073, 42399075, 42399076, 42399077, 42399079, 42399080, 4793149154, 42399081, 42399082, 42399083, 42399084, 42399085, 42399086] {'addr:city': 'Newport', 'addr:housename': 'Robin Hill Country Park', 'addr:postcode': 'PO30 2NU', 'alt_name:en': 'Robin Hill', 'contact:phone': '+44(0)1983 527352', 'name': 'Robin Hill Country Park', 'name:en': 'Robin Hill Country Park', 'tourism': 'theme_park', 'website': 'http://www.robin-hill.com/'}),
  Way(5721497 ->  [43145633, 1980928994, 1980928999, 1980929000, 3641440792, 1980934807, 1980934809, 43145626, 43145629, 43145631, 3641441694, 3641441700, 3641441693, 43145633] {'name': 'Bembridge CofE Primary School', 'amenity': 'school', 'addr:city': 'Bembridge', 'addr:street': 'Walls Road', 'addr:postcode': 'PO35 5RH'})])

Finally for relations

Rather few. These tend to be special cases: usually when the building is non-convex (say a stately home, with an inner courtyard) so a relation is required to specify the "inner" and "outer" ways.


In [10]:
building_rel_ids = []
addr_rel_ids = []

for x in digest.parse(filename):
    if isinstance(x, digest.Relation):
        if "building" in x.tags:
            building_rel_ids.append(x)
        if any(key.startswith("addr:") for key in x.tags):
            addr_rel_ids.append(x)

In [11]:
len(building_rel_ids), building_rel_ids[:5]


Out[11]:
(33,
 [Relation(70978 ->  [Member(type='way', ref=30533570, role='outer'), Member(type='way', ref=30533571, role='inner')] {'building': 'monastery', 'community': 'OSB', 'community:en': 'benedictine', 'denomination': 'catholic', 'name': 'Quarr Abbey', 'religion': 'christian', 'type': 'multipolygon', 'website': 'http://www.quarrabbey.co.uk/'}),
  Relation(1369783 ->  [Member(type='way', ref=94481636, role='inner'), Member(type='way', ref=35821252, role='outer'), Member(type='way', ref=94481643, role='inner'), Member(type='way', ref=94481639, role='inner'), Member(type='way', ref=94481641, role='inner'), Member(type='way', ref=94481638, role='inner')] {'type': 'multipolygon', 'building': 'yes'}),
  Relation(1578648 ->  [Member(type='way', ref=112449476, role='inner'), Member(type='way', ref=30665632, role='outer')] {'type': 'multipolygon', 'building': 'yes'}),
  Relation(1584149 ->  [Member(type='way', ref=19215850, role='outer'), Member(type='way', ref=113058329, role='inner')] {'building': 'yes', 'historic': 'fort', 'name': 'Golden Hill Fort', 'note': 'Under conversion to residential, was victorian fort', 'type': 'multipolygon'}),
  Relation(1589570 ->  [Member(type='way', ref=113700258, role='inner'), Member(type='way', ref=113700249, role='outer')] {'type': 'multipolygon', 'source': 'Bing', 'building': 'yes'})])

In [12]:
len(addr_rel_ids), addr_rel_ids[:5]


Out[12]:
(6,
 [Relation(1593581 ->  [Member(type='way', ref=114135843, role='outer'), Member(type='way', ref=114135841, role='inner')] {'addr:city': 'Bembridge', 'addr:housename': 'Solent Landing', 'addr:postcode': 'PO35 5NZ', 'addr:street': 'Beach Road', 'building': 'residential', 'type': 'multipolygon'}),
  Relation(1844051 ->  [Member(type='way', ref=228750548, role='outer'), Member(type='way', ref=136843896, role='inner')] {'name': 'Bugle Hotel', 'type': 'multipolygon', 'wifi': 'free', 'phone': '+44 1983 760272', 'source': 'Bing', 'amenity': 'pub', 'tourism': 'hotel', 'website': 'http://www.thebugleyarmouth.co.uk/', 'alt_name': 'The Bugle Coaching Inn', 'building': 'yes', 'addr:city': 'Yarmouth', 'addr:street': 'The Square', 'addr:postcode': 'PO41 0NS', 'addr:housename': 'Bugle Coaching Inn'}),
  Relation(5808141 ->  [Member(type='way', ref=168129028, role='outer'), Member(type='way', ref=378172008, role='inner')] {'addr:postcode': 'PO36 0HL', 'addr:street': 'Lower Road', 'capacity:pitches': '270', 'caravans': 'yes', 'name': 'Camping & Caravanning Club (Adgestone)', 'opening_hours': 'May-Sep', 'phone': '+44 1983 403432', 'tents': 'yes', 'tourism': 'camp_site', 'type': 'multipolygon', 'website': 'http://www.campingandcaravanningclub.co.uk/campsites/uk/isleofwight/adgestone/adgestone'}),
  Relation(5834380 ->  [Member(type='way', ref=39328539, role='outer'), Member(type='way', ref=390042809, role='inner')] {'addr:city': 'Sandown', 'addr:postcode': 'PO36 9PR', 'addr:street': 'The Fairway Lake', 'description': '18 hole Par 70', 'golf:course': '18_hole', 'golf:par': '70', 'leisure': 'golf_course', 'name': 'Shanklin & Sandown Golf Club', 'phone': '+44 1983 403217; +44 1983 404424 (Pro Shop)', 'type': 'multipolygon', 'website': 'http://www.ssgolfclub.com/'}),
  Relation(6520669 ->  [Member(type='way', ref=405110409, role='outer'), Member(type='way', ref=438326549, role='outer')] {'name': 'West Ashey Cottages', 'type': 'multipolygon', 'landuse': 'residential', 'addr:postcode': 'PO33 4AX'})])

Process to a pandas dataframe

In a separate notebook, we explore how to use geopandas to also store and manipulate geometry...


In [13]:
import numpy as np
import pandas as pd

In [14]:
gen = digest.parse(filename)
print(next(gen))
print(next(gen))

possible_address_tags = set()
for x in gen:
    for key in x.tags:
        if key.startswith("addr:"):
            possible_address_tags.add(key)
            
possible_address_tags


OSM(version=0.6, generator=osmconvert 0.8.5, timestamp=2017-04-25 20:43:28)
Bounds(longitude:[-1.659074,-1.0313699], latitude:[50.50555,50.80102]
Out[14]:
{'addr:city',
 'addr:country',
 'addr:county',
 'addr:flats',
 'addr:floor',
 'addr:hamlet',
 'addr:housename',
 'addr:housenumber',
 'addr:inclusion',
 'addr:interpolation',
 'addr:name',
 'addr:place',
 'addr:postcode',
 'addr:province',
 'addr:street',
 'addr:unit'}

In [15]:
gen = digest.parse(filename)
osm = next(gen)
bounds = next(gen)

address_data = { key : [] for key in possible_address_tags }
address_data["osm_id"] = []

for x in gen:
    addr = {key : x.tags[key] for key in x.tags if key.startswith("addr:")}
    if len(addr) > 0:
        address_data["osm_id"].append(x.name+"/"+str(x.osm_id))
        for key in possible_address_tags:
            if key in addr:
                address_data[key].append(addr[key])
            else:
                address_data[key].append(np.nan)

In [16]:
data = pd.DataFrame(address_data)
data = data.set_index("osm_id")
data[:5]


Out[16]:
addr:city addr:country addr:county addr:flats addr:floor addr:hamlet addr:housename addr:housenumber addr:inclusion addr:interpolation addr:name addr:place addr:postcode addr:province addr:street addr:unit
osm_id
node/2383584 Yarmouth NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN PO41 0PB NaN Quay Street NaN
node/2387351 Bembridge NaN NaN NaN NaN NaN Bembridge Windmill NaN NaN NaN NaN NaN PO35 5SQ NaN Mill Road NaN
node/2433320 Totland GB NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN PO39 0HY NaN Highdown Lane NaN
node/7227760 Havenstreet, near Ryde NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Main Road NaN
node/8093989 Ryde NaN NaN NaN NaN NaN NaN 41 NaN NaN NaN NaN PO33 2LF NaN Union Street NaN

Do the same for USA / Chicago data

Let's look at a different country, namely the state of Illinois in the USA.

We'll then load the data from the SQLite database, as this is far more memory efficient. We'll find that we still end up with massive python data structures...

The overall pattern is the same, even though the dataset is much larger.

  • Most buildings are "ways" and most addresses are "ways".
  • There are a few point addresses stored as nodes, and complicated structures (like an airforce base) are stored as relations.

In [4]:
import osmdigest.sqlite as sq
import os

In [5]:
filename = os.path.join("//tmp", "aaa", "illinois-latest.db")
#filename = os.path.join("..", "..", "..", "Data", "illinois-latest.db")

In [6]:
db = sq.OSM_SQLite(filename)

Nodes


In [7]:
def iterate_over_tags(iterator):
    buildings, addresses = [], []
    for element in iterator:
        if any(key.startswith("building") for key in element.tags):
            buildings.append(element)
        if any(key.startswith("addr") for key in element.tags):
            addresses.append(element)
    return buildings, addresses

In [8]:
building_nodes, address_nodes = iterate_over_tags(db.nodes())

In [9]:
len(building_nodes), building_nodes[:5]


Out[9]:
(2359,
 [Node(153356428 @ [40.5011471,-89.0061875] {'ele': '231', 'name': 'The Oaks', 'is_in': 'McLean,Illinois,Ill.,IL,USA', 'gnis:id': '1822565', 'building': 'apartments', 'gnis:Class': 'Populated Place', 'gnis:County': 'McLean', 'gnis:ST_num': '17', 'import_uuid': 'bb7269ee-502a-5391-8056-e3ce0e66489c', 'gnis:ST_alpha': 'IL', 'gnis:County_num': '113'}),
  Node(153529104 @ [41.1361448,-88.8153516] {'ele': '192', 'name': 'Evans Heights Housing Project', 'is_in': 'La Salle,Illinois,Ill.,IL,USA', 'gnis:id': '1816035', 'building': 'apartments', 'gnis:Class': 'Populated Place', 'gnis:County': 'La Salle', 'gnis:ST_num': '17', 'import_uuid': 'bb7269ee-502a-5391-8056-e3ce0e66489c', 'gnis:ST_alpha': 'IL', 'gnis:County_num': '099'}),
  Node(153579003 @ [41.1397559,-88.8417415] {'ele': '190', 'name': 'Delbert Egan Housing Project', 'is_in': 'La Salle,Illinois,Ill.,IL,USA', 'gnis:id': '1816030', 'building': 'apartments', 'gnis:Class': 'Populated Place', 'gnis:County': 'La Salle', 'gnis:ST_num': '17', 'import_uuid': 'bb7269ee-502a-5391-8056-e3ce0e66489c', 'gnis:ST_alpha': 'IL', 'gnis:County_num': '099'}),
  Node(321556096 @ [40.7917277,-89.3624722] {'ele': '250', 'name': 'Metamora Court House State Historic Site', 'name_1': 'Metamora Courthouse', 'source': 'USGS Geonames', 'building': 'civic', 'heritage': '2', 'historic': 'courthouse', 'ref:nrhp': '78001203', 'wikidata': 'Q6823000', 'addr:city': 'Metamora', 'addr:state': 'IL', 'addr:street': 'East Partridge Street', 'addr:country': 'US', 'addr:postcode': '61548', 'gnis:reviewed': 'no', 'gnis:feature_id': '2041412', 'addr:housenumber': '113', 'gnis:county_name': 'Woodford', 'gnis:import_uuid': '57871b70-0100-4405-bb30-88b2e001a944', 'heritage:operator': 'nhrp'}),
  Node(347159885 @ [41.9112846,-87.6348689] {'name': 'Starbucks', 'amenity': 'cafe', 'building': 'entrance', 'addr:city': 'Chicago', 'addr:state': 'IL', 'addr:street': 'West North Avenue', 'addr:country': 'US', 'addr:postcode': '60610', 'addr:housenumber': '210'})])

In [10]:
len(address_nodes), address_nodes[:5]


Out[10]:
(25570,
 [Node(153632538 @ [38.0114393,-89.2361935] {'ele': '140', 'name': 'Du Quoin', 'is_in': 'Perry,Illinois,Ill.,IL,USA', 'place': 'village', 'gnis:id': '407442', 'website': 'http://duquoin.org/', 'wikipedia': 'en:Du Quoin, Illinois', 'gnis:Class': 'Populated Place', 'population': '6427', 'gnis:County': 'Perry', 'gnis:ST_num': '17', 'import_uuid': 'bb7269ee-502a-5391-8056-e3ce0e66489c', 'addr:postcode': '62832', 'gnis:ST_alpha': 'IL', 'gnis:County_num': '145', 'census:population': '6427;2006'}),
  Node(233814226 @ [42.279127,-88.9216445] {'name': 'Centaur Drive', 'highway': 'turning_circle', 'addr:street': 'Centaur Drive'}),
  Node(233820177 @ [42.2790679,-88.9241119] {'addr:street': 'Centaur Drive', 'addr:province': '61008'}),
  Node(233820181 @ [42.2791024,-88.9242578] {'highway': 'turning_circle', 'addr:city': 'Belvidere', 'addr:street': 'Olympus Drive', 'addr:postcode': '61008'}),
  Node(233858025 @ [42.2790251,-88.924224] {'addr:state': 'IL', 'addr:street': 'Olympus Drive', 'addr:postcode': '61008'})])

Ways


In [11]:
building_ways, address_ways = iterate_over_tags(db.ways())

In [12]:
len(building_ways), building_ways[:5]


Out[12]:
(1063853,
 [Way(4374907 ->  [26678161, 26678162, 4666066956, 26678163, 26678160, 26678165, 26678161] {'amenity': 'parking', 'building': 'yes', 'parking': 'multi-storey'}),
  Way(4375988 ->  [26686573, 26686578, 26686583, 26686586, 26686591, 26686594, 26686597, 26686615, 26686617, 26686619, 26686621, 26686623, 26686625, 26686627, 26686629, 26686631, 26686633, 26686635, 2011478878, 2011478996, 2011478857, 2011478982, 2011478993, 2011478925, 2011478976, 2011478863, 2011478918, 2011478887, 2011478903, 2011478980, 2011478930, 2011478966, 2011478999, 2011478961, 2011478969, 2011478927, 26686462, 2011478867, 2011478936, 26686456, 2011478870, 2011478964, 2011478922, 2011478898, 26686469, 26686475, 26686481, 26686486, 26686492, 26686497, 26686503, 26686510, 26686515, 26686520, 26686522, 26686527, 26686532, 26686538, 26686542, 2011478892, 2011478884, 2011478984, 2011478972, 2011478862, 2011478895, 2011478987, 2011478985, 2011478859, 2011478900, 2011478955, 26686550, 2011478881, 2011478978, 2011478975, 2011478865, 2011478860, 2011478939, 2011478958, 2011479001, 2011478873, 2011479004, 2011478889, 2011478933, 2011478947, 2011478915, 2011478990, 2011478950, 2011478875, 2011478941, 2011478855, 2011478952, 2011478944, 26686555, 26686561, 26686567, 26686573] {'iata': 'ORD', 'icao': 'KORD', 'name': 'Terminal 5 - International', 'aeroway': 'terminal', 'building': 'yes', 'building:levels': '1'}),
  Way(12412091 ->  [939903733, 939903734, 939903737, 112986634, 939903740, 939903742, 939903744, 939903746, 112986635, 939903749, 939903751, 4269213685, 112986641, 939903754, 939903756, 939903758, 939903760, 939903763, 939903765, 112986642, 4382397717, 4382397721, 4382397724, 4382397733, 4382397740, 4382397760, 112986644, 939903507, 939903508, 112986646, 4269213703, 4269213702, 4269213699, 4269213700, 112986647, 4269213694, 4269213687, 4269213689, 4269213688, 4269213690, 4269213692, 4269213693, 4269213697, 4269213696, 4269213706, 4269213707, 4269213718, 4269213710, 112986649, 112986650, 4382397784, 4382397993, 4382397998, 939903505, 939903506, 112986652, 112986653, 112986654, 112990134, 939903510, 4269213747, 4269213748, 4269213746, 939903512, 4269213741, 112990135, 1723799062, 1723799257, 4269213740, 112990136, 4269213744, 112990138, 4269213754, 4269213760, 4269213763, 4269213764, 4269213761, 4269213762, 4269213757, 4269213759, 4269213765, 4269213766, 4269213767, 4269213750, 4269213749, 4269213742, 4269213743, 4269213739, 4269213738, 4269213736, 4269213737, 4269213734, 4269213733, 4269213726, 4269213727, 4269213723, 4269213722, 365188500, 365188501, 365188502, 112990142, 939903769, 4269213711, 4269213715, 4269213716, 4269213720, 4269213729, 4269213731, 4269213732, 112990143, 4269213735, 1723798884, 1723799232, 1723799284, 1723799348, 112990145, 1723799252, 112990146, 939903770, 939903772, 112990128, 939901571, 939903728, 4269213684, 4269213683, 939901572, 939903731, 4269213679, 4269213680, 4269213675, 4269213674, 4269213673, 4269213672, 4269213668, 4269213669, 4269213665, 4269213666, 4269213664, 4269213663, 4269213661, 4269213662, 4269213658, 4269213657, 4269213655, 4269213656, 112990129, 4269213654, 4269213653, 4269213652, 4269213651, 4269213650, 4269213648, 4269213649, 4269213647, 4269213646, 939903923, 4269213641, 4269213643, 112990130, 4269213634, 112990131, 112990149, 4269213630, 4269213631, 112986630, 4269213632, 4269213633, 4269213635, 939904673, 939904674, 4269213637, 939904675, 4269213640, 4269213642, 939904676, 4269213645, 4269213644, 4269213639, 4269213638, 4269213636, 939903924, 112986631, 4269213678, 939903733] {'name': 'Midway Airport Terminal', 'layer': '1', 'aeroway': 'terminal', 'building': 'yes', 'max_level': '1', 'min_level': '0', 'addr:street': 'South Cicero Avenue', 'addr:housenumber': '5600-5800', 'addr:street:name': 'Cicero', 'addr:street:type': 'Avenue', 'addr:street:prefix': 'South', 'chicago:building_id': '827157'}),
  Way(12412343 ->  [112992018, 1740050109, 1740050464, 1740050261, 1740050071, 1740050397, 1740050234, 1740050229, 1740049987, 1740050359, 1740050003, 1740050319, 1740050415, 1740050335, 1740050463, 1740050374, 1740049955, 1740050125, 1740049946, 1740050031, 1740050148, 1740050110, 1740050029, 1740050307, 1740050382, 1740050240, 1740050181, 1740050475, 1210044022, 112992019, 2416744122, 1741502338, 112992020, 1743802932, 1740050263, 1740050127, 1740050337, 1740049957, 1740050312, 1740050327, 1740050394, 1740050349, 1740050296, 1740050231, 1740050413, 1740050149, 1740050290, 1740050143, 1740050343, 1740050034, 1740050032, 1740050225, 1740050150, 1740050305, 1740050329, 1740050313, 1740050450, 1740050233, 1740050372, 1740050348, 1740050358, 1740050295, 1740050221, 1740049983, 1740050323, 1740050284, 365188413, 365188500, 4269213722, 4269213723, 4269213727, 4269213726, 4269213733, 4269213734, 4269213737, 4269213736, 4269213738, 4269213739, 4269213743, 4269213742, 4269213749, 4269213750, 4269213767, 4269213766, 418447542, 112992018] {'name': 'Midway Airport Parking Garage', 'amenity': 'parking', 'parking': 'multi-storey', 'building': 'yes', 'addr:street': 'South Cicero Avenue', 'addr:housenumber': '5701', 'addr:street:name': 'Cicero', 'addr:street:type': 'Avenue', 'addr:street:prefix': 'South', 'chicago:building_id': '827158'}),
  Way(20078459 ->  [718380261, 212129155, 212129157, 212129159, 212129161, 718380262, 718380263, 212129163, 718380264, 718380265, 212129164, 718380245, 718380246, 718380266, 718380267, 718380268, 718380269, 718380270, 718380271, 718380272, 718380273, 718380274, 718380275, 718380276, 718380261] {'name': 'Saint Zachary School', 'building': 'school', 'addr:street': 'West Algonquin Road', 'gnis:created': '01/15/1980', 'gnis:state_id': '17', 'gnis:county_id': '31', 'building:levels': '2', 'gnis:feature_id': '417846', 'addr:housenumber': '567'})])

In [13]:
len(address_ways), address_ways[:5]


Out[13]:
(511096,
 [Way(5327657 ->  [37974740, 37954742, 37974742, 37946312, 37974745, 37946268, 37974747, 37961896, 37974750, 37974751, 37974753, 2804451055, 37974754, 2804539691, 2384928198, 37974756, 37974758, 2711599472, 2805236584, 2805236585, 37974762, 37974763, 3365324539, 2384927636, 37974767, 37974769, 37974771, 37974773] {'addr:postcode': '61820', 'highway': 'residential', 'is_in': 'Champaign, IL', 'maxspeed': '25 mph', 'name': 'South Sixth Street', 'oneway': 'yes', 'tiger:reviewed': 'no'}),
  Way(5328776 ->  [37985146, 37954746, 37985149, 2366289498, 37946314, 2366289499] {'addr:postcode': '61820', 'highway': 'primary', 'lanes': '2', 'maxspeed': '30 mph', 'name': 'South Wright Street', 'ref': 'US 45;US 150', 'tiger:reviewed': 'no'}),
  Way(5329151 ->  [38005445, 38005446, 38005448, 38005450, 38005452, 38005455, 38005457, 38005458, 38005461, 38005463, 38005465, 37965767, 38005469, 38005471, 38005472, 38005475, 37979470, 38005477, 38005478, 38005481, 38005484, 38005488, 38005489, 38005491, 38005495, 38005498, 38005500, 38005502, 38005506, 38005508, 38005511, 38005512, 38005513, 38005516, 38005519, 38005523, 38005525, 38005527, 38005528, 38005531, 38005534, 38005535, 38005536, 38005541, 37988751, 37988753, 37988758, 37988762, 37988768, 37988773, 37988775, 37988780, 37988784, 37988788, 37988792, 37988794, 37988796, 37988801] {'ref': 'IL 130', 'name': 'County Road 1600  E', 'highway': 'secondary', 'tiger:tlid': '8800469:8800750:8800510', 'tiger:source': 'tiger_import_dch_v0.6_20070809', 'addr:postcode': '61864', 'tiger:reviewed': 'no', 'tiger:upload_uuid': 'bulk_upload.pl-9d431e3e-750d-4932-bce5-cd0cfd0651ce'}),
  Way(5329943 ->  [37997293, 37997294, 37997297, 38005010, 38005009, 38005005, 38005002, 37949624, 38005000, 38004999] {'ref': 'IL 130', 'name': 'South Lincoln Street', 'name_1': 'County Road 1600  E', 'highway': 'secondary', 'tiger:tlid': '8814868:8814878; 8800383; 8800421:8800406:8800640', 'tiger:source': 'tiger_import_dch_v0.6_20070809', 'addr:postcode': '61864', 'tiger:reviewed': 'no', 'tiger:upload_uuid': 'bulk_upload.pl-9d431e3e-750d-4932-bce5-cd0cfd0651ce'}),
  Way(5331172 ->  [37999274, 38009718, 38009719, 38009721, 38009723, 38009725, 38009727, 38009728, 38009730, 37970446, 38009731, 38009732, 38009734, 38009736, 37986833, 38009737, 38009738, 38009741] {'name': 'Bloomington Road', 'highway': 'secondary', 'addr:postcode': '61820', 'honorary_name': 'Veterans Parkway', 'tiger:reviewed': 'no'})])

Relations


In [14]:
building_rels, address_rels = iterate_over_tags(db.relations())

In [15]:
len(building_rels), building_rels[:5]


Out[15]:
(844,
 [Relation(153529 ->  [Member(type='way', ref=35566659, role=''), Member(type='way', ref=35566905, role='inner')] {'type': 'multipolygon', 'building': 'school'}),
  Relation(153559 ->  [Member(type='way', ref=35567371, role='outer'), Member(type='way', ref=35567372, role='inner'), Member(type='way', ref=35567373, role='inner'), Member(type='way', ref=35567374, role='inner')] {'type': 'multipolygon', 'building': 'school'}),
  Relation(173602 ->  [Member(type='way', ref=34574316, role='outer'), Member(type='way', ref=37744533, role='inner'), Member(type='way', ref=37744565, role='inner'), Member(type='way', ref=183679094, role='inner'), Member(type='way', ref=183679085, role='inner')] {'building': 'school', 'type': 'multipolygon'}),
  Relation(174304 ->  [Member(type='way', ref=26191075, role='outer'), Member(type='way', ref=37781465, role='inner'), Member(type='way', ref=37781606, role='inner')] {'building': 'school', 'type': 'multipolygon'}),
  Relation(912193 ->  [Member(type='way', ref=59129147, role='outer'), Member(type='way', ref=59129084, role='inner')] {'type': 'multipolygon', 'building': 'yes'})])

In [16]:
len(address_rels), address_rels[:5]


Out[16]:
(418,
 [Relation(122949 ->  [Member(type='way', ref=33833789, role='outer'), Member(type='way', ref=33833788, role='outer'), Member(type='way', ref=33833791, role='outer'), Member(type='way', ref=33833851, role='outer'), Member(type='way', ref=33833836, role='outer'), Member(type='way', ref=33833796, role='outer'), Member(type='way', ref=33833795, role='outer')] {'ele': '140', 'iata': 'BLV', 'icao': 'KBLV', 'name': 'Scott Air Force Base', 'type': 'boundary', 'is_in': 'USA, Illinois', 'source': 'TIGER/Line® 2008 Place Shapefiles (http://www.census.gov/geo/www/tiger/)', 'landuse': 'military', 'ref:faa': 'BLV', 'website': 'http://www.scott.af.mil/', 'boundary': 'administrative', 'military': 'airfield', 'wikidata': 'Q576617', 'tiger:CPI': 'N', 'wikipedia': 'en:Scott Air Force Base', 'addr:state': 'IL', 'tiger:LSAD': '57', 'tiger:NAME': 'Scott AFB', 'is_in:state': 'Illinois', 'tiger:MTFCC': 'G4210', 'gnis:created': '11/17/2008', 'is_in:country': 'USA', 'tiger:CLASSFP': 'M2', 'tiger:PCICBSA': 'N', 'tiger:PLACEFP': '68328', 'tiger:PLACENS': '02393227', 'tiger:PLCIDFP': '1768328', 'tiger:STATEFP': '17', 'tiger:FUNCSTAT': 'S', 'tiger:NAMELSAD': 'Scott AFB CDP', 'tiger:PCINECTA': 'N', 'gnis:feature_id': '2512005', 'gnis:county_name': 'St. Clair', 'is_in:iso_3166_2': 'US:IL', 'is_in:state_code': 'IL', 'gnis:feature_type': 'Military', 'is_in:country_code': 'US'}),
  Relation(151440 ->  [Member(type='way', ref=35366687, role='outer'), Member(type='way', ref=35366688, role='inner')] {'addr:state': 'IL', 'ele': '210', 'gnis:county_name': 'Cook', 'gnis:created': '01/15/1980', 'gnis:feature_id': '410549', 'gnis:feature_type': 'Swamp', 'name': 'Horse Collar Slough', 'natural': 'water', 'NHD:ComID': '109990950', 'NHD:FCode': '39004', 'NHD:FDate': '2003/11/05', 'NHD:FTYPE': 'LakePond', 'NHD:ReachCode': '07120004008150', 'NHD:RESOLUTION': 'High', 'source': 'NHD', 'type': 'multipolygon'}),
  Relation(1407988 ->  [Member(type='way', ref=98236779, role='outer'), Member(type='way', ref=98236773, role='inner'), Member(type='relation', ref=2083717, role='inner')] {'addr:city': 'Chicago', 'addr:country': 'US', 'addr:housenumber': '1060', 'addr:postcode': '60613', 'addr:state': 'IL', 'addr:street': 'West Addison Street', 'addr:street:name': 'Addison', 'addr:street:prefix': 'West', 'addr:street:type': 'Street', 'building': 'historic', 'chicago:building_id': '170572', 'leisure': 'stadium', 'name': 'Wrigley Field', 'name:ru': 'Ригли Филд', 'sport': 'baseball', 'type': 'multipolygon', 'wikidata': 'Q1052807', 'wikipedia': 'en:Wrigley Field'}),
  Relation(1467696 ->  [Member(type='way', ref=103532289, role='inner'), Member(type='way', ref=103532290, role='outer'), Member(type='way', ref=103532280, role='inner')] {'addr:housenumber': '3535', 'addr:street': 'East 114th Street', 'addr:street:name': '114th', 'addr:street:prefix': 'East', 'addr:street:type': 'Street', 'building': 'school', 'chicago:building_id': '775256', 'type': 'multipolygon'}),
  Relation(1870546 ->  [Member(type='way', ref=23891004, role='outer'), Member(type='way', ref=139013466, role='inner')] {'addr:housenumber': '111', 'addr:postcode': '60603', 'addr:street': 'South Michigan Avenue', 'addr:street:name': 'Michigan', 'addr:street:prefix': 'South', 'addr:street:type': 'Avenue', 'building': 'yes', 'chicago:building_id': '881847', 'name': 'The Art Institute of Chicago', 'tourism': 'museum', 'type': 'multipolygon', 'website': 'http://www.artic.edu/', 'wikidata': 'Q4796889', 'wikipedia': 'en:Art Institute of Chicago Building'})])

Process into a useful form

Ultimately, I want:

  • Elements which have a street name and a housenumber. These are addr:street and addr:housenumber.
  • A single coordinate to use. For a way we can take the centroid. For a relation, we have to perform a bit of exploring: it is tempting to hope there is always one way with role "outer". This doesn't work, so we settle on looking at each member and taking its centroid, working recursively if necessary. This will not be particularly meaningful in some situations, but should suffice for now.

We construct a GeoJSON-like data structure, and then import it into geoPandas.


In [62]:
features = []

def make_feature(el, centroid):
    return { "properties": {
                    "street": el.tags["addr:street"],
                    "housenumber": el.tags["addr:housenumber"],
                    "osm_id": "{}/{}".format(el.name, el.osm_id)
                },
                "geometry": { "type": "Point",
                    "coordinates": centroid } }

for el in db.search_node_tag_keys({"addr:street", "addr:housenumber"}):
    features.append(make_feature(el, [el.longitude, el.latitude]))
    
for el in db.search_way_tag_keys({"addr:street", "addr:housenumber"}):
    way = db.complete_way(el)
    features.append(make_feature(el, way.centroid()))

for el in db.search_relation_tag_keys({"addr:street", "addr:housenumber"}):
    rel = db.complete_relation(el)
    features.append(make_feature(el, rel.centroid()))

In [63]:
import geopandas as gpd

In [64]:
frame = gpd.GeoDataFrame.from_features(features)
#frame = frame.set_geometry("centroid")
frame[:5]


Out[64]:
geometry housenumber osm_id street
0 POINT (-88.114125 41.736407) 1764 node/237932890 Deerpath Court
1 POINT (-87.685828 42.064201) 1022 node/249656713 Central Street
2 POINT (-87.6659686 42.0080864) 1358 node/252643581 West Morse Avenue
3 POINT (-87.654928 41.9538873) 3940 node/252643632 North Sheridan Road
4 POINT (-87.65362709999999 41.9475198) 940 node/252683058 West Addison Street

Explore inconsistencies

Many of the "housenumber" values are not integers.

  • From the 5 examples below, "2211 W" should be "2211"; "145 N." should be "145" but the street should be "North Curtis Avenue". For the remaining 3, I do not know enough about North American addresses to be certain.
  • All these examples come from areas of data where we don't have house-level building data. So in many ways, the data is not useful for my application anyway.

In [65]:
unexpected_addresses = frame[~ frame.housenumber.map(lambda x : all(y>='0' and y<='9' for y in x))]
unexpected_addresses.head()


Out[65]:
geometry housenumber osm_id street
54 POINT (-87.6810535 41.8568924) 2211 W node/354130275 West 18th Place
58 POINT (-87.87672600000001 41.8180869) 145 N. node/354136550 Waiola Ave.
103 POINT (-88.1808913 41.8191108) 3S460 node/354209159 Curtis Avenue
104 POINT (-88.17635009999999 41.8176825) 28W441 node/354209175 Warrenville Road
126 POINT (-88.40341189999999 41.9372496) 4N782 School Street node/354221533 School Street
  • The addresses with "#" in appear to be neighbours in a "trailer park", judging from satelite images. This addressing scheme follows how apartments/flats are addressed.
  • The address "14543-59" is a church, i.e. a large building which probably occupied more than one notional address.

In [66]:
unexpected_addresses[5:10]


Out[66]:
geometry housenumber osm_id street
169 POINT (-88.1770258 41.8205142) 28W444 node/354257996 Main Street
191 POINT (-87.6429097 41.6242516) 14543-59 node/354284238 Green Street
287 POINT (-87.8224087 42.4181001) 38285 #100 node/480537523 N Sheridan Rd
288 POINT (-87.8225374 42.4181001) 38285 #101 node/480537524 N Sheridan Rd
289 POINT (-87.8226662 42.4180937) 38285 #102 node/480537527 N Sheridan Rd

So let's filter out things which match. (Stand-back, I know regular expressions).

  • digits, space, #, digits "\d+\s+#\d+"
  • digits, one of NSEW, digits "\d+[NSEW]\d+"
  • digits, maybe a space, a single letter. maybe a full stop "\d+\s[a-zA-Z]\."
  • digits, maybe a space, "East"/"West" etc.
  • things like "123 1/2"

In [67]:
import re

one = re.compile("^\\d+\\s+#\\d+$")
assert one.match("4262 #12") is not None
assert one.match("4 62 #12") is None
two = re.compile("^\\d+[NSEW]\\d+$")
assert two.match("19N479") is not None
assert two.match("19NS479") is None
assert two.match("19 479") is None
three = re.compile("^\\d+\\s*[a-zA-Z]\\.*$")
assert three.match("152A") is not None
assert three.match("152 A") is not None
assert three.match("152 A.") is not None
assert three.match("152Ac") is None
four = re.compile("^\\d+\\s*1/2")

matches = {one, two, three, four}

left = unexpected_addresses[~ unexpected_addresses.housenumber.map(lambda x : any(m.match(x) is not None for m in matches))]
left.head()


Out[67]:
geometry housenumber osm_id street
126 POINT (-88.40341189999999 41.9372496) 4N782 School Street node/354221533 School Street
191 POINT (-87.6429097 41.6242516) 14543-59 node/354284238 Green Street
558 POINT (-87.6280391 41.8812077) 26 - 32 node/1376826841 South State Street
673 POINT (-87.696406 41.9027443) 2739-41 node/1588091293 West Division Street
761 POINT (-88.2252161 40.1067707) 1209 node/1700549689 W. Oregon Street, Urbana, Illinois

This leaves a lot left over.

What interests me is whether there are any "way"s which "interpolate" addresses, see http://wiki.openstreetmap.org/wiki/Addresses

The answer is: "no". Eyeballing these few in OSM doesn't show anything interesting.


In [70]:
for way in db.search_way_tag_keys({"addr:interpolation"}):
    print(way)


Way(31458117 ->  [351216792, 351216802, 351221977, 351225719, 351226097, 351228005, 351228010, 351232763, 351232765, 351232767] {'addr:city': 'Skokie', 'addr:street': 'West Touhy Avenue', 'addr:interpolation': 'even'})
Way(35676806 ->  [417737750, 417737751] {'addr:interpolation': 'odd'})
Way(35676807 ->  [417737752, 417737753] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(35676808 ->  [417737754, 417737755] {'addr:interpolation': 'odd'})
Way(35676809 ->  [417737758, 417737757] {'addr:interpolation': 'odd'})
Way(35676810 ->  [417737758, 413519205] {'addr:interpolation': 'odd'})
Way(35676811 ->  [417737760, 417737761] {'addr:interpolation': 'odd'})
Way(35676812 ->  [417737768, 417737763, 3850772663] {'addr:interpolation': 'even'})
Way(35676813 ->  [1262642237, 417737765, 3850772667] {'addr:interpolation': 'odd'})
Way(35676815 ->  [417737768, 1262642232, 2586914143, 3174700506, 1262642239, 1262642224] {'footway': 'sidewalk', 'highway': 'footway', 'addr:interpolation': 'even'})
Way(35676816 ->  [417737776, 3174700507, 1262642224] {'footway': 'sidewalk', 'highway': 'footway', 'addr:interpolation': 'even'})
Way(35676817 ->  [417737774, 417737773, 1262642228, 1262642230, 1262642236, 1262642222, 4498381306, 1262642241, 4498381305, 4498381304, 4498381303] {'footway': 'sidewalk', 'highway': 'footway', 'addr:interpolation': 'odd'})
Way(35676818 ->  [417737774, 417737775, 3174700508, 1262642237] {'footway': 'sidewalk', 'highway': 'footway', 'addr:interpolation': 'odd'})
Way(35676819 ->  [417737776, 1262642238] {'footway': 'sidewalk', 'highway': 'footway', 'addr:interpolation': 'even'})
Way(35676820 ->  [417737781, 1262642238] {'footway': 'sidewalk', 'highway': 'footway', 'addr:interpolation': 'even'})
Way(35676821 ->  [4498381310, 4498381311, 1262642223, 4498381312, 1262642229, 417737780, 417737781] {'footway': 'sidewalk', 'highway': 'footway', 'addr:interpolation': 'even'})
Way(35745278 ->  [418095238, 418095239] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(35745279 ->  [418095240, 418095241] {'addr:street': 'Lake Ave', 'addr:interpolation': 'odd'})
Way(35745280 ->  [418095242, 418095243] {'addr:street': 'Lake Ave', 'addr:interpolation': 'odd'})
Way(35745281 ->  [418095244, 418095245] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(35745299 ->  [418095833, 418095834] {'addr:street': 'Lake Ave', 'addr:interpolation': 'odd'})
Way(35745300 ->  [418095835, 418095836] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(35745301 ->  [418095837, 418095838] {'addr:street': 'Lake Ave', 'addr:interpolation': 'odd'})
Way(35745302 ->  [418095839, 418095840] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(35745303 ->  [418095841, 418095842] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(35745304 ->  [418095843, 418095844] {'addr:street': 'Lake Ave', 'addr:interpolation': 'odd'})
Way(35745322 ->  [418096031, 418096032] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(35745323 ->  [418096033, 418096034] {'addr:street': 'Lake Ave', 'addr:interpolation': 'odd'})
Way(35745324 ->  [418096035, 418096036] {'addr:street': 'Lake Ave', 'addr:interpolation': 'odd'})
Way(35745325 ->  [418096037, 418096038] {'addr:street': 'Lake Ave', 'addr:interpolation': 'even'})
Way(40336304 ->  [486820432, 486820435] {'addr:city': 'Beach Park', 'addr:street': 'N. Sheridan Rd', 'addr:postcode': '60087', 'addr:interpolation': 'all'})
Way(53758867 ->  [678697321, 678697347, 678697357, 678697364, 678697381, 678697399, 678697411, 678697424, 678697431, 678697446, 678697453, 678697463, 678697476, 678697491, 678697508, 678697518, 678697529, 678697540, 678697575, 678697586, 678697591, 678697595, 678697601, 678697612, 678697615, 678697623, 678697629, 678697638, 678697649, 678697662, 678697673, 678697677, 678697681, 678697685, 678697693, 678697706, 678697714, 678697321] {'amenity': 'school', 'addr:city': 'Edwardsville', 'addr:street': 'District Drive', 'addr:postcode': '62025', 'addr:housenumber': '1', 'addr:interpolation': 'all'})

Finally, save the data out. We can use any supported fiona driver. Here I use GeoJSON, as it's human readable, and no less space efficient than a Shapefile. A Shapefile can be imported into QGis etc., of course.


In [71]:
import fiona
fiona.supported_drivers


Out[71]:
{'ARCGEN': 'r',
 'AeronavFAA': 'r',
 'BNA': 'raw',
 'DGN': 'raw',
 'DXF': 'raw',
 'ESRI Shapefile': 'raw',
 'GPKG': 'rw',
 'GPSTrackMaker': 'raw',
 'GPX': 'raw',
 'GeoJSON': 'rw',
 'Idrisi': 'r',
 'MapInfo File': 'raw',
 'OpenFileGDB': 'r',
 'PCIDSK': 'r',
 'SEGY': 'r',
 'SUA': 'r'}

In [72]:
frame.to_file("illinois_building.json", driver="GeoJSON")

In [ ]: