Issue with Copy Features in Python

1748
13
06-21-2014 04:38 PM
ryank
by
New Contributor
I'm fairly new to writing scripts in python.  I'm creating one to take a feature class of about 100 points and turn it into individual points then run a cost path analysis on each of them.  The cost rasters and backlink rasters are already created.

The problem with the script is that it will create the individual points, but they won't work with the rest of the script that creates the cost paths while it's running.  If the script stops running and restarts with the section of code commented out to create the points, it will run the cost paths on the points it created the last time it ran.

     i = 1
     number_of_points = int(arcpy.GetCount_management("route_one_points").getOutput(0))
     print number_of_points
     while i <= number_of_points:
          print "testing"
          print i               
          pointname = "route_one_point" + str(i)
          arcpy.MakeFeatureLayer_management("route_one_points", pointname)
          arcpy.SelectLayerByAttribute_management(pointname, "NEW_SELECTION", "OBJECTID = %s" % i)
          arcpy.CopyFeatures_management("route_one_point" + str(i), "route_one_point" + str(i))
          print pointname
          
          outCostPath = arcpy.sa.CostPath(pointname, "route_one_cost", "route_one_backlink")
          outCostPath.save("route_one_point" + str(i) + "_path")
          i += 1


I'm pretty sure the problem is in Copy Features.  The script will recognize the features exist, but gives this error message:

arcgisscripting.ExecuteError: ERROR 010045: COSTPATH: The number of FROM cells is 0.
ERROR 010067: Error in executing grid expression.


Again, if I run it with the costpath lines commented out, it will run fine.  If I rerun it with the lines making the points commented out, it will run fine and create the costpaths.

The whole thing has to run in one go, so I can't just create 2 separate scripts and run them one at a time unfortunately.

Any suggestions on how to solve this problem?
Tags (2)
0 Kudos
13 Replies
DanPatterson_Retired
MVP Emeritus
reformat your code using code blocks so that indentation can be checked
0 Kudos
ryank
by
New Contributor
Is that what you're looking for?
0 Kudos
DanPatterson_Retired
MVP Emeritus
you should try to explicitly set the overwrite ability to be true and specify a working folder (env settings) so that the output file will be created in a particular (alternately, specify a full path and filename)
0 Kudos
ryank
by
New Contributor
I already did.  I didn't add those sections because I didn't believe it was relevant to this particular problem, and this section of code is going to be added to another much larger section.  It's just a bunch of extra stuff, but if you think the problem might be somewhere else in the code.  This is everything that runs in this script.  The commented out sections that all start with "arcpy" are not going to be commented out.  I was just running it to make sure the point features actually can run.

# cost paths tests

import sys, string, os, arcgisscripting, arcpy, datetime, time, math
arcpy.CheckOutExtension("Spatial")

#CostPath (in_destination_data, in_cost_distance_raster, in_cost_backlink_raster, {path_type}, {destination_field})
#route_one

arcpy.env.workspace = "C:/Users/Ryan/Documents/arcgis_folder/sitetwoworkarea.gdb"
#arcpy.env.workspace = "C:\Users\Ryan\Desktop\GIS\python\project_test\project_test_gdb.gdb"

#script will overwrite existing data

arcpy.env.overwriteOutput = 1


begin = datetime.datetime.now ()
start = time.clock ()
loopcounter = 0
raster_list = arcpy.ListRasters()


print raster_list
#def create_cost_paths():
     #print "I'm making the route cost."
     #i = 1
     #number_of_points = int(arcpy.GetCount_management("route_one_points").getOutput(0))
     #print number_of_points
     #loopcounter = 0
     #while i <= number_of_points:
          #print "testing"
          #print i               
          #pointname = "route_one_point" + str(i)
          #arcpy.MakeFeatureLayer_management("route_one_points", pointname)
          #arcpy.SelectLayerByAttribute_management(pointname, "NEW_SELECTION", "OBJECTID = %s" % i)
          #arcpy.CopyFeatures_management("route_one_point" + str(i), "route_one_point" + str(i))
          #print pointname
          
          ##outCostPath = arcpy.sa.CostPath(pointname, "route_one_cost", "route_one_backlink")
          ##outCostPath.save("route_one_point" + str(i) + "_path")
          #i += 1
def create_cost_paths():
     print "I'm making the route cost."
     i = 1
     number_of_points = int(arcpy.GetCount_management("route_one_points").getOutput(0))
     print number_of_points
     loopcounter = 0
     while i <= number_of_points:
          print "testing"
          print i               
          pointname = "route_one_point" + str(i)
          #arcpy.MakeFeatureLayer_management("route_one_points", pointname)
          #arcpy.SelectLayerByAttribute_management(pointname, "NEW_SELECTION", "OBJECTID = %s" % i)
          #arcpy.CopyFeatures_management("route_one_point" + str(i), "route_one_point" + str(i))
          print pointname
          
          outCostPath = arcpy.sa.CostPath(pointname, "route_one_cost", "route_one_backlink")
          outCostPath.save("route_one_point" + str(i) + "_path")
          i += 1

     i = 1


