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 memory management so you don't have to worry about large files. (How to read large file, line by line in python)
In short
with open("my_large_file.shp", "w") as f:
for line in f:
(code here)
Illustration with a Python module that allows that, Fiona, with data from where do I append point values with pyshp
data = [(33.21, -122.15, 'France'), (35.31, -122.15, 'Germany'), (35.41, -123.15, 'Hawaii'), (30.51, -122.15, 'Philippines'),(32.30, -122.15, 'Texas')]
import fiona
# schema of the shapefile
schema = {'geometry': 'Point', 'properties': {'location':'str:20'}
with fiona.open('my_shapefile.shp', 'w', driver='ESRI Shapefile', schema=schema) as output:
for i in data:
point = {'type': 'Point', 'coordinates': (l[0],l[1])}
prop = {'location': l[2]}
output.write({'geometry': point, 'properties':prop})
The equivalent solution with Pyshp leads to an error AttributeError: Writer instance has no attribute '__exit__
:
with sf.Writer(sf.POINT) as w:
w.field('location','C', 20))
for l in data:
w.point(l[0], l[1])
w.record(l[2])
w.save("my_shapefile.shp")
Unfortunately, you cannot use directly with
here because PyShp,by design, "constructs' the entire shapefile in memory before saving it (but can use with
or yield
to read a shapefile, look at PyShp as Fiona (with the GeoJSON-like protocol)).
w = sf.Writer(sf.POINT)
w.field('location','C', 20)
for l in data:
w.point(l[0], l[1])
w.record(l[2])
and w grows, grows ...(it remain open in memory)
Then
w.save("my_shapefile.shp")
You may be try to append each feature to an existing shapefile as in Appending using PyShp but it is more complicated.