How to batch geocode from script using python 2.7

793
1
Jump to solution
11-04-2020 07:38 AM
FranklinAlexander
Occasional Contributor II

This is starting to seem like an insurmountable task, so I am hoping I can get a few hints and pointers on how to do this. I need to automate the process of geocoding a db table and unfortunately our ArgGIS Enterprise server is still using ArcMap 10.4, so ArcPro is not an option. I have tried all of the obvious tricks like creating a model, running it to make sure it runs successfully, then exporting to a python script file. This doesn't work because the I need to use the esri World Geocode Service, and the url is different depending on whether you are geocoding from within ArcMap, or from a standalone script. I know the service url is "https://geocode.arcgis.com/arcgis/rest/services/ " and this seems to be consistent no matter the source doc (and the fact I was given this url by esri support). 

Basically I have 2 issues:

1. finding the correct locator url (the second  part of the url), for instance:

      "World/GeocodeServer/ArcGIS World Geocoding Service"

      "World.GeocodeServer"

      "World/GeocodeServer"

      

2. Authenticating the request. So far I have tried creating a connection file, or signing in to ArcGIS online via arcpy.

Below are some examples of what I have tried. Of note, I spent a an hour yesterday doing a screenshare with esri support with no luck.

Here is the attempt with no connection file:

import arcpy

cwd = sys.path[0]
output_gdb_name = "Temp.gdb"
output_gdb = os.path.join(cwd, output_gdb_name)

#Overwrite the output feature class if it already exists
arcpy.env.overwriteOutput = True

#creating field map for geocode service
field_input = {"Address": "MailingAddressStreet",
            "City": "MailingAddressCityText",
            "Postal": "MailingAddressZipID"
            }
fieldMap = arcpy.FieldInfo()
for field in field_input:
    fieldMap.addField(field, field_input[field], "VISIBLE", "NONE")    
 
addr_table = os.path.join(output_gdb, "WildlifeOperatorInformationTable")
geocodeServer = "https://geocode.arcgis.com/arcgis/rest/services"

### I have tried each of these locators
addr_locator = os.path.join(geocodeServer, "World.GeocodeServer")
#addr_locator = os.path.join(geocodeServer, "World/GeocodeServer")
#addr_locator = os.path.join(geocodeServer, "World/ArcGIS World Geocoding Service")

geocode_result = os.path.join(output_gdb,"geocodeResult")

#geocoding addresses
arcpy.GeocodeAddresses_geocoding(addr_table, addr_locator, fieldMap, geocode_result, 'STATIC')‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Attempted to create a connection file and get no error, but no connection file exists for output directory:

import arcpy, os, sys

cwd = sys.path[0]
output_gdb_name = "Temp.gdb"
output_gdb = os.path.join(cwd, output_gdb_name)

#Overwrite the output feature class if it already exists
arcpy.env.overwriteOutput = True

#Create the ArcGIS Server connection file
outPath = r"...\NuisanceWildlifeTrappers"
#outPath = "GIS Servers"
server_url = "https://geocode.arcgis.com/arcgis/rest/services"
conn_file_name = "arcGIS_geocoding.ags"
conn_file = os.path.join(outPath, conn_file_name)
user = "John.Smith"
pwd = "xxxxxxx"
arcpy.mapping.CreateGISServerConnectionFile("USE_GIS_SERVICES",
                                            outPath,
                                            conn_file_name,
                                            server_url,
                                            "ARCGIS_SERVER",
                                            username=user,
                                            password=pwd,
                                            save_username_password=True)


print "completed"
print arcpy.GetMessages()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I then created a GIS server connection using ArcCatalog for testing to see if I could  get it to work. 

locator = "GIS Servers\arcgis on geocode.arcgis.com (user)"

field_input = {"Address": "MailingAddressStreet",
            "City": "MailingAddressCityText",
            "Postal": "MailingAddressZipID"
            }
fieldMap = arcpy.FieldInfo()
for field in field_input:
    fieldMap.addField(field, field_input[field], "VISIBLE", "NONE")    
 
addr_table = os.path.join(output_gdb, "WildlifeOperatorInformationTable")

geocode_result = os.path.join(output_gdb,"geocodeResult_fromScript")

#geocoding addresses
arcpy.GeocodeAddresses_geocoding(addr_table, locator, fieldMap, geocode_result, 'STATIC')‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

....and got the following error:

I did try signing in to the portal by placing this code in the python script just before the geocode function but it makes no difference:

cwd = sys.path[0]
output_gdb_name = "Temp.gdb"
output_gdb = os.path.join(cwd, output_gdb_name)

field_input = {"Address": "MailingAddressStreet",
            "City": "MailingAddressCityText",
            "Postal": "MailingAddressZipID"
            }
fieldMap = arcpy.FieldInfo()
for field in field_input:
    fieldMap.addField(field, field_input[field], "VISIBLE", "NONE")    
 
addr_table = os.path.join(output_gdb, "WildlifeOperatorInformationTable")
geocodeServer = "https://geocode.arcgis.com/arcgis/rest/services"
addr_locator = os.path.join(geocodeServer, "World.GeocodeServer")
#addr_locator = os.path.join(geocodeServer, "World/GeocodeServer")
#addr_locator = os.path.join(geocodeServer, "World/ArcGIS World Geocoding Service")

