Monday, 24 June 2013

Arcpy helper....used in many of my toolsets

I will try to keep this updated.  I use it for many of my tools, so look for an import arcpy_helper line and copy this script to the same spot as the other scripts.

'''
arcpy_helper.py
  Author
  Dan Patterson
  Dept of Geography and Environmental Studies
  Carleton University, Ottawa, Canada
  Dan_Patterson@carleton.ca
  Date  August 18, 2010
  Modified  June 2013
  Purpose:
  Helper functions, that use the geoprocessor created by arcpy
 
'''
#---------------------------------------------------------------
#required modules
import arcpy, os, sys
def gp_create(vers=None):
  if vers == None:
    info = (arcpy.GetInstallInfo()['Version'])
  else:
    info = "\nRequires Arcmap version 10 or above"
    arcpy.AddMessage(info)
  return info
def get_toolboxes(toolboxes, arcpy):
  '''a list of toolboxes to add to the geoprocessor, arcpy'''
  sub_folder = "ArcToolbox/Toolboxes/"
  install_dir = arcpy.GetInstallInfo()['InstallDir'].replace("\\","/")
  tbx_home = os.path.join(install_dir, sub_folder)
  msg = ""
  passed = True
  for a_tbx in toolboxes:
    try:
      tbx = tbx_home + a_tbx
      arcpy.AddToolbox(tbx)
      msg = msg + "\n  Adding toolbox: " + str(tbx)
    except:
      msg = msg + "\n  The toolbox:  " + str(tbx) + \
            "\n  could not be loaded.  Check your toolbox path "
      passed = False
  return [arcpy, msg, passed]
def createFC (outFC, outType, SR, arcpy):
  '''
  Requires
    outFC    output feature class name. eg. "c:/temp/myfile.shp"
    outType  output type "Polygon" or "Polyline"
    SR       Spatial reference from input feature class
    arcpy    the geoprocessor object created in the source
  '''
  #Create the output filename and feature class, use the Spatial
  #Reference of the input feature class
  fullName = os.path.split(outFC)
  outFolder = fullName[0].replace("\\","/")
  outFName =  fullName[1].replace(" ", "_")
  outFullName = (outFolder + "/" + outFName)
  #Create a shapefile
  try:
    arcpy.CreateFeatureclass_management(outFolder, outFName, outType, "", "DISABLED", "DISABLED", SR)
    arcpy.AddMessage("\n  Creating " + str(outFullName) +
                  "\n  Spatial reference: \n\t" + str(SR.Name))
  except:
    arcpy.AddMessage("\n  Failed to create feature class" + "\n" + arcpy.GetMessages())
    sys.exit()
  #
  try:
    cur = arcpy.InsertCursor(outFC)
  except:
    arcpy.AddMessage("\n  Failed to create cursor")
    del arcpy
    sys.exit()
#------------------------------------------------------------------------------
def pntXY(pnt):
  '''Gets X,Y coordinates given a point object, returns a list'''
  XY= [pnt.X, pnt.Y]
  return XY
#---------------------------------------------------------------
def pntXYtoTuple(pnt):
  '''Gets X,Y coordinates given a point object, returns a tuple'''
  XY= (pnt.X, pnt.Y)
  return XY
#------------------------------------------------------------------------------
def polyFromPoints (outFC, outType, SR, outPntsList, theFields, arcpy):
  '''
  Requires
    outFC        output feature class name "c:/temp/myfile.shp"
    outType      output type "Polygon" or "Polyline"
    SR           Spatial reference from input feature class
    outPntsList  a list of lists of points
                  eg [ [10,10], [12,15], [7,3] ]
    theFields    the fields to add and their format
    arcpy        the Geoprocessor Object
  '''
  #Create the output filename and feature class, use the Spatial
  #Reference of the input feature class
  #import os, sys    #required if used in other modules
  fullName = os.path.split(outFC)
  outFolder = fullName[0].replace("\\","/")
  outFName =  fullName[1].replace(" ", "_")
  outFullName = (outFolder + "/" + outFName)
  #
  #Create a polygon shapefile
  try:
    arcpy.CreateFeatureclass_management(outFolder, outFName, outType, "", "DISABLED", "DISABLED", SR)
    arcpy.AddMessage("\n  Creating " + str(outFullName) +
                  "\n  Spatial reference: \n\t" + str(SR.Name))
  except:
    arcpy.AddMessage("\n  Failed to create feature class")
    sys.exit()
  #
  #Add any required fields fields
  if len(theFields) != 0:
    for i in range(0, len(theFields)):
      aField = theFields[i]
      try:
        arcpy.AddField_management(outFullName, aField[0], aField[1], aField[2], aField[3])
      except:
        arcpy.AddMessage("\n  Cannot add field " + str(aField[0]) + arcpy.GetMessages())
  try:
    insert_cursor = arcpy.InsertCursor(outFC)
  except:
    arcpy.AddMessage("\n  Failed to create cursor")
    del arcpy
    sys.exit()
  anID=0
  polyArray = arcpy.CreateObject("Array")
  aPnt = arcpy.CreateObject("Point")
  for i in range(0,len(outPntsList)):
    outShape = outPntsList[i][0]
    for aPair in outShape:
      aPnt.X = aPair[0]
      aPnt.Y = aPair[1]
      polyArray.add(aPnt)
    feat = insert_cursor.newRow()
    feat.shape = polyArray
    feat.id = anID
    if len(theFields) != 0:
      for j in range(0, len(theFields)):
        aField = theFields[j]
        feat.setValue(aField[0],outPntsList[i][j+1])
    insert_cursor.insertRow(feat)
    polyArray.removeAll()
    anID=anID+1
  del polyArray
  del aPnt
