From f2f94c0d27786afe29d82df04eff7de27d0a690c Mon Sep 17 00:00:00 2001 From: Matthew Perry Date: Fri, 11 Jul 2014 14:34:31 -0500 Subject: [PATCH] preliminary geo interface for geodataframes --- geopandas/geodataframe.py | 35 ++++++++++++++++++++++++++++++----- tests/test_geodataframe.py | 6 ++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/geopandas/geodataframe.py b/geopandas/geodataframe.py index a3809ec..8976aab 100644 --- a/geopandas/geodataframe.py +++ b/geopandas/geodataframe.py @@ -202,7 +202,7 @@ class GeoDataFrame(GeoPandasBase, DataFrame): def to_json(self, na='null', **kwargs): - """Returns a GeoJSON representation of the GeoDataFrame. + """Returns a GeoJSON string representation of the GeoDataFrame. Parameters ---------- @@ -216,6 +216,33 @@ class GeoDataFrame(GeoPandasBase, DataFrame): The remaining *kwargs* are passed to json.dumps(). """ + return json.dumps(self._to_geo(na), **kwargs) + + @property + def __geo_interface__(self): + """Returns a python feature collection (i.e. the geointerface) + representation of the GeoDataFrame. + + This differs from `_to_geo()` only in that it is a property + with a default `na` arg instead of a method + """ + return self._to_geo(na='null') + + def _to_geo(self, na='null'): + """Returns a python feature collection (i.e. the geointerface) + representation of the GeoDataFrame. + + Parameters + ---------- + na : {'null', 'drop', 'keep'}, default 'null' + Indicates how to output missing (NaN) values in the GeoDataFrame + * null: ouput the missing entries as JSON null + * drop: remove the property from the feature. This applies to + each feature individually so that features may have + different properties + * keep: output the missing entries as NaN + """ + def fill_none(row): """ Takes in a Series, converts to a dictionary with null values @@ -246,10 +273,8 @@ class GeoDataFrame(GeoPandasBase, DataFrame): dict((k, v) for k, v in iteritems(row) if k != self._geometry_column_name), 'geometry': mapping(row[self._geometry_column_name]) } - return json.dumps( - {'type': 'FeatureCollection', - 'features': [feature(i, row) for i, row in self.iterrows()]}, - **kwargs ) + return {'type': 'FeatureCollection', + 'features': [feature(i, row) for i, row in self.iterrows()]} def to_file(self, filename, driver="ESRI Shapefile", **kwargs): """ diff --git a/tests/test_geodataframe.py b/tests/test_geodataframe.py index db2b9f8..144f239 100644 --- a/tests/test_geodataframe.py +++ b/tests/test_geodataframe.py @@ -425,3 +425,9 @@ class TestDataFrame(unittest.TestCase): with self.assertRaises(ValueError): df.set_geometry('location', inplace=True) + + def test_geodataframe_geointerface(self): + self.assertEqual(self.df.__geo_interface__['type'], 'FeatureCollection') + self.assertEqual(len(self.df.__geo_interface__['features']), + self.df.shape[0]) +