I'm a bit lost here, so my answer may be off base. When you say you want the ExtentID
, that appears to be the name of the Dataframe you're exporting the extent of. If this is the case (which is what your code is doing to my best guess), you don't need the [x] index when printing it. :
for el in arcpy.mapping.ListLayoutElements(mxd2, "DATAFRAME_ELEMENT"):
ExtentIDStore = str(el.name)
#print x, y, z <--- You don't need to print x y and z. They are unrelated at this point.
print ExtentIDStore #used to see which item to add to the shape file
print ExtentIDStore[x] # <- This will just print an indexed character in the string
By the time you reach the loop above, your code is only concerned with the Dataframe Element in question, so there is no need to do any indexing for storage. ExtendIDStore
should be what you add to the shapefile row.
Your error which results at this line:
row.strField = str(x)
Is probably because you are not referencing a field that exists. What comes after the row reference is the name of the Field. In this case, it should be:
row.ExtentID = ExtentIDStore
File name you can get via the filePath
property of the MapDocument class and the os.path.basename
method, i.e.:
filepath = mxd2.filePath # Gets full path of MXD used in your dataframe loop
filename = os.path.basename(filepath) # Extracts the file name and extension
row.FileRef = filename
If you don't want the extension, use filename.strip(".mxd")
to remove it.
Scale would be:
scale = el.scale # Scale of the dataframe referenced in the loop
row.Scale = scale
And that should fill in the rows you're looking for.
For the new problem, I think you are misusing the insert cursor. The second argument should be a spatial reference, which cannot be gleaned via an MXD. I would recommend creating the cursor with only one argument (the output file or dfStore). You also forgot the last (and most important) line:
rows.insertRow(row)
Without that your data never gets put into the table. Put that down at the end of the row loop so that the data is actually inserted after all the variables are set.
For more information about accessing Dataframe, layer, and map properties (scale, name, current position), check out the mapping module. The scale property of the Dataframe class can be seen on the classes page of the same name.
You might want to try putting del row
inside of the loop as the last call after rows.updateRow{row}
. Your object deletion does not take place until you are outside of the loop, so it might just be the rather large collection of row objects that you are creating. I would think that the row objects are being deleted as you go out of scope, but that might not be the case.
You can also try using the garbage collection module to debug and/or fix the issue:
http://docs.python.org/library/gc.html
Some other issues... do all of your casting outside the loop.
e.g. LL = int(LL)
before the loop, so that inside the loop you just do 'row.LL = LL'
It looks like you are doing no calculations inside the loop that would change any of these values from row to row, so there is no need to do the casting inside the loop.
Edit:
I did not realize that you were looping this against many files. The problem might be in your outer loop call, not in your function call. Since it works correctly in ArcMap, but not outside of ArcMap, you might be reloading arcpy or creating new geoprocessor objects with each call to a file. This is a very costly operation that gets much worse the more times you execute it.
I ran into a similar problem with an operation that I was trying to call every 20 seconds outside of ArcMap. Every time that I called the inner function from the outer timing loop, arcpy was being reloaded even though I imported arcpy into the outer timing loop. As a result, my inner function kept running slower and slower and was impossible to finish in 20 seconds.
To get around this, I imported arcpy into the outer timing loop, and then passed arcpy as an argument into the inner function. Once I did this, my inner function was executing in under 3 seconds every time.
So, for your function, you might want to try changing its definition to:
def createGeom(geom,header,band,scratchDB,buffer, dist, arcpy):
and then when you call it, make sure you pass arcpy
as the 7th argument.
As far as I can tell, inside of ArcMap, arcpy is loaded once and then maintained for any calls against it, even if called by an inner function. Hence the much better performance when executed in ArcMap.
Best Answer
There were issues with this at 10.0, but we've ironed out all the visible ones in the service packs. You should be seeing a significant improvement in performance on
ListLayoutElements
and friends using SP2 over SP1 or 10.0. Are subsequent calls to the same function as slow? What if you add the time that it takes to load the document into ArcMap into account? Would that bring the two to something close to one another?Try this:
Outside of ArcMap, the Map Document classes need to set up what is essentially a hardware context to draw to to ensure the metrics of layout elements are correct. This is not necessary in the active ArcMap document because it has the hardware context of the application's window, but it may account to some extent for the speed differences.