Dan_Patterson

Geometry : Part 8

Blog Post created by Dan_Patterson Champion on May 30, 2019

Geometry

 

 

Geometry in NumPy... # 1

Geometry ... ArcPy and NumPy... # 2

Geometry ... Deconstructing poly* features # 3

Geometry ... Reconstructing Poly Features # 4

Geometry ... Attributes actually... the other bits # 5

Geometry: Don't believe what you see ... # 6

Geometry : Forms of the same feature # 7

 

Two multipart shapes, (one with holes, one without) and a singlepart shape.

 

Shapes

 

The shape itself is represented by an arcpy array of points.  Since there are two parts to the shape, there are two arrays.  The inner rings/holes are separated by None.

 

Each point carries the extra baggage of Z and M values whether they are needed or not.

 

 

 

Shape 1...

Object array... an array of arrays

Shapes 2 and 3...

ndarray...ndim = 3 shape = (2, 9, 2)

ndarray...ndim = 2 shape =  (4, 2)

Geo array (last 2 olumns, X, Y)

first 3 columns are for printing

array([
array([[10., 20.],  # first
       [10., 10.],  # outer
       [ 0., 10.],
       [ 0., 20.],
       [10., 20.],
       [nan, nan],
       [ 3., 19.],  # first
       [ 3., 13.],  # inner
       [ 9., 13.],
       [ 9., 19.],
       [ 3., 19.]]),
array([[ 8., 18.],  # second
       [ 8., 14.],  # outer
       [ 4., 14.],
       [ 4., 18.],
       [ 8., 18.],
       [nan, nan],
       [ 6., 17.],  # second
       [ 5., 15.],  # inner
       [ 7., 15.],
       [ 6., 17.]])],
dtype=object)

 

 

[<Array 
[<Point (300010.0, 5000020.0, #, #)>,
<Point (300010.0, 5000010.0, #, #)>,
<Point (300000.0, 5000010.0, #, #)>,
<Point (300000.0, 5000020.0, #, #)>,
<Point (300010.0, 5000020.0, #, #)>,
None,
<Point (300003.0, 5000019.0, #, #)>,
<Point (300003.0, 5000013.0, #, #)>,
<Point (300009.0, 5000013.0, #, #)>,
<Point (300009.0, 5000019.0, #, #)>,
<Point (300003.0, 5000019.0, #, #)>]>,
<Array
[<Point (300008.0, 5000018.0, #, #)>,
<Point (300008.0, 5000014.0, #, #)>,
<Point (300004.0, 5000014.0, #, #)>,
<Point (300004.0, 5000018.0, #, #)>,
<Point (300008.0, 5000018.0, #, #)>,
None,
<Point (300006.0, 5000017.0, #, #)>,
<Point (300005.0, 5000015.0, #, #)>,
<Point (300007.0, 5000015.0, #, #)>,
<Point (300006.0, 5000017.0, #, #)>]>]
array([[[12., 18.], # first
        [12., 12.],
        [20., 12.],
        [20., 10.],
        [10., 10.],
        [10., 20.],
        [20., 20.],
        [20., 18.],
        [12., 18.]],

       [[25., 24.],  # second
        [25., 14.],
        [15., 14.],
        [15., 16.],
        [23., 16.],
        [23., 22.],
        [15., 22.],
        [15., 24.],
        [25., 24.]]],
      dtype('float64'))

 

 

 

array([[14., 20.],
       [10., 20.],
       [15., 28.],
       [14., 20.]])
pnt shape  part  X       Y     
--------------------------------
000     0         10.00   20.00
001     0         10.00   10.00
002     0          0.00   10.00
003     0          0.00   20.00
004     0         10.00   20.00
005     0   x       nan     nan
006     0          3.00   19.00
007     0          3.00   13.00
008     0          9.00   13.00
009     0          9.00   19.00
010     0          3.00   19.00
011     0   o      8.00   18.00
012     0          8.00   14.00
013     0          4.00   14.00
014     0          4.00   18.00
015     0          8.00   18.00
016     0   x       nan     nan
017     0          6.00   17.00
018     0          5.00   15.00
019     0          7.00   15.00
020     0  ___     6.00   17.00
021     1   o     12.00   18.00
022     1         12.00   12.00
023     1         20.00   12.00
024     1         20.00   10.00
025     1         10.00   10.00
026     1         10.00   20.00
027     1         20.00   20.00
028     1         20.00   18.00
029     1         12.00   18.00
030     1   o     25.00   24.00
031     1         25.00   14.00
032     1         15.00   14.00
033     1         15.00   16.00
034     1         23.00   16.00
035     1         23.00   22.00
036     1         15.00   22.00
037     1         15.00   24.00
038     1  ___    25.00   24.00
039     2   o     14.00   20.00
040     2         10.00   20.00
041     2         15.00   28.00
042     2         14.00   20.00

 

s2.IFT

array([[ 0,  0, 11],
       [ 0, 11, 21],
       [ 1, 21, 30],
       [ 1, 30, 39],
       [ 2, 39, 43]])

 

Arcpy geometry representation

 

This is the dissection of the first polygon down to its elemental parts and the arcpy class methods and properties that can be accessed through the standard interface.

 

arcpy.da.SearchCursor

cur = arcpy.da.SearchCursor(in_fc2, 'SHAPE@', spatial_reference=SR)
dir(cur)
[[... snip ..., '_as_narray', '_dtype', 'fields', 'next', 'reset']

arcpy.Polygon

p0  # ---- the first polygon
<Polygon object at 0x1e5284a3320[0x1e5284c1e18]>
dir(p0)
['JSON', 'WKB', 'WKT', … '_fromGeoJson', …  'angleAndDistanceTo', 'area', 'boundary', 'buffer', 'centroid',
 'clip', 'contains', 'convexHull', 'crosses', 'cut', 'densify', 'difference', 'disjoint', 'distanceTo', 'equals', 'extent',
 'firstPoint', 'generalize', 'getArea', 'getGeohash', 'getLength', 'getPart', 'hullRectangle', 'intersect', 'isMultipart',
 'labelPoint', 'lastPoint', 'length', 'length3D', 'measureOnLine', 'overlaps', 'partCount', 'pointCount',
 'pointFromAngleAndDistance', 'positionAlongLine', 'projectAs', 'queryPointAndDistance', 'segmentAlongLine',
 'snapToLine', 'spatialReference', 'symmetricDifference', 'touches', 'trueCentroid', 'type', 'union', 'within']

arcpy.Array

p0[0]  # ---- first polygon's first part... aka, an array of point objects
<Array [<Point (300010.0, 5000020.0, #, #)>, … snip, <Point (300003.0, 5000019.0, #, #)>]>
dir(p0[0])
[ … snip ..., 'add', 'append', 'clone', 'count', 'extend', 'getObject', 'insert', 'next', 'remove', 'removeAll', 'replace', 'reset']
arcpy.Point
dir(p0[0][0])  # ---- the point
['ID', 'M', 'X', 'Y', 'Z', … snip …, 'clone', 'contains', 'crosses', 'disjoint', 'equals', 'overlaps', 'touches', 'within']

...the coordinates

p0[0][0].X  # ----  finally, the X coordinate of the first point of the first array in the first shape of the
                            first polygon... got it?
300010.0

Geo class vs ndarray

This is a summary of the methods and properties that I have added to the Geo array
gs = set(dir(g))
ss = set(dir(g.base))
sorted(gs.difference(ss))
['AOI_extent', 'AOI_rectangle', 'FT', 'IDs', 'IFT', 'Info', 'K', 'N', 'X', 'XY', 'Y', 'Z', '__dict__', '__module__',
 'angles', 'areas', 'bits', 'centers', 'centroids', 'convex_hulls', 'densify_by_distance', 'extent_rectangles', 'extents',
 'fill_holes', 'get', 'holes_to_shape', 'is_convex', 'is_multipart', 'lengths', 'maxs', 'means', 'min_area_rect', 'mins',
 'move', 'od_pairs', 'outer_rings', 'part_cnt', 'parts', 'pnt_info', 'pnts', 'polylines_to_polygons', 'polys_to_segments',
 'pull', 'rotate', 'shapes', 'split', 'translate', 'unique_pnts']

Continued at...

Options for different representations of arcpy geometry arrays are there.

I will continue the development of the Geo class based on numpy's ndarray in my GitHub at...

 

npGeo ... a geometry class

Outcomes