arcpy Array methods

7860
5
02-01-2012 01:00 PM
by Anonymous User
Not applicable
Has anyone else had problems with the Array class? I'm trying to do a sort on line segments that I have stored as arrays of points. All the Array methods seem to work fine except for insert and clone. Every time I use the insert method it appends.

Also does anybody have a working example of how to use the clone method?
Tags (2)
0 Kudos
5 Replies
DanPatterson_Retired
MVP Emeritus
do you have a code example?
0 Kudos
by Anonymous User
Not applicable
import arcpy

infc = "C:/Pipeline"

# Identify the geometry field
#
desc = arcpy.Describe(infc)
shapefieldname = desc.ShapeFieldName

# Create search cursor
#
rows = arcpy.SearchCursor(infc)
featureList=[]
array = arcpy.Array()
point = arcpy.Point()

# Build polyline list
#
for row in rows:
    
    feat = row.getValue(shapefieldname)
    partnum = 0
    partcount = feat.partCount

    while partnum < partcount:
        part = feat.getPart(partnum)
        pnt = part.next()
        pntcount = 0
        pntArray = arcpy.Array()
         
        while pnt:
            
            if pnt:
                point = arcpy.Point()
                point.X = pnt.X
                point.Y = pnt.Y
                point.ID = pnt.ID
                point.Z = pnt.Z
                point.M = pnt.M
                
                #Create an array of points representing a line
                pntArray.add(point)
                
                pnt = part.next()
                pntcount += 1

            if not pnt: 
                pnt = part.next()
                    
        partnum += 1

        #Create a master array of point arrays in order to sort them
        array.add(pntArray)
        

# Sort polyline array
#

pLineMax = array.count
dummyPoint = arcpy.Point()
dummyArray = arcpy.Array()

#Index for point arrays that needs comparison
pLineIndex = 0

while pLineIndex < pLineMax - 1:

    #Index for point arrays that is a test comparison
    pLineIndex2 = pLineIndex + 2

    while pLineIndex2 < pLineMax - 1:

        # Compare endpoint of line to endpoints of other lines
        tempPoint1 = array[pLineIndex].getObject(array[pLineIndex].count-1)
        tempPoint2 = array[pLineIndex2].getObject(0)
        tempPoint3 = array[pLineIndex2].getObject(array[pLineIndex2].count-1)

        # if endpoint matches another segment
        if str(tempPoint1) == str(tempPoint2):
            
            # Assign pointer to point array that needs to be moved
            pntArray = array.getObject(pLineIndex2)

            # Remove point array from master array
            array.remove(pLineIndex2)

            # Insert point array in the appropriate place
            array.insert(pLineIndex + 1, pntArray)

            # Exit the while loop
            pLineIndex2 = pLineMax
                          
        pLineIndex2 += 1

    pLineIndex +=1



The first part is copied from the help files and modified. I wrote this in PythonWin 2.6. I only have the sort for one end of the line segment so far.

I'm new to Python but I have some experience as a programmer.

Thank you very much
0 Kudos
by Anonymous User
Not applicable
The only workaround I've found is to redraw the array of point arrays in the order I want. I know that the Array insert and replace methods expect a point or array object, and the clone method expects a point object. I can only think that the problem is that these methods aren't accepting the parameters as array or point objects, even though I built the arrays using arcpy.Array(), array.add(), and pntArray.add(), and I've built the points using arcpy.Point(). I'm passing the objects based as addresses retrieved by using the getObject method. It almost seems like the methods will only accept static objects and not dynamic objects, but isn't the array just a set of pointers?
0 Kudos
RobFlemming
New Contributor II
Another bug, I think:

import arcpy
p = arcpy.Point()
a = arcpy.Array()
a.add(p)
a.add(p)
a.add(p)
p.X=11
a.replace(0,p) #so far so good
p.X=12
a.replace(2,p) #but, they are both replaced
p2 = arcpy.Point() #however, if you make a new point...
p2.X=42
a.replace(2,p2)#...it goes only where expected

If you change an attribute of an existing point object, even the id, and then replace it somewhere, it will replace all the old instances in the array with the new attribute.
(So maybe it's not a bug?)
(just a little annoying)
0 Kudos
KimOllivier
Occasional Contributor III
Maybe it is because we are all too casual with the difference between immutable and mutable objects in Python. The arrays are mutable, so assigning a new value does not work as expected.
# classic example of mutabilty in action
a = ['spam', 'eggs', 100, 1234]
b = a
b.append("abc")

print a
# ['spam','eggs',100,1234,'abc'] # << note that a is altered when we only appended to b
print b
# ['spam','eggs',100,1234,'abc']

0 Kudos