SlideShare uma empresa Scribd logo
1 de 86
Advanced geoprocessing with…



               MAGIC 2012
   Chad Cooper – chad@cast.uark.edu
 Center for Advanced Spatial Technologies
    University of Arkansas, Fayetteville
Intros
• your name
• what you do/where you work
• used Python much?
  – any formal training?
  – what do you use it for?
• know any other languages?
Objectives
• informal class
  – expect tangents
  – code as we go
• not geared totally to ArcGIS
• THINK – oddball and out of the ordinary
  applications will make you want more…
Outline
•   data types review    • documentation
•   functions            • 3rd party modules
•   procedural vs. OOP   • module installation
•   geometries           • the web
•   rasters                 – fetching
                            – scraping
•   spatial references
                            – email
•   error
                            – FTP
    handling/logging
                         • files
Strings
•   ordered collections of characters
•   immutable – can’t change it
•   raw strings: path = r”C:tempchad”
•   slicing                                   fruit[0]
                              „b‟

• indexing: fruit[1:3] >> „an‟
• iteration/membership:              for each in fruit
                                    „f‟ in fruit
Strings
• string formatting:    „a %s parrot‟ % „dead‟
                            „a dead parrot‟



• useful string formatting:

  import arcpy
  f = "string"
  arcpy.CalculateField_management(fc,
                                  “some_field",
                                  '"%s"' % f)
Lists
• list – ordered collection of arbitrary objects
  list1 = [0,1,2,3]
  list2 = ['zero','one','two','three']
  list3 = [0,'zero',1,'one',2,'two',3,'three']

• ordered
  list2.sort()            list2.sort(reverse=True)
  ['one','three',...]     ['zero','two',...]

• mutable – you can change it
  list1.append(4) list1.reverse() list2.insert(0,‟one-half‟)
  [0,1,2,3,4]     [4,3,2,1,0]      [„one-half‟,‟zero‟…]


  list2.extend([„four‟,‟five‟])   <- Extend concats lists
Lists…
• iterable – very important!     for l in list3
                                        0
                                        zero ...

• membership 3 in list3 -->      True

• nestable – 2D array/matrix
  list4 = [[0,1,2],
           [3,4,5],
           [6,7,8]]

• access by index – zero based
  list4[1]     list4[1][2]
   [3,4,5]        5
Dictionaries
• unordered collection of arbitrary objects
   d = {1:‟foo‟, 2:‟bar‟}
• key/value pairs – think hash/lookup table (keys
  don’t have to be numbers)
   d.keys()       d.values()
   [1, 2]         [„foo‟,‟bar‟]
• nestable, mutable
   d[3] = „spam‟         del d[key]
• access by key, not offset
   d[2]   >> „bar‟
Dictionaries
• iterable
  d.iteritems()
  <dictionary-itemiterator object at
  0x1D2D8330>

  for k, v in d.iteritems():
     print k, v
  ...
  1   foo
  2   bar
Tuples
•   ordered collection of arbitrary objects
•   immutable – cannot add, remove, find
•   access by offset
•   basically an unchangeable list
    (1,2,‟three‟,4,…)
• so what’s the purpose?
    – FAST – great for iterating over constant set of
      values
    – SAFE – you can’t change it
List comprehensions
• Map one list to another by applying a function
  to each of the list elements
• Original list goes unchanged
   L =   [2,4,6,8]
   J =   [elem * 2 for elem in L]
   >>>   J
   [4,   8, 12, 16]
Sets
• unordered collections of objects
• like mathematical sets – collection of distinct
  objects – NO DUPLICATES
• example – get rid of dups in a list via list comp
   L1=[2,2,3,4,5,5,3]
   L2=[]
   [L2.append(x) for x in L1 if x not in L2]
   >>> L2
   [2, 3, 4, 5]
Sets
• get rid of dups via set:
   >>> L1=[2,2,3,4,5,5,3]
   >>> set(L1)
   set([2, 3, 4, 5])
   >>>
   L1 = list(set(L1))
   >>>
   >>> L1
   [2, 3, 4, 5]

• union:
   >>>   L2 = [4,5,6,7]
   >>>   L1 + L2
   [2,   3, 4, 5, 4, 5, 6, 7]
   >>>
   >>>   list(set(L1).union(set(L2)))
   [2,   3, 4, 5, 6, 7]
Sets
   >>>   L1
   [2,   2, 3, 4, 5, 5, 3]
   >>>   L2
   [4,   5, 6, 7]

• intersection – data are the same
   >>> set(L1).intersection(set(L2))
   set([4, 5])
   >>>
• symmetrical difference – data are not the same
   >>> set(L1).symmetric_difference(set(L2))
   set([2, 3, 6, 7])

• difference – data in first set but not second
   >>> set(L1).difference(set(L2))
   set([2, 3])
   >>> set(L2).difference(set(L1))
   set([6, 7])
Programming paradigms:
            big blob of code
•   OK on a small scale for GP scripts
•   gets out of hand quickly
•   hard to follow
•   think ModelBuilder-exported code
Programming paradigms:
        procedural programming
• basically a list of instructions
• program is built from one or more procedures
  (functions) – reusable chunks
• procedures called at anytime, anywhere in
  program
• focus is to break task into collection of variables,
  data structures, subroutines
• natural style, easy to understand
• strict separation between code and data
Functions
• portion of code within a larger program that
  performs a specific task
• can be called anytime, anyplace
• can accept arguments
                               >>> def foo(bar):
• should return a value        ...    print bar
                               ...
• keeps code neat              >>> foo(“yo”)
• promotes smooth flow         yo
Functions
import arcpy

def get_raster_props(in_raster):
    """Get properties of a raster, return as dict"""
    # Cast input layer to a Raster
    r = arcpy.Raster(in_raster)
    raster_props = {} # Create empty dictionary to put props in below
    raster_props["x_center"] = r.extent.XMin + (r.extent.XMax - r.extent.
    raster_props["y_center"] = r.extent.YMin + (r.extent.YMax - r.extent.
    raster_props["max_elev"] = r.maximum
    raster_props["min_elev"] = r.minimum
    raster_props["no_data"] = r.noDataValue
    raster_props["terr_width"] = r.width
    raster_props["terr_height"] = r.height
    raster_props["terr_cell_res"] = r.meanCellHeight
    # Return the dictionary of properties
    return raster_props
Programming paradigms:
                Procedural example
import arcpy

def add_field(in_fc="Magic.gdb/Fields",
              in_fields=[("Distance", "Float", "0"),
                         ("Name",     "Text",   50)]):
    """Add fields to FC"""
    for in_field in in_fields:
        if in_field[1] == 'Text':
            arcpy.AddField_management(in_fc,in_field[0],in_field[1],"#
                        "#",in_field[2],"#","NULLABLE","NON_REQUIRED",
        else:
            arcpy.AddField_management(in_fc,in_field[0],in_field[1],"#
                        "#","#","#","NULLABLE","NON_REQUIRED","#")

add_field()
Programming paradigms:
 Object-oriented programming (OOP)
• break program down into data types (classes)
  that associate behavior (methods) with data
  (members or attributes)
• code becomes more abstract
• data and functions for dealing with it are
  bound together in one object
Programming paradigms:
Object-oriented programming (OOP)
      import arcpy

      class Fields(object):
          """Class for working with fields"""
          # __init__ --> method signature
          def __init__(self,
                       in_fc="Magic.gdb/Fields",
                       in_fields=[("Distance", "Float", "0"),
                                  ("Name",     "Text",   50)]):
              self.in_fc = in_fc
              self.in_fields = in_fields

         def add_field(self):
             """Add fields to FC"""
             for in_field in self.in_fields:
                 if in_field[1] == "Text":
                     arcpy.AddField_management(self.in_fc, in_field[0],
                                               in_field[1], "#", "#",
                                               in_field[2], "#", "NULLABLE",
                                               "NON_REQUIRED", "#")
                 else:
                     arcpy.AddField_management(self.in_fc, in_field[0],
                                               in_field[1], "#", "#", "#",
                                               "#", "NULLABLE", "NON_REQUIRED", "#")

      if __name__ == "__main__":
          # Instantiate the Fields class
          f = Fields()
          # Call the add_field method
          f.add_field()
          print f.in_fields
          print f.in_fc
Programming paradigms:
 Object-oriented programming (OOP)
• objects let you wrap complex processes, but
  present a simple interface to them
• methods and attributes are encapsulated
  inside the object
• methods and attributes are exposed to users
• you can then update the object without
  breaking the interface
• you can pass objects around - carefully
Programming paradigms:
           OOP - Inheritance
• classes can inherit attributes and methods
• allows you to reuse and customize existing
  code inside a new class
• you can override methods
• you can add new methods to a class without
  modifying the existing class
import arcpy

                         class Fields(object):
                             """Class for working with fields"""
Programming paradigms:       def __init__(self,
                                          in_fc="Magic.gdb/Fields",
                                          in_fields=[("Distance", "Float", "0"),
                                                     ("Name",     "Text",   50)]):
                                 self.in_fc = in_fc
   OOP - Inheritance             self.in_fields = in_fields

                            def add_field(self):
                                """Add fields to FC"""
                                for in_field in self.in_fields:
                                    if in_field[1] == "Text":
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#",
                                                                  in_field[2], "#", "NULLABLE",
                                                                  "NON_REQUIRED", "#")
                                    else:
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#", "#",
                                                                  "#", "NULLABLE", "NON_REQUIRED", "#")

                         class MyFields(Fields):
                             """Customized fields class"""
                             def add_field(self):
                                 """Add fields to FC"""
                                 for in_field in self.in_fields:
                                     # Test to see if in_field exists already in featureclass
                                     if in_field[0] in [f.name for f in arcpy.ListFields(self.in_fc)]:
                                         # If field exists, delete it
                                         arcpy.DeleteField_management(self.in_fc, in_field[0])
                                         print in_field[0], "deleted"

                                    if in_field[1] == "Text":
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#",
                                                                  in_field[2], "#", "NULLABLE",
                                                                  "NON_REQUIRED", "#")
                                    else:
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#", "#",
                                                                  "#", "NULLABLE", "NON_REQUIRED", "#")

                         if __name__ == "__main__":
                             # Instantiate MyFields class, which in inherits the Fields class
                             f = MyFields()
                             # Call add_field method
                             f.add_field()
