Beer Me - The Beer Map Download Tool
After unleasing the Brewery Finder on the world yesterday, a lot of people have been asking about the data source. Since I actually wrote a script to get the data and convert it, rather than force anybody who wants to do the same to recreate the wheel, I decided to simply give the tool away for you to be able to recreate it yourself if you so desire. Hence, here is the full code in a GitHub repository, beer-me-download
.
"""
Name: Beer Me
Purpose: Snag data data from CraftBeer.com and save as a feature class.
DOB: 09Oct2015
Author: Joel McCune (https://github.com/knu2xs)
"""
# import modules
import xml.etree.ElementTree as ElementTree
import os.path as path
from urllib import request
from time import strftime
import arcpy
# list of attributes in the xml file to be converted into fields in the output feature class
field_list = [
'id',
'company',
'address',
'city',
'state',
'zip',
'country',
'phone',
'member_type',
'type',
'url'
]
# url to craft beer xml file
craft_beer_xml = 'http://www.craftbeer.com/wp-content/uploads/ba-us.xml'
def create_feature_class(feature_class):
"""
Add the craft beer fields to the output feature class.
:param feature_class: The polygon feature class where attributes will be added to.
:return: Path to feature class.
"""
# create the feature class if it does not already exist
if not arcpy.Exists(feature_class):
# create the feature class
fc = arcpy.CreateFeatureclass_management(
out_path=path.dirname(feature_class),
out_name=path.basename(feature_class),
geometry_type='POINT',
spatial_reference=arcpy.SpatialReference(4326) # WGS84
)[0]
# since all the fields are text, we are just going to iterate and add them all
for field in field_list:
# account for the url field needing to be longer
if field == 'url':
length = 500
else:
length = 100
# add the field
arcpy.AddField_management(
in_table=fc,
field_name=field,
field_type='TEXT',
field_length=length
)
# return path
return feature_class
def craft_beer_xml_to_feature_class(xml_file, feature_class):
"""
Convert the craft beer file to a feature class.
:param xml_file: XML file of all breweries.
:param feature_class: Output feature class of breweries.
:return: String path to the breweries.
"""
# load the xml file into an element tree object
tree = ElementTree.parse(xml_file)
# create the feature class
create_feature_class(feature_class)
# extend field list to include coordinates
cursor_fields = field_list + ['SHAPE@XY']
# create an insert cursor to add records to the feature class
with arcpy.da.InsertCursor(feature_class, cursor_fields) as insert_cursor:
# iterate the markers in the xml file
for node in tree.findall('marker'):
# sequentially extract the elements from the node into a list representing the new row attributes
row = [str.encode(node.attrib.get(field), 'utf-8') for field in field_list]
# now get the geometry and add this to the row
row.append((
float(node.attrib.get('lng')),
float(node.attrib.get('lat'))
))
# insert the new row into the output feature class
insert_cursor.insertRow(row)
# return the path to the output feature class
return feature_class
def create_craft_beer_feature_class(feature_class):
"""
Assuming the url does not change, grab the most recent version of the xml file and create a feature class from it.
:param feature_class: Output brewery feature class.
:return: Path to feature class.
"""
# file location to temporarily save the xml
xml_file = path.join(arcpy.env.scratchFolder, 'craft_beer.xml')
# get the data as a response object from Al Gore's interwebs
request.urlretrieve(craft_beer_xml, xml_file)
# convert the xml file into a feature class
craft_beer_xml_to_feature_class(xml_file, feature_class)
# return the path
return feature_class
# now, because I am lazy, I am going to just build it here and set it up to timestamp the output feature class
if __name__ == '__main__':
# output to the ArcGIS default geodatabase for the current user
output_fc = path.join(
path.expanduser('~'), # get user directory
r'Documents\ArcGIS\Default.gdb', # place in default user geodatabase
'craft_beer_' + strftime('%Y%m%d') # append YYYYMMDD onto the end of the filename for timestamp
)
# let the big dawg eat
create_craft_beer_feature_class(output_fc)