Array of Coordinates

2193
9
01-14-2019 05:24 AM
LieslDe_Swardt1
New Contributor III

Can someone please assist me with the following task at hand:

I need to export the coordinates of polygon vertices in the following format:

Polygon_1, y,x ; y,x ; y,x ; y,x ; y,x

I have 120 000 vertices that needs to be exported in this format (either txt or xls). I have used export feature attribute to ASCII and export as table, but it exports in the following format:

Polygon_1, y,x 

Polygon_1, y,x 

Polygon_1, y,x 

Polygon_1, y,x 

Polygon_1, y,x 

Reason it needs to be in the above mentioned array format is to be able to use it in VB and SQL.

I have also tried the transpose tool, which is not giving the desired outcome.

Any help will be appreciated.

Tags (4)
0 Kudos
9 Replies
JoshuaBixby
MVP Esteemed Contributor

FeatureClassToNumPyArray—Help | ArcGIS Desktop , tell it to explode points.

UPDATE:   Something along the lines of:

import arcpy
import numpy

fc = # path to feature class
csv  = # path to csv file (full path with file extension)

arcpy.da.FeatureClassToNumPyArray(
    fc,
    ["OID@", "SHAPE@Y", "SHAPE@X"],
    explode_to_points=True
)
numpy.savetxt(csv, narr, delimiter=",", fmt=("%d", "%f", "%f"))
LieslDe_Swardt1
New Contributor III

Hi Joshua, thanx - I have been trying to put a script together for that, but I am still very new to python so I am failing terribly.

0 Kudos
DanPatterson_Retired
MVP Emeritus

to get it into row format

# ---- a structured array, p, as below
p
array([('Polygon_1',  0.,  0.), ('Polygon_1', 10.,  0.),
       ('Polygon_1', 10., 10.), ('Polygon_1', 10.,  0.),
       ('Polygon_1',  0., 10.), ('Polygon_2', 10., 10.),
       ('Polygon_2', 20., 10.), ('Polygon_2', 20., 20.),
       ('Polygon_2', 20., 10.), ('Polygon_2', 10., 20.)],
      dtype=[('P_id', '<U15'), ('y', '<f8'), ('x', '<f8')])

# ---- done simply so you can see the steps
ID, Y, X = p.dtype.names
polys = np.unique(p[names[0]])
out = []
for poly in polys:
    rows = p[np.where(p[ID] == poly)[0]]
    ys = rows[Y]
    xs = rows[X]
    out.append((poly, *list(zip(ys,xs))))

# ---- some of the inputs
ID, Y,# ('P_id', 'y', 'x')

polys  # array(['Polygon_1', 'Polygon_2'], dtype='<U15')

out  # in its simplest form by row

[('Polygon_1', (0.0, 0.0), (10.0, 0.0), (10.0, 10.0), (10.0, 0.0), (0.0, 10.0)), ('Polygon_2', (10.0, 10.0), (20.0, 10.0), (20.0, 20.0), (20.0, 10.0), (10.0, 20.0))]

Liesi, this can at least get your started... there are other ways of getting the geometry in many forms

The output format can obviously be changed.

The key is to use the structured array format that would come from FeatureclassToNumPyArray.

You need a key id field, which identifies which polygon is what,

then you query on that id (row 15... yes you need the [0] since a tuple is returned

pull out the ys, and xs using their appropriate field names

name some output container to store the bits zipping the ys,xs to form pairs

decide on your output format

JoeBorgione
MVP Emeritus

edited to add:  Don beat me to it, but here is a list approach...

Take a look at python - CSV of XY coordinates for multiple polygons - Stack Overflow 

Using it as starting point I came up with this:

import arcpy
arcpy.env.workspace = r'X\path\to\gdb'
fc = 'YourPolygon'

vertexFile = r'X\path\to\your\file.txt'
vertexList = ['Polygon_1']

 with arcpy.da.SearchCursor(fc, ["OID@", "SHAPE@"]) as cursor:
    for row in cursor:
     for part in row[1]:
      for vertex in part:
        vertexList.append('{},{}'.format(vertex.X,vertex.Y))

f = open(listFile,'w')

for i in vertexList:
    if i == 'Polygon_1':
      f.write('{},'.format(i))
    else:
      f.write('{};'.format(i))
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
That should just about do it....
DanPatterson_Retired
MVP Emeritus

some other variants, 

ID, Y, X = p.dtype.names
polys = np.unique(p[names[0]])
out = []
for poly in polys:
    rows = p[np.where(p[ID] == poly)[0]]
    xys = rows[[Y, X]]
    out.append((poly, *list(xys.ravel())))
    

for i in out:
    print(i)
    
('Polygon_1', (0., 0.), (10., 0.), (10., 10.), (10., 0.), (0., 10.))
('Polygon_2', (10., 10.), (20., 10.), (20., 20.), (20., 10.), (10., 20.))

variant 2

 ID, Y, X = p.dtype.names
polys = np.unique(p[names[0]])
out = []
for poly in polys:
    rows = p[np.where(p[ID] == poly)[0]]
    xys = rows[[Y, X]]
    coords = list(xys.ravel())
    c = ",".join(['{};{}'.format(*c) for c in coords])
    out.append((poly,c))
   

out
Out[138]: [('Polygon_1', '0.0;0.0,10.0;0.0,10.0;10.0,10.0;0.0,0.0;10.0'), ('Polygon_2', '10.0;10.0,20.0;10.0,20.0;20.0,20.0;10.0,10.0;20.0')]

for i in out:
    print(i)
    
('Polygon_1', '0.0;0.0,10.0;0.0,10.0;10.0,10.0;0.0,0.0;10.0')
('Polygon_2', '10.0;10.0,20.0;10.0,20.0;20.0,20.0;10.0,10.0;20.0')

There are more, but just sticking to python/numpy for now

XanderBakker
Esri Esteemed Contributor

Hi Liesl De Swardt ,

Just wondering did you try the snippet I posted in the other thread? https://community.esri.com/thread/191684-how-do-i-export-cordinates-of-polygon-shapes-to-excel#comme... 

A non-python intensive method would be to use arctoolbox, data management, features -  "feature vertices to points" to collect all vertices as points, then calculate geometry fields/add XY on the points, then export the result to a shapefile or a csv table.  It will have the format you described, feature to vertex will give you an attribute(s) or ID relating to the original polygon FID in the vertex points.

JoeBorgione
MVP Emeritus

The only gotcha with feature vertices to points is the licensing level needed: advanced only....

That should just about do it....
DanPatterson_Retired
MVP Emeritus

FeatureClassToNumPyArray—Data Access module | ArcGIS Desktop sends all the information out, but it is column formatted.

That is what I use.

Liesl's issue is getting an export from 'whatever' out into a row format... of which there are numerous variants.

Sticking with arrays, makes the whole process simpler