Hot answers tagged

14

The pyshp module is a bit tricky to get the hang of, but really useful once you get it going. I've written a script that reads in a csv of the example data and writes out a shapefile with the data stored as attributes of the correct datatypes. The pyshp/xbase datatyping has always been tricky for me until I found this user guide for the xbase format and as a ...


12

It is the same thing with pyshp, except that you cannot update directly the dbf file. When you read a shapefile, the data are stored in Python lists import shapefile input = shapefile.Reader("yourfile.shp") shapes = input.shapes() # -> the geometries in a list fields = input.fields[1:] -> the fields definition in a list fields_name = = [field[0] for ...


7

You can easily create a dictionary of attributes: import shapefile sf = shapefile.Reader('MyFile.shp') # name of fields fields = sf.fields[1:] field_names = [field[0] for field in fields] # construction of a dctionary field_name:value for r in sf.shapeRecords(): atr = dict(zip(field_names, r.record))   As a result: {'field1': 'value1', '...


6

Each piece of your complex polygon, including the hole, is called a "part" in the shapefile spec. Parts are how they tie multiple distinct geometries to a single dbf record. In pyshp, parts are a list of lists passed to the poly method. The example you followed only has one list of points within the parts. But your shapefile has 3 distinct polygons. So ...


6

From the pyshp documentation page: >>> # Create a polygon shapefile >>> w = shapefile.Writer(shapefile.POLYGON) >>> w.poly(parts=[[[1,5],[5,5],[5,1],[3,3],[1,1]]]) >>> w.field('FIRST_FLD','C','40') >>> w.field('SECOND_FLD','C','40') >>> w.record('First','Polygon') >>> w.save('shapefiles/test/...


5

It looks like you're creating a single point and constantly overwriting the shapefile with just that single point file. Try moving your instance of the sf.Writer class before your for loop and saving filename2 after the for loop. w = sf.Writer(sf.POINT) for l in lis: w.point(l[0], l[1]) w.field('location') w.record(l[2], 'Point') w.save(...


5

You can use dbfpy to directly access and edit the attributes in the shape file's dbf file. from dbfpy import dbf db = dbf.Dbf("your_file.dbf") #Editing a value, assuming you want to edit the first field of the first record rec = db[0] rec["FIRST_FIELD"] = "New value" rec.store() del rec db.close()


5

I have written a set of scripts to solve this problem and have published the output in case anyone else needs it. See the bottom of this answer for details. GeospatialPython.com pointed me in the right direction. I was able to throw together a quick Python script to do this. I'm sure there are issues here because I'm not very familiar with pyqgis, but it ...


5

To process large files, you need to use a generator which only read/write one line at a time and Python has a command that does that: with. The with statement handles opening and closing the file, including if an exception is raised in the inner block. The for line in f treats the file object f as an iterable, which automatically uses buffered IO and ...


4

The problem I think is that you created four attributes w.field("fid_nr","N") w.field("x","F",10,8) w.field("y","F",10,8) w.field("angle","N") but you tried to put six things on it w.record(k,y[j],fid_nr[j],x[j],y[j],angle[j]) It should just be w.record(fid_nr[j],x[j],y[j],angle[j]) If you want to add k and y[j] then you'd have to create the ...


4

You need to ensure that the angle read from the csv is cast as an integer and not a string as it may be at present. To do this change the line: angle.append(row[3]) to: angle.append(int(row[3])) The second thing to correct is that you have not specified a length of the angle field, which can cause pyshp some problems, so specify a length, in this case 4 ...


4

I'm the author of PyShp. Both R.K. and Gene are correct. Editing a file like a dbf is just an illusion. What you are really doing is reading in the old one into a Python object, changing some variable values, and writing over the old file. If you are going to do a bunch of dbf editing definitely use dbfpy. Like PyShp it is pure python but has more ...


4

This expands on the answer posted by BradHards: The error message sounds like pyshp is expecting floats where it is not getting them. If your coordinate list is a set of ints, try casting them to floats: list = [[1,5],[5,5],[5,1],[3,3],[1,1]] list = [[float(coord) for coord in pair] for pair in list]


4

Pyshp does not have a WKT method but it does support the geo_interface protocol at the shape level. That protocol returns each shape as geojson. You can then use the lightweight, pure-python pygeoif module to convert to WKT. The pygeoif module is available on the Python Package Index and Github: https://pypi.python.org/pypi/pygeoif/ https://github.com/...


4

If you examine GeospatialPython.com: Working with Elevation Values in Shapefiles (the blog of Joel Lawhead, creator of the Pyshp module) When you read 3D shapefiles the elevation values will be stored separately....And know that the z values are stored in the "z" property of each shape instead of being integrated with the x,y value lists. From the ...