import arcpy

                         class Fields(object):
                             """Class for working with fields"""
                             def __init__(self,
                                          in_fc="Magic.gdb/Fields",
Programming paradigms:                    in_fields=[("Distance", "Float", "0"),
                                                     ("Name",     "Text",   50)]):
                                 self.in_fc = in_fc
                                 self.in_fields = in_fields

                            def add_field(self):
                                """Add fields to FC"""
   OOP - Inheritance
                                for in_field in self.in_fields:
                                    if in_field[1] == "Text":
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#",
                                                                  in_field[2], "#", "NULLABLE",
                                                                  "NON_REQUIRED", "#")
                                    else:
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#", "#",
                                                                  "#", "NULLABLE", "NON_REQUIRED", "#")
                            def get_field_props(self):
                                desc = arcpy.Describe(self.in_fc)
                                for field in desc.fields:
                                    print field.name, "-->", field.type

                         class MyFields(Fields):
                             """Customized fields class"""
                             def add_field(self):
                                 """Add fields to FC"""
                                 for in_field in self.in_fields:
                                     if in_field[0] in [f.name for f in arcpy.ListFields(self.in_fc)]:
                                         arcpy.DeleteField_management(self.in_fc, in_field[0])
                                         print in_field[0], "deleted"

                                    if in_field[1] == "Text":
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#",
                                                                  in_field[2], "#", "NULLABLE",
                                                                  "NON_REQUIRED", "#")
                                    else:
                                        arcpy.AddField_management(self.in_fc, in_field[0],
                                                                  in_field[1], "#", "#", "#",
                                                                  "#", "NULLABLE", "NON_REQUIRED", "#")

                         if __name__ == "__main__":
                             # Instantiate MyFields class
                             f = MyFields()
                             # Call add_field method
                             f.add_field()
                             print f.in_fields
                             # See, we really do inherit everything from the Fields class
                             f.get_field_props()
Modularizing code
• I’m lazy, so I want to reuse code
• import statement – call functionality in
  another module
• Have one custom module (a .py file) with code
  you use all the time
• Great way to package up helper functions
• ESRI does this with ConversionUtils.py
  C:Program Files (x86)ArcGISServer10.0ArcToolBoxScripts
Geometries
• heirarchy:
  – feature class is made of features
  – feature is made of parts
  – part is made of points
• heirarchy in Pythonic terms:
  – part: [[pnt, pnt, pnt, ...]]
  – multipart polygon: [[pnt, pnt, pnt, ...],
                            [pnt, pnt, pnt, ...]]
  – single part polygon with hole:
    [[pnt, pnt, pnt,         ,pnt, pnt, pnt]]
Reading geometry
• accessed through the geometry object of a
  feature
• example: describe_geometry_arcmap.py
1.open up          import arcpy
                   desc =
  SearchCursor     arcpy.Describe("Points")
2.loop through     sfn = desc.ShapeFieldName
  rows             rows =
                   arcpy.SearchCursor("Points"
3.get geometry     )
4.print out X, Y   for row in rows:
                       geom =
                   row.getValue(sfn)
Reading geometry
import arcpy

desc =
arcpy.Describe("Points")
sfn = desc.ShapeFieldName
rows =
arcpy.SearchCursor("Points"
)
for row in rows:
    geom =
row.getValue(sfn)
    pnt = geom.getPart()
    print pnt.X, pnt.Y
import arcpy

                   infc = "Magic.gdb/Polygons"

                   # Identify the geometry field
Reading geometry
                   desc = arcpy.Describe(infc)
                   shapefieldname = desc.ShapeFieldName
                   # Create search cursor
                   rows = arcpy.SearchCursor(infc)

                   # Enter for loop for each feature/row
                   for row in rows:
                       # Create the geometry object
                       feat = row.getValue(shapefieldname)
                       # Print the current multipoint's ID
                       print "Feature %i:" % row.getValue(desc.OIDFieldName)
                       partnum = 0
                       # Step through each part of the feature
                       for part in feat:
                           # Print the part number
                           print "Part %i:" % partnum
                           # Step through each vertex in the feature
                           for pnt in feat.getPart(partnum):
                               if pnt:
                                    # Print x,y coordinates of current point
                                    print pnt.X, pnt.Y
                               else:
                                    # If pnt is None, this represents an interior ring
                                    print "Interior Ring:"
                           partnum += 1
import arcpy

                   infc = "Magic.gdb/Polygons"
Reading geometry
                   desc = arcpy.Describe(infc)
                   shapefieldname = desc.ShapeFieldName

                   rows = arcpy.SearchCursor(infc)

                   for row in rows:
                       feat = row.getValue(shapefieldname)

                      print "tFeature %i:" % row.getValue(desc.OIDFieldName)
                      partnum = 0

                      for part in feat:
                          parts = []
                          print "Part %i:" % partnum

                          for pnt in feat.getPart(partnum):
                              if pnt:
                                  parts.append([pnt.X, pnt.Y])
                              else:
                                  parts.append(" ")
                          partnum += 1
                      print parts
Writing geometry
• arcpy.Point
• point features are point objects, lines and
  polygons are arrays of point objects
  – arcpy.PolyLine, arcpy.Polygon
• Geometry objects can be created using the
  Geometry, Mulitpoint, PointGeometry, Polygo
  n, or Polyline classes
data_list = [[33.09500,-93.90389],
                                [33.03194,-93.89806],
                                [34.34111,-93.50056],
                                [34.24917,-93.67667],
                                [34.22500,-93.89500],
                                [33.76833,-92.48500],
Writing geometry
                                [33.74500,-92.47667],
                                [33.68000,-92.46667],
                                [35.05425,-94.12711],
                                [35.03472,-94.12233],
                                [35.03333,-94.12236],
                                [35.01500,-94.12108],
                                [35.00392,-94.12033]]

                   import arcpy
                   import time
                   def PushNbiToFeatureclass( inFc, inList):
                       """ Take a list of NBI data and push it directly to a FGDB point FC """
                       try:
                            cur = arcpy.InsertCursor(inFc)
                            for line in inList:
                                t = 0
                                feat = cur.newRow()
                                feat.shape = arcpy.Point(line[1], line[0])
                                feat.setValue("Timestamp", time.strftime("%m/%d/%Y %H:%M:%S", time.localt
                                cur.insertRow(feat)
                            del cur
                       except Exception as e:
                            print e.message

                   PushNbiToFeatureclass(r”path to fc”, data_list)
import arcpy

                   arcpy.env.overwriteOutput = 1

                   # A list of features and coordinate pairs
                   coordList = [[[1,2], [2,4], [3,7]],
Writing geometry
                               [[6,8], [5,7], [7,2], [9,18]]]

                   # Create empty Point and Array objects
                   point = arcpy.Point()
                   array = arcpy.Array()
                   # A list that will hold each of the Polygon objects
                   featureList = []

                   for feature in coordList:
                       # For each coordinate pair, set the x,y properties and add to the
                       # Array object
                       for coordPair in feature:
                           point.X = coordPair[0]
                           point.Y = coordPair[1]
                           array.add(point)
                       # Add the first point of the array in to close off the polygon
                       array.add(array.getObject(0))
                       # Create a Polygon object based on the array of points
                       polygon = arcpy.Polygon(array)
                       # Clear the array for future use
                       array.removeAll()
                       # Append to the list of Polygon objects
                       featureList.append(polygon)

                   # Copy Polygon object to a featureclass
                   arcpy.CopyFeatures_management(featureList, "d:/temp/polygons.shp")
Rasters
• arcpy.Raster class
  – raster object: variable that references a raster
    dataset
  – gives access to raster props
• raster calculations – Map Algebra
  – outras = Slope(“in_raster”)
  – can cast to Raster object for calculations
Rasters
import arcpy

def get_raster_props(in_raster):
    """Get properties of a raster, return as dict"""
    # Cast input layer to a Raster
    r = arcpy.Raster(in_raster)
    raster_props = {} # Create empty dictionary to put props in below
    raster_props["x_center"] = r.extent.XMin + (r.extent.XMax - r.extent.
    raster_props["y_center"] = r.extent.YMin + (r.extent.YMax - r.extent.
    raster_props["max_elev"] = r.maximum
    raster_props["min_elev"] = r.minimum
    raster_props["no_data"] = r.noDataValue
    raster_props["terr_width"] = r.width
    raster_props["terr_height"] = r.height
    raster_props["terr_cell_res"] = r.meanCellHeight
    # Return the dictionary of properties
    return raster_props
Spatial references
• can get properties from arcpy.Describe
  >>> sr =
  arcpy.Describe(fc).spatialReference
  >>> sr.type
  u‟Projected‟ or u‟Geographic‟
• arcpy.SpatialReference class
  • methods to create/edit spatial refs
Spatial references
• arcpy.SpatialReference class
  • methods to create/edit spatial refs
 >>>   sr_utm = arcpy.SpatialReference()
 >>>   sr_utm.factoryCode = 26915
 >>>   sr_utm.create()
 >>>   sr_utm.name
 ...
Exception Handling
•   It’s necessary, stuff fails
•   Useful error reporting
•   Proper application cleanup
•   Combine it with logging
      try:
          do something...
      except:
          handle error...
      finally:
          clean up...
Exception handling – try/except
• most basic form of error handling
• wrap whole program or portions of code
• use optional finally clause for cleanup
  – close open files
  – close database connections
  – check extensions back in
Exception handling

import arcpy
try:
     arcpy.Buffer_analysis("Observer")
except Exception as e:
     print e.message
Exception handling
import arcpy

try:
    if arcpy.CheckExtension("3D") == "Available":
         arcpy.CheckOutExtension("3D")
         arcpy.Slope_3d("Magic.gdb/NWA10mNED",
"Magic.gdb/SlopeNWA")
except:
    print arcpy.GetMessages(2)
finally:
    # Check in the 3D Analyst extension
    arcpy.CheckInExtension("3D")
Exception handling - raise
• allows you to force an exception to occur
• can be used to alert of conditions
Exception handling - raise
import arcpy

class LicenseError(Exception):
    pass

try:
       if arcpy.CheckExtension("3D") == "Available":
           arcpy.CheckOutExtension("3D")
       else:
           raise LicenseError

    arcpy.Slope_3d("NWA10mNED", "SlopeNWA")
except LicenseError:
    print "3D Analyst license unavailable"
except:
    print arcpy.GetMessages(2)
finally:
    # Check in the 3D Analyst extension
    arcpy.CheckInExtension("3D")
Exception handling
         AddError and traceback
• AddError – returns GP-specific errors
• traceback – prints stack trace; determines
  precise location of error
  – good for larger, more complex programs
import arcpy
                         import sys
AddError and traceback   import traceback
 Exception handling –
                         arcpy.env.workspace = r"C:StudentCodeMAGIC.gdb"
                         try:
                             # Your code goes here
                             float("a string")

                         except:
                             # Get the traceback object
                             tb = sys.exc_info()[2]
                             tbinfo = traceback.format_tb(tb)[0]
                             # Concatenate information together concerning the error into a
                         message string
                             #   tbinfo: where error occurred
                             #   sys.exc_info: 3-tuple of type, value, traceback
                             pymsg = "PYTHON ERRORS:nTraceback info:n" + tbinfo + "nError
                         Info:n" + str(sys.exc_info()[1])
                             msgs = "ArcPy ERRORS:n" + arcpy.GetMessages(2) + "n"
                             # Return python error messages for use in script tool or Python
                         Window
                             arcpy.AddError(pymsg)
                             if arcpy.GetMessages(2):
                                 arcpy.AddError(msgs)
                                 print msgs
                             # Print Python error messages for use in Python / Python Window
                             print pymsg + "n"
Logging
• logging module
• logging levels:
  – DEBUG: detailed; for troubleshooting
  – INFO: normal operation, statuses
  – WARNING: still working, but unexpected behavior
  – ERROR: more serious, some function not working
  – CRITICAL: program cannot continue
Super-basic logging
import logging
logging.warning("Look out!")
logging.info("Does this print?")
Super-basic logging to a log file
import logging
logging.basicConfig(filename='log_example.l
og',
                    level=logging.DEBUG)
logging.debug('This message should get
logged')
logging.info('So should this')
logging.warning('And this, too')
Super-basic logging to a log file
import logging
logging.basicConfig(filename="log_example.log",level=logging.D
EBUG)
logging.debug("This message should go to the log file")
logging.info("So should this")
logging.warning("And this, too")
Meaningful logging
•   “customize” the logger
•   add in info-level message(s) to get logged
•   log our errors to log file
•   can get much more advanced, see the docs
import   arcpy
                     import   sys
                     import   traceback
                     import   logging
                     import   datetime

                     log_file = "meaningful_log_%s.log" % datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
Meaningful logging
                     arcpy.env.workspace = r"C:StudentCodeMAGIC.gdb"

                     # Setup logger
                     logging.basicConfig(level=logging.DEBUG,
                                         format='%(asctime)s %(levelname)-8s %(message)s',
                                         datefmt='%Y-%m-%d %H:%M:%S',
                                         filename=log_file,
                                         filemode='w')
                     logging.info(': START LOGGING')

                     try:
                         # Your code goes here
                         float("lfkjdlk")

                        logging.info(": DONE")

                     except:
                         # Get the traceback object
                         tb = sys.exc_info()[2]
                         tbinfo = traceback.format_tb(tb)[0]
                         # Concatenate information together concerning the error into a message string
                         #   tbinfo: where error occurred
                         #   sys.exc_info: 3-tuple of type, value, traceback
                         pymsg = "PYTHON ERRORS:nTraceback info:n" + tbinfo + "nError Info:n" + str(sys.exc_info()[1])
                         msgs = "ArcPy ERRORS:n" + arcpy.GetMessages(2) + "n"
                         # Return python error messages for use in script tool or Python Window
                         arcpy.AddError(pymsg)
                         if arcpy.GetMessages(2):
                             arcpy.AddError(msgs)
                             logging.error(": %s" % msgs)
                         # Log Python error messages for use in Python / Python Window
                         logging.error(": %s" % pymsg + "n")
Meaningful logging
Code documentation
•   Pythonic standards covered in PEPs 8 and 257
•   help()
•   comments need to be worth it
•   name items well
•   be precise and compact
•   comments may be for you
Creating documentation
• pydoc – built-in; used by help()
  – generate HTML on any module
  – kinda plain
• epydoc – old, rumored to be dead
  – produces nicely formatted HTML
  – easy to install and use
• Sphinx framework
  – “intelligent and beautiful documentation”
  – all the cool kids are using it (docs.python.org)
  – more involved to setup and use
Branching out
Installing packages
Installing packages (on Windows)
• Windows executables
• Python eggs
  – .zip file with metadata, renamed .egg
  – distributes code as a bundle
  – need easy_install
• pip
  – tool for installing and managing Python packages
  – replacement for easy_install
pip
C:pip search “kml”

C:pip install BeautifulSoup

C:pip install –upgrade pykml

C:pip uninstall BeautifulSoup

• can take care of dependencies for you
• uninstallation!
• install via easy_install, ironically
virtualenv
• a tool to create isolated Python environments
• manage dependencies on a per-project basis,
  rather than globally installing
• test modules without installing into site-
  packages
• avoid unintentional upgrades
virtualenv
• install via pip, easy_install, or by
    C:python virtualenv.py
• create the env
    C:dir virtualenv <env>
• activate the env
    C:dir<env>Scripts activate
• use the env
    (<env>) C:dir<env>Scriptspython
    >>>
virtualenv
• installs Python where you tell it, modifies
  system path to point there
  – good only while the env is activated
• use yolk to list installed packages in env
    (test) C:dir> yolk -l

• But can this work in ArcMap Python prompt?
virtualenv
• YES, with a little work...
>>>
execfile(r'C:<env>Scriptsactivate_this.py'
, {'__file__':
• tells ArcMap to use Python interpreter in
r'C:<env>Scriptsactivate_this.py'}) our
  virtualenv
   – kill ArcMap, back to using default interpreter
The web
• Infinite source of information
• Right-click and “Save as” is so lame (and too
  much work)
• Python can help you exploit the web
  – ftplib, http (urllib), mechanize, scraping (Beautiful
    Soup), send email (smtplib)
Fetching data
• Built-in libraries for ftp and http
• ftplib – log in, nav to directory, retrieve files
• urllib/urllib2 – pass in the url you want, get it
  back
• wget – GNU commandline tool
   – Can call with os.system()
Fetching data
import urllib
urllib.urlretrieve("http://www.fhwa.dot.gov/bridge/nbi/2011/RI
11.txt",
                   "C:/temp/RI11.txt")
Scraping
• Scrape data from a web page
• Well-structured content is a HUGE help, as is
  valid markup, which isn’t always there
• BeautifulSoup 3rd party module
  – Built in methods and regex’s help out
  – Great for getting at tables of data
Scraping addresses
http://www.phillypal.com/pal_locations.php
Scraping addresses
import BeautifulSoup as bs
import urllib2

url = "http://www.phillypal.com/pal_locations.php"

# Open the URL
response = urllib2.urlopen(url)
# Slurp all the HTML code into memory
html = response.read()
# Feed it into BS parser
soup = bs.BeautifulSoup(html)
# Find all the table cells whose width=37%
addresses = soup.findAll("td", {"width":"37%"})

print len(addresses)

for address in addresses:
    # Print out just the text
    print address.find(text=True)
Scraping addresses
   1845 N. 23rd Street, 19121
   3301 Tasker Street, 19145
   5801 Media Street, 19131
   250 S. 63rd Street, 19139
   732 N. 17th Street, 19130
   631 Snyder Avenue, 19148
   6901 Rising Sun Avenue, 19111
   851 E. Tioga Street, 19134
   720 W. Cumberland St., 19133
   3890 N. 10th Street, 19140
   4550 Haverford Avenue, 19139
   1100 W. Rockland St., 19141
   1500 W. Ontario Street, 19140
   2423 N. 27th Street, 19132
   1267 E. Cheltenham Ave., 24
   5330 Germantown Ave., 19144
   1599 Wharton Street, 19146
   4253 Frankford Avenue, 19124
   2524 E. Clearfield St., 19134
   6300 Garnet Street, 19126
   5900 Elmwood Street, 19143
   4301 Wayne Avenue, 19140
   4401 Aldine Street, 19136
   4614 Woodland Avenue, 19143
   4419 Comly Street, 19135
   2251 N. 54th Street, 19131
Emailing
• smtp built-in library
• best if you have IP of your email server
• port blocking can be an issue
   import smtplib
   server = smtplib.SMTP(email_server_ip)
   msg = „All TPS reports need new cover
  sheets‟
   server.sendmail('from@me.com',
                   'to@you.com',
                    msg)
   server.quit()
• there’s always Gmail too…
Files
• built in open function – slurp entire file into
  memory – OK except for huge files
        data = open(file).read().splitlines()

• iterate over the lines
        for line in data:
          do something

• CSV module
        reader =
  csv.reader(open('C:/file.csv','rb'))
        for line in reader:
            do something
Excel
• love, hate, love
• many modules out there
  – xlrd (read) / xlwt (write) – only .xls
  – openPyXL – read/write .xlsx
• uses
  – Push text data to Excel file
  – Push featureclass data to Excel programmatically
  – Read someone else’s “database”
Reading Excel
import xlrd

# Open the workbook
wb = xlrd.open_workbook('Employees.xls')
wb.sheet_names()

# Get first sheet
sh=wb.sheet_by_index(0)
# Print out the rows
for row in range(sh.nrows):
     print sh.row_values(row)

# Get a single cell
cell_b2 = sh.cell(1,1).value
print "n", cell_b2
# Write an XLS file with a single worksheet, containing
                # a heading row and some rows of data.

                import   xlwt
                import   datetime
                import   bs_scrape as bs
                import   nbi_data_processing as nbi
                ezxf =   xlwt.easyxf

                def write_xls(file_name, sheet_name, headings, data, heading_xf, data_xfs):
                    book = xlwt.Workbook()
                    sheet = book.add_sheet(sheet_name)
                    rowx = 0
                    for colx, value in enumerate(headings):
Writing Excel

                        sheet.write(rowx, colx, value, heading_xf)
                    sheet.set_panes_frozen(True) # frozen headings instead of split panes
                    sheet.set_horz_split_pos(rowx+1) # in general, freeze after last heading row
                    sheet.set_remove_splits(True) # if user does unfreeze, don"t leave a split there
                    for row in data:
                        rowx += 1
                        for colx, value in enumerate(row):
                            sheet.write(rowx, colx, value, data_xfs[colx])
                    book.save(file_name)

                if __name__ == "__main__":
                    import sys

                   files = ["RI","HI"]
                   all_data = []
                   stateDict = bs.FetchFipsCodes( )
                   for f in files:
                       k = nbi.ParseNbiFile('C:/student/inputs/' + f + '11.txt', stateDict )
                       all_data.extend(k)
                   hdngs = ["Structure","State","Facility carried","Lat","Lon","Year built"]
                   kinds = "text text text double double yr".split()
                   data = []
                   for each_row in all_data:
                       data.extend([each_row])
                   # Format the headers
                   heading_xf = ezxf("font: bold on; align: wrap on, vert centre, horiz center")
                   # Set the data type formats
                   kind_to_xf_map = {
                       "date": ezxf(num_format_str="yyyy-mm-dd"),
                       "int": ezxf(num_format_str="#,##0"),
                       "money": ezxf("font: italic on; pattern: pattern solid, fore-colour grey25",
                           num_format_str="$#,##0.00"),
                       "price": ezxf(num_format_str="#0.000000"),
                       "double":ezxf(num_format_str="00.00000"),
                       "text": ezxf(),
                       "yr": ezxf(num_format_str="0000")
                       }
                   data_xfs = [kind_to_xf_map[k] for k in kinds]
                   write_xls("NBI_Data_To_Excel.xls", "NBI", hdngs, data, heading_xf, data_xfs)
Writing Excel
Databases
•   You can connect to pretty much ANY database
•   Is there one true solution??
•   pyodbc – Access, SQL Server, MySQL
•   Oracle – cx_Oracle
•   Others – pymssql, _mssql, MySQLdb
•   Execute SQL statements through a connection
     conn = library.connect(driver/user/pwd)
     cursor = conn.cursor()
     for row in cursor.execute(sql)
        do something
Resources - FREE
•   Dive into Python
•   Python Cookbook
•   Think Python
•   Python docs
•   gis.stackexchange.com
•   Google is your friend (as always)
•   Python community is HUGE and GIVING
Conferences
• pyArkansas – annually in Conway
  – pyar2 list on python.org
• PyCon – THE national US Python conference
• FOSS4G – international open source for GIS
• ESRI Developer Summit – major dork-fest, but
  great learning opportunity and Palm Springs in
  March
IDEs and editors
•   Wing – different license levels, good people
•   PyScripter – open source, code completion
•   Komodo – free version also available
•   Notepad2 – ole’ standby editor
•   Notepad++ - people swear by it
•   PythonWin – another standby, but barebones
•   …dozens (at least) more editors out there…
More reading
• http://www.voidspace.org.uk/python/articles/
  OOP.shtml - great OOP article (which I used a
  a lot)
Advanced geoprocessing with Python

Mais conteúdo relacionado

Mais procurados

Pa1 session 3_slides
Pa1 session 3_slidesPa1 session 3_slides
Pa1 session 3_slidesaiclub_slides
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge O T
 
Learn python - for beginners - part-2
Learn python - for beginners - part-2Learn python - for beginners - part-2
Learn python - for beginners - part-2RajKumar Rampelli
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programaciónSoftware Guru
 
Python Workshop Part 2. LUG Maniapl
Python Workshop Part 2. LUG ManiaplPython Workshop Part 2. LUG Maniapl
Python Workshop Part 2. LUG ManiaplAnkur Shrivastava
 
Dynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship groupDynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship groupReuven Lerner
 
Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwoEishay Smith
 
Marc’s (bio)perl course
Marc’s (bio)perl courseMarc’s (bio)perl course
Marc’s (bio)perl courseMarc Logghe
 
Python Datatypes by SujithKumar
Python Datatypes by SujithKumarPython Datatypes by SujithKumar
Python Datatypes by SujithKumarSujith Kumar
 
Datastructures in python
Datastructures in pythonDatastructures in python
Datastructures in pythonhydpy
 

Mais procurados (18)

Pa1 session 3_slides
Pa1 session 3_slidesPa1 session 3_slides
Pa1 session 3_slides
 
Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge Beginners python cheat sheet - Basic knowledge
Beginners python cheat sheet - Basic knowledge
 
1. python
1. python1. python
1. python
 
Learn python - for beginners - part-2
Learn python - for beginners - part-2Learn python - for beginners - part-2
Learn python - for beginners - part-2
 
Scala - en bedre Java?
Scala - en bedre Java?Scala - en bedre Java?
Scala - en bedre Java?
 
Ejercicios de estilo en la programación
Ejercicios de estilo en la programaciónEjercicios de estilo en la programación
Ejercicios de estilo en la programación
 
P3 2017 python_regexes
P3 2017 python_regexesP3 2017 python_regexes
P3 2017 python_regexes
 
20170509 rand db_lesugent
20170509 rand db_lesugent20170509 rand db_lesugent
20170509 rand db_lesugent
 
Python Workshop Part 2. LUG Maniapl
Python Workshop Part 2. LUG ManiaplPython Workshop Part 2. LUG Maniapl
Python Workshop Part 2. LUG Maniapl
 
Spsl v unit - final
Spsl v unit - finalSpsl v unit - final
Spsl v unit - final
 
Python: Basic Inheritance
Python: Basic InheritancePython: Basic Inheritance
Python: Basic Inheritance
 
Dynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship groupDynamic languages, for software craftmanship group
Dynamic languages, for software craftmanship group
 
Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwo
 
Meet scala
Meet scalaMeet scala
Meet scala
 
Marc’s (bio)perl course
Marc’s (bio)perl courseMarc’s (bio)perl course
Marc’s (bio)perl course
 
Sparklyr
SparklyrSparklyr
Sparklyr
 
Python Datatypes by SujithKumar
Python Datatypes by SujithKumarPython Datatypes by SujithKumar
Python Datatypes by SujithKumar
 
Datastructures in python
Datastructures in pythonDatastructures in python
Datastructures in python
 

Semelhante a Advanced geoprocessing with Python

PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...Maulik Borsaniya
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 
An Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in PythonAn Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in Pythonyashar Aliabasi
 
Object.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examplesObject.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examplesRobert Lujo
 
R for Pirates. ESCCONF October 27, 2011
R for Pirates. ESCCONF October 27, 2011R for Pirates. ESCCONF October 27, 2011
R for Pirates. ESCCONF October 27, 2011Mandi Walls
 
Migrating from matlab to python
Migrating from matlab to pythonMigrating from matlab to python
Migrating from matlab to pythonActiveState
 
Scala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldWerner Hofstra
 
Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2Henry S
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingIstanbul Tech Talks
 
Functional Python Webinar from October 22nd, 2014
Functional Python Webinar from October 22nd, 2014Functional Python Webinar from October 22nd, 2014
Functional Python Webinar from October 22nd, 2014Reuven Lerner
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CAlexis Gallagher
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
 
The Fuss about || Haskell | Scala | F# ||
The Fuss about || Haskell | Scala | F# ||The Fuss about || Haskell | Scala | F# ||
The Fuss about || Haskell | Scala | F# ||Ashwin Rao
 
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Tomer Gabel
 
Programming with Python - Week 3
Programming with Python - Week 3Programming with Python - Week 3
Programming with Python - Week 3Ahmet Bulut
 
Python 101 language features and functional programming
Python 101 language features and functional programmingPython 101 language features and functional programming
Python 101 language features and functional programmingLukasz Dynowski
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovyIsuru Samaraweera
 

Semelhante a Advanced geoprocessing with Python (20)

PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
An Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in PythonAn Introduction to Tuple List Dictionary in Python
An Introduction to Tuple List Dictionary in Python
 
Object.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examplesObject.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examples
 
R for Pirates. ESCCONF October 27, 2011
R for Pirates. ESCCONF October 27, 2011R for Pirates. ESCCONF October 27, 2011
R for Pirates. ESCCONF October 27, 2011
 
Migrating from matlab to python
Migrating from matlab to pythonMigrating from matlab to python
Migrating from matlab to python
 
Scala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereld
 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
 
Python: The Dynamic!
Python: The Dynamic!Python: The Dynamic!
Python: The Dynamic!
 
Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2Code for Startup MVP (Ruby on Rails) Session 2
Code for Startup MVP (Ruby on Rails) Session 2
 
ITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingITT 2015 - Saul Mora - Object Oriented Function Programming
ITT 2015 - Saul Mora - Object Oriented Function Programming
 
Functional Python Webinar from October 22nd, 2014
Functional Python Webinar from October 22nd, 2014Functional Python Webinar from October 22nd, 2014
Functional Python Webinar from October 22nd, 2014
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-C
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
The Fuss about || Haskell | Scala | F# ||
The Fuss about || Haskell | Scala | F# ||The Fuss about || Haskell | Scala | F# ||
The Fuss about || Haskell | Scala | F# ||
 
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)
 
Programming with Python - Week 3
Programming with Python - Week 3Programming with Python - Week 3
Programming with Python - Week 3
 
Python 101 language features and functional programming
Python 101 language features and functional programmingPython 101 language features and functional programming
Python 101 language features and functional programming
 
Introductionto fp with groovy
Introductionto fp with groovyIntroductionto fp with groovy
Introductionto fp with groovy
 

Mais de Chad Cooper

VIESORE - Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE - Visual Impact Evaluation System for Offshore Renewable EnergyVIESORE - Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE - Visual Impact Evaluation System for Offshore Renewable EnergyChad Cooper
 
Implementation of a geographic information systems (GIS)-based system to eval...
Implementation of a geographic information systems (GIS)-based system to eval...Implementation of a geographic information systems (GIS)-based system to eval...
Implementation of a geographic information systems (GIS)-based system to eval...Chad Cooper
 
VIESORE: Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE: Visual Impact Evaluation System for Offshore Renewable EnergyVIESORE: Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE: Visual Impact Evaluation System for Offshore Renewable EnergyChad Cooper
 
Reading and writing spatial data for the non-spatial programmer
Reading and writing spatial data for the non-spatial programmerReading and writing spatial data for the non-spatial programmer
Reading and writing spatial data for the non-spatial programmerChad Cooper
 
IPAS: An ArcGIS Server-based framework for oil and gas E and P decision support
IPAS: An ArcGIS Server-based framework for oil and gas E and P decision supportIPAS: An ArcGIS Server-based framework for oil and gas E and P decision support
IPAS: An ArcGIS Server-based framework for oil and gas E and P decision supportChad Cooper
 
Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...
Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...
Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...Chad Cooper
 
Python And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And PythonwinPython And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And PythonwinChad Cooper
 

Mais de Chad Cooper (7)

VIESORE - Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE - Visual Impact Evaluation System for Offshore Renewable EnergyVIESORE - Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE - Visual Impact Evaluation System for Offshore Renewable Energy
 
Implementation of a geographic information systems (GIS)-based system to eval...
Implementation of a geographic information systems (GIS)-based system to eval...Implementation of a geographic information systems (GIS)-based system to eval...
Implementation of a geographic information systems (GIS)-based system to eval...
 
VIESORE: Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE: Visual Impact Evaluation System for Offshore Renewable EnergyVIESORE: Visual Impact Evaluation System for Offshore Renewable Energy
VIESORE: Visual Impact Evaluation System for Offshore Renewable Energy
 
Reading and writing spatial data for the non-spatial programmer
Reading and writing spatial data for the non-spatial programmerReading and writing spatial data for the non-spatial programmer
Reading and writing spatial data for the non-spatial programmer
 
IPAS: An ArcGIS Server-based framework for oil and gas E and P decision support
IPAS: An ArcGIS Server-based framework for oil and gas E and P decision supportIPAS: An ArcGIS Server-based framework for oil and gas E and P decision support
IPAS: An ArcGIS Server-based framework for oil and gas E and P decision support
 
Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...
Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...
Water resources and hydrochemistry of the Alluvial and Sparta aquifers of the...
 
Python And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And PythonwinPython And GIS - Beyond Modelbuilder And Pythonwin
Python And GIS - Beyond Modelbuilder And Pythonwin
 

Último

Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 

Último (20)

Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 

Advanced geoprocessing with Python

  • 1. Advanced geoprocessing with… MAGIC 2012 Chad Cooper – chad@cast.uark.edu Center for Advanced Spatial Technologies University of Arkansas, Fayetteville
  • 2. Intros • your name • what you do/where you work • used Python much? – any formal training? – what do you use it for? • know any other languages?
  • 3. Objectives • informal class – expect tangents – code as we go • not geared totally to ArcGIS • THINK – oddball and out of the ordinary applications will make you want more…
  • 4. Outline • data types review • documentation • functions • 3rd party modules • procedural vs. OOP • module installation • geometries • the web • rasters – fetching – scraping • spatial references – email • error – FTP handling/logging • files
  • 5. Strings • ordered collections of characters • immutable – can’t change it • raw strings: path = r”C:tempchad” • slicing fruit[0] „b‟ • indexing: fruit[1:3] >> „an‟ • iteration/membership: for each in fruit „f‟ in fruit
  • 6. Strings • string formatting: „a %s parrot‟ % „dead‟ „a dead parrot‟ • useful string formatting: import arcpy f = "string" arcpy.CalculateField_management(fc, “some_field", '"%s"' % f)
  • 7. Lists • list – ordered collection of arbitrary objects list1 = [0,1,2,3] list2 = ['zero','one','two','three'] list3 = [0,'zero',1,'one',2,'two',3,'three'] • ordered list2.sort() list2.sort(reverse=True) ['one','three',...] ['zero','two',...] • mutable – you can change it list1.append(4) list1.reverse() list2.insert(0,‟one-half‟) [0,1,2,3,4] [4,3,2,1,0] [„one-half‟,‟zero‟…] list2.extend([„four‟,‟five‟]) <- Extend concats lists
  • 8. Lists… • iterable – very important! for l in list3 0 zero ... • membership 3 in list3 --> True • nestable – 2D array/matrix list4 = [[0,1,2], [3,4,5], [6,7,8]] • access by index – zero based list4[1] list4[1][2] [3,4,5] 5
  • 9. Dictionaries • unordered collection of arbitrary objects d = {1:‟foo‟, 2:‟bar‟} • key/value pairs – think hash/lookup table (keys don’t have to be numbers) d.keys() d.values() [1, 2] [„foo‟,‟bar‟] • nestable, mutable d[3] = „spam‟ del d[key] • access by key, not offset d[2] >> „bar‟
  • 10. Dictionaries • iterable d.iteritems() <dictionary-itemiterator object at 0x1D2D8330> for k, v in d.iteritems(): print k, v ... 1 foo 2 bar
  • 11. Tuples • ordered collection of arbitrary objects • immutable – cannot add, remove, find • access by offset • basically an unchangeable list (1,2,‟three‟,4,…) • so what’s the purpose? – FAST – great for iterating over constant set of values – SAFE – you can’t change it
  • 12. List comprehensions • Map one list to another by applying a function to each of the list elements • Original list goes unchanged L = [2,4,6,8] J = [elem * 2 for elem in L] >>> J [4, 8, 12, 16]
  • 13. Sets • unordered collections of objects • like mathematical sets – collection of distinct objects – NO DUPLICATES • example – get rid of dups in a list via list comp L1=[2,2,3,4,5,5,3] L2=[] [L2.append(x) for x in L1 if x not in L2] >>> L2 [2, 3, 4, 5]
  • 14. Sets • get rid of dups via set: >>> L1=[2,2,3,4,5,5,3] >>> set(L1) set([2, 3, 4, 5]) >>> L1 = list(set(L1)) >>> >>> L1 [2, 3, 4, 5] • union: >>> L2 = [4,5,6,7] >>> L1 + L2 [2, 3, 4, 5, 4, 5, 6, 7] >>> >>> list(set(L1).union(set(L2))) [2, 3, 4, 5, 6, 7]
  • 15. Sets >>> L1 [2, 2, 3, 4, 5, 5, 3] >>> L2 [4, 5, 6, 7] • intersection – data are the same >>> set(L1).intersection(set(L2)) set([4, 5]) >>> • symmetrical difference – data are not the same >>> set(L1).symmetric_difference(set(L2)) set([2, 3, 6, 7]) • difference – data in first set but not second >>> set(L1).difference(set(L2)) set([2, 3]) >>> set(L2).difference(set(L1)) set([6, 7])
  • 16. Programming paradigms: big blob of code • OK on a small scale for GP scripts • gets out of hand quickly • hard to follow • think ModelBuilder-exported code
  • 17. Programming paradigms: procedural programming • basically a list of instructions • program is built from one or more procedures (functions) – reusable chunks • procedures called at anytime, anywhere in program • focus is to break task into collection of variables, data structures, subroutines • natural style, easy to understand • strict separation between code and data
  • 18. Functions • portion of code within a larger program that performs a specific task • can be called anytime, anyplace • can accept arguments >>> def foo(bar): • should return a value ... print bar ... • keeps code neat >>> foo(“yo”) • promotes smooth flow yo
  • 19. Functions import arcpy def get_raster_props(in_raster): """Get properties of a raster, return as dict""" # Cast input layer to a Raster r = arcpy.Raster(in_raster) raster_props = {} # Create empty dictionary to put props in below raster_props["x_center"] = r.extent.XMin + (r.extent.XMax - r.extent. raster_props["y_center"] = r.extent.YMin + (r.extent.YMax - r.extent. raster_props["max_elev"] = r.maximum raster_props["min_elev"] = r.minimum raster_props["no_data"] = r.noDataValue raster_props["terr_width"] = r.width raster_props["terr_height"] = r.height raster_props["terr_cell_res"] = r.meanCellHeight # Return the dictionary of properties return raster_props
  • 20. Programming paradigms: Procedural example import arcpy def add_field(in_fc="Magic.gdb/Fields", in_fields=[("Distance", "Float", "0"), ("Name", "Text", 50)]): """Add fields to FC""" for in_field in in_fields: if in_field[1] == 'Text': arcpy.AddField_management(in_fc,in_field[0],in_field[1],"# "#",in_field[2],"#","NULLABLE","NON_REQUIRED", else: arcpy.AddField_management(in_fc,in_field[0],in_field[1],"# "#","#","#","NULLABLE","NON_REQUIRED","#") add_field()
  • 21. Programming paradigms: Object-oriented programming (OOP) • break program down into data types (classes) that associate behavior (methods) with data (members or attributes) • code becomes more abstract • data and functions for dealing with it are bound together in one object
  • 22. Programming paradigms: Object-oriented programming (OOP) import arcpy class Fields(object): """Class for working with fields""" # __init__ --> method signature def __init__(self, in_fc="Magic.gdb/Fields", in_fields=[("Distance", "Float", "0"), ("Name", "Text", 50)]): self.in_fc = in_fc self.in_fields = in_fields def add_field(self): """Add fields to FC""" for in_field in self.in_fields: if in_field[1] == "Text": arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", in_field[2], "#", "NULLABLE", "NON_REQUIRED", "#") else: arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", "#", "#", "NULLABLE", "NON_REQUIRED", "#") if __name__ == "__main__": # Instantiate the Fields class f = Fields() # Call the add_field method f.add_field() print f.in_fields print f.in_fc
  • 23. Programming paradigms: Object-oriented programming (OOP) • objects let you wrap complex processes, but present a simple interface to them • methods and attributes are encapsulated inside the object • methods and attributes are exposed to users • you can then update the object without breaking the interface • you can pass objects around - carefully
  • 24. Programming paradigms: OOP - Inheritance • classes can inherit attributes and methods • allows you to reuse and customize existing code inside a new class • you can override methods • you can add new methods to a class without modifying the existing class
  • 25. import arcpy class Fields(object): """Class for working with fields""" Programming paradigms: def __init__(self, in_fc="Magic.gdb/Fields", in_fields=[("Distance", "Float", "0"), ("Name", "Text", 50)]): self.in_fc = in_fc OOP - Inheritance self.in_fields = in_fields def add_field(self): """Add fields to FC""" for in_field in self.in_fields: if in_field[1] == "Text": arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", in_field[2], "#", "NULLABLE", "NON_REQUIRED", "#") else: arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", "#", "#", "NULLABLE", "NON_REQUIRED", "#") class MyFields(Fields): """Customized fields class""" def add_field(self): """Add fields to FC""" for in_field in self.in_fields: # Test to see if in_field exists already in featureclass if in_field[0] in [f.name for f in arcpy.ListFields(self.in_fc)]: # If field exists, delete it arcpy.DeleteField_management(self.in_fc, in_field[0]) print in_field[0], "deleted" if in_field[1] == "Text": arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", in_field[2], "#", "NULLABLE", "NON_REQUIRED", "#") else: arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", "#", "#", "NULLABLE", "NON_REQUIRED", "#") if __name__ == "__main__": # Instantiate MyFields class, which in inherits the Fields class f = MyFields() # Call add_field method f.add_field()
  • 26. import arcpy class Fields(object): """Class for working with fields""" def __init__(self, in_fc="Magic.gdb/Fields", Programming paradigms: in_fields=[("Distance", "Float", "0"), ("Name", "Text", 50)]): self.in_fc = in_fc self.in_fields = in_fields def add_field(self): """Add fields to FC""" OOP - Inheritance for in_field in self.in_fields: if in_field[1] == "Text": arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", in_field[2], "#", "NULLABLE", "NON_REQUIRED", "#") else: arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", "#", "#", "NULLABLE", "NON_REQUIRED", "#") def get_field_props(self): desc = arcpy.Describe(self.in_fc) for field in desc.fields: print field.name, "-->", field.type class MyFields(Fields): """Customized fields class""" def add_field(self): """Add fields to FC""" for in_field in self.in_fields: if in_field[0] in [f.name for f in arcpy.ListFields(self.in_fc)]: arcpy.DeleteField_management(self.in_fc, in_field[0]) print in_field[0], "deleted" if in_field[1] == "Text": arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", in_field[2], "#", "NULLABLE", "NON_REQUIRED", "#") else: arcpy.AddField_management(self.in_fc, in_field[0], in_field[1], "#", "#", "#", "#", "NULLABLE", "NON_REQUIRED", "#") if __name__ == "__main__": # Instantiate MyFields class f = MyFields() # Call add_field method f.add_field() print f.in_fields # See, we really do inherit everything from the Fields class f.get_field_props()
  • 27. Modularizing code • I’m lazy, so I want to reuse code • import statement – call functionality in another module • Have one custom module (a .py file) with code you use all the time • Great way to package up helper functions • ESRI does this with ConversionUtils.py C:Program Files (x86)ArcGISServer10.0ArcToolBoxScripts
  • 28. Geometries • heirarchy: – feature class is made of features – feature is made of parts – part is made of points • heirarchy in Pythonic terms: – part: [[pnt, pnt, pnt, ...]] – multipart polygon: [[pnt, pnt, pnt, ...], [pnt, pnt, pnt, ...]] – single part polygon with hole: [[pnt, pnt, pnt, ,pnt, pnt, pnt]]
  • 29. Reading geometry • accessed through the geometry object of a feature • example: describe_geometry_arcmap.py 1.open up import arcpy desc = SearchCursor arcpy.Describe("Points") 2.loop through sfn = desc.ShapeFieldName rows rows = arcpy.SearchCursor("Points" 3.get geometry ) 4.print out X, Y for row in rows: geom = row.getValue(sfn)
  • 30. Reading geometry import arcpy desc = arcpy.Describe("Points") sfn = desc.ShapeFieldName rows = arcpy.SearchCursor("Points" ) for row in rows: geom = row.getValue(sfn) pnt = geom.getPart() print pnt.X, pnt.Y
  • 31. import arcpy infc = "Magic.gdb/Polygons" # Identify the geometry field Reading geometry desc = arcpy.Describe(infc) shapefieldname = desc.ShapeFieldName # Create search cursor rows = arcpy.SearchCursor(infc) # Enter for loop for each feature/row for row in rows: # Create the geometry object feat = row.getValue(shapefieldname) # Print the current multipoint's ID print "Feature %i:" % row.getValue(desc.OIDFieldName) partnum = 0 # Step through each part of the feature for part in feat: # Print the part number print "Part %i:" % partnum # Step through each vertex in the feature for pnt in feat.getPart(partnum): if pnt: # Print x,y coordinates of current point print pnt.X, pnt.Y else: # If pnt is None, this represents an interior ring print "Interior Ring:" partnum += 1
  • 32. import arcpy infc = "Magic.gdb/Polygons" Reading geometry desc = arcpy.Describe(infc) shapefieldname = desc.ShapeFieldName rows = arcpy.SearchCursor(infc) for row in rows: feat = row.getValue(shapefieldname) print "tFeature %i:" % row.getValue(desc.OIDFieldName) partnum = 0 for part in feat: parts = [] print "Part %i:" % partnum for pnt in feat.getPart(partnum): if pnt: parts.append([pnt.X, pnt.Y]) else: parts.append(" ") partnum += 1 print parts
  • 33. Writing geometry • arcpy.Point • point features are point objects, lines and polygons are arrays of point objects – arcpy.PolyLine, arcpy.Polygon • Geometry objects can be created using the Geometry, Mulitpoint, PointGeometry, Polygo n, or Polyline classes
  • 34. data_list = [[33.09500,-93.90389], [33.03194,-93.89806], [34.34111,-93.50056], [34.24917,-93.67667], [34.22500,-93.89500], [33.76833,-92.48500], Writing geometry [33.74500,-92.47667], [33.68000,-92.46667], [35.05425,-94.12711], [35.03472,-94.12233], [35.03333,-94.12236], [35.01500,-94.12108], [35.00392,-94.12033]] import arcpy import time def PushNbiToFeatureclass( inFc, inList): """ Take a list of NBI data and push it directly to a FGDB point FC """ try: cur = arcpy.InsertCursor(inFc) for line in inList: t = 0 feat = cur.newRow() feat.shape = arcpy.Point(line[1], line[0]) feat.setValue("Timestamp", time.strftime("%m/%d/%Y %H:%M:%S", time.localt cur.insertRow(feat) del cur except Exception as e: print e.message PushNbiToFeatureclass(r”path to fc”, data_list)
  • 35. import arcpy arcpy.env.overwriteOutput = 1 # A list of features and coordinate pairs coordList = [[[1,2], [2,4], [3,7]], Writing geometry [[6,8], [5,7], [7,2], [9,18]]] # Create empty Point and Array objects point = arcpy.Point() array = arcpy.Array() # A list that will hold each of the Polygon objects featureList = [] for feature in coordList: # For each coordinate pair, set the x,y properties and add to the # Array object for coordPair in feature: point.X = coordPair[0] point.Y = coordPair[1] array.add(point) # Add the first point of the array in to close off the polygon array.add(array.getObject(0)) # Create a Polygon object based on the array of points polygon = arcpy.Polygon(array) # Clear the array for future use array.removeAll() # Append to the list of Polygon objects featureList.append(polygon) # Copy Polygon object to a featureclass arcpy.CopyFeatures_management(featureList, "d:/temp/polygons.shp")
  • 36. Rasters • arcpy.Raster class – raster object: variable that references a raster dataset – gives access to raster props • raster calculations – Map Algebra – outras = Slope(“in_raster”) – can cast to Raster object for calculations
  • 37. Rasters import arcpy def get_raster_props(in_raster): """Get properties of a raster, return as dict""" # Cast input layer to a Raster r = arcpy.Raster(in_raster) raster_props = {} # Create empty dictionary to put props in below raster_props["x_center"] = r.extent.XMin + (r.extent.XMax - r.extent. raster_props["y_center"] = r.extent.YMin + (r.extent.YMax - r.extent. raster_props["max_elev"] = r.maximum raster_props["min_elev"] = r.minimum raster_props["no_data"] = r.noDataValue raster_props["terr_width"] = r.width raster_props["terr_height"] = r.height raster_props["terr_cell_res"] = r.meanCellHeight # Return the dictionary of properties return raster_props
  • 38. Spatial references • can get properties from arcpy.Describe >>> sr = arcpy.Describe(fc).spatialReference >>> sr.type u‟Projected‟ or u‟Geographic‟ • arcpy.SpatialReference class • methods to create/edit spatial refs
  • 39. Spatial references • arcpy.SpatialReference class • methods to create/edit spatial refs >>> sr_utm = arcpy.SpatialReference() >>> sr_utm.factoryCode = 26915 >>> sr_utm.create() >>> sr_utm.name ...
  • 40.
  • 41. Exception Handling • It’s necessary, stuff fails • Useful error reporting • Proper application cleanup • Combine it with logging try: do something... except: handle error... finally: clean up...
  • 42. Exception handling – try/except • most basic form of error handling • wrap whole program or portions of code • use optional finally clause for cleanup – close open files – close database connections – check extensions back in
  • 43. Exception handling import arcpy try: arcpy.Buffer_analysis("Observer") except Exception as e: print e.message
  • 44. Exception handling import arcpy try: if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") arcpy.Slope_3d("Magic.gdb/NWA10mNED", "Magic.gdb/SlopeNWA") except: print arcpy.GetMessages(2) finally: # Check in the 3D Analyst extension arcpy.CheckInExtension("3D")
  • 45. Exception handling - raise • allows you to force an exception to occur • can be used to alert of conditions
  • 46. Exception handling - raise import arcpy class LicenseError(Exception): pass try: if arcpy.CheckExtension("3D") == "Available": arcpy.CheckOutExtension("3D") else: raise LicenseError arcpy.Slope_3d("NWA10mNED", "SlopeNWA") except LicenseError: print "3D Analyst license unavailable" except: print arcpy.GetMessages(2) finally: # Check in the 3D Analyst extension arcpy.CheckInExtension("3D")
  • 47. Exception handling AddError and traceback • AddError – returns GP-specific errors • traceback – prints stack trace; determines precise location of error – good for larger, more complex programs
  • 48. import arcpy import sys AddError and traceback import traceback Exception handling – arcpy.env.workspace = r"C:StudentCodeMAGIC.gdb" try: # Your code goes here float("a string") except: # Get the traceback object tb = sys.exc_info()[2] tbinfo = traceback.format_tb(tb)[0] # Concatenate information together concerning the error into a message string # tbinfo: where error occurred # sys.exc_info: 3-tuple of type, value, traceback pymsg = "PYTHON ERRORS:nTraceback info:n" + tbinfo + "nError Info:n" + str(sys.exc_info()[1]) msgs = "ArcPy ERRORS:n" + arcpy.GetMessages(2) + "n" # Return python error messages for use in script tool or Python Window arcpy.AddError(pymsg) if arcpy.GetMessages(2): arcpy.AddError(msgs) print msgs # Print Python error messages for use in Python / Python Window print pymsg + "n"
  • 49. Logging • logging module • logging levels: – DEBUG: detailed; for troubleshooting – INFO: normal operation, statuses – WARNING: still working, but unexpected behavior – ERROR: more serious, some function not working – CRITICAL: program cannot continue
  • 50. Super-basic logging import logging logging.warning("Look out!") logging.info("Does this print?")
  • 51. Super-basic logging to a log file import logging logging.basicConfig(filename='log_example.l og', level=logging.DEBUG) logging.debug('This message should get logged') logging.info('So should this') logging.warning('And this, too')
  • 52. Super-basic logging to a log file import logging logging.basicConfig(filename="log_example.log",level=logging.D EBUG) logging.debug("This message should go to the log file") logging.info("So should this") logging.warning("And this, too")
  • 53. Meaningful logging • “customize” the logger • add in info-level message(s) to get logged • log our errors to log file • can get much more advanced, see the docs
  • 54. import arcpy import sys import traceback import logging import datetime log_file = "meaningful_log_%s.log" % datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S") Meaningful logging arcpy.env.workspace = r"C:StudentCodeMAGIC.gdb" # Setup logger logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=log_file, filemode='w') logging.info(': START LOGGING') try: # Your code goes here float("lfkjdlk") logging.info(": DONE") except: # Get the traceback object tb = sys.exc_info()[2] tbinfo = traceback.format_tb(tb)[0] # Concatenate information together concerning the error into a message string # tbinfo: where error occurred # sys.exc_info: 3-tuple of type, value, traceback pymsg = "PYTHON ERRORS:nTraceback info:n" + tbinfo + "nError Info:n" + str(sys.exc_info()[1]) msgs = "ArcPy ERRORS:n" + arcpy.GetMessages(2) + "n" # Return python error messages for use in script tool or Python Window arcpy.AddError(pymsg) if arcpy.GetMessages(2): arcpy.AddError(msgs) logging.error(": %s" % msgs) # Log Python error messages for use in Python / Python Window logging.error(": %s" % pymsg + "n")
  • 56. Code documentation • Pythonic standards covered in PEPs 8 and 257 • help() • comments need to be worth it • name items well • be precise and compact • comments may be for you
  • 57. Creating documentation • pydoc – built-in; used by help() – generate HTML on any module – kinda plain • epydoc – old, rumored to be dead – produces nicely formatted HTML – easy to install and use • Sphinx framework – “intelligent and beautiful documentation” – all the cool kids are using it (docs.python.org) – more involved to setup and use
  • 60. Installing packages (on Windows) • Windows executables • Python eggs – .zip file with metadata, renamed .egg – distributes code as a bundle – need easy_install • pip – tool for installing and managing Python packages – replacement for easy_install
  • 61. pip C:pip search “kml” C:pip install BeautifulSoup C:pip install –upgrade pykml C:pip uninstall BeautifulSoup • can take care of dependencies for you • uninstallation! • install via easy_install, ironically
  • 62. virtualenv • a tool to create isolated Python environments • manage dependencies on a per-project basis, rather than globally installing • test modules without installing into site- packages • avoid unintentional upgrades
  • 63. virtualenv • install via pip, easy_install, or by C:python virtualenv.py • create the env C:dir virtualenv <env> • activate the env C:dir<env>Scripts activate • use the env (<env>) C:dir<env>Scriptspython >>>
  • 64. virtualenv • installs Python where you tell it, modifies system path to point there – good only while the env is activated • use yolk to list installed packages in env (test) C:dir> yolk -l • But can this work in ArcMap Python prompt?
  • 65. virtualenv • YES, with a little work... >>> execfile(r'C:<env>Scriptsactivate_this.py' , {'__file__': • tells ArcMap to use Python interpreter in r'C:<env>Scriptsactivate_this.py'}) our virtualenv – kill ArcMap, back to using default interpreter
  • 66.
  • 67. The web • Infinite source of information • Right-click and “Save as” is so lame (and too much work) • Python can help you exploit the web – ftplib, http (urllib), mechanize, scraping (Beautiful Soup), send email (smtplib)
  • 68. Fetching data • Built-in libraries for ftp and http • ftplib – log in, nav to directory, retrieve files • urllib/urllib2 – pass in the url you want, get it back • wget – GNU commandline tool – Can call with os.system()
  • 70. Scraping • Scrape data from a web page • Well-structured content is a HUGE help, as is valid markup, which isn’t always there • BeautifulSoup 3rd party module – Built in methods and regex’s help out – Great for getting at tables of data
  • 72. Scraping addresses import BeautifulSoup as bs import urllib2 url = "http://www.phillypal.com/pal_locations.php" # Open the URL response = urllib2.urlopen(url) # Slurp all the HTML code into memory html = response.read() # Feed it into BS parser soup = bs.BeautifulSoup(html) # Find all the table cells whose width=37% addresses = soup.findAll("td", {"width":"37%"}) print len(addresses) for address in addresses: # Print out just the text print address.find(text=True)
  • 73. Scraping addresses 1845 N. 23rd Street, 19121 3301 Tasker Street, 19145 5801 Media Street, 19131 250 S. 63rd Street, 19139 732 N. 17th Street, 19130 631 Snyder Avenue, 19148 6901 Rising Sun Avenue, 19111 851 E. Tioga Street, 19134 720 W. Cumberland St., 19133 3890 N. 10th Street, 19140 4550 Haverford Avenue, 19139 1100 W. Rockland St., 19141 1500 W. Ontario Street, 19140 2423 N. 27th Street, 19132 1267 E. Cheltenham Ave., 24 5330 Germantown Ave., 19144 1599 Wharton Street, 19146 4253 Frankford Avenue, 19124 2524 E. Clearfield St., 19134 6300 Garnet Street, 19126 5900 Elmwood Street, 19143 4301 Wayne Avenue, 19140 4401 Aldine Street, 19136 4614 Woodland Avenue, 19143 4419 Comly Street, 19135 2251 N. 54th Street, 19131
  • 74. Emailing • smtp built-in library • best if you have IP of your email server • port blocking can be an issue import smtplib server = smtplib.SMTP(email_server_ip) msg = „All TPS reports need new cover sheets‟ server.sendmail('from@me.com', 'to@you.com', msg) server.quit() • there’s always Gmail too…
  • 75. Files • built in open function – slurp entire file into memory – OK except for huge files data = open(file).read().splitlines() • iterate over the lines for line in data: do something • CSV module reader = csv.reader(open('C:/file.csv','rb')) for line in reader: do something
  • 76.
  • 77. Excel • love, hate, love • many modules out there – xlrd (read) / xlwt (write) – only .xls – openPyXL – read/write .xlsx • uses – Push text data to Excel file – Push featureclass data to Excel programmatically – Read someone else’s “database”
  • 78. Reading Excel import xlrd # Open the workbook wb = xlrd.open_workbook('Employees.xls') wb.sheet_names() # Get first sheet sh=wb.sheet_by_index(0) # Print out the rows for row in range(sh.nrows): print sh.row_values(row) # Get a single cell cell_b2 = sh.cell(1,1).value print "n", cell_b2
  • 79. # Write an XLS file with a single worksheet, containing # a heading row and some rows of data. import xlwt import datetime import bs_scrape as bs import nbi_data_processing as nbi ezxf = xlwt.easyxf def write_xls(file_name, sheet_name, headings, data, heading_xf, data_xfs): book = xlwt.Workbook() sheet = book.add_sheet(sheet_name) rowx = 0 for colx, value in enumerate(headings): Writing Excel sheet.write(rowx, colx, value, heading_xf) sheet.set_panes_frozen(True) # frozen headings instead of split panes sheet.set_horz_split_pos(rowx+1) # in general, freeze after last heading row sheet.set_remove_splits(True) # if user does unfreeze, don"t leave a split there for row in data: rowx += 1 for colx, value in enumerate(row): sheet.write(rowx, colx, value, data_xfs[colx]) book.save(file_name) if __name__ == "__main__": import sys files = ["RI","HI"] all_data = [] stateDict = bs.FetchFipsCodes( ) for f in files: k = nbi.ParseNbiFile('C:/student/inputs/' + f + '11.txt', stateDict ) all_data.extend(k) hdngs = ["Structure","State","Facility carried","Lat","Lon","Year built"] kinds = "text text text double double yr".split() data = [] for each_row in all_data: data.extend([each_row]) # Format the headers heading_xf = ezxf("font: bold on; align: wrap on, vert centre, horiz center") # Set the data type formats kind_to_xf_map = { "date": ezxf(num_format_str="yyyy-mm-dd"), "int": ezxf(num_format_str="#,##0"), "money": ezxf("font: italic on; pattern: pattern solid, fore-colour grey25", num_format_str="$#,##0.00"), "price": ezxf(num_format_str="#0.000000"), "double":ezxf(num_format_str="00.00000"), "text": ezxf(), "yr": ezxf(num_format_str="0000") } data_xfs = [kind_to_xf_map[k] for k in kinds] write_xls("NBI_Data_To_Excel.xls", "NBI", hdngs, data, heading_xf, data_xfs)
  • 81. Databases • You can connect to pretty much ANY database • Is there one true solution?? • pyodbc – Access, SQL Server, MySQL • Oracle – cx_Oracle • Others – pymssql, _mssql, MySQLdb • Execute SQL statements through a connection conn = library.connect(driver/user/pwd) cursor = conn.cursor() for row in cursor.execute(sql) do something
  • 82. Resources - FREE • Dive into Python • Python Cookbook • Think Python • Python docs • gis.stackexchange.com • Google is your friend (as always) • Python community is HUGE and GIVING
  • 83. Conferences • pyArkansas – annually in Conway – pyar2 list on python.org • PyCon – THE national US Python conference • FOSS4G – international open source for GIS • ESRI Developer Summit – major dork-fest, but great learning opportunity and Palm Springs in March
  • 84. IDEs and editors • Wing – different license levels, good people • PyScripter – open source, code completion • Komodo – free version also available • Notepad2 – ole’ standby editor • Notepad++ - people swear by it • PythonWin – another standby, but barebones • …dozens (at least) more editors out there…
  • 85. More reading • http://www.voidspace.org.uk/python/articles/ OOP.shtml - great OOP article (which I used a a lot)

Notas do Editor

  1. __init__  method signature. Called when method is instantiated, which is done by calling the class. Class by itself is just a structure, instance of a class contains content. A class is like a form that everyone has to fill out – same type of form. But content of the form varies from person to person. Your copy of the form with your specific info is an instance of the form.self  a reference to the __init__ method. self lets you access __init__ object attributes. in Fields class, in_fc and in_fields are object attributes that get set when __init__ is called. That’s how we do print f.infields.The “functions” that are part of an object are called methods. The values are called attributes.
  2. __init__  method signature. Called when method is instantiated, which is done by calling the classself  a reference to the __init__ method. self lets you access __init__ object attributes. in Fields class, in_fc and in_fields are object attributes that get set when __init__ is called. That’s how we do print f.infields.The “functions” that are part of an object are called methods. The values are called attributes.
  3. Show how Data Management\\Raster\\Raster Properties\\Build Batch Pyramids uses ConversionUtils.py in C:\\Program Files (x86)\\ArcGIS\\Desktop10.0\\ArcToolbox\\Scripts
  4. Run: 1) describe_geometry_arcmap.py 2) describe_geometry_polygons.py 3) describe_geometry_polygons_2.py
  5. Run: 1) describe_geometry_arcmap.py 2) describe_geometry_polygons.py 3) describe_geometry_polygons_2.py
  6. Run: 1) describe_geometry_arcmap.py 2) describe_geometry_polygons.py 3) describe_geometry_polygons_2.py
  7. Run: 1) describe_geometry_arcmap.py 2) describe_geometry_polygons.py 3) describe_geometry_polygons_2.py
  8. Do nbi_list.txt exercise. The function call is PushNbiToFeatureclass(r”path to fc”, data_list)Do create_geometry_polygon.py. Run it, examine output, then mess around with the coordList.
  9. Run get_raster_props.py within arcmap Python console.d = get_raster_props(‘NWA10mNED’)# map keys to listl = [k for k in d.iterkeys()]# map values to listo = [v for v in d.itervalues()]# put into a tuplet = tuple(v for v in d.itervalues())===================================Raster calculations at ArcMap Python prompt:import arcpy.sa (explain about from arcpy.sa import * vs. import arcpy.sa)out_raster = arcpy.sa.IsNull(“NWA10mNED”)------------------------------------------------------------Look at arcpy.env settings -- in help under ArcPy site package &gt; Classes &gt; envarcpy.ListEnvironments()------------------------------------------------------Something really stupid like:out_raster_3 = arcpy.Raster(‘NWA10mNED’) * 10out_raster_3.save(path to Magic.gdb)--------------------------------------------------------outr_slope = arcpy.sa.Viewshed(“NWA10mNED”, “Observer”) ------------------------------------------------------------where are raster calcs stored? arcpy.env.scratchworkspace
  10. Example – get_raster_props.py used in ArcMap
  11. &gt;&gt;&gt; import arcpy&gt;&gt;&gt; sr = arcpy.Describe(&quot;KittyHawkClip&quot;).spatialReference&gt;&gt;&gt; sr.typeu&apos;Projected&apos;&gt;&gt;&gt; =======================================sr.factoryCodesr.GCSCode,sr.PCSCode, sr.name
  12. sr_utm.exportToString()sr3 = arcpy.SpatialReference()sr3.createFromFile(path to prj)sr3.namesr3.type
  13. Finally used to execute tasks that should be executed whether an exception has occurred or not.For finally test, change the second argument in Slope_3D call to a integer, it will bomb.
  14. Scenarios for error_handling_AddError_traceback.py:arcpy.GetCount_management(&quot;&quot;)x = &quot;a&quot; + 1float(&quot;a text string&quot;)
  15. Log files can save your hide.Console output is great when testing or developing code, but no good for production environments. Print statements are worthless.Go to docs.python.org/howto/logging.html (link in logging on slide) and look over “When to use logging”.
  16. Info doesn’t print because default level is warning, and info is lower level than warning.
  17. All print out since we explicitly set level to debug, the lowest level.
  18. arcpy.GetCount_management(&quot;&quot;)x = &quot;a&quot; + 1float(&quot;a text string&quot;)float(10) – will work and print out our info statement “DONE”logging_meaningful.py
  19. At command prompt:import oshelp(os.path.join)At ArcMap Python prompt:import arcpyhelp(arcpy.whatever) -- play around here====================================The purpose of commenting is to help the reader know as much as the writer did.
  20. PYDOCC:\\&gt; python –m pydoc sysat python prompt:import syshelp(sys)  same as pydoc callD:\\Projects\\Chad\\Training\\MAGIC\\Code&gt;python C:\\Python26\\ArcGIS10.0\\Lib\\pydoc.py –gD:\\Projects\\Chad\\Training\\MAGIC\\Code&gt;python C:\\Python26\\ArcGIS10.0\\Lib\\pydoc.py -w arcpyshow the Python docs for Sphinx example
  21. Browse packages | Topic | Scientific/Engineering | Topic | GIS
  22. Install and uninstall BeautifulSoup&gt;&gt; pip install BeautifulSoup&gt;&gt; pip uninstall BeautifulSoup
  23. nbi_url.txt&gt;&gt;&gt; import urllib&gt;&gt;&gt; urllib.urlretrieve(&quot;http://www.fhwa.dot.gov/bridge/nbi/2011/RI11.txt&quot;, &quot;C:/temp/RI11.txt&quot;)(&apos;C:/temp/RI11.txt&apos;, &lt;httplib.HTTPMessage instance at 0x286F9990&gt;)&gt;&gt;&gt;
  24. Students need BeautifulSoup.py module in same dir as their scripts.
  25. http://www.phillypal.com/pal_locations.phpInspect the address element in Chromescraping_philly_pals.py
  26. Love-hate relationship with Excel.
  27. Lots of talks by the big-hitters of Python