#-------------------------------------------------------------
def createPointFile (outFC, outType, SR, pnts, fieldsToAdd, arcpy):
  '''Requires
    outFC     output feature class name "c:/temp/myfile.shp"
    outType   output type e.g. "Point"
    SR        Spatial reference from input feature class
    pnts      a list of lists of points eg.
              [[pnt list 1],[pnt list 2]...[pnt list n]]
          or  [[pnt list 1]]
    arcpy     the Geoprocessor Object
  Create the output filename and feature class, use the Spatial Reference
    of the input feature class
  '''
  import os, sys    #required if used in other modules
  fullName = os.path.split(outFC)
  outFolder = fullName[0].replace("\\","/")
  outFName =  fullName[1].replace(" ", "_")
  outFullName = outFolder + "/" + outFName
  try:
    arcpy.CreateFeatureclass_management(outFolder, outFName, outType, "#", "Disabled", "Disabled", SR)
    arcpy.AddMessage( "\n" + "Creating " + str(outFName))
  except:
    arcpy.AddMessage( "Failed to create feature class" + arcpy.GetMessages())
    sys.exit()
  for aField in fieldsToAdd:
    arcpy.AddMessage("Adding field " + str(aField))
    try:
      arcpy.AddField_management(outFullName, str(aField[0]), "LONG", "9")
    except:
      arcpy.AddMessage("Failed to add fields: " + arcpy.GetMessages())
      sys.exit()
  #
  #Create the insert cursor
  aPnt = arcpy.Point()
  try:
    cur = arcpy.InsertCursor(outFC)
  except:
    arcpy.AddMessage("failed to create cursor")
    sys.exit()
  anID=0
  for i in range(0,len(pnts)):   
    aList = pnts[i]
    aCount = 0
    for j in range(len(aList)):
      try:      
        aPnt.X = aList[j][0] #.x
        aPnt.Y = aList[j][1] #.y
        aPnt.ID = aCount
        feat = cur.newRow()
        feat.shape = aPnt
        feat.setValue("ID", aCount)
        #feat.SetValue("Group", anID)
        cur.insertRow(feat)
        aCount = aCount + 1
      except:
        arcpy.AddMessage("cannot create feature ")
    anID = anID + 1
  del cur
 
def shapeToPoints(a_shape,theType,arcpy):
  '''
  pnts = shapeToPoints(a_shape, shape type, geoprocessor)
  Purpose:  Converts a shape to points, the shape and its type
  are passed by the calling script
  Requires:  def pntXY(pnt)
  '''
  outList=[]
  part_num = 0
  part_count = a_shape.partCount
  if theType == "Multipoint":    #Multipoints
    while part_num < part_count:
      pnt = a_shape.getPart(part_num)
      XY = pntXY(pnt)
      if XY not in outList:
        outList.append(XY)
      part_num += 1
  else:                          #Poly* features
    while part_num < part_count: #cycle through the parts
      a_part = a_shape.getPart(part_num)
      pnt = a_part.next()
      while pnt:                 #cycle through the points
        XY = pntXY(pnt)
        if XY not in outList:
          outList.append(XY)
        pnt = a_part.next()     
        if not pnt:              #null point check (rings/donuts)
          pnt = a_part.next()
          if pnt:
            XY = pntXY(pnt)
            if XY not in outList:
              outList.append(XY)
      part_num += 1
  return outList
#
#-------------------------------------------------------------
if __name__ == '__main__':
  import arcpy
  info = gp_create()
  message = str(info)
  print "\nScript:   arcpy_helper ", "\nArcMap version: ", str(info)
  arcpy.AddMessage("\narcpy_helper " + "\nArcMap version: " + str(info))

No comments:

Post a Comment