Adding layer created using Python to the active data frame will not work

3788
16
Jump to solution
10-26-2015 08:10 AM
GerryGabrisch
Occasional Contributor III

I have Python code that uses a Model Builder Feature Set as an input to prompt the user to manually create a line inside the data view of the active data frame.  Then Python code calculates the grid north azimuth and the true north azimuth of the line and prints those values to the geoprocessing results window.  The feature set (and code) create in_memory data using CreateFeatureclass_management....That all works fine but what I want to do is add the in_memory data to the active data frame.

I can get the name of the data frame using mxd.activeDataFrame.name but adding the layer is not working.  See my code around line 72 - 74.

Any help is appreciated.

try:
    import sys, traceback
    import arcpy
    import time, math
    
    arcpy.AddMessage("\nGet the Azimuth From A User Defined Line.")
    arcpy.AddMessage("Created by Gerry Gabrisch GISP, GIS Manager Lummi Indian Business Council, geraldg@lummi-nsn.gov\n")
    arcpy.env.overwriteOutput = True
    
    inFC = arcpy.GetParameterAsText(0)
    
    outFL = "outFL"
    outlayer = "outlayer"
    arcpy.MakeFeatureLayer_management(inFC, outFL)
    arcpy.SaveToLayerFile_management(outFL, outlayer)

    def cart2pol(x, y):
        rho = math.sqrt(x**2 + y**2)
        phi = math.atan2(y, x)
        return(rho, phi)
    
    def UnitCircleDegreesToTrueNorthAzimuth(theta):
        '''Converts Arithmatic Degrees (East = 0 then counter clockwise)
        to Geographic Degrees (North = 0 then clockwise).'''
        import math
        #theta = math.degrees(theta)
        theta = theta - 90.0
        if theta < 0:
            theta = theta + 360.0
        theta = -1*(theta * 2 * math.pi / 360.0)
        return 360.0 + math.degrees(theta)
    
    for row in arcpy.da.SearchCursor(inFC, ["OID@", "SHAPE@"]):
    #Set start point
        startpt = row[1].firstPoint
        startX = startpt.X
        startY = startpt.Y
        endpt = row[1].lastPoint
        endX = endpt.X
        endY = endpt.Y
    
    arcpy.AddMessage("Normalizing coordinates...")
    x = endX - startX
    y = endY - startY
    
    arcpy.AddMessage("Radians, degrees, and grid convergence, oh my!\n")
    pol = cart2pol(x, y)
    degs = math.degrees(pol[1])
    
    azi = UnitCircleDegreesToTrueNorthAzimuth(degs)
    
    mxd = arcpy.mapping.MapDocument("CURRENT")
    spacRef = mxd.activeDataFrame.spatialReference
    
    tempFC = arcpy.CreateFeatureclass_management("in_memory", "tempFC", geometry_type = "POINT", spatial_reference = spacRef )
    arcpy.AddField_management(tempFC, "angle", "DOUBLE")
    
    cursor = arcpy.da.InsertCursor(tempFC, ["SHAPE@XY"])
    xy = (startX, startY)
    cursor.insertRow([xy])
    
    arcpy.CalculateGridConvergenceAngle_cartography(tempFC, "angle")
    
    for row in arcpy.da.SearchCursor(tempFC, ["angle"]):
        convergence = row[0]
    
    arcpy.AddMessage("Line azimuth from grid north in degrees = " + str(azi))
    azi = str(azi + convergence)
    arcpy.AddMessage("Line azimuth from true north in degrees= " + azi)
    
    
    arcpy.mapping.AddLayer(mxd.activeDataFrame.name, tempFC, "TOP")
    arcpy.RefreshActiveView()
    arcpy.RefreshTOC()
    
    time.sleep(10)
    arcpy.AddMessage("\nClosing")

except arcpy.ExecuteError: 
    msgs = arcpy.GetMessages(2) 
    arcpy.AddError(msgs)  
    arcpy.AddMessage(msgs)
except:
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
    print pymsg


0 Kudos
1 Solution

Accepted Solutions
LukeSturtevant
Occasional Contributor III

Yes you are correct. I should have referenced the layer object. Did you try this yet:

lyr = arcpy.mapping.Layer("in_memory\\tempFC")

arcpy.mapping.AddLayer(mxd.activeDataFrame, lyr,"TOP")

View solution in original post

16 Replies
DanPatterson_Retired
MVP Emeritus

you have 2 except lines but I can only find one try

0 Kudos
LukeSturtevant
Occasional Contributor III

You can have multiple except lines within a single try statement. That should not effect the code.

DanPatterson_Retired
MVP Emeritus

hmmmm tested in python 3.4

try:
    import ArCpY
except:
    print("such a failure")

result

>>> such a failure

try:
    import ArCpY
except:                       # with or without this colon
    print("such a failure")
except:
    print("I repeat")

Failed to check - syntax error -default 'except:' must be last

hmmmmm

try:
    import ArCpY
except:
    print("such a failure")
finally:
    print("I repeat")

result

such a failure
I repeat

What version are you using?

0 Kudos
LukeSturtevant
Occasional Contributor III

Python 2.7. It looks like that functionality is either redundant or did not follow over to 3.4. That's too bad.

0 Kudos
GerryGabrisch
Occasional Contributor III

Dan, I am on ArcGIS 10.3 with Python 2.7

Here is the link to the ESRI help from ArcGIS 10

ArcGIS Desktop

I did alter the code to have only one except statement but that was not the cause of the troubles...

0 Kudos
LukeSturtevant
Occasional Contributor III

Dan, just out of curiosity, did you try a double except statement  with the first except block invoking a specific error set up similar to Gerry's except arcpy.ExecuteError: ?

0 Kudos
DanPatterson_Retired
MVP Emeritus

It is still there but slight changes

You have to do it like this now explicitly

import sys
def divide(x, y):
...    try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...    else:
...         print("result is", result)
...    finally:
...         print("executing finally clause")

So for the most part, nothing changes except I can't get anything to print after an arcpy.ExecuteError.

I never use try except blocks .  I find them less informative than an actual error message, then I clean up using locals().keys() to find then delete any namespace.  The only upside with Pro is RefreshActiveView is no longer needed with the new mp module

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Multiple except clauses work fine as long as the catch-all "except:" statement is last.  From the 2.7 Python docs on Handling Exceptions, which is the same as the 3.5 docs:

A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same try statement.

....

The last except clause may omit the exception name(s), to serve as a wildcard. Use this with extreme caution, since it is easy to mask a real programming error in this way! It can also be used to print an error message and then re-raise the exception (allowing a caller to handle the exception as well):

0 Kudos
LukeSturtevant
Occasional Contributor III

The Add Layer​ function looks for a data frame object not a data frame name. You should be able to just change your code to:

arcpy.mapping.AddLayer(mxd.activeDataFrame, tempFC,"TOP")

However, sometimes you need to explicitly set the layer to a full path like so:

arcpy.mapping.AddLayer(mxd.activeDataFrame, "in_memory\\tempFC","TOP")