def test():
     outCostPath = arcpy.sa.CostPath("route_one_point1", "route_one_cost", "route_one_backlink")
     outCostPath.save("route_one_point1_path")
     
create_cost_paths()




print "I started at " + str(begin.hour) + ":" + str(begin.minute) 
print "I took " + str(int((time.clock() - start) / 3600)) + " hours and " + str((int(time.clock() - start) / 60 ) % 60) + " minutes to finish"
0 Kudos
markdenil
Occasional Contributor III
A couple things:

You test the count of features in the input fc using GetCount_management,
why not test the output too?. You can test both the layer and the new fc.

Why do you make a layer, make a selection, make a fc?
Why not just make a layer with your selection where clause
and pass the layer to CostPath?

The Help for Cost Path says it takes an input feature layer, not a feature class.

I agree that you should also explicitly handle your layers and FCs with full paths
and an explicit " if Exists: Delete " function...

EDIT:  very good point from Dallas (below); to wit:
iterate through the cursor, don't rely on a separate counter,
and feature IDs are internally set: they can be useful, but Arc puts them there
for its own benefit, not yours...
0 Kudos
ryank
by
New Contributor

Sorry for the long response.  A lot came up with the reserves this last month.

I set up a count so I can set up a try/except later.  I use it in a similar loop and it works out pretty well.  If I don't use a separate counter, it can't keep track of both the iteration and which point is being run.  At least I don't know enough about running cursors to do so.

If I don't include the MakeFeatureLayer it throws this error

arcgisscripting.ExecuteError: Failed to execute. Parameters are not valid.

The value cannot be a feature class

The help for the Select Layer By Attribute scripting gives this as the example for performing this process

# Name: ExtactFeaturesByLocationAndAttribute.py

# Description: Extract features to a new feature class based on a spatial relationships to another layer AND an attribute query

# Author: ESRI

# Import system modules

import arcpy

# Set the workspace

env.workspace = "c:/data/mexico.gdb"

# Make a layer from the feature class

arcpy.MakeFeatureLayer_management("cities", "lyr")

# Select all cities which overlap the chihuahua polygon

arcpy.SelectLayerByLocation_management("lyr", "intersect", "chihuahua", 0, "new_selection")

# Within selected features, further select only those cities which have a population > 10,000  

arcpy.SelectLayerByAttribute_management("lyr", "SUBSET_SELECTION", ' "population" > 10000 ')

# Write the selected features to a new featureclass

arcpy.CopyFeatures_management("lyr", "chihuahua_10000plus")

I'm mostly using their example as a startpoint for this.  I'm perfectly willing to try something else, but again keep in mind I'm pretty new to this.  I'm not sure if that's what you meant when you asked why I go through that.  And I'm not sure how to pass the where clause straight to the costpath, but I also need to keep each point individually, because each point is going to be used later.

The Help for Cost Path says it takes an input feature layer, not a feature class.

The thing is, it will accept the output if I run the cost path in another script.  I'm not sure if that matters.

I don't see a post by Dallas.  Mark Denil's post is the last I can see.  Are there other posts?

0 Kudos
ToddUlery
Occasional Contributor

Hi Ryan,

Just looking over the Bulk of the scipt and have questions:

arcpy.env.workspace = "SET TO A GDB"

You have your environment set to a GDB.

raster_list = arcpy.ListRasters()

Listing Rasters from the environment.

I don't think you going to get a list of Rasters, they are stored in Raster Datasets within a GDB.

When i Print the list it is NONE.

The environment should be set to a folder where the Rasters are stored.

def create_cost_paths(**ARGUMENTS**):

Your create_cost_paths() function has no Arguments()

So when you set variables referenced to "route_one_cost" (RASTER) it doesn't reference anything. It doesn't find anything.

This is because you carry nothing into in the function from the environment or list from the environment.

You can fix this be either taking your arcpy.env.workspace and moving it into the function, or you can add the LIST from the environment as argument for the function that uses it.

0 Kudos
ryank
by
New Contributor

I don't think you going to get a list of Rasters, they are stored in Raster Datasets within a GDB.

When i Print the list it is NONE.

The environment should be set to a folder where the Rasters are stored.

Again, I'm new to python, but wouldn't it return none for you no matter what since you don't have the rasters?  When I print the list it does return the rasters, even when I place print code inside the function.

0 Kudos
ToddUlery
Occasional Contributor

You are correct, but I have raster datasets inside another GDB that i am using to test with.

What are you setting for your env?

I feel like your env, is not set to a GDB.

0 Kudos