More

Creating records in output shapefile using Python

Creating records in output shapefile using Python


I have a list (output from a previous loop) containing attributes from an input shapefile. What I am stuck with is inputting those attributes to a new shapefile.

I have plotted the point data usingw.point(x, y)and also created the relevant fieldsw.field()from the input shapefile fields.

Where I am stuck is with the copy of the records, which is giving me an Error related to Deletion Flag.

AttributeError: 'tuple' object has no attribute 'startswith'

I am pasting a section of the code with my queries.

from datetime import datetime import osgeo.ogr, osgeo.ogr from osgeo import ogr from osgeo import gdal import shapefile import os sf = shapefile.Reader("-- Input File Location --") # Reading the Shapefile fields = sf.fields # Reading the attribute fields records = sf.records() # Reading the records of the features shapRecs = sf.shapeRecords() # Read Geometry and Records simultaneously w = shapefile.Writer(shapefile.POINT) w.autoBalance = 1 result1 = [] result2 = [] # ??? Is the error because we cannot query for list in a list ??? print '** Call function pt(p) where p is node index… **' # Prompting the user to # call the function with # the required number of nodes def pt(p): for i in range(len(shapRecs)): u = shapRecs[i].shape.points[p-1] # Gives the XY Coordinates of # the queried points v = shapRecs[i].record[0:] # Generating the Attributes result1.append(u) result2.append(v) w.point(u[0], u[1]) # Create points from coordinates each time the loop runs w.autoBalance = 1 # -- Adding the fields w.field(fields[0]) # Adding the first field, WITH Deletion Flag (???) for i in range(1, len(fields)): # Loop begins from the second field (???) w.field(fields[i]) w.autoBalance = 1 # CODE SHOWS THE ERROR STATED ABOVE FROM THE w.record() statement # -- Adding the records for i in range(len(result2)): w.record(*result2[i]) w.autoBalance = 1 w.save('-- Output File Location --')

I don't understand your script. Why use PyShp (shapefile), if you use osgeo.ogr ? You could do the same thing with ogr only ( better way to duplicate a layer using ogr in python? ).

If you want to import ogr and gdal from osgeo, the formulation

import osgeo.ogr, osgeo.ogr from osgeo import ogr from osgeo import gdal

is a redundancy (you import ogr and gdal twice)

Same forsf.records()andsf.shapeRecords():

sf = shapefile.Reader("strati") records = sf.records() # Reading the records of the features for rec in records: print rec [30, 130, 'incl'] [55, 145, 'incl'] [40, 155, 'incl']

and

shapRecs = sf.shapeRecords() for rec in shapRecs: print rec.record [30, 130, 'incl'] [55, 145, 'incl'] [40, 155, 'incl']

If you only want the geometry:

for rec in sf.iterShapes(): x,y = rec.points[0] print x,y 272070.600041, 155389.3879200000 271066.03214800003, 154475.63137700001 273481.498868, 153923.49298800001

and

for rec in shapRecs: x,y = rec.shape.points[0]

If you just want to copy the shapefile:

w = shapefile.Writer(shapefile.POINT) sf = shapefile.Reader("strati") w.fields = list(sf.fields) for rec in sf.records(): w.records.append(rec) w._shapes.extend(sf.shapes()) w.save("duplicate")

If you want to add a Field, look at Add a Field to an Existing Shapefile

If you want lists, the easiest way is:

sf = shapefile.Reader("yourfile.shp") shapes = sf.shapes() # -> list of all the geometries fields = sf.fields[1:] #-> fields definition in a list (without the Deletion Flag) field_names = = [field[0] for field in fields] #-> list of fields names attributes = sf.records() #-> list with all the attributes