Quantcast
Channel: Question and Answer » arcpy
Viewing all 767 articles
Browse latest View live

Problem with Nested For Loop in ArcPy

$
0
0

I have two vector layer files, ‘hausnummer_cropped5′ and ‘gebaudepoints_cropped5 – Kopie2′. Both have a point geometry and I am trying to shift the locations of the gebaudepoints_cropped5 points onto the corresponding hausnummer_cropped5 points (there is a one-to-one correlation between them) if certain conditions are met (their original locations are slightly different). There are 68 gebaudepoints and 62 hausnummers.

The code I have written is this:

import arcpy

gebaudepoints_no = 68
hausnummer_no = 62
count = 0

with arcpy.da.UpdateCursor('hausnummer_cropped5', ['HAUSNR','STRASSE','SHAPE@XY']) as cursor1:

    for row1 in cursor1:

      with arcpy.da.UpdateCursor('gebaudepoints_cropped5 - Kopie2', ['ZA3',     'ZA2','GN5','SHAPE@XY']) as cursor2: 

         for row2 in cursor2:    

                if (row2[0] == row1[0]) and (row2[1] == row1[1]): # and (row2[2] > 0):

                  X = row1[2][0] 
                  Y = row1[2][1]  
                  count += 1 

                  cursor2.updateRow([row2[0], row2[1], row2[2], [(X),(Y)]])
                  #cursor2.deleteRow()

                  print count, gebaudepoints_no - count

There are 2 things I don’t understand:

  1. After the code has been run, the value of ‘count’ is 92 and not 68. That means the loop has run 92 times even though it should have run only 68 times.

  2. Most of the gebaudepoints actually get placed on top of the hausnummer points, but around 5 to 6 don’t, even though they meet the required conditions. However, if I use the cursor2.deleteRow() statement (which is written as a comment above), all the gebaudepoints get removed so that indicates that the code is actually going through those points as well, but it’s just not shifting them.

I didn’t have these two problems when I was using a different set of gebaudepoints and hausnummers so I’m wondering why this is occurring in this case.

Note: I am using ArcGis 10.2.2

Thank you for your help


Multi Value User Input as Variable in SQL Statement

$
0
0

I’m attempting to write a script that takes a user’s selection as a parameter and uses that as part of the SelectByAttributes function. The parameter represents field attributes and is multi value, and the user can select one or multiple.

So what I have at this point is the list of all available attributes, and each selected as the defualt.

enter image description here

Also, Here is the tool validation code and Parameter Properties:

import arcpy
class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""
    shape = "G:_DPDSTEVENFIELD.shp"
    rows = arcpy.SearchCursor(shape)
    self.params[0].filter.list = sorted(list(set(r.getValue('DPD_FLD_TY') for r in rows)))
    all = self.params[0].filter.list
    self.params[0].value = all
    del rows
    return

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    return

enter image description here

I want the user to have the option to run the tool with multiple attributes selected or
with just one selected, and use that as part of the SQL statement within the SelectByAttribute function. For example, if the user selects “GAS” and “UNKNOWN”, the SelectByAttributes function would look like

arcpy.SelectLayerByAttribute_management(lyr,"NEW_SELECTION",""""DPD_FLD_TY" = 'GAS' OR "DPD_FLD_TY" ='UNKNOWN'""")

So my main question is: what would the code be to check how many attributes are selected and based on that, have the SQL statement contain the proper amount of “OR” statements? Also, would the parameter be considered just one, or would it be multiple parameters i.e. GetParameterAsText(0) vs. GetParameterAsText(0)…GetParameterAsText(3)

I’m sorry if this is confusing, but I don’t know exactly where to start with this problem.

This is how I am referencing the layer:

import arcpy

mxd = arcpy.mapping.MapDocument('CURRENT')
mm = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
lyr = arcpy.mapping.ListLayers(mxd, 'FIELD')[0]
field = arcpy.GetParameterAsText(0)

Arcpy: Processing multiple files subsequently

$
0
0

I have an indexed dictionary containing files and want to “mosaic” (arcpy.MosaicToNewRaster_management) all files with the same index. The number of files per index range from 1 to about 30.

