---- The SearchCursor Approach ----The functions getSR and _view_ are described at the end. They are helper functions used to derive the spatial reference and to reshape the coordinates. The key operative in this approach is on line 8, _as_narray, which does the conversion behind the scenes. def cur_xy(in_fc, to_pnts=True):
"""Convert featureclass geometry (in_fc) to a simple 2D structured array
with ID, X, Y values. Optionally convert to points, otherwise centroid.
"""
SR = getSR(in_fc)
flds = ['SHAPE@X', 'SHAPE@Y']
cur = arcpy.da.SearchCursor(in_fc, flds, spatial_reference=SR,
explode_to_points=to_pnts)
a = cur._as_narray()
a = _view_(a)
return a
---- Results .... Essentially you have a simplified list of X, Y coordinates since the 'shp' was defined as 'SHAPE@X' and 'SHAPE@Y' with 'explode_to_points' set to True (False, returns centroids). Sadly you can't reconstruct the polygons unless you deal with the which points belong to what polygon. array([[ 300020., 5000000.],
[ 300010., 5000000.],
[ 300010., 5000010.],
...,
[ 300002., 5000002.],
[ 300008., 5000002.],
[ 300005., 5000008.]])
|
---- Retrieving shape objects ---- If you want to use arcpy directly because of the builtin methods, you need the contents of the 'shape' fields using SHAPE@' rather than just extracting the X and Y coordinates as in the previous example def fc_shapes(in_fc, as_array=True):
"""Derive, arcpy geometry objects from a featureClass searchcursor.
Parameters
----------
in_fc : text
Path to the input featureclass
as_array: boolean
True, return an object array of arcpy polygon objects. False, returns
a list.
"""
SR = getSR(in_fc)
with arcpy.da.SearchCursor(in_fc, 'SHAPE@', None, SR) as cursor:
a = [row[0] for row in cursor]
if as_array:
return np.asarray(a)
return a
---- Put it to work ---- polys = fc_shapes(in_fc, as_array=True)
polys
array([<Polygon object at 0x197f1bcebe0[0x197f0199968]>,
<Polygon object at 0x197f1bcec18[0x197e9b48da0]>,
<Polygon object at 0x197f1bceb70[0x197f005b738]>,
<Polygon object at 0x197f1bceb38[0x197f005b5a8]>,
<Polygon object at 0x197f1bceac8[0x197f005b760]>], dtype=object)
|
---- Geometry as a structured array ----Nothing fancy, but there is an integer ID field indicating which feature a point belongs to and the coordinates. A simpler version of the above... just an ID field and coordinates. def fc_xyID(in_fc, to_pnts=True):
"""Convert featureclass geometry (in_fc) to a simple 2D structured array
with ID, X, Y values. Optionally convert to points, otherwise centroid.
"""
SR = getSR(in_fc)
flds = ['OID@', 'SHAPE@X', 'SHAPE@Y']
cur = arcpy.da.SearchCursor(in_fc, flds, spatial_reference=SR,
explode_to_points=to_pnts)
a = cur._as_narray()
a.dtype = [('IDs', '<i4'), ('X_s', '<f8'), ('Y_s', '<f8')]
return a
---- The results ---- a = fc_xyID(in_fc, to_pnts=True)
a
array([(1, 300010., 5000000.), (1, 300000., 5000000.), (1, 300000., 5000010.),
(1, 300010., 5000010.),(1, 300010., 5000000.),
... snip
(5, 300020., 5000010.),(5, 300022., 5000010.), (5, 300025., 5000002.),
(5, 300028., 5000010.), (5, 300030., 5000010.),(5, 300026., 5000000.),
(5, 300024., 5000000.), (5, 300020., 5000010.)],
dtype=[('IDs', '<i4'), ('X_s', '<f8'), ('Y_s', '<f8')])
The polygon ID that each point belongs to is retained, however, it is replicated many times and the null points separating polygon parts is removed. |