jazzband / geojson

Python bindings and utilities for GeoJSON
https://pypi.python.org/pypi/geojson/
BSD 3-Clause "New" or "Revised" License
915 stars 121 forks source link

Numpy scalars don't work in feature properties #49

Closed phobson closed 9 years ago

phobson commented 9 years ago

I noticed that the json library in Python 3.3 (and likely other versions) isn't playing nice with numpy scalars. Given the GIS ecosystem's affinity for numpy, I'm curious if:

  1. if this has come up before and
  2. it's something we could shield users from (via some form of sanitizer)

Consider the following:

import numpy
import geojson

pnt = geojson.Point(coordinates=(15.7, 12.2))
props_np = {'area': numpy.float64(20.5), 'sections': numpy.int64(100), 'name': 'Test Area'}
props_std = {'area': 20.5, 'sections': 100, 'name': 'Test Area'}

feat_np = geojson.Feature(id=0, geometry=pnt, properties=props_np)
feat_std = geojson.Feature(id=0, geometry=pnt, properties=props_std)

print(feat_std) # works fine
print(feat_np) 
{"geometry": {"coordinates": [15.7, 12.2], "type": "Point"}, "id": 0, "properties": {"area": 20.5, "name": "Test Area", "sections": 100}, "type": "Feature"}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-15-beb75a42ffbc> in <module>()
     17 
     18 print(feat_std)
---> 19 print(feat_np)
------------------------
... [yada yada]
C:\Miniconda3\envs\pnr\lib\json\encoder.py in encode(self, o)
    190         # exceptions aren't as detailed.  The list call should be roughly
    191         # equivalent to the PySequence_Fast that ''.join() would do.
--> 192         chunks = self.iterencode(o, _one_shot=True)
    193         if not isinstance(chunks, (list, tuple)):
    194             chunks = list(chunks)

C:\Miniconda3\envs\pnr\lib\json\encoder.py in iterencode(self, o, _one_shot)
    248                 self.key_separator, self.item_separator, self.sort_keys,
    249                 self.skipkeys, _one_shot)
--> 250         return _iterencode(o, 0)
    251 
    252 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

C:\Miniconda3\envs\pnr\lib\json\encoder.py in default(self, o)
    171 
    172         """
--> 173         raise TypeError(repr(o) + " is not JSON serializable")
    174 
    175     def encode(self, o):

TypeError: 100 is not JSON serializable
frewsxcv commented 9 years ago

I'm not sure it's fair for python-geojson to handle encoding for non-standard numeric types. If you're looking for a solution, you can always write your own JSON encoder/decoder and pass it to dumps/loads. Does this answer your question? Let me know if it doesn't.

phobson commented 9 years ago

It absolutely does. I just wanted to check in case this wasn't expected behavior.

The library is wonderful :+1:

And many thanks for the SO link. Very useful.

groteworld commented 9 years ago

Ugh. I have have a mind to write a new numpy. More modular, more interoperable, less clusterfuckery.

On Thu, Nov 20, 2014 at 8:44 PM, Corey Farwell notifications@github.com wrote:

I'm not sure it's fair for python-geojson to handle encoding for non-standard numeric types. If you're looking for a solution, you can always write your own JSON encoder/decoder and pass it to dumps/loads. Does this answer your question? Let me know if it doesn't.

Reply to this email directly or view it on GitHub: https://github.com/frewsxcv/python-geojson/issues/49#issuecomment-63912485