dic_of_files = {"index1":["file11", "file12","file13"], "index2":["file21", "file22"]}

for key in dic_of_files.iterkeys():
    arcpy.MosaicToNewRaster_management(dic_of_files[key], otherarcpyoptions)

Mosaicing 30 files in one go doesnt seem to work, I guess number is just to high. I had the idea of writing a script where python counts the number of files per index via and the loops through processing first file 1 and 2, then processing the result with file 3 and so on till it reaches the last file.

for key in dic_of_files.iterkeys():
    key_len = len(dic_of_files[key])
    if key_len < 2:
        arcpy.MosaicToNewRaster_management(dic_of_files[key], otherarcpyoptions)
    else:
        yes.. else what?

Can anybody tell me if this is a reasonable way to solve the problem? And maybe give me a hint how to script this solution?

EDIT:
ok I’ve gotten one step farther. I’ve nested a couple of loops so that python pairs up the first two items in the list, then the next two and so on (in case of an uneven item number it pairs up the last three).

The code now looks as follows (I’m omitting the arcpy function to keep it as simple as possible):

dic_of_files = {"index1": ["file10", "file11", "file12", "file13", "file14", "file15", "file16", "file17"], "index2": ["file20", "file21", "file22"]}
dic_of_pairs = {}

def addstuff(i="", v="", mydict=""):
    if i not in mydict:
        mydict[i] = []
    mydict[i].append(v)

for key, val in dic_of_files.items():
    key_len = len(val)
    if key_len < 2:
        print "do nothing"
    else:
        if key_len % 2 == 0:
            for j in range(0, (key_len - 1), 2):
                # Even number of files, process pairs all through
                output = str(str(j) + str(j + 1))
                addstuff(key, output, dic_of_pairs)
        else:
            for k in range(0, (key_len - 2), 2):
                if k < (key_len - 3):
                    # Uneven number of files. Process pairs at first..
                    output = str(str(k) + str(k + 1))
                    addstuff(key, output, dic_of_pairs)
                else:
                    # ... and process the last three files as triplets
                    output = str(str(k) + str(k + 1) + str(k + 2))
                    addstuff(key, output, dic_of_pairs)

Sadly, one round doesn’t do the trick, I have to repeat this block of code on the new dictionary (here: “dic_of_pairs”). It would be very elegant if I could use this same piece of code for the second (and all succeeding) rounds, until the every index contains just one file.

Is there a way to do this? Is overwriting the original dictionary (“dic_of_files”) an option, or better to pack this code into a function?

Using ArcGIS ModelBuilder and GeoCoding

$
0
0

I looked at ArcGIS and python and I’m not quite ready for that rabbit hole as I’m on a schedule. I have a little experience but not at the level to pick it up quickly enough for my time frame.

The model runs well, I’ve munged the tables so the geocoder picks up all the fields properly. But I can’t get it to save the results of each geocoding process to an individual file. It just keeps overwriting the same file.

enter image description here

I tried connecting the name variable to the geocode addresses function but get this:
enter image description here

Which doesn’t work.

Any suggestions how I can get this done? If there’s a simple edit in scripting outside of the model builder I can do that. Thank you.

arcpy.da.UpdateCursor where clause persists

$
0
0

I have some unexpected behaviour in an UpdateCursor. I’m iterating over quite a large dataset, and I’ve found that Python freaks out less if I break up the iteration into chunks:

env.workspace = r"ROADS.gdb"
arcpy.MakeFeatureLayer_management("JUNCTIONS", "jn_layer")

for i in range(-70000, 1500000, 10000):
    strFilter = "UFI >= " + str(i) + " AND UFI < " + str(i+10000)
    print strFilter

    with arcpy.da.UpdateCursor("jn_layer", ["OID@","UFI"], strFilter) as upCursor:
        for rowInt in upCursor:
            # do stuff

I would expect this to create a new cursor for each iteration with different filters, as per the print line:

UFI >= -70000 AND UFI < -60000
UFI >= -60000 AND UFI < -50000
UFI >= -50000 AND UFI < -40000
...etc

