Skip to content

Geocoding with Mapzen Search and picogeojson

Nat Wilson edited this page Apr 23, 2017 · 1 revision

Geocoding with Mapzen Search and picogeojson

The Mapzen search API performs forward geocoding and return results as GeoJSON. Using picogeojson we can quickly map and visualize data from a list of addresses.

I'm starting with a list of addresses, which I've loaded as a pandas.DataFrame:

Name Address City
0 Coal Habour Brewing Company 1967 Triumph St Vancouver
1 Bomber Brewing 1488 Adanac St Vancouver
2 Andina Brewing Company 1507 Powell St Vancouver
3 Strange Fellows Brewing Company 1345 Clark Dr Vancouver
4 Postmark Brewing 55 Dunlevy Ave Vancouver

Each address is forward geocoded

import picogeojson
import requests

breweries = dict()

for _, rec in breweries.iterrows():

    r = requests.get("https://search.mapzen.com/v1/search?text={}, {}?"
                         "size=1?api_key=API_KEY".format(rec.Address, rec.City))

    if r.status_code == 200:
        geo = picogeojson.loads(r.content.decode("utf-8"))
        brewery_results[rec.Name] = geo

When picogeojson loads each JSON string, it constructs an object modelled after a GeoJSON type. The responses from the Mapzen API are GeoJSON FeatureCollections, so the picogeojson object will be

FeatureCollection(
    features : [Feature...],
    [...]
)

Each Feature contains a Point geometry member:

Feature(
    geometry : Point,
    properties : dict
    [...]
)

and each Point has a coordinates member:

Point(
    coordinates: [longitude, latitude],
    [...]
)

So the longitude and latitude can be accessed from the picogeojson-wrapped response as

    (longitude, latitude) = geo.features[0].geometry.coordinates[:2]

Putting this together, updating our original list of addresses looks like:

names, lons, lats = [], [], []

for name in breweries.Name:
    try:
        longitude = brewery_results[name].features[0].geometry.coordinates[1]
        latitude = brewery_results[name].features[0].geometry.coordinates[0]
    except KeyError:
        longitude = math.nan
        latitude = math.nan
    names.append(name)
    lons.append(longitude)
    lats.append(latitude)

locations = pandas.DataFrame({"Name": names, "Longitude": lons, "Latitudes": lats})
breweries_with_location = pandas.merge(breweries, locations, how="left", on="Name")

Now we have:

Name Address City Latitude Longitude
0 Coal Habour Brewing Company 1967 Triumph St Vancouver -123.064046 49.284168
1 Bomber Brewing 1488 Adanac St Vancouver -123.074610 49.277358
2 Andina Brewing Company 1507 Powell St Vancouver -123.073795 49.283278
3 Strange Fellows Brewing Company 1345 Clark Dr Vancouver -123.077947 49.272511
4 Postmark Brewing 55 Dunlevy Ave Vancouver -123.095437 49.284374