geocode_result = os.path.join(output_gdb,"geocodeResult")

portalUrl = arcpy.GetActivePortalURL()
print portalUrl
arcpy.SignInToPortal_server('John.Smith', 'xxxxxx')‍‍‍

#geocoding addresses
arcpy.GeocodeAddresses_geocoding(addr_table, addr_locator, fieldMap, geocode_result, 'STATIC')
arcpy.SignOutFromPortal_server()

print "completed"
print arcpy.GetMessages()
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Got this error:

I also read the documentation about authenticating a request by generating a token and followed the steps by creating an application at developers.arcgis.com, but am not sure how generated the token and use it from a python script. There isn't any documentation I can find on how to do this. 

Sorry for the long post, but I have been at this for a while. Thanks for letting  me know what I am doing wrong and for any suggestions.

1 Solution

Accepted Solutions
FranklinAlexander
Occasional Contributor II

I got it to work using the python 3x idle. I created a model in ArcPro and exported to a script file, made a few tweaks and it ran from my c: drive. I then copied and pasted the code to the server, ran it again successfully. Not sure why this worked since we don't have ArcPro installed on the server, we are still using ArmMap 10.4. If anyone knows how a python 3x script can run on a server that only has python 2x, I would love to know. Hope this helps someone else. Here is the working script:

"""
Generated by ArcGIS ModelBuilder on : 2020-10-28 10:45:06
"""
import arcpy, os, pandas as pd

outputGdb = r"...\NuisanceWildlifeTrappers\Temp.gdb"

arcpy.SignInToPortal(arcpy.GetActivePortalURL(), 
                     'john.smith', 'xxxxxx')

arcpy.env.overwriteOutput = True

WildlifeOperators = r"...\WildlifeOperators.csv"
data = pd.read_csv(WildlifeOperators, encoding='utf8')
print (data)
ArcGIS_World_Geocoding_Service = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/ArcGIS World Geocoding Service"
geocodeResult = os.path.join(outputGdb, "geocodeResult_fromScript")

# Process: Geocode Addresses (Geocode Addresses) 
geocode_results = "r\\...\\NuisanceWildlifeTrappers.gdb\\geocode_results"
arcpy.GeocodeAddresses_geocoding(WildlifeOperators, ArcGIS_World_Geocoding_Service, 
                "Address Street VISIBLE NONE;" +                                                                                     
                "Address2 <None> VISIBLE NONE;" +                                                                                     
                "Address3 <None> VISIBLE NONE;" +                                                                                     
                "Neighborhood <None> VISIBLE NONE;" +                                                                                     
                "City City VISIBLE NONE;" +                                                                                     
                "County <None> VISIBLE NONE;" +                                                                                     
                "State State VISIBLE NONE;" +                                                                                     
                "ZIP ZIP VISIBLE NONE;" +                                                                                     
                "ZIP4 <None> VISIBLE NONE;" +                                                                                     
                "Country <None> VISIBLE NONE", geocodeResult, "STATIC")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

0 Kudos
1 Reply
FranklinAlexander
Occasional Contributor II

I got it to work using the python 3x idle. I created a model in ArcPro and exported to a script file, made a few tweaks and it ran from my c: drive. I then copied and pasted the code to the server, ran it again successfully. Not sure why this worked since we don't have ArcPro installed on the server, we are still using ArmMap 10.4. If anyone knows how a python 3x script can run on a server that only has python 2x, I would love to know. Hope this helps someone else. Here is the working script:

"""
Generated by ArcGIS ModelBuilder on : 2020-10-28 10:45:06
"""
import arcpy, os, pandas as pd

outputGdb = r"...\NuisanceWildlifeTrappers\Temp.gdb"

arcpy.SignInToPortal(arcpy.GetActivePortalURL(), 
                     'john.smith', 'xxxxxx')

arcpy.env.overwriteOutput = True

WildlifeOperators = r"...\WildlifeOperators.csv"
data = pd.read_csv(WildlifeOperators, encoding='utf8')
print (data)
ArcGIS_World_Geocoding_Service = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/ArcGIS World Geocoding Service"
geocodeResult = os.path.join(outputGdb, "geocodeResult_fromScript")

# Process: Geocode Addresses (Geocode Addresses) 
geocode_results = "r\\...\\NuisanceWildlifeTrappers.gdb\\geocode_results"
arcpy.GeocodeAddresses_geocoding(WildlifeOperators, ArcGIS_World_Geocoding_Service, 
                "Address Street VISIBLE NONE;" +                                                                                     
                "Address2 <None> VISIBLE NONE;" +                                                                                     
                "Address3 <None> VISIBLE NONE;" +                                                                                     
                "Neighborhood <None> VISIBLE NONE;" +                                                                                     
                "City City VISIBLE NONE;" +                                                                                     
                "County <None> VISIBLE NONE;" +                                                                                     
                "State State VISIBLE NONE;" +                                                                                     
                "ZIP ZIP VISIBLE NONE;" +                                                                                     
                "ZIP4 <None> VISIBLE NONE;" +                                                                                     
                "Country <None> VISIBLE NONE", geocodeResult, "STATIC")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos