I have a set of polygons I have calculated the centroids of, but am having trouble finding a way to output these values to a point shapefile. I dabbled with
arcpy.MakeXYEvents_management, but it only creates a temporary layer file.
Here is an arcpy soloution:
import os, sys, arcpy InFC = sys.argv OutFC = sys.argv #split the output into directory and name Folder = os.path.dirname(OutFC) Name = os.path.basename(OutFC) # Get the existins spatial reference as it's going to match desc = arcpy.Describe(InFC) SR = desc.spatialReference # create or append if not arcpy.Exists(OutFC): arcpy.CreateFeatureclass_management(Folder,Name,"POINT",spatial_reference = SR) # open up the 'writer' with arcpy.da.InsertCursor(OutFC,"SHAPE@XY") as iCur: # open up the 'reader' with arcpy.da.SearchCursor(InFC,"SHAPE@") as sCur: # loop through each polygon in the InFC for sRow in sCur: cent = sRow.centroid # get the centroid iCur.insertRow([(cent.X,cent.Y)])# write it to the new feature class
This creates a new feature class, opens an insert cursor, loops through each geometry in the InFC and writes the centroid property to the output.. note that multi-part geometries will not have a centroid per part but rather a single centroid for the whole geometry.. it's not much more difficult to loop through the parts - let's keep this example fairly simple though to show the basics.
This should do the trick:
import arcpy import os def polysToPoints(in_polys, out_points): """converts polygons to centroids in_polys -- input polygons out_points -- output points """ ws, name = os.path.split(out_points) sr = arcpy.Describe(in_polys).spatialReference arcpy.management.CreateFeatureclass(ws, name, 'POINT', template=in_polys, spatial_reference=sr) # populate records fields = ['SHAPE@'] + [f.name for f in arcpy.ListFields(out_points) if f.type not in ('OID', 'Geometry')] with arcpy.da.InsertCursor(out_points, fields) as irows: with arcpy.da.SearchCursor(in_polys, fields) as rows: for r in rows: irows.insertRow((arcpy.PointGeometry(r.centroid),) + r[1:]) return out_points if __name__ == '__main__': polys = r'C:\path_to_your\polys.shp' points = r'C:\path_to_your\points.shp' polysToPoints(polys, points)
shapelib library is ideal for this task.
No depedecies, just a simple module to create shapefiles:
import shapefile coord_list = ((20,40), (0,0), ) w = shapefile.Writer(shapefile.POINT) w.field('ID_FIELD','C','40') for id,(x,y) in enumerate(coord_list): w.record(ID_FIELD=id) w.point(x,y) w.save("file\to\save")
it's very simple you might want to add the projection file afterwards (manually).
Check the manual on additional info
I'm still somewhat of a an arcpy beginner so perhaps this is not as sophisticated, but I created a script tool for this and it works for me. In your toolbox, add a new script tool. Make the python script below the source. Set the tools 1st parameter as feature layer input and the 2nd parameter as feature layer output (make sure you set it to an output parameter). Note, this tool will return points inside the input layer rather than the true centroid.
import arcpy import os inputFC = arcpy.GetParameterAsText(0) outputPath = arcpy.GetParameterAsText(1) scratchPath = arcpy.env.scratchGDB inputFCSpatialReference = arcpy.Describe(inputFC).spatialReference ##copy to new fc in scratchGBD and make new layer FCCopy = arcpy.CopyFeatures_management(inputFC,os.path.join(scratchPath,"FCCopy")) FCLyr = arcpy.MakeFeatureLayer_management(FCCopy,"FCLyr") arcpy.AddMessage("FC LAYER CREATED") ##add and calculate X and Y fields arcpy.AddField_management(FCLyr,"Xcoor","DOUBLE") arcpy.CalculateField_management(FCLyr,"Xcoor","!SHAPE!.centroid.X","PYTHON") arcpy.AddField_management(FCLyr,"Ycoor","DOUBLE") arcpy.CalculateField_management(FCLyr,"Ycoor","!SHAPE!.centroid.Y","PYTHON") arcpy.AddMessage("X,Y FIELDS CREATED") ##create point layer from X Y fields FCTable = arcpy.MakeTableView_management(FCLyr,"FCTable") pointsLyr = arcpy.MakeXYEventLayer_management(FCTable,"Xcoor","Ycoor","pointsLyr",inputFCSpatialReference) arcpy.AddMessage("TABLE LAYER CREATED") ##export points to feature class arcpy.CopyFeatures_management(pointsLyr,outputPath) arcpy.AddMessage("POINT LAYER CREATED") ##delete data from scratchGBD arcpy.Delete_management(FCCopy)