4

PyShp will let you read the shapefile, but won't help you figure out if a point is in a boundary. You'll have to combine it with something like Shapely to do the geometric calculations. Luckily, the two modules can interoperate through the Python Geo Interface. Some basic functionality (untested) would be like: import shapefile from Shapely.geometry import ...


4

a shapefile can only contain one geometry-type. For each of them, you have to create another shapefile. More info: https://gis.stackexchange.com/a/74629/7849


3

Hi The column time 4th is like "2014-05-30T16:32:39+0000" and I´d like to format it as '30 / 16:32 UTC' to show this in the label. For that you can use Regular expressions: you want to extract '30T16:32' from the string (This isn't geospatial but ...) The pattern (regular expression to be matched) is [0-9]+T[0-9]+:[0-9]+or \d+T\d+:\d+(search for the ...


3

One easy (one time) solution is to use the QuickWKT Plugin. Transform your list into a EWKT string by adding a the header with the SRID and the type of geometry. Add a comma in the end of each XY pair. SRID=4326;POLYGON (( 30 10, 10 20, 20 40, 40 40, 30 10 )) Copy + paste the all thing to QuickWKT Plugin's dialog, and press OK. Your polygon will be ...


3

The DBF records in that Shapefile are apparently invalid. Their deleted flag values are 0x00 whereas the value should be either 0x20 (valid) or 0x2A (deleted) as per http://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_STRUCT. Pyshp interprets everything except 0x20 as deleted.


3

Found an answer after mailing to the author of this library: just use w.record(*attrs).


3

You could do this in a few lines with shapely and GeoPandas (which uses Fiona under the hood for file i/o). You can use shapely.geometry.box to create the rectangles, convert it to a GeoDataFrame, and use the to_file method to save as a shapefile: from pandas import DataFrame from geopandas import GeoDataFrame from shapely.geometry import box data = ...


3

Your approach is good, but you could make things clearer using dictionaries instead of list and the csv module allows it. Moreover, your script use two loops while it is possible to simplify using only one (the second loop is redundant, one line of the csv file = one record of the shapefile). 1) With dictionaries: Reading the csv file: with open('your.csv'...


3

It's not good coding practice to set your iterator variable in a for loop to the same name of the list you are looping over. You should change one of the name variables. I ran your code on my machine with your small dataset and it correctly created the shapefile. I'm able to view it in ArcMap, along with the attribute table. Of course, there is no spatial ...


3

You are doing good so far. Just try to change the syntax of your polygonz declaration. I did it for you. Here is the complete working code with comments where neccessary: # import shapefile library import shapefile #create an in memory polygon shapefile w = shapefile.Writer(shapeType=shapefile.POLYGONZ) #add a name field to it w.field('NAME') #fill ...


3

If you want to use the WKT format, the correct syntax is: "POLYGON Z ((398000.0 7542000.0 279.9, 398000.0 7541990.0 281.0, 398010.0 7541990.0 280.4, 398010.0 7542000.0 279.4, 398000.0 7542000.0 279.9))" and not POLYGONZ( but it is very easy to transform your original format to correct WKT poly = 'POLYGONZ((398000.0 7542000.0 279.9, 398000.0 ...


3

I'm the author of PyShp. What you are trying to do is very standard GIS stuff. Download QGIS. It is basically the open-source ArcGIS. It bundles all of the best of breed open source GIS tools into a nice GUI as well as a fantastic Python automation framework. There are dozens of free tutorials and videos for performing different tasks. There also lots of ...


3

Try replacing line 4 with this: filenames = [ f for f in os.listdir(homefolder) if os.path.isfile(os.path.join(homefolder,f)) and f.endswith(".shp")] This will create a list containing only files with the extension ".shp" Expanded for clarity: # create empty list filenames = [] # begin iterating over files in homefolder directory for f in os.listdir(...


3

You're close - just a few minor issues. Multipatch shapefiles need a specialized type for each part which can be: VALUE PART TYPE 0 Triangle Strip 1 Triangle Fan 2 Outer Ring 3 Inner Ring 4 First Ring 5 Ring In pyshp, this is defined in your parts array using the array "partTypes" All polygons must move in clockwise order ...


3

In your first example, the problem is the cut function expects a shapely LineString object and you passed it a shapefile object. For the second part of your question, the following example takes a point shapefile with one or more points, and cuts a line shapefile using those points. The line shapefile can be as complex as you want: import os import ...


Only top voted, non community-wiki answers of a minimum length are eligible