POST
|
Hi Chris, I haven't tried using edit.stopEditing(False), but I did try simply commenting out edit.stopEditing(True), which removes the error. I'm assuming that "edit" was never really a valid Python edit object because the editor arcobject (at the heart of the Python editor object) is a singleton object, so only one instance can exist at a time. An "edit" session can't be closed if it doesn't really exist, hense the error. No clue why the start/stopOperations don't cause errors. Unfortunately the add-in framework requires edit sessions to be started within the add-in for SDE edits, so I have to put in the edit.startEditing(True,True) code just to avoid the errors, but the "editor" within the addin otherwise unfunctional. I'm pretty sure that my add-ins worked with all of the edit code included, as long as the user did not have a pre-existing edit session running in ArcMap, but that doesn't seem to be the case now (10.3 upgrade, maybe?), so now I don't have much of a reason to keep the edit.stopEditing(True) line in my add-ins. However, I just discovered another post by someone else who just removes that line, and they noticed some issues if they try to make additional edits on newly created features that haven't been properly saved. Bottom line, I think, is that there is no "correct" way to handle this arcpy/SDE edit issue... just different workarounds with different disadvantages. Kerry
... View more
10-02-2015
07:17 AM
|
0
|
0
|
3746
|
POST
|
Chris, Thanks for the manual edit workaround. You're right...it isn't convenient to remember to have to do manual edits, and it's hard to explain to others who might use the scripts. I added arcpy.da.edit code to my scripts that edit SDE data, even if the scripts might be executed from within ArcMap during an edit session. The "edit.startOperation()" function prevents "The requested operation is invalid on a closed state" error from being thrown. It's an ugly workaround, but I had to use it with a similar issue within my Python Add-ins to bypass an apparent hardwired "protection" against making edits to SDE data without being in an edit session. However...there are some weird consequences of starting the edit session within the script when it already exists in ArcMap. Although there is a "fatal" error in the script when it encounters edit.stopEditing(True), the edits actually persist. The edits made by the script can also be "undone" if there was a manual edit before the script was run, but the previous manual edit will also be undone. I remain somewhat concerned about the potential issues due to improper handling of the edit session and edit operations with SDE data, but it might be less of an issue for us than others, since we register our data as "versioned moving edits to base" and rarely have to deal conflicting edits. Kerry
... View more
09-14-2015
08:32 AM
|
2
|
7
|
3746
|
POST
|
If you are ok with using an older version of pandas, the installation process I used was relatively simple: I installed pandas by running an executable installation file (built with distutils) downloaded from pypi.python.org via download links on the pandas homepage. The key for me was choosing an older version of pandas that was built using the same version of NumPy that I was already running. To find out what version of numpy you are running, import NumPy and then type: numpy.version.full_version Although pandas 15.2 is the latest release, it (the executable installation file) requires NumPy 1.8.1. I'm running ArcMap 10.2 which comes with NumPy 1.7.1. I browsed through the older releases of pandas (listed on the right hand pandas homepage) until I found a release that was based on NumPy 1.7.1, which happened to be pandas 12.0. It was only later that I realized that the pandas 13.0 and 13.1 were also based on NumPy 1.7.1, but I didn't bother to change it. Although python-dateutil and pytz are listed as pandas 15.2 dependencies, I think they aren't for pandas 12.0 since I didn't bother installing them. I hope that helps! Kerry
... View more
03-06-2015
08:46 AM
|
1
|
0
|
1768
|
POST
|
I had already deleted all the .pyc and .pyo files from comtypes/gen. At your suggestion I also deleted them from the comtypes folder, but I still had errors (I forget which). I uninstalled and reinstalled comtypes-0.6.2 (from sourceforge) and that seems to have fixed everything! Sometimes a fresh start is easier than figuring out what went wrong.
... View more
02-23-2015
11:11 AM
|
0
|
0
|
1805
|
POST
|
Alas, I do not have Background Processing enabled. Any other ideas?
... View more
02-20-2015
02:08 PM
|
0
|
2
|
1805
|
POST
|
I'm running from the ArcMap Python window. My code is: import arcpy, comtypes, Snippets
Snippets.ArcMap_GetSelectedGeometry(bStandalone=False) The error message: Runtime error
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "V:\Projects\Shared\kalley\PythonScripts\Snippets.py", line 258, in ArcMap_GetSelectedGeometry
pApp = GetCurrentApp()
File "V:\Projects\Shared\kalley\PythonScripts\Snippets.py", line 126, in GetCurrentApp
return NewObj(esriFramework.AppRef, esriFramework.IApplication)
AttributeError: 'module' object has no attribute 'AppRef' The entire Snippets.py file is in the link in my original post, but the snippets involved in my line of code are: def GetLibPath():
"""Return location of ArcGIS type libraries as string"""
# This will still work on 64-bit machines because Python runs in 32 bit mode
import _winreg
keyESRI = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\ESRI\\Desktop10.2")
return _winreg.QueryValueEx(keyESRI, "InstallDir")[0] + "com\\"
def GetModule(sModuleName):
"""Import ArcGIS module"""
from comtypes.client import GetModule
sLibPath = GetLibPath()
GetModule(sLibPath + sModuleName)
def GetDesktopModules():
"""Import basic ArcGIS Desktop libraries"""
GetModule("esriFramework.olb")
GetModule("esriArcMapUI.olb")
GetModule("esriArcCatalogUI.olb")
#**** Helper Functions ****
def NewObj(MyClass, MyInterface):
"""Creates a new comtypes POINTER object where\n\
MyClass is the class to be instantiated,\n\
MyInterface is the interface to be assigned"""
from comtypes.client import CreateObject
try:
ptr = CreateObject(MyClass, interface=MyInterface)
return ptr
except:
return None
def GetCurrentApp():
"""Gets an IApplication handle to the current app.\n\
Must be run inside the app's Python window.\n\
Execute GetDesktopModules() first"""
import comtypes.gen.esriFramework as esriFramework
return NewObj(esriFramework.AppRef, esriFramework.IApplication)
def ArcMap_GetSelectedGeometry(bStandalone=False):
GetDesktopModules()
if bStandalone:
InitStandalone()
pApp = GetApp()
else:
pApp = GetCurrentApp()
if not pApp:
print "We found this spoon, sir."
return
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriArcMapUI as esriArcMapUI
import comtypes.gen.esriSystem as esriSystem
import comtypes.gen.esriCarto as esriCarto
import comtypes.gen.esriGeoDatabase as esriGeoDatabase
import comtypes.gen.esriGeometry as esriGeometry
# Get selected feature geometry
pDoc = pApp.Document
pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
pMap = pMxDoc.FocusMap
pFeatSel = pMap.FeatureSelection
pEnumFeat = CType(pFeatSel, esriGeoDatabase.IEnumFeature)
pEnumFeat.Reset()
pFeat = pEnumFeat.Next()
if not pFeat:
print "No selection found."
return
pShape = pFeat.ShapeCopy
eType = pShape.GeometryType
if eType == esriGeometry.esriGeometryPoint:
print "Geometry type = Point"
elif eType == esriGeometry.esriGeometryPolyline:
print "Geometry type = Line"
elif eType == esriGeometry.esriGeometryPolygon:
print "Geometry type = Poly"
else:
print "Geometry type = Other"
return pShape
... View more
02-20-2015
01:46 PM
|
0
|
4
|
1805
|
POST
|
I am using comtypes and Mark Cederholm's Snippets.py (10.2 version) and have not been able to access comtypes.gen.esriFramework.AppRef. I have made the required comtype edits for 10.2 compatibility, and verified that the relevant .pyc files are new. The error message I get when I try to access comtypes.gen.esriFramework.AppRef is "AttributeError: 'module' object has no attribute 'AppRef'". The attributes listed by executing "dir(comtypes.gen.esriFramework)" are: ['_866AE5D3_530C_11D2_A2BD_0000F8774FB5_0_10_2', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'typelib_path'] which does not include "AppRef", although the Class "AppRef" is in the code of the freshly created comtypes\gen\_866AE5D3_530C_11D2_A2BD_0000F8774FB5_0_10_2.py But I also noticed that a class does not seem to show up as an attribute when I execute "dir(comtypes.gen.esriFramework._866AE5D3_530C_11D2_A2BD_0000F8774FB5_0_10_2)" that yields ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'typelib_path'] Any idea what the problem is? Is the information I provided above relevant to figuring it out? How else can I troubleshoot this?
... View more
02-20-2015
12:15 PM
|
0
|
6
|
8234
|
POST
|
Our methods of searching for keys have the same functionality, and they're both described here.
... View more
07-25-2014
12:12 PM
|
0
|
0
|
726
|
POST
|
Since Ian brought it up, I'll add that you don't need specify the full path for the output feature class either, as long as you want it to be saved in the already-specified workspace. As with most geoprocessing tools, CopyFeatures_management honors selections and definition queries, so make sure you know what you're copying. If the code below doesn't work, try commenting out the try and except lines (and de-indenting the arcpy.CopyFeatures_management and print lines) to see what error occurs. Also, I found typos in my previous post. There should only be one line (that looks like this) in the except block: print 'Could not copy %s'%layer.name
import os
import arcpy
arcpy.env.workspace = ws = 'C:\\WorkSpace\\sahie_saipe\\sahie_saipe.gdb'
dictionary_Layer = {'co06_Layer':'co06', 'co07_Layer':'co07', 'cnty08_Layer':'co08', 'co09_Layer':'co09', 'co10_Layer':'co10', 'co11_Layer':'co11', 'co12_Layer':'co12', 'st_Select':'state'}
mxd = arcpy.mapping.MapDocument('C:\\WorkSpace\\sahie_saipe\\sahie_saipe.mxd')
for layer in arcpy.mapping.ListLayers(mxd):
if layer.name in dictionary_Layer.keys():
try:
arcpy.CopyFeatures_management(layer.name, dictionary_Layer[layer.name]) #only 2 required parameters, full path not necessary to output to workspace
print 'copy %s to %s' %(layer.name, dictionary_Layer[layer.name])
except:
print 'Could not copy %s'%layer.name
... View more
07-24-2014
02:24 PM
|
0
|
4
|
726
|
POST
|
Hello, The variable "layer" represents the layer object, not the name of the layer (a string). You therefore need to look for layer.name in the dictionary, and more specifically look in the list of the dictionary keys. I've copied your code and edited lines 6-12 below for clarification... hopefully I didn't introduce typos! Kerry
import os
import arcpy
arcpy.env.workspace = ws = 'C:\\WorkSpace\\sahie_saipe\\sahie_saipe.gdb'
dictionary_Layer = {'co06_Layer':'co06', 'co07_Layer':'co07', 'cnty08_Layer':'co08', 'co09_Layer':'co09', 'co10_Layer':'co10', 'co11_Layer':'co11', 'co12_Layer':'co12', 'st_Select':'state'}
for layer in arcpy.mapping.ListLayers(mxd):
if layer.name in dictionary_Layer.keys():
old = os.path.join(ws, layer.name)
new = os.path.join(ws, dictionary_Layer[layer.name])
try:
arcpy.CopyFeatures_management(old,new,"")
print 'copy %s to %s' %(layer.name, dictionary_Layer[layer.name])
except:
print 'Could not copy %s'(layer.name)
print 'Could not copy %s'
... View more
07-24-2014
11:07 AM
|
1
|
0
|
726
|
POST
|
I don't know of a single tool to accomplish your task, but I do it in two steps: After creating a feature class with road arc endpoints using FeatureVerticesToPoints_management, I remove the duplicate (overlapping) points with DeleteIdentical_management, specifying the "Shape" field to end up with one point at each endpoint. Alternatively, if I want a feature class without dangles or pseudonodes, there is an intermediate step. I do a one-to-many spatial join after using FeatureVerticesToPoints. The output has a "Join_Count" field which tells me how many points are at each location, so I can query out the points with Join_Count >= 3 (assuming arcs are split at intersections) to get the true nodes (intersections) only, and then I delete the identical points.
... View more
07-23-2014
01:57 PM
|
3
|
1
|
2320
|
POST
|
Did you specifically create a toolbar for your add-in, as well as a tool (or button)? If not, open the customize window, and select the "commands" tab, and type the name of your tool in the "Show commands containing" box. If your tool installed properly, regardless of whether it is part of a toolbar, then it should be there. You can then drag the tool and place it in any open toolbar. Kerry
... View more
06-26-2014
08:41 AM
|
0
|
0
|
525
|
POST
|
Aaaargh! You're right! The field.defaultValue *is* a valid property...it just isn't documented in 10.1 or 10.2!!! I was relying on the documentation for the arcpy field class. I also tried searching the 10.2 help for "defaultValue," and finally gave up and parsed the default values out of the metadata xml files (ugh!). I submitted feedback through the Help pages, so hopefully that will be updated. Kerry
... View more
06-26-2014
07:52 AM
|
1
|
0
|
460
|
POST
|
Here's the code for the Python add-in I was referring to. Keep in mind that it is meant to work with our own data, so it would require significant changes to perform similarly with someone else's data.
#ShieldToolAddin.py
#By Kerry Alley 2013-03-12
#Vermont Agency of Transportation
#
#Python Add-In for ArcMap 10.1, 10.2
#
#SELECT_ROAD (button)
#When activated, will select features within 20 map-meters of the mouse click on the map.
#The features are selected only from the top-most layer with the GDB_HMS.HMSADMIN.rdsmall_arc
# data source, regardless of layer name.
#
#CREATE_SHIELD (button)
#Requires that a single rdsmall_arc feature already be selected
#User makes a single click on the map to indicate the location of the highway shield, and
# makes a double-click where the leader line extending from the highway shield will end.
#Both a point feature and a line feature are created, with relevant attributes transferred
# from the selected rdsmall_arc feature.
#There is an un-commentable option in this script that sets the length of the leader line to
# a fixed length, for uniformity.
#
#NOTE: This addin works "normally" if there is not an active editing session in ArcMap, but if
# there is an active editing session, the addin "crashes" at the call to stopEditing(). The
# features will still be created, but the screen will not refresh if there is a pre-existing
# editing session active.
import arcpy, time, os, math
import pythonaddins
class SelectRoadClass(object):
"""Implementation for ShieldToolAddinA_addin.tool (Tool)"""
def __init__(self):
self.enabled = True
self.shape = "NONE"
def onMouseDownMap(self, x, y, button, shift):
#start_time = time.time() #only used to compare run-times of different versions of the script
arcpy.env.overwriteOutput = True
rdsmall_dataSource = r"GDB_HMS.HMSADMIN.rdsmall_arc"
mxd = arcpy.mapping.MapDocument('current')
flag_rdsmall = 0 #flag_rdsmall is used to flag the first occurence of a layer having the desired dataSource in TOC
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.supports("dataSource"):
if str(lyr.dataSource).endswith(rdsmall_dataSource) and not flag_rdsmall:
rdsmall_lyr = lyr
flag_rdsmall = 1
point = arcpy.Point()
point.X = x
point.Y = y
pointGeometry = arcpy.PointGeometry(point)
arcpy.SelectLayerByLocation_management(rdsmall_lyr, "WITHIN_A_DISTANCE", pointGeometry, "20 Meters", "NEW_SELECTION")
#print time.time() - start_time, "seconds"
class CreateShieldClass(object):
"""Implementation for ShieldToolAddinB_addin.tool (Tool)"""
def __init__(self):
self.enabled = True
self.cursor = 3
self.shape = "LINE"
def onLine(self, line_geometry):
#start_time = time.time() #only used to compare rough run-times of different versions of the script
arcpy.env.overwriteOutput = True
#Hard-wiring the exact feature classes that will be edited with shield tool.
shield_points_dataSource = r"GDB_HMS.HMSADMIN.hms_shields_points"
shield_arcs_dataSource = r"GDB_HMS.HMSADMIN.hms_shields_arcs"
rdsmall_dataSource = r"GDB_HMS.HMSADMIN.rdsmall_arc"
mxd = arcpy.mapping.MapDocument('current')
#for new shields to appear in current mxd, this script must refer to layers in the current mxd
lyrs = arcpy.mapping.ListLayers(mxd)
flag_points = 0
flag_arcs = 0
flag_rdsmall = 0
for lyr in arcpy.mapping.ListLayers(mxd):
if lyr.supports("dataSource"):
if str(lyr.dataSource).endswith(shield_points_dataSource) and flag_points == 0:
shield_points_lyr = lyr
flag_points = 1
if str(lyr.dataSource).endswith(shield_arcs_dataSource) and flag_arcs == 0:
shield_arcs_lyr = lyr
flag_arcs = 1
if str(lyr.dataSource).endswith(rdsmall_dataSource) and flag_rdsmall == 0:
rdsmall_lyr = lyr
flag_rdsmall = 1
if not (shield_points_lyr and shield_arcs_lyr and rdsmall_lyr):
print "Must have 3 layers in this mxd: shield points, shield arcs, and rdsmall"
#only allow shield creation if a single road arc is selected
num_road_arcs = int(arcpy.GetCount_management(rdsmall_lyr).getOutput(0))
print "%s rdsmall arc(s) selected" %num_road_arcs
if num_road_arcs == 1:
workspace = rdsmall_lyr.workspacePath #(refers to .sde file in DatabaseConnections)
arcpy.env.workspace = workspace
edit = arcpy.da.Editor(workspace)
edit.startEditing(True, True) #with undo, multiuser mode
#identify maximum SHI_GRP_ID value currently used in shields feature class
max_id = sorted(arcpy.da.SearchCursor(shield_points_lyr.dataSource, "SHI_GRP_ID"), reverse = 1)[0][0]
#print max_id + 1
#collect selected road arc attributes
rdsmall_values = sorted(arcpy.da.SearchCursor(rdsmall_lyr, ["UA", "FAID_S", "CTCODE", "RTNUMBER", "AOTCLASS"]))
#uncomment the last line of this block of code to turn off the truncation of the leader line
#determine line coordinates, slope, and truncated line geometry based on first and last point.
a_pt = line_geometry.firstPoint
b_pt = line_geometry.lastPoint
slope = (b_pt.Y - a_pt.Y)/(b_pt.X - a_pt.X)
theta = math.atan(slope)
#fixed_length = 150.
fixed_length = 185.
if b_pt.X - a_pt.X < 0:
x = fixed_length * math.cos(theta) * -1
y = fixed_length * math.sin(theta) * -1
else:
x = fixed_length * math.cos(theta)
y = fixed_length * math.sin(theta)
point = arcpy.Point()
point.X = a_pt.X + x
point.Y = a_pt.Y + y
array = arcpy.Array()
array.add(line_geometry.firstPoint)
array.add(point)
fixed_line = arcpy.Polyline(array)
#To remove the constraint of fixed shield arc lengths, uncomment the following line:
fixed_line = line_geometry #this line reverts the fixed_line to the original input geometry
#create shield point feature and populate attributes
new_points_Cur = arcpy.da.InsertCursor(shield_points_lyr, ["SHAPE@XY", "UA", "FAID_S", "CTCODE", "RTNUMBER", "AOTCLASS", "SHI_GRP_ID", "INSET", "ISVISIBLE", "SUBINSET"])
test = (fixed_line.firstPoint,) + tuple(rdsmall_values) + (max_id + 1,)
test_tuple = ((test[0].X, test[0].Y), test[1][0], test[1][1], str(test[1][2]), str(test[1][3]), test[1][4], test[2], "N", 1, "N")
#test_tuple = ((test[0].X, test[0].Y), rdsmall_values[0], str(rdsmall_values[2]), str(rdsmall_values[3]), rdsmall_values[4], max_id + 1, "N", 1, "N")
edit.startOperation()
new_points_Cur.insertRow(test_tuple)
edit.stopOperation()
del new_points_Cur
#create shield arc feature and populate SHI_GRP_ID, CTCODE, UA, INSET, ISVISIBLE, and SUBINSET fields
new_arc_Cur = arcpy.da.InsertCursor(shield_arcs_lyr.dataSource, ["SHAPE@", "SHI_GRP_ID", "CTCODE", "UA", "INSET", "ISVISIBLE", "SUBINSET"])
edit.startOperation()
new_arc_Cur.insertRow([fixed_line, max_id + 1, str(rdsmall_values[0][2]), rdsmall_values[0][0], "N", 1, "N"])
edit.stopOperation()
del new_arc_Cur
edit.stopEditing(True) #save changes (doesn't work if an editing session is open in ArcMap, but )
arcpy.SelectLayerByAttribute_management(rdsmall_lyr, "CLEAR_SELECTION")
arcpy.RefreshActiveView()
else:
print "Shield Not Created"
print "Must select a single arc from rdsmall"
#print time.time() - start_time, "seconds"
... View more
06-26-2014
07:12 AM
|
0
|
0
|
533
|
POST
|
Hi Jim, The paths do help. It isn't clear to me, however, exactly what information is in your lookup table or how you want to use it. For example, does the lookup table identify which fips codes belong to which state? If so, how? Is every fips code listed in one field, with another field providing the name of the state the code belongs to? Will each shape file correspond to a single or multiple fips codes? I would need to understand these kinds of relationships between relevant fields, and to know the names of the fields, in order to incorporate the lookup table into the script. Kerry
... View more
06-24-2014
08:45 AM
|
0
|
0
|
415
|
Title | Kudos | Posted |
---|---|---|
1 | 03-06-2015 08:46 AM | |
1 | 07-24-2014 11:07 AM | |
1 | 06-03-2013 06:39 AM | |
2 | 09-14-2015 08:32 AM | |
3 | 07-23-2014 01:57 PM |
Online Status |
Offline
|
Date Last Visited |
11-03-2021
02:31 PM
|