Pyshp: shapefile to GeoJSON

1,333 views
Skip to first unread message

M. Laloux

unread,
Jul 23, 2013, 2:36:05 PM7/23/13
to geospati...@googlegroups.com
Hello,

With the geo_interface, It is now possible to easily transform a shapefile into a GeoJSON file (see my pyshp_geojson.py)


import shapefile
# read the shapefile
reader = shapefile.Reader("my.shp")
fields = reader.fields[1:]
field_names = [field[0] for field in fields]
buffer = []
for sr in reader.shapeRecords():
      atr = dict(zip(field_names, sr.record))
      geom = sr.shape.__geo_interface__
      buffer.append(dict(type="Feature", geometry=geom, properties=atr))
   
   # write the GeoJSON file
from json import dumps
geojson = open("pyshp-demo.json", "w")
geojson.write(dumps({"type": "FeatureCollection","features": buffer}, indent=2) + "\n")
geojson.close()

The result is a GeoJSON file
you can use directly with Leaflet as example (Using GeoJSON with Leaflet or Edit GeoJSON)

Michael Breland

unread,
Jul 23, 2013, 2:50:46 PM7/23/13
to geospati...@googlegroups.com
Nice!
--
You received this message because you are subscribed to the Google Groups "Geospatial Python" group.
To unsubscribe from this group and stop receiving emails from it, send an email to geospatialpyth...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 


--
Joel Lawhead, PMP
E-mail: jlaw...@geospatialpython.com
Web: GeospatialPython.com
Twitter: @SpatialPython

Zia Sobhani

unread,
Apr 5, 2014, 4:16:02 PM4/5/14
to geospati...@googlegroups.com
Hi, I found this post helpful. I was working with an enormous shapefile and found the following change to the loop useful.

import itertools

for (sr, ss) in itertools.izip(reader.iterRecords(), reader.iterShapes()):
    atr = dict(zip(field_names, sr))
    geom = ss.__geo_interface__
    buffer.append(dict(type="Feature", geometry=geom, properties=atr)) 

Zia

Joel Lawhead

unread,
Apr 5, 2014, 4:16:55 PM4/5/14
to geospati...@googlegroups.com
Awesome - thanks Zia!

- Joel
--
You received this message because you are subscribed to the Google Groups "Geospatial Python" group.
To unsubscribe from this group and stop receiving emails from it, send an email to geospatialpyth...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Isaac Boates

unread,
Aug 10, 2015, 9:07:05 PM8/10/15
to Geospatial Python
Hi, so I see that this is two years old but I'm being a lazy dink and trying to use this script out-of-the-box.  I'm trying to use this script and I am getting the error:

TypeError: b'        ' is not JSON serializable

I'm just wondering if there has been any changes to JSON encoding or anything similar that may stop this script from working as-is? I plan to keep picking away at it because I really want a convenient way to go from from shp to GeoJSON... But a lot of this stuff seems to be really high-level Python that I'm not really used to.  Can anyone help?

Here's the full error:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Isaac\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 580, in runfile
    execfile(filename, namespace)
  File "C:\Users\Isaac\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 48, in execfile
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)
  File "C:/python_projects/shp_to_geojson.py", line 24, in <module>
    "features": buffer}, indent=2) + "\n")
  File "C:\Users\Isaac\Anaconda3\lib\json\__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 194, in encode
    chunks = list(chunks)
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 422, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 396, in _iterencode_dict
    yield from chunks
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 317, in _iterencode_list
    yield from chunks
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 396, in _iterencode_dict
    yield from chunks
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 396, in _iterencode_dict
    yield from chunks
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 429, in _iterencode
    o = _default(o)
  File "C:\Users\Isaac\Anaconda3\lib\json\encoder.py", line 173, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: b'        ' is not JSON serializable

Joel Lawhead

unread,
Aug 10, 2015, 9:32:03 PM8/10/15
to Geospatial Python
Isaac,

It looks like you might be using Python 3?  Can you try the same thing with Python 2?  The module itself is Python 3 compatible but the geojson portion may need a patch.

- Joel

Joel Lawhead

unread,
Aug 10, 2015, 9:54:56 PM8/10/15
to Geospatial Python
Isaac,

I was able to recreate the problem in Python 3.

The following should work.  Right before the line:

# write the GeoJSON file

insert:

buffer = str(buffer)

Then it should work.

- Joel

On Monday, August 10, 2015 at 8:07:05 PM UTC-5, Isaac Boates wrote:

Joel Lawhead

unread,
Aug 11, 2015, 7:50:09 PM8/11/15
to Geospatial Python
Isaac,

I was able to recreate the problem in Python 3.

The following should work.  Right before the line:

# write the GeoJSON file

insert:

buffer = str(buffer)

Then it should work.

- Joel

Reply all
Reply to author
Forward
0 new messages