A Better Python GeoEncoding Script to Use with NYS SAM

I rewrote the short little geocoder that I posted last night in Python, using the multiple address function in NY’s Street and Address Maintenance (SAM) Program. This should be able to encode up to 1,000 lines in a text file. You would use this script by typing python sam-geocode.csv with one address per line.

By running python sam-geocode.py address.txt, with a file like this:

5 Winding Brook Drive 	Guilderland	NY	12084
1224 Union Street 	Schenectady	NY	12308
6239 Randomwood Drive 	Schenectady	NY	12030
1529 Western Avenue  Suite 102 	Albany	NY	12203
4017b State Street 	Schenectady	NY	12304
4017b State Street 	Schenectady	NY	12304
1529 Western Avenue  Suite 102 	Albany	NY	12203
1529 Western Avenue  Suite 102 	Albany	NY	12203
2842 W. Lydius Street 	Schenectady	NY	12306
200 Bloomingdale Road 	Altamont	NY	12009

Gives you out a CSV file named address-geocoded.csv.

"1224 Union St, Schenectady, NY, 12308",42.81103508600006,-73.92220575399995
"6239 Randomwood Dr, Schenectady, NY, 12303",42.74713565800005,-73.93299995099994
"1529 Western Ave, Albany, NY, 12203",42.68293244500006,-73.84222237599994
"4017 B State St, Schenectady, NY, 12304",42.76677680800003,-73.88794539599996
"4017 B State St, Schenectady, NY, 12304",42.76677680800003,-73.88794539599996
"1529 Western Ave, Albany, NY, 12203",42.68293244500006,-73.84222237599994
"1529 Western Ave, Albany, NY, 12203",42.68293244500006,-73.84222237599994
"2842 W Lydius St, Schenectady, NY, 12306",42.75003186400005,-73.95573429299998
"23 Dresden Ct, Albany, NY, 12203",42.69198706100008,-73.87999566599996
"629 Salvia Ln, Schenectady, NY, 12303",42.73869920900006,-73.93268336399996
"5 Winding Brook Dr, Guilderland, NY, 12084",42.69401880400005,-73.90855096599995
"3 Feeney Ln, Schenectady, NY, 12303",42.72653497400006,-73.90924777399994
"730 Sachem Cir, Slingerlands, NY, 12159",42.67422884300004,-73.88860130999996
"200 Bloomingdale Ln, Altamont, NY, 12009",42.69634668300006,-73.94903687499993

Now, I could improve error capture on this script but for my purposes this is very simple and works wells for well-formed addresses. Maybe not as simple as the PHP script I posted last night, but this way of Geocoding is much faster and written in a language that’s more appropriate for such purposes.

#!/usr/bin/python

import requests,sys,json,csv,os

query = '{"records": ['
f = open(sys.argv[-1], 'r+')
with open(sys.argv[-1]) as f:
	i = 0
	for line in f:
		query += '{ "attributes": { "OBJECTID":'+str(i)+', "SINGLELINE": "'+line.rstrip()+'"} },'+"n"
		i+=1	
query += ']}'

post = { 'f':'pjson', 'outSR': 4326, 'addresses': query }
url = 'https://gisservices.its.ny.gov/arcgis/rest/services/Locators/Street_and_Address_Composite/GeocodeServer/geocodeAddresses'

req = requests.post(url, data = post)
addresses = json.loads(req.text)['locations']

csv = open(os.path.splitext(sys.argv[-1])[0]+'-geocode.csv', "w")

for place in addresses:
	csv.write('"'+place['address'].replace('"', '\"')+'",'+str(place['location']['y'])+','+str(place['location']['x'])+"n")
	
csv.close()

This also works for most other states, as most states have geocoding endpoints, as otherwise the fire department wouldn’t necessarily be able to find your house when it’s on fire when you call 911. To find your state, try searching for StateName "GeocodeServer/geocodeAddresses". For example, replace URL with:

Massachusetts – https://gis.massdot.state.ma.us/arcgis/rest/services/General/MassDOTStreetAddressLocator/GeocodeServer/geocodeAddresses
Pennsylvania – https://maps.pasda.psu.edu/arcgis/rest/services/apps/AddressLocator/GeocodeServer/geocodeAddresses

Leave a Reply

Your email address will not be published. Required fields are marked *