#sources:
#creating and deleting paths: https://stackabuse.com/creating-and-deleting-directories-with-python/
#using requests to download data from URLs: https://realpython.com/python-requests/
#using arrays to download a list of URLs: https://likegeeks.com/downloading-files-using-python/
#reading zipped shapefiles: https://medium.com/@loldja/reading-shapefile-zips-from-a-url-in-python-3-93ea8d727856
#listing feature classes: https://pro.arcgis.com/en/pro-app/arcpy/functions/listfeatureclasses.htm
import os #manipulate files and paths
import arcpy #Esri data management
import zipfile #manipulate zipped files
import io #work with input/output
import requests #requests allows you to download large files without consuming a lot of memory
import shutil #shutil supports file copying and removal
#list of tuples of counties and download URLs
urls = [('Benton', 'http://www.mediafire.com/file/gnd4a9yjcya9zsc/Parcel.zip/file'),
('Clallam', 'http://www.clallam.net/Maps/parcel.zip'),
('Ferry', 'https://www.ferry-county.com/Other_Depts/GIS_Dept_Files/Parcel%20Layer/2020-02%20FC%20PARCEL%20LAYER.zip'),
('Franklin', 'http://franklingis.org/Data/Parcels_Web.zip'),
('Grant', 'http://www.grantcountywa.gov/GIS/MISC/ZIPDATA/Parcel_boundaries.zip'),
('GraysHarbor', 'http://www.co.grays-harbor.wa.us/GIS/Data_Download/Parcel.zip'),
('Island', 'https://maps.islandcountywa.gov/WebFiles/DataDownloads/Parcels.zip'),
('Jefferson', 'https://opendata.arcgis.com/datasets/c0fa49b507ed4d57b9aa2dbc4314c4f0_4.zip?outSR=%7B%22latestWkid%22%3A3857%2C%22wkid%22%3A102100%7D'),
('King', 'https://opendata.arcgis.com/datasets/c7a17b7ad3ec44b7ae64796dca691d72_1722.zip'),
('Kittitas', 'https://opendata.arcgis.com/datasets/bda6b56b35cd461b8b600b4f98f564c7_1.zip?outSR=%7B%22latestVcsWkid%22%3A6360%2C%22latestWkid%22%3A2286%2C%22wkid%22%3A102749%2C%22vcsWkid%22%3A105703%7D'),
('Lewis', 'https://maps.lewiscountywa.gov/data/parcels_NoOwner.zip'),
('Mason', 'http://www.arcgis.com/sharing/rest/content/items/186d264834fd4d1c84eed4b617f4b0ac/data'),
('Okanogan', 'http://www.okanogancounty.org/planning/zip/parcels.zip'),
('Pacific', 'https://www.co.pacific.wa.us/gis/DesktopGIS/WEB/data_2006/tax_lots.zip'),
('Pierce', 'https://opendata.arcgis.com/datasets/0ef33b5e288f49b38b936f6047ba1ace_0.zip?outSR=%7B%22latestWkid%22%3A2927%2C%22wkid%22%3A2927%7D'),
('SanJuan', 'https://opendata.arcgis.com/datasets/03e90bc346594df88f9b3edc73eb83dd_1.zip'),
('Spokane', 'https://opendata.arcgis.com/datasets/228db1be1d6940a3b5e3f2104e470134_0.zip'),
('Thurston', 'https://opendata.arcgis.com/datasets/04030948640b42a992fa2d644898e359_0.zip'),
('Yakima', 'https://opendata.arcgis.com/datasets/681e5ccefbb24cb59c0f7969fd8994b4_0.zip')]
#create temp folder for workspace
work_path = r'<PATH>\temp' #this would be changed if you wanted a different location
os.mkdir(work_path)
print('Temp folder created')
#set workspace
arcpy.env.workspace = work_path
#create file GDB
gdb_folder_path = r'<PATH>' #this would be changed if you wanted a different location
gdb_name = 'counties.gdb'
arcpy.CreateFileGDB_management(gdb_folder_path, gdb_name)
print('Geodatabase created')
#define lists to add failed download and extracts to
download_failure = []
extract_failure = []
print('Beginning data download...')
#function for downloading and extracting parcel shapefiles
def county_download(url):
path, url = url
response = requests.get(url, stream=True) #'get' the URL. set stream to true to only dowload one file at a time
if response: #if county shapefile download succeeds
try: #try to extract the contents of the zipped folder
zipshape = zipfile.ZipFile(io.BytesIO(response.content))
zipshape.extractall(work_path + '\/' + str(path)) #extract to folder with same name as county
except: #if it is a bad zip file, add it to the extract_failure list
extract_failure.append(x)
else: #if error code is returned/download failed, add it to the download_failure list
download_failure.append(x)
#run the county_download function for each county's URL in list
for x in urls:
county_download(x)
#print lists of failed downloads and extracts
print('Failed downloads: ' + str(download_failure))
print('Failed extracts: ' + str(extract_failure))
print('Data download complete!')
print('Exporting to geodatabase...')
#create list of county folders in the temp downloads folder
import os
FileDirectoryPath = work_path
files = []
files = [f for f in sorted(os.listdir(FileDirectoryPath))]
#print(files) #optional to list the county folders in the temp downloads folder
#create list to append failed exports to
export_failure = []
#function for exporting each shapefile to the gdb
def county_export(i):
arcpy.env.workspace = work_path + '\/' + str(i)
gdb = r'<PATH>\counties.gdb' #this would be changed if you used a different location to create the gdb
fc = arcpy.ListFeatureClasses()
for shp in fc:
inFeatures = shp
outLocation = gdb
outFeatureClass = str(i)
#export shapefiles to gdb
try:
arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outFeatureClass)
except:
export_failure.append(i)
#run county_export function
for i in files:
county_export(i)
#print list of failed exports
print('Failed exports: ' + str(export_failure))
#delete county folders
shutil.rmtree(FileDirectoryPath)
print('County folders deleted')
print('Script complete!')