The problem is the first iteration works as expected, but each subsequent iteration of i returns no rows – it spits out each subsequent filter value but does nothing inside the with loop. Once it finishes, if I change the initial value:

for i in range(-60000, 1500000, 10000):

then it processes the first 10000 values (which were ignored before), but again the rest of the iterations of the with loop return no values. It feels like it’s keeping the first filter on jn_layer and trying to apply the second filter to that filtered set, which of course returns no rows since there’s no overlap between the ranges.

Is this the expected behaviour? I would have thought creating a cursor on a layer would only filter the layer for as long as the cursor exists, and the with keyword should be destroying the cursor before the filter changes…? Any advice would be most welcome.

Parsing long lat xml tags into shapefile using ArcPy? [closed]

Why Arcpy ExtractByMask returns a mysterious value “-128”

$
0
0

I’m getting an unexpected value of “-128″ as a results of arcpy Extract by mask analysis. Input data is Esri GRID only containing values 0 or 1. Output format is .tif.

For example, in this picture white area is -128, while it should be orange, as a part of the area correctly is (VALUE = 0). Blue, (VALUE = 1), is also correctly depicted here.

Example

I think that it’s some sort of compression issue, but I don’t know where it arises and how to avoid it in arcpy. If I rerun the tool manually from Geoprocessing results window this artefact does not appear.The results of the analyse is good enough for me, since it doesn’t matter whether the area is 0 or -128, but I’m still wondering where these values appear from.

I’m using a for-loop to run through ten rasters. Like this

 for i in range(0,10):
   outrast = ExtractByMask(inrast, masklist[i])

Inrast is one binary raster (32 bit, ESRI GRID), which I’m splitting into 10 different result files (.tif). masklist contains ten different .shp-locations, i.e. “C:/data/mask1.shp”, “C:/data/mask2.shp” and so on

I’m using ArcMap v. 10.2.1

Thanks.

Add multiple Layer files in subdirectories to mxd using python

$
0
0

I have more than 300 layer files located in many sub-Folders and sub-sub-Folders. All Sub Folders are located in one large directory.I read Use python to add layers to TOC
and I try, with arcpy, to detect all the layers and add them to mxd.
Is it possible?


A mistake in very easy python code (Buffer 1 – Buffer 2- Erase 2 fom 1)

$
0
0

I need to make 500m rings (not full circle) around points (cities). I try to make 1. buffer: 2500 – 8500m (each 500m) and second buffer 3000 – 9000 (each 500m) and then erase 2500m from 3000m, 3000m (1.st buffer) from 3500m (second buffer), … to get those 500m rings. But everytime i get an error.

import arcpy.sa
... k = 3000
... while k<=9000:
...     arcpy.Buffer_analysis("sidla","sidlaBuff"+str(k),k)
...     k=k+500
... l = 2500
... while l<=8500:
...     arcpy.Buffer_analysis("sidla","vyrezBuff"+str(l),l)
...     l=l+500
arcpy.Erase_analysis("sidlaBuff"+str(k),"vyrezBuff"+str(l),"vysledek"+str(l))

The error is something about that it can’t do the layer sidlaBuff9500 and vyrezBuff9000, but those layers i dont want to do… but if i run that code WITHOUT the Erase, all buffer run correctly. Can anyone help?

Animating alterations to DEM based on function using ArcGIS for Desktop?

$
0
0

I’ve generated a function that alters height values of a DEM based on certain criteria. What I’m looking at doing now is animating this in ArcScene. Is there a way, in ArcGIS, for each frame to be the result of a raster calculation?

eg Frame_Timecode–>(function)–>Adjusted_DEM–>render

I’m a strong Python programmer, but have not yet done any scripting with ArcGIS, so I’m quite happy if the answer involves some coding.

Python column checker-comparing 2 fields

$
0
0

One problem I am having is the following:

I want to create an automatic program to see how well the automozation has been with comparing the results of 2 columns to each other in the same column.

In python psedocode, it would look like this:

rows= "all rows in table X"
row=rows.next()

counter =0
row counter= rows.length()// amount of rows

