0

I couldn't find a tool in ArcGIS Desktop (10.2.2) to convert a CSV into a shapefile, which was surprising to me, so I decided to script my own.

I found a helpful example script on ESRI's website (converting a dbf to layer) here: http://desktop.arcgis.com/en/arcmap/10.3/tools/data-management-toolbox/make-xy-event-layer.htm

I took the bulk of that script and added a CopyFeatures_management step to create the shapefile I wanted (relevant portions of my script below).

# Make the XY event layer
arcpy.MakeXYEventLayer_management(Input_Table, x_coords, y_coords, XYevent_Layer, spRef)

# Save to a layer file
arcpy.SaveToLayerFile_management(XYevent_Layer, Saved_Layer_path)

# Copy features to shapefile
arcpy.CopyFeatures_management(Saved_Layer_path, Output_FC)

My script works fine.

But this seems like it should be a one-step task (CSV to shapefile).

Can anyone tell me what is going on "under the hood" that requires 3 separate steps, OR why ESRI doesn't have a CSV to shapefile tool? I don't see anything like that in the Conversion Tools folder.

I realize this question isn't focused on a problem per se, but I hope it is allowed because I think it would be valuable to those who want to better understand Arcpy scripting AND I've already tried searching the web to no avail.

closed as primarily opinion-based by PolyGeo Feb 8 '18 at 2:38

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    You can skip the SaveToLayerFile by using XYevent_Layer in your copyfeatures, (i.e. arcpy.CopyFeatures_management(XYevent_Layer, Output_FC)) thus a two step process. – Michael Stimson Feb 8 '18 at 2:10
3

As commented by @MichaelStimson, this could be a "one-step task (CSV to shapefile)" by authoring a model or Python script tool that incorporates these two tools and a layer to link them:

  1. arcpy.MakeXYEventLayer_management()
  2. arcpy.CopyFeatures_management()

Why Esri has not chosen to provide this as an out-of-the-box (OOTB) single tool is something anyone can have an opinion on. I suspect that there are many thousands of tools that Esri could supply OOTB by stringing together Geoprocessing tools, and that sometimes the case will be there to do so and at others it will not.

1

Let's clarify some definitions using the ESRI Dictionary:

Feature Layer

A layer that references a set of feature data. Feature data represents geographic entities as points, lines, and polygons.

Feature Class

A collection of geographic features with the same geometry type (such as point, line, or polygon), the same attributes, and the same spatial reference. Feature classes can be stored in geodatabases, shapefiles, coverages, or other data formats.

In other words, a feature layer does not store the data. When you create the layer file it is referencing the data, including the coordinates, in your CSV file. If you would like to store the data in a self contained way, you can then choose a feature class, in this case a shapefile.

This all just comes down to data models: table > feature layer > feature class. Rather than ESRI allowing the tool to output to both feature layer and feature class I guess they chose just feature layer knowing that users can use a second function to save the feature layer to a feature class.

0

I cannot guarantee this script using ogr is exactly what happens 'under the hood' when using ArcPy tools. However, it might give you a hint of what creating a shapefile from a CSV requires.

from osgeo import ogr, osr

csv_fn = r"Albatrosses.csv"  # csv file
shp_fn = r"albatros_dd.shp"  # shapefile (to create)
sr = osr.SpatialReference(osr.SRS_WKT_WGS84)  # spatial reference

# Create empty shapefile
driver = ogr.GetDriverByName('ESRI Shapefile')
shp_ds = driver.CreateDataSource(shp_fn)
shp_lyr = shp_ds.CreateLayer('albatros_dd', sr, ogr.wkbPoint)

# Create attribute table fields
shp_lyr.CreateField(ogr.FieldDefn('tag_id', ogr.OFTString))
shp_lyr.CreateField(ogr.FieldDefn('timestamp', ogr.OFTString))

# Create dummy feature to populate with every row in the csv file
shp_row = ogr.Feature(shp_lyr.GetLayerDefn())

# Read csv file
csv_ds = ogr.Open(csv_fn)
csv_lyr = csv_ds.GetLayer()

# Loop through each row (feature) in the csv file
for csv_row in csv_lyr:

    # Get feature coordinates
    x = csv_row.GetFieldAsDouble('location_long')
    y = csv_row.GetFieldAsDouble('location-lat')

    # Create feature geometry
    shp_pt = ogr.Geometry(ogr.wkbPoint)
    shp_pt.AddPoint(x, y)
    shp_row.SetGeometry(shp_pt)

    # Get and set attribute table information
    tag_id = csv_row.GetField('individual-local-identifier')
    timestamp = csv_row.GetField('timestamp')
    shp_row.SetField('tag_id', tag_id)
    shp_row.SetField('timestamp', timestamp)

    # Create actual feature
    shp_lyr.CreateFeature(shp_row)

del csv_ds, shp_ds
  • 1
    I can guarantee that it's not. Esri uses Esri objects which predates the existence of OGR. XY Event layers have been around since 8.3, and probably 8.1 but I didn't have much to do with that version, preferring ArcINFO commandline. If you want to know about what creating a shapefile really requires you could have a look at ArcObjects CreateFeatureClass resources.arcgis.com/en/help/arcobjects-net/componenthelp/… – Michael Stimson Feb 8 '18 at 2:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.