Playing Around With ArcPY…

I was playing around with ArcPY and tried to recreate a version of the qgis2leaf plugin just for ArcGIS just to get to know that ArcGIS doesn’t seem to have native support for GeoJSON. So I’ll not show you how to build a leaflet map from within ArcGIS but I would like to show you some basic tasks in ArcPY by exporting a point shapefile to a CSV.

What Will We Do?

We will use a point shapefile and export it as a CSV file using ArcPY. So in the end you will have a new toolbox with a custom tool just for you.

What Will I Learn?

You will learn to:
  • iterate over features of a layer
  • file operations in ArcPY
  • create “interfaces” for your sript

What Do I need?

“Unfortunately” you’ll need a running version of ArcGIS version 10.x. A text editor with syntax highlighting like sublime 3 would be a plus.

1) Iterate Over Features

The iteration over features works with a so-called searchCursor:
The SearchCursor function establishes a read-only cursor on a feature class or table. The SearchCursor can be used to iterate through row objects and extract field values. The search can optionally be limited by a where clause or by field, and optionally sorted.
And according to the example in the help file it’s really easy, assuming our shapefile has the name “point_shape” and we are interested in the attribute name:
import arcpy
cursor = arcpy.SearchCursor("point_shape")
for row in cursor:
	print(row.getValue("name"))
This is quite easy and works like a charm. The geometry for a simple point shapefile is probably stored in the field called shape and we can also extract coordinates by row:
import arcpy
cursor = arcpy.SearchCursor("point_shape")
for row in cursor:
	print row.getValue("Shape").getPart().X, row.getValue("Shape").getPart().Y
This will print X and Y coordinates for every feature. As point features can be multipart as well we needed to call the getPart() function to get the part we are interested in for our singlepart points. If you’re not sure whether your shape information is stored in “Shape” as above you can ask the feature for the name of the shape information using the describe function:
desc = arcpy.Describe("point_shape")
desc.ShapeFieldName
By now we can iterate over features and print the coordinates and one attribute. As we don’t know the attribute names in the shapefiles by default we need to get a list of field names. We can do this right away using listFields:
fields = arcpy.ListFields("point_shape")
for field in fields:
	print field.name

2) File Writing

As we want to store all the information in a single file we need some other module to write a file and determine OS paths and so on:
import os
userhome = os.path.expanduser('~')
desktop = os.path.join(userhome,'Desktop')
For the file writing itself we will open a new file, write lines into it, save it and close it:
with open(desktop + os.sep + 'data.txt', 'w') as file:
	text = """This is my line to write to the file"""
	file.write(text)
	file.close()
I am using the triple quotes to be able to use single quotes in the string which I want to write to the file.

3) Bringing It Together

All we need to do now is to iterate over the features and write each feature information to a line. The basic code would look like this:
import arcpy
import os
cursor = arcpy.SearchCursor("point_shape")
fields = arcpy.ListFields("point_shape")
userhome = os.path.expanduser('~')
desktop = os.path.join(userhome,'Desktop')
text = ''
with open(desktop + os.sep + 'data.txt', 'w') as file:
	for field in fields: 
		text += field.name + """;"""
	text += """X;Y
"""
	for row in cursor:
		for field in fields:
			text += str(row.getValue(field.name)) + """;"""
		text += str(row.getValue("Shape").getPart().X) + """;""" + str(row.getValue("Shape").getPart().Y) + """
"""
	file.write(text)
	file.close()
The strange quotation marks mimic the line breaks we need to put into our file. Furthermore we need to change anything we get to a string so we use th str() function in line 15.

4) Making It Generic

At the moment we have one fixed attribute which is the name of the shapefile. As we want to call the tool independently from the shapefiles name we need to get this generic. We will combine this with the creation of the toolbox itself. But first: ArcPY has an easy way of generalisation when creating a toolbox we will use the first (or in Python language the “zeroest” element of inputs of the toolbox:
inputshape= arcpy.GetParameterAsText(0)
But where do we get the Parameter as text from? Open up the toolbox, Right click inside the toolbox window and select Add Toolbox,New Toolbox in the popup and give it a nice name:
add new toolbox
Add New Toolbox
Now we need to add the script to the toolbox by right clicking the new toolbox and selecting Add Script:
Add Script Dialog
Add Script Dialog
Select your saved python script from above in the next dialog:
Selected Script
Selected Script
Now comes the crucial part: We need to define the input parameter which is a point feature class in our case. So in the upper box select Feature Layer as Data Type and give it a name for the screen:
Input Dialog Definition
Input Dialog Definition
As we are just interested in Single Part Point feature classes we select Feature Class as Filter and deselect everything except Point In the end the tool looks like this and should only list point feature classes of your current project:
Export to CSV Tool
Export to CSV Tool
What we need to do in the end? Use the input in our script. So right-click on the script in the toolbox and edit it. Simply add the following line after our import XX lines:
inputshape= arcpy.GetParameterAsText(0)
This stores the name of the feature class in the variable inputshape. Now just replace these lines:
cursor = arcpy.SearchCursor("point_shape")
fields = arcpy.ListFields("point_shape")
with these two lines:
cursor = arcpy.SearchCursor(inputshape)
fields = arcpy.ListFields(inputshape)
That’s it! You can download the python script here.

What Next?

Try yourself to make the output filename generic/selectable.

Thank you for reading. Your comments will be valuable.

ps: There is a script/toolbox from @calvinmetcalf on github called esri2open which adds GeoJSON/CSV export to ArcGIS.
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Richard Law
Richard Law
9 years ago

ArcGIS Online seems to have recently started supporting GeoJSON: http://blogs.esri.com/esri/arcgis/2014/12/16/arcgis-online-geojson/

Doofus90210
Doofus90210
9 years ago

Hi, if I may add a few remarks to your code: Your SearchCursor object isn’t deleted, so the script does not necessarily remove the lock from the feature class you’re processing. To do this, add del cursor at the end, when you’re finished. Even better would be to use a with statement for the SearchCursor as well, as this will ensure that the feature class is unlocked even if the script throws an error. (credits to /u/sarcasmful[1] *) Your writer now writes the ‘value’ of the shapefield as well to the output file. This results in a column holding values… Read more »

Riccardo
9 years ago
Reply to  Doofus90210

Thanks for pasting your reddit comment!

Gato0
Gato0
8 years ago

Thanks for this!