-
Notifications
You must be signed in to change notification settings - Fork 0
/
SingleInputScript.py
97 lines (71 loc) · 3.85 KB
/
SingleInputScript.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import os, sys
import time
process_start_time = time.time()
import arcpy
import multiprocessing
from SingleInputClipFunction import worker
# Input parameters
clipper = arcpy.GetParameterAsText(0)
tobeclipped = arcpy.GetParameterAsText(1)
outLocation = arcpy.GetParameterAsText(2)
def get_install_path():
''' Return 64bit python install path from registry (if installed and registered),
otherwise fall back to current 32bit process install path.
'''
if sys.maxsize > 2**32: return sys.exec_prefix #We're running in a 64bit process
#We're 32 bit so see if there's a 64bit install
path = r'SOFTWARE\Python\PythonCore\2.7'
from _winreg import OpenKey, QueryValue
from _winreg import HKEY_LOCAL_MACHINE, KEY_READ, KEY_WOW64_64KEY
try:
with OpenKey(HKEY_LOCAL_MACHINE, path, 0, KEY_READ | KEY_WOW64_64KEY) as key:
return QueryValue(key, "InstallPath").strip(os.sep) #We have a 64bit install, so return that.
except: return sys.exec_prefix #No 64bit, so return 32bit path
def mp_handler():
try:
# Create a list of object IDs for clipper polygons
arcpy.AddMessage("Creating Polygon OID list...")
print("Creating Polygon OID list...")
clipperDescObj = arcpy.Describe(clipper)
field = clipperDescObj.OIDFieldName
idList = []
with arcpy.da.SearchCursor(clipper, [field]) as cursor:
for row in cursor:
id = row[0]
idList.append(id)
arcpy.AddMessage("There are " + str(len(idList)) + " object IDs (polygons) to process.")
print("There are " + str(len(idList)) + " object IDs (polygons) to process.")
# Create a task list with parameter tuples for each call of the worker function. Tuples consist of the clippper, tobeclipped, field, and oid values.
jobs = []
for id in idList:
jobs.append((clipper,tobeclipped,field,id,outLocation)) # adds tuples of the parameters that need to be given to the worker function to the jobs list
arcpy.AddMessage("Job list has " + str(len(jobs)) + " elements.")
print("Job list has " + str(len(jobs)) + " elements.")
# Create and run multiprocessing pool.
multiprocessing.set_executable(os.path.join(get_install_path(), 'pythonw.exe')) # make sure Python environment is used for running processes, even when this is run as a script tool
arcpy.AddMessage("Sending to pool")
print("Sending to pool")
cpuNum = multiprocessing.cpu_count() # determine number of cores to use
print("there are: " + str(cpuNum) + " cpu cores on this machine")
with multiprocessing.Pool(processes=cpuNum) as pool: # Create the pool object
res = pool.starmap(worker, jobs) # run jobs in job list; res is a list with return values of the worker function
# If an error has occurred report it
failed = res.count(False) # count how many times False appears in the list with the return values
if failed > 0:
arcpy.AddError("{} workers failed!".format(failed))
print("{} workers failed!".format(failed))
arcpy.AddMessage("Finished multiprocessing!")
print("Finished multiprocessing!")
except arcpy.ExecuteError:
# Geoprocessor threw an error
arcpy.AddError(arcpy.GetMessages(2))
print("Execute Error:", arcpy.ExecuteError)
except Exception as e:
# Capture all other errors
arcpy.AddError(str(e))
print("Exception:", e)
if __name__ == '__main__':
mp_handler()
# Output how long the whole process took.
arcpy.AddMessage("Total program runtime: --- %s seconds ---" % (time.time() - process_start_time))
print ("Total program runtime: --- %s seconds ---" % (time.time() - process_start_time))