Create four points with slightly different properties to test other properties.
>>> pnt0 = arcpy.Point(X=1,Y=2,Z=3,M=4,ID=0)
>>> pnt1 = arcpy.Point(X=1,Y=2,Z=1,M=0,ID=1)
>>> pnt2 = arcpy.Point(X=3,Y=4,Z=2,M=2,ID=2)
>>> pnt3 = arcpy.Point(X=1,Y=2,Z=3,M=4,ID=3)
Perform some equality checks to test what is comparable to pnt0. There is some fancy attribute collection and print formatting.
>>> all_pnts = [pnt0,pnt1,pnt2,pnt3]
>>> equality = [[getattr(pnt0,i) == getattr(p,i) for i in props] for p in all_pnts]
>>> for i in range(len(equality)):
... print('pnt0 vs pnt{}: {}'.format(i, equality[i]))
...
pnt0 vs pnt0: [True, True, True, True, True]
pnt0 vs pnt1: [True, True, False, False, False]
pnt0 vs pnt2: [False, False, False, False, False]
pnt0 vs pnt3: [True, True, True, True, False]
>>>
It is good, that pnt0 is identical to itself, and pnt3 only differs by the ID number. All the other comparisons identify what attributes in the properties list (prop) differ. Why not simplify things then and use the built-in methods? Well...because...
>>> pnt0 == pnt3
False
>>> pnt0.equals(pnt3)
True
>>>
The first equality check ( == ) is comparing objects and all its properties, whilst the second
check doesn’t consider the ID value. To confirm this consider the following tests.
I would expect this behaviour
real_pnt = arcpy.Point(0,0,1,1,0)
>>> real_pnt2 = arcpy.Point(0,0,1,1,0)
>>> real_pnt == real_pnt
True
>>> real_pnt == real_pnt2
False
not this
>>> real_pnt.equals(real_pnt2)
True
>>> a = arcpy.Point(X=1,Y=2,Z=3,M=4)
>>> b = arcpy.Point(X=1,Y=2,Z=3,M=0)
>>> c = arcpy.Point(X=1,Y=2,Z=0,M=0)
>>> a == b, a == c, b == c
(False, False, False)
>>> a.equals(b), a.equals(c), b.equals(c)
(True, True, True)
>>>
Shades of George Orwell...
"...all Points are equal but some Points are more equal than others..."
Disappointing if you require comparisons on all point properties.
Well PointGeometry is no better, since it depends upon the points that are used to construct it. Consider the equality check again, using PointGeometry objects instead of Point objects.
>>> pg_a = arcpy.PointGeometry(a)
>>> pg_b = arcpy.PointGeometry(b)
>>> pg_c = arcpy.PointGeometry(c)
>>>
>>> pg_a == pg_b, pg_a == pg_c, pg_b == pg_c
(False, False, False)
>>> pg_a.equals(pg_b), pg_a.equals(pg_c), pg_b.equals(pg_c)
(True, True, True)
>>>
Any comments as to why the Arcpy Point and PointGeometry class are so feable? Is the implementation in ArcObjects better? Or should I go back to using my own geometry classes.
I will be producing a summary on my blog after my musings about the various geometry classes is complete but my impressions are somewhat muted by the seemingly poor implementation or exposure to useful properties and methods.