while row:
         //If the row`s attribute1 and attribute 2 are the same, add 1 to counter...
         if row. Atrribute1 == row.Attribute:
            counter+= counter
            row=rows.next()
         else:
             // Just go on to next row
            row=row.next()

//Give an overall percentage of success
print(counter/row_counter)*100

I cannot imagine that this is hard, but I cannot get it to work with the code from research

One of the major problems is I cannot find a way to compare 2 field to each other. Ive been searching for a while now, but have found that you can see what a field is, but not how to directly call it.


Originally this question included the error message below which was addressed by one of the answers:

‘module’ object has no attribute ‘searchCursor’

Debugging ArcPy ImportToolBox AttributeError: Object: Tool or environment not found?

$
0
0

First post here.

I am trying to use the ConcatenateRowValues tool provided by ESRI. My overall code for my script is working fine except when it tries to use the ConcantenateRowValues Tool. I start by importing the proper toolbox and then attempt to get my script to access it. Below is my code to do this:

arcpy.ImportToolbox("C:/Users/'USERNAME'/Desktop/BaseLayer/ConcatenateRowValue101/ConcatenateRowValues101.tbx")
arcpy.ConcatenateRowValues_AA(hlint, "SHORT_DESC", "NAME", "Hydro_Line", "-")

The Error that’s returned is:

Runtime error
Traceback (most recent call last):
File "<string>", line 67, in <module>
File "C:Users'USERNAME'DesktopBaseLayerConcatenateRowValue101ConcatenateRowValues101.tbx", line 54, in ConcatenateRowValues
/jVXV+BHwwJ5+Gfgv/wnbP8A+NV2Eo+ZTjHPQ9qlR60cIvojBSkupxw+Avwvz/yTTwX/AOE7Z/8A
AttributeError: Object: Tool or environment <ConcatenateRowValues_AA> not found

TypeError: 'NoneType' object is not iterable from Python Scripting for Geoprocessing Workflow exercise?

$
0
0

I am currently taking ESRI’s Python Scripting for Geoprocessing Workflows. I have following their step by step however there seem to be a problem that I am getting an error.

import arcpy
#Set geoprocessing environments
arcpy.env.workspace = "C:/Student/PythonGP10_0/Data/SanJuan.gdb)"

arcpy.env.overwriteOutput = True

#Create list of feature classes in SanJuan.gdb
fclList = arcpy.ListFeatureClasses()

#Create a loop to buffer Lakes and Streams
bufferList = []
for fc in fcList:
    if fc == "Lakes" or fc == "Streams":
        arcpy.Buffer_analysis(fc, fc + "Buffer", "1000 meters")
        bufferList.append(fc + "Buffer")
arcpy.Union_analysis(bufferList, "WaterBuffers")

The error I get here from the IDE Window shows the error:

PythonWin 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32.
Portions Copyright 1994-2008 Mark Hammond - see 'Help/About PythonWin' for further copyright information.
>>> import arcpy
Traceback (most recent call last):
  File "C:Python27Libsite-packagespythonwinpywinframeworkscriptutils.py", line 326, in RunScript
    exec codeObject in __main__.__dict__
  File "C:StudentPythonGP10_0ScriptsBufferWater.py", line 9, in <module>
    for fc in fcList:
TypeError: 'NoneType' object is not iterable

List File Geodatabase Topology

$
0
0

I’m trying to write a script that looks into a dataset and list all the elements in the dataset. The dataset comprises of Feature classes and FGDB Toppology. When I uses ListFeatureClasses, it outputs all the feature classes in the dataset,so I know the code works, but I want to list also the topology file. ListFiles does not work. Which of the List functions should I use to list topology?
This is the code I have so far:

import arcpy
import os
PATH1 = r"C:UsersDaimon NurseDesktopDFMPROJECTDFM.gdb"
PATH2 = r"C:UsersDaimon NurseDesktopDFMPROJECTComplete Final Capstone MapZ2 Map File Geodatabase.gdb"
arcpy.env.workspace = PATH2
arcpy.env.overwriteOutput=True
for data in arcpy.ListDatasets():
    if data == "AllZones":
        print data + "1"
        path = os.path.join(PATH2,data)
        print path
        arcpy.env.workspace = path
        for file in arcpy.ListFiles():
            print file 

If I change arcpy.ListFiles() to arcpy.ListFeatureClasses(), the code works as I stated above.

How to solve performance issues with this ArcPy code?

$
0
0

This is my ArcPy code. Only this part of code was active (and a few lines before to be able to use those variables) what was running for 1 hour and inserted only 2863 records instead of 33000. This is the long-running code block, and now only this part is running. That hsz contains topographical numbers. There are at least 30-40 of them. The “telekterulete” table has ~33000 rows and the “shp” has 28000 rows. The “telek” is an empty table in the beginning. I have Windows 7 operating system, with NTFS file system. I don’t know the time of the queries and the insert. I don’t think the code needs to be more described, because everybody can see what I want to do here from the code itself.

How could I optimize this code or what should I use to achieve this goal faster?

hsz = [row[0] for row in arcpy.da.SearchCursor(telekterulete, (Helyrajziszam_egyedi))]
helyrajziszamok = set(hsz)
lista=list(helyrajziszamok)
for elem in lista: 
    cursor = arcpy.da.SearchCursor(shp,("Helyrajziszam_egyedi","Ter","Ter_est"))
    valt=0
    for sor in cursor:
        if sor[0] == elem:
            if sor[1] is None and sor[2] is not None:
                    valt=valt+sor[2]
            elif sor[1] is not None:
                valt=valt+sor[1]

    rows=arcpy.da.InsertCursor(telek,("Helyrajziszam_egyedi","Tt_e_est"))
    sor=list()
    sor.extend([elem,valt])
    rows.insertRow(sor)

Output raster from IDW interpolation tool is from 3.40282e+038 to -3.40282e+038 in ArcPy

$
0
0

I am not familiar with Python in ArcGIS, so I used ModelBuilder first to set the environment and put the tool in. The model worked right and the output raster seemed good.

Then I exported the model to a Python script. The raster output is generated, but the value of raster is from from 3.40282e+038 to -3.40282e+038. Why did this happen and how can I fix it?

My script is like this:

# Import arcpy module
import arcpy

# Check out any necessary licenses
arcpy.CheckOutExtension("3D")

# Set Geoprocessing environments
arcpy.env.scratchWorkspace = "C:\Documents\ArcGIS\biomass.gdb"
arcpy.env.outputCoordinateSystem = "PROJCS['WGS_1984_Plate_Carree',GEOGCS['GCS_WGS_1984',DATUM['D_WGS_1984',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Plate_Carree'],PARAMETER['False_Easting',0.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',0.0],UNIT['Meter',1.0]]"

arcpy.env.extent = "60.8785969898536 -11.0048500049116 148.898540012983 53.560734"
arcpy.env.cellSize = "MAXOF"
arcpy.env.workspace = "C:\Desktop\shape"
arcpy.env.mask = "newasia.shp"
# Local variables:
xyz_shp = "xyz.shp"
b1_ald22222 = "C:\Documents\ArcGIS\mass.gdb\b1_ald22222"
# Process: IDW
arcpy.Idw_3d(xyz_shp, "ALDX", b1_ald22222, "27000", "2", "VARIABLE 8", "")

Can not SET a Value in table using Python?

$
0
0

I’am trying to set values in table, the code run good, i don’t got errors, but nothing is done !
I’m using Arcgis10.1, arcpy and Python
This is the code :

 import arcpy
 import math
 import arcview
 from arcpy import env


 arcpy.env.workspace = "D:/Users/saadiya/Documents/ArcGIS/Default1.gdb"
 arcpy.env.overwriteOutput = True

 cur = arcpy.UpdateCursor("Join_Dataset")
 for row in cur :
     SW = row.getValue("RefName_SW")
     S  = row.getValue("RefName_S")
     SE  = row.getValue("RefName_SE")
     new_s = S
     if (SW != S):
         new_s = new_s+", "+SW
     elif (SE != S):
         new_s = new_s+", "+SE
         row.setValue("Sud", new_s)
         cur.updateRow(row)
         print new_s

I got this error :

Traceback (most recent call last):
  File "<string>", line 11, in <module>
  File "d:program files (x86)arcgisdesktop10.1arcpyarcpyarcobjectsarcobjects.py", line 102, in updateRow
    return convertArcObjectToPythonObject(self._arc_object.UpdateRow(*gp_fixargs(args)))
RuntimeError: ERROR 999999: Error executing function.
Objects in this class cannot be updated outside an edit session [Join_Dataset]

Converting geographic units with ArcPy

$
0
0

I am trying to compare a set of point features to the centroid of a single feature polygon using ArcPy. The problem is that the polygon generates a set of XY coordinates in meters, whereas the set of points generates a set of XY coordinates in decimal degrees. Is there anyway to ensure consistency? Using some variations of SHAPE@XY@DECIMALDEGREES threw errors. When I do the following:

with arcpy.da.SearchCursor("prim_catch_dissolved", ["TR", "SHAPE@XY"]) as cursor:

I get the results in meters, which is not what I’m after. Thanks.

UpdateCursor stops after the first iteration

$
0
0

My arcpy script includes two updateCursor Objects. The first iteration of the “outer” coursor works fine, but the programm stops when it comes to the second iteration at updateRow(). Has somebody an idea, where the problem could be?

Here is the code snippet:

arcpy.env.workspace = "I:/GIS/VoGIS_Projekte/Wanderwege/Basisdaten/Basisdaten_Sommer/wandern_SK.gdb"

# Use row object to get and set field values
cursor = arcpy.UpdateCursor("wanderwege/wander_wege_3d")

# Iterate through rows and update values
row_i = 1
wa_j = 1
for row in cursor:
    print row_i
    row.WEG_LAENGE = '999'
    cursor.updateRow(row)               # The 2nd iteration stops here...
    wwege = arcpy.UpdateCursor("wanderwege/wander_wege")

    for wa in wwege:
        print wa_j
        wa.WEG_KATEGO = "Kaps999"
        wwege.updateRow(wa)                 # save
        wa_j = wa_j + 1
    del wwege
    del wa

    row_i = row_i + 1


del row
del cursor

I am working with:
ArcGIS 10.2
Python 2.7
Windows 7

P.S.: I know, that this code doesn’t make much sense – I just wanted to reproduce the error of a quite complicated script.

Ignoring group layers when iterating through layers

$
0
0

I have this nice code that goes through each dataframe in the current MXD, and through each layer in the dataframe, and generates a list containing the name of the dataframe, the name of the layer, and the name of the coordinate system of that layer, divided by commas. Something like this:

Focus Area,SubArea,South_Pole_Lambert_Azimuthal_Equal_Area
Focus Area,SubArea_2,South_Pole_Lambert_Azimuthal_Equal_Area
and so on.

The code is this:

import arcpy
mxd=arcpy.mapping.MapDocument("CURRENT")
dataframes=arcpy.mapping.ListDataFrames(mxd)
for dataframe in dataframes:
    for lyr in arcpy.mapping.ListLayers(mxd, "", dataframe):
        print(dataframe.name+","+lyr.name+","+arcpy.Describe(lyr).spatialReference.name)

The code works well if there are no Group Layers in the dataframes. If there is a group layer containing layers, the code will stop and throw this message:

Runtime error 
Traceback (most recent call last):
  File "<string>", line 6, in <module>
  File "c:program files (x86)arcgisdesktop10.2arcpyarcpy__init__.py", line 1234, in Describe
    return gp.describe(value)
  File "c:program files (x86)arcgisdesktop10.2arcpyarcpygeoprocessing_base.py", line 374, in describe
    self._gp.Describe(*gp_fixargs(args, True)))
IOError: "Climatology and environment (L)" does not exist

So, “Climatology and environment (L)” is a group layer. In my understanding, the code is trying to find the “layer” and get its coordinate system, but there is no actual layer, so it just breaks. Do you think of any workaround to this? A way to ignore the group layers maybe?

Viewing all 767 articles
Browse latest View live