PYT:  how to set symbology on output feature class?

799
13
Jump to solution
01-17-2013 07:50 AM
KevinBell
Occasional Contributor III
Ok, I'm stumped (again!)...  If I comment out my output parameter this works great and I have point features in my FC, but I need set the output symbology with a lyr file.  If I keep the code the way it is the layer is added to the TOC, but no features are inserted to the FC. 

You can really ignore most of this and just know that after the insert cursor I have the expected data (gps points).

Any ideas?!!


import arcpy import re import os  class Toolbox(object):     def __init__(self):         """Define the toolbox (the name of the toolbox is the name of the         .pyt file)."""         self.label = "GPS Isolator"         self.alias = "GPS Isolator"          # List of tool classes associated with this toolbox         self.tools = [isolateGPS]   class isolateGPS(object):     def __init__(self):         """Define the tool (tool name is the name of the class)."""         self.label = "Get a track"         self.description = "this will pull out one officers gps track..."         self.canRunInBackground = True      def getParameterInfo(self):         """Define parameter definitions"""          unitid = arcpy.Parameter(                 displayName="Unit ID",                 name="unitId",                 datatype="String",                 parameterType="Required",                 direction="Input")                  theDate = arcpy.Parameter(             displayName="Date",             name="date",             datatype="Date",             parameterType="Required",             direction="Input")              #startTime = arcpy.Parameter(             #displayName="Start Time",             #name="starttime",             #datatype="Date",             #parameterType="Optional",             #direction="Input")             #endTime = arcpy.Parameter(             #displayName="End Time",             #name="endtime",             #datatype="Date",             #parameterType="Optional",             #direction="Input")       outdir = arcpy.Parameter(       displayName="Output Directory",       name="outDir",       datatype="Folder",       parameterType="Required",       direction="Input")            output = arcpy.Parameter(             displayName = "AVL",             name = "avl",             datatype = "Feature Class",             parameterType = "Derived",             direction = "Output")  output.symbology= os.path.join(os.path.dirname(__file__), 'AVL.lyr')    params = [unitid, theDate, outdir, output]         return params       def isLicensed(self):         """Set whether tool is licensed to execute."""         return True      def updateParameters(self, parameters):         """Modify the values and properties of parameters before internal         validation is performed.  This method is called whenever a parameter         has been changed."""              return      def updateMessages(self, parameters):         """Modify the messages created by internal validation for each tool         parameter.  This method is called after internal validation."""         return      def execute(self, parameters, messages):    def reformatDateTime(dt):      s = str(dt)      dtList = re.findall('..', s)      return  dtList[1] + '/' +dtList[2] + '/20' + dtList[0]  + ' ' + dtList[3] +':' + dtList[4]   +':' + dtList[5]        arcpy.AddMessage('\n')  arcpy.AddMessage('the unit id is: ' + parameters[0].valueAsText)  arcpy.AddMessage('the Date is: ' + parameters[1].valueAsText)  arcpy.AddMessage('the output directory is: ' + parameters[2].valueAsText)  arcpy.AddMessage('\n')       unitID = parameters[0].valueAsText  theDate = parameters[1].valueAsText  outdir = parameters[2].valueAsText     #-------------CREATE THE FILE GEODATABASE-----------------------------   gpspath = r'E:\gis\rawgps'      m, d, y = theDate.split('/')  if len(m) == 1:       m = '0' + m  if len(d) == 1:      d = '0' + d  goodDate = y + m + d     gps = gpspath + '\\' + goodDate + '.gps'  arcpy.AddMessage(gps)    arcpy.env.workspace = outdir + '\\' + 'avl_' + goodDate + '_' + unitID + '.gdb'  arcpy.CreateFileGDB_management (outdir, 'avl_' + goodDate + '_' + unitID + '.gdb')    arcpy.CreateFeatureclass_management(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb', unitID, 'POINT')  arcpy.AddField_management(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb\\'  + unitID, 'unitid', 'TEXT')  arcpy.AddField_management(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb\\'  + unitID, 'gpstime', 'DATE')  arcpy.AddField_management(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb\\'  + unitID, 'xcoord', 'LONG')  arcpy.AddField_management(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb\\'  + unitID, 'ycoord', 'LONG')  arcpy.AddField_management(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb\\'  + unitID, 'hspeed', 'DOUBLE')  arcpy.AddField_management(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb\\'  + unitID, 'heading', 'DOUBLE')    c = arcpy.da.InsertCursor(outdir + '\\' +'avl_' + goodDate + '_' + unitID + '.gdb\\'  + unitID,                             ('unitid',  'gpstime', 'xcoord', 'ycoord', 'hspeed',  'heading',  'SHAPE@XY'))    i = 0  f = open(gps, 'r')  for line in f.readlines():      i+=1      if len(line) > 40:   #arcpy.AddMessage(line)   if str(i).endswith('000'):       arcpy.AddMessage('.....processed ' + str(i) + ' records.')   sp = line.split('|')   try:       if sp[0] == unitID:    c.insertRow((sp[0], reformatDateTime(sp[2]), int(sp[4]) +211, int(sp[5]),                  float(sp[7]), float(sp[9]), (float(sp[4]) +211, float(sp[5]))))   except:       pass     f.close()  del f, c    parameters[3].value = outdir + '\\' + 'avl_' + goodDate + '_' + unitID + '.gdb' + '\\' + unitID        return
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
KevinBell
Occasional Contributor III
Duh...  I was trying to set the parameter[3].value to a feature class, but all I need to do was pass it a layer.

arcpy.MakeFeatureLayer_management(outdir + '\\' + 'avl_' + goodDate + '_' + unitID + '.gdb' + '\\' + unitID, 'avllyr')
parameters[3].value = 'avllyr'

Now this works great!

View solution in original post

0 Kudos
13 Replies
T__WayneWhitley
Frequent Contributor
Your insert works correctly, right?  Just your layer isn't refreshed, am I reading you correctly?

You may have to establish a Layer object from the lyr file, then use UpdateLayer and simply refresh your map.  This more or less mimics what you'd be doing manually anyway, making the map (or lyr) aware of your changes.  You may be able to get away with refreshing the map and/or TOC.

Sorry, at the present time I do not have the coding details....just thought your code is interesting, and I don't think you're far at all from a fix.
0 Kudos
T__WayneWhitley
Frequent Contributor
Kevin, I think this snippet contains your answer, sample code from the bottom of the help web page (link listed further below):
[I added the comments]

import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "County Maps")[0]

# your layer object from your TOC
updateLayer = arcpy.mapping.ListLayers(mxd, "Rivers", df)[0]

# the critical part, gaining access to the lyr file
sourceLayer = arcpy.mapping.Layer(r"C:\Project\Data\Rivers.lyr")

# updating the layer in the map, based on the source layer (from file)
arcpy.mapping.UpdateLayer(df, updateLayer, sourceLayer, True)

mxd.saveACopy(r"C:\Project\Project2.mxd")
del mxd, sourceLayer

From:
UpdateLayer
Resource Center » Professional Library » Geoprocessing » The ArcPy site package » Mapping module » Functions » Managing Documents and Layers
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00s30000003p000000


EDIT:
If the added features do not show up, I think all you may need:
arcpy.RefreshActiveView()

Additionally, as necessary:
arcpy.RefreshTOC()

Hope that helps.
-Wayne
0 Kudos
KevinBell
Occasional Contributor III
Your insert works correctly, right?  Just your layer isn't refreshed, am I reading you correctly?


We have gps records from our entire fleet that all dump into one file.gps (text file like) and this code extracts a single vehicles records and maps it all out. *The layer file is suppose to rotate an arrow and color code for speed.

Yes, the insert cursor works great as long as I comment out the output parameter in the getParameterInfo, and the last line above "return" in the execute method. 

I'll take a look at the UpdateLayer, thanks.  I suppose I could use refreshActiveWhatever and use the "Current" map so it runs in any map session.

This is what I'm trying to do:  http://resources.arcgis.com/en/help/main/10.1/index.html#/Defining_parameters_in_a_Python_toolbox/00...

Go down to the second to the last topic titled "symbology"...
0 Kudos
T__WayneWhitley
Frequent Contributor
Kevin, see the bottom of my last post -- I believe as long as you aren't changing the actual symbology scheme, then you just need to refresh:

arcpy.RefreshActiveView()
# you may not need this one?
arcpy.RefreshTOC()

I'll check out what you added in your last post edit...
0 Kudos
T__WayneWhitley
Frequent Contributor
So you are working with a feature set?  (just checking)
0 Kudos
KevinBell
Occasional Contributor III
I changed the output parameter type to GPFeatureLayer...

What I'm seeing now is that the lyr is added to the map, AND the features are inserted correctly, BUT the lyr file isn't seeing the feature class EVEN THOUGH looking at the lyr's source in the lyr's properties says that it is pointed to the feature class.
0 Kudos
T__WayneWhitley
Frequent Contributor
...mmmm, off the top of my head, I think you have to delete the cursor reference when done -- they're notorious for locking layers.

So, if you don't already have it:

# object in a list, if that's convenient, then loop through and clean up all refs:
objList = [row, rows, thisDurnLocking, thatPieceOwork]
for eachObj in objList:
     if eachObj:
          del eachObj
0 Kudos
T__WayneWhitley
Frequent Contributor
Kevin, I could not get the reference from the list as I thought as shown in the code my last post...

Explicitly deleting the obj var worked though:

if row: del row

if rows: del rows


if c: del c

Not sure why the other method did not work?
0 Kudos
KevinBell
Occasional Contributor III
I was already deleting the cursor just after closing the gps file

f.close()
del f, c
0 Kudos