POST
|
Yeah, that's what I was afraid of. I'll probably end up doing something similar, but I'll use try/except with getattr, instead of eval. Maybe I'm missing something, but it seems to me that the factory pattern would make more sense than whatever hidden implementation is going on here. They may very well be using the factory pattern on the back-end C classes (I'm assuming that's what they are). But the combination of inconsistent return types and no introspection makes for grotesquely un-Pythonic code.
... View more
06-22-2017
03:55 PM
|
0
|
0
|
3538
|
POST
|
Though the documentation refers to a "Describe object", it must be some sort of C class (apparently via the arcgisscripting.create function), instead of a Python class. The standard Python introspection methods don't turn up much information (see below). If one wishes to summarize all the known info of a dataset, how might one dynamically identify which properties apply to the current instance--without writing a long series of if statements and/or going through all the potential properties? For reference: given a variable named "desc" returned from a call to arcpy.Describe, here are the results of some inspection and introspection operations: >>> type(desc)
<type 'geoprocessing describe data object'>
>>> dir(desc)
[]
>>> desc.__name__
'Describe Object'
>>> desc.__class__
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: DescribeData: Method __class__ does not exist
>>> desc.__repr__
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: DescribeData: Method __repr__ does not exist
>>> isinstance(desc, object)
True
>>> desc.__dict__
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: DescribeData: Method __dict__ does not exist
>>> help(desc)
Help on geoprocessing describe data object object:
Describe Object = class geoprocessing describe data object(object)
>>> print(inspect.getmodule(desc))
None
>>> inspect.getclasstree(desc)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\Python27\ArcGISx6410.4\Lib\inspect.py", line 726, in getclasstree
for c in classes:
TypeError: 'geoprocessing describe data object' object is not iterable
>>> inspect.getmro(desc)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\Python27\ArcGISx6410.4\Lib\inspect.py", line 346, in getmro
_searchbases(cls, result)
File "C:\Python27\ArcGISx6410.4\Lib\inspect.py", line 337, in _searchbases
for base in cls.__bases__:
AttributeError: DescribeData: Method __bases__ does not exist
... View more
06-22-2017
12:41 PM
|
2
|
11
|
6875
|
POST
|
No need to mess around with ArcObjects and .NET. You can create your own edit stack. You can simply set a global variable that tracks the edits and is then accessible to other buttons. For example, depending on the complexity of the edits performed by your add-in, you could have a global list to which you append information about the edits. Here's an example of a simple edit button (it just buffers the selected features) with undo and redo buttons. Note that these are not the built-in undo/redo buttons, but Add-In buttons that you create. The edits here will be in a separate stack from the built-in edits. import arcpy
import pythonaddins
MXD = arcpy.mapping.MapDocument('CURRENT')
FN_SHAPE = 'SHAPE@'
# Global variables that will store the edit histories forward and backward
undo_stack = list()
redo_stack = list()
class MakeEdits(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
# Get the selected layer in the table of contents
lyr = pythonaddins.GetSelectedTOCLayerOrDataFrame()
# Get a count of selected features in the selected layer
fid_set = arcpy.Describe(lyr).FIDSet
if fid_set == '':
count = 0
else:
count = len(fid_set.split(';'))
# If at least one feature is selected
if count > 0:
# Enable global modification of the undo_stack
global undo_stack
# Get the name of the layer's OID field
fn_oid = arcpy.Describe(lyr).OIDFieldName
with arcpy.da.UpdateCursor(lyr, [fn_oid, FN_SHAPE]) as cur:
for row in cur:
# Add the relevant details to the editing stack
undo_stack.append((lyr, fn_oid, row[0], row[1]))
# An arbitrary example edit
row[1] = row[1].buffer(500)
cur.updateRow(row)
arcpy.RefreshActiveView()
class RedoEdits(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
global undo_stack
global redo_stack
if len(redo_stack) > 0:
# Get the last item in the edit stack
edit = redo_stack.pop()
# Clear any existing selection on the layer, or else the cursor may
# not hit the necessary feature
arcpy.SelectLayerByAttribute_management(edit[0], 'CLEAR_SELECTION')
# A where clause to select the most recently edited feature
wc = '{} = {}'.format(edit[1], edit[2])
with arcpy.da.UpdateCursor(edit[0], FN_SHAPE, wc) as cur:
for row in cur:
# Update the undo edit stack
edit_out = list(edit[:-1])
edit_out.append(row[0])
undo_stack.append(edit_out)
# Apply the edit
row[0] = edit[3]
cur.updateRow(row)
break
arcpy.RefreshActiveView()
class UndoEdits(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
global undo_stack
global redo_stack
if len(undo_stack) > 0:
edit = undo_stack.pop()
arcpy.SelectLayerByAttribute_management(edit[0], 'CLEAR_SELECTION')
wc = '{} = {}'.format(edit[1], edit[2])
with arcpy.da.UpdateCursor(edit[0], FN_SHAPE, wc) as cur:
for row in cur:
edit_out = list(edit[:-1])
edit_out.append(row[0])
redo_stack.append(edit_out)
row[0] = edit[3]
cur.updateRow(row)
break
arcpy.RefreshActiveView()
return
... View more
12-20-2016
02:27 PM
|
0
|
0
|
786
|
POST
|
Since the edit stack is not preserved outside of a given add-in edit session, you can simply set a global variable that tracks the edits and is then accessible to other buttons. For example, depending on the complexity of the edits performed by your add-in, you could have a global list to which you append information about the edits. Here's an example of a simple edit button (it just buffers the selected features) with undo and redo buttons. Note that these are not the built-in undo/redo buttons, but Add-In buttons that you create. The edits here will be in a separate stack from the built-in edits. import arcpy
import pythonaddins
MXD = arcpy.mapping.MapDocument('CURRENT')
FN_SHAPE = 'SHAPE@'
# Global variables that will store the edit histories forward and backward
undo_stack = list()
redo_stack = list()
class MakeEdits(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
# Get the selected layer in the table of contents
lyr = pythonaddins.GetSelectedTOCLayerOrDataFrame()
# Get a count of selected features in the selected layer
fid_set = arcpy.Describe(lyr).FIDSet
if fid_set == '':
count = 0
else:
count = len(fid_set.split(';'))
# If at least one feature is selected
if count > 0:
# Enable global modification of the undo_stack
global undo_stack
# Get the name of the layer's OID field
fn_oid = arcpy.Describe(lyr).OIDFieldName
with arcpy.da.UpdateCursor(lyr, [fn_oid, FN_SHAPE]) as cur:
for row in cur:
# Add the relevant details to the editing stack
undo_stack.append((lyr, fn_oid, row[0], row[1]))
# An arbitrary example edit
row[1] = row[1].buffer(500)
cur.updateRow(row)
arcpy.RefreshActiveView()
class RedoEdits(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
global undo_stack
global redo_stack
if len(redo_stack) > 0:
# Get the last item in the edit stack
edit = redo_stack.pop()
# Clear any existing selection on the layer, or else the cursor may
# not hit the necessary feature
arcpy.SelectLayerByAttribute_management(edit[0], 'CLEAR_SELECTION')
# A where clause to select the most recently edited feature
wc = '{} = {}'.format(edit[1], edit[2])
with arcpy.da.UpdateCursor(edit[0], FN_SHAPE, wc) as cur:
for row in cur:
# Update the undo edit stack
edit_out = list(edit[:-1])
edit_out.append(row[0])
undo_stack.append(edit_out)
# Apply the edit
row[0] = edit[3]
cur.updateRow(row)
break
arcpy.RefreshActiveView()
class UndoEdits(object):
def __init__(self):
self.enabled = True
self.checked = False
def onClick(self):
global undo_stack
global redo_stack
if len(undo_stack) > 0:
edit = undo_stack.pop()
arcpy.SelectLayerByAttribute_management(edit[0], 'CLEAR_SELECTION')
wc = '{} = {}'.format(edit[1], edit[2])
with arcpy.da.UpdateCursor(edit[0], FN_SHAPE, wc) as cur:
for row in cur:
edit_out = list(edit[:-1])
edit_out.append(row[0])
redo_stack.append(edit_out)
row[0] = edit[3]
cur.updateRow(row)
break
arcpy.RefreshActiveView()
return
... View more
12-20-2016
02:25 PM
|
1
|
0
|
701
|
POST
|
For anyone else who might come across this, an answer on StackExchange worked for me. "this is a resources issue". Doing whatever you can to use fewer resources; e.g.: - Ensure you're in a 64-bit/background environment) - Generalize/Simplify your geometries - Repair geometries - Use fgdb (my issue was that I was processing data in an .mdb that some dinosaur had sent me) Best of luck.
... View more
05-03-2016
04:43 PM
|
1
|
0
|
600
|
POST
|
You've got to love ESRI's completely misleading error messages. After encountering the same problem as you, I'm just going to start ignoring the messages--I'll probably save a lot of wasted time.
... View more
02-18-2016
12:34 PM
|
0
|
0
|
1113
|
POST
|
This is discussed in detail here: http://forums.arcgis.com/threads/79087-Problem-importing-arcpy-in-ArcMap-console-64-bit-DLL-conflict The most reasonable solution to me is uninstalling Python and then running the repair installation of ArcGIS.
... View more
04-04-2014
11:28 AM
|
0
|
0
|
524
|
POST
|
In my experience, these types of issues appear to be caused by installing PyScripter after installing ArcGIS. The PyScripter installation futzes with the system environment variables and causes some inconsistent behavior, such as sometimes not properly importing arcpy, yielding this error: ImportError: DLL load failed: %1 is not a valid Win32 application. Then again, sometimes it works just fine. The only thing that worked for me was uninstalling Python and then running the repair installation of ArcGIS.
... View more
04-04-2014
11:26 AM
|
0
|
0
|
671
|
POST
|
This error (010093) often occurs when trying to create an improperly named raster file. For GRIDs, the naming restrictions include: ...a grid should not be named with spaces or any other special characters in its name. A multiple-band grid cannot have more than 9 characters in its file name, and a single-band raster dataset cannot have more than 13 characters. Todd, this probably applies in your case, if you're using HUC 12s; the appending of your four characters ('fdr_') puts you over the 13 character limit. See ESRI's help page on GRIDs for more info.
... View more
11-26-2013
09:36 AM
|
0
|
0
|
639
|
POST
|
Internally, we convert the polygon mask to a raster then use that raster to do the extraction. Is this type of behind-the-scenes processing documented somewhere? Being aware of such extraneous steps could really help to reduce processing time. For example, I'm masking 500 rasters to one polygon layer. According to this, it would save me a ton of processing time to convert the polygon layer to a raster just once and then use that raster as my mask layer. The help page for the Extract by Mask tool does not mention this crucial piece of information; is there some other resource where such details are noted for all tools?
... View more
10-30-2013
09:01 AM
|
0
|
0
|
820
|
POST
|
If it's a coworker, then you should be happy that your company/organization can now run a little bit more efficiently due to the code that you wrote. Just make sure that your superiors know who wrote the code when your next performance review rolls around.
... View more
07-16-2013
03:58 PM
|
0
|
0
|
609
|
POST
|
Josh, I've just started looking into this myself. Depending on how much data you want to display on your maps, it doesn't take too much work to draw a table using text boxes in an mxd and then change the content of them via a script. Another option is to export the map to a pdf, and use ReportLab (see pp. 10 and 75 of this user guide) to generate a table and then merge the table and map into a single pdf page. Within the next couple of days, I should have worked this out with ReportLab for myself, and I'll post any helpful code here. Good luck.
... View more
07-16-2013
03:46 PM
|
0
|
0
|
239
|
POST
|
Even though I was setting the symbology by an attribute field that shared a consistent structure (i.e., type, precision, etc.) among all the rasters, inconsistency in the pixel depth of the value fields was throwing off the symbology. Solutions: Quickest processing: Create a layer file unique to each pixel type; as each raster is brought in, describe the raster and identify the pixel type; based on the layer's pixel type, select the appropriate .lyr file for assigning symbology. Quickest script-writing: Copy all the rasters with the pixel type explicitly set to a common (maximum) size. Here's the relevant portion of code that I used for the first option, with variable names adapted for clarity: lyrDict = {'U16':'mylayer_u16.lyr', 'S16':'mylayer_s16.lyr', 'U8':'mylayer_u8.lyr'} d = arcpy.Describe(rast) symLayer = arcpy.mapping.Layer(os.path.join(lyrDir, lyrDict[d.pixelType])) myLayer = arcpy.mapping.Layer(rast) arcpy.mapping.AddLayer(myDF, myLayer) myLyr = arcpy.mapping.ListLayers(mxd, '', dfSpecies)[0] arcpy.ApplySymbologyFromLayer_management(myLyr, symLayer)
... View more
07-16-2013
02:22 PM
|
0
|
0
|
740
|
POST
|
I apologize in advance for the verbose post: I am trying to symbolize raster data, not based on the value, but based on another field in the raster attribute table. I've created a .lyr file, and, in order to easily script the map production, I am simply replacing the data source (I need to create nationwide maps of more than 1000 30-meter raster datasets). However, when the raster values (from the value field, not from the symbology field) exceed those that were in the raster from which the .lyr was created, then that portion of the raster will not draw at all. In theory, one could work around this problem by creating the .lyr file from the raster that has the greatest number of values...Unfortunately, the value field and the field of interest have an arbitrary and inconsistent relationship; value 1346 in one raster may refer to code 3 in one raster's attribute table, but it may refer to code 2 in another raster. So, when I replace the data source, even though ArcMap says that it is symbolizing on my field of interest, the symbols don't match the underlying data. For example, a pixel that is actually code 1 is symbolized as if it were code 4. It seems as if ArcMap gives the appearance of setting symbology by field B, when behind the scenes it is actually basing the symbology on the original relationship of the value field to field B. Is that as clear as mud? Using UpdateLayer() or ApplySymbologyFromLayer() does not resolve the above issues. Should these work in this situation? All of the work-arounds that I can think of require incredibly long processing periods (or ArcObjects). At the rate that I am observing, running lookup() on each raster (in order to set the field on which I'd like to symbolize as the value field) would take about 6 months...and I actually want to do this for two different fields, so it would take a year. That's not feasible, and I might as well do it manually. My only other option seems to be getting a 10.1 license and trying UniqueValuesSymbology to reset the symbology field; however, given that nothing else has worked as expected, I don't know if it's worth the time/money to try what may be another dead end. Can anyone think of any other ways to address this? Thanks. Thomas
... View more
07-15-2013
03:10 PM
|
0
|
1
|
979
|
POST
|
I know this is an old question, but I just encountered a need for this functionality as well, so I thought I'd share my solution: Use Extract By Polygon, and set the extraction area parameter to 'OUTSIDE'. See: http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Extract_by_Polygon/009z0000002q000000/ No need to convert between vector and raster and run a series of clips and reclassifications. Just one tool and done.
... View more
12-12-2012
10:47 AM
|
1
|
0
|
17945
|
Title | Kudos | Posted |
---|---|---|
1 | 12-12-2012 10:47 AM | |
1 | 05-03-2016 04:43 PM | |
2 | 06-22-2017 12:41 PM | |
1 | 12-20-2016 02:25 PM |
Online Status |
Offline
|
Date Last Visited |
04-24-2024
06:32 AM
|