mirror of
https://github.com/wassname/geopandas.git
synced 2026-09-09 11:22:50 +08:00
Merge branch 'master' into feature/coordinate_index
Conflicts: tests/test_geoseries.py
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@ In particular, when submitting a pull request:
|
||||
|
||||
- All existing tests should pass. Please make sure that the test
|
||||
suite passes, both locally and on
|
||||
[Travis CI](https://travis-ci.org/kjordahl/geopandas). Status on
|
||||
[Travis CI](https://travis-ci.org/geopandas/geopandas). Status on
|
||||
Travis will be visible on a pull request. If you want to enable
|
||||
Travis CI on your own fork, please read the pandas guidelines link
|
||||
above or the
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
GeoPandas [](https://travis-ci.org/kjordahl/geopandas) [](https://coveralls.io/r/kjordahl/geopandas)
|
||||
GeoPandas [](https://travis-ci.org/geopandas/geopandas) [](https://coveralls.io/r/geopandas/geopandas)
|
||||
=========
|
||||
|
||||
Python tools for geographic data
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'GeoPandas'
|
||||
copyright = u'2013, GeoPandas developers'
|
||||
copyright = u'2013-2014, GeoPandas developers'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@@ -52,7 +52,7 @@ try:
|
||||
version = release = d['version']
|
||||
except:
|
||||
# FIXME: This shouldn't be hardwired, but should be set one place only
|
||||
version = release = '0.1.0.dev'
|
||||
version = release = '0.2.0.dev'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
+17
-8
@@ -1,14 +1,23 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
GeoPandas is continuous-release software. You may install the latest
|
||||
source from `GitHub`_ and use the setup script::
|
||||
The released version of GeoPandas is 0.1. To install the released
|
||||
version, use ``pip install geopandas``.
|
||||
|
||||
You may install the latest development version by cloning the
|
||||
`GitHub`_ repository and using the setup script::
|
||||
|
||||
git clone https://github.com/geopandas/geopandas.git
|
||||
cd geopandas
|
||||
python setup.py install
|
||||
|
||||
GeoPandas is also available on `PyPI`_, so ``pip install geopandas``
|
||||
should work as well. You will have to add the ``--pre`` flag
|
||||
for pip 1.4 and later.
|
||||
It is also possible to install the latest development version
|
||||
available on PyPI with `pip` by adding the ``--pre`` flag for pip 1.4
|
||||
and later, or to use `pip` to install directly from the GitHub
|
||||
repository with::
|
||||
|
||||
pip install git+git://github.com/geopandas/geopandas.git
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
@@ -20,7 +29,7 @@ Supports Python versions 2.6, 2.7, and 3.2+.
|
||||
- `shapely`_
|
||||
- `fiona`_
|
||||
- `six`_
|
||||
- `geopy`_ 0.96.3 (optional; for geocoding)
|
||||
- `geopy`_ 0.99 (optional; for geocoding)
|
||||
- `psycopg2`_ (optional; for PostGIS connection)
|
||||
|
||||
For plotting, these additional packages may be used:
|
||||
@@ -42,7 +51,7 @@ Tests are automatically run on all commits on the GitHub repository,
|
||||
including pull requests, on `Travis CI`_.
|
||||
|
||||
.. _PyPI: https://pypi.python.org/pypi/geopandas
|
||||
.. _GitHub: https://github.com/kjordahl/geopandas
|
||||
.. _GitHub: https://github.com/geopandas/geopandas
|
||||
.. _numpy: http://www.numpy.org
|
||||
.. _pandas: http://pandas.pydata.org
|
||||
.. _shapely: http://toblerity.github.io/shapely
|
||||
@@ -53,7 +62,7 @@ including pull requests, on `Travis CI`_.
|
||||
.. _six: https://pythonhosted.org/six
|
||||
.. _psycopg2: https://pypi.python.org/pypi/psycopg2
|
||||
.. _pysal: http://pysal.org
|
||||
.. _Travis CI: https://travis-ci.org/kjordahl/geopandas
|
||||
.. _Travis CI: https://travis-ci.org/geopandas/geopandas
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
@@ -254,6 +254,12 @@ Additionally, the following methods are implemented:
|
||||
See ``GeoSeries.bounds`` for the bounds of the geometries contained
|
||||
in the series.
|
||||
|
||||
.. attribute:: GeoSeries.__geo_interface__
|
||||
|
||||
Implements the `geo_interface`_. Returns a python data structure
|
||||
to represent the ``GeoSeries`` as a GeoJSON-like ``FeatureCollection``.
|
||||
Note that the features will have an empty ``properties`` dict as they don't
|
||||
have associated attributes (geometry only).
|
||||
|
||||
Methods of pandas ``Series`` objects are also available, although not
|
||||
all are applicable to geometric objects and some may return a
|
||||
@@ -312,6 +318,11 @@ Currently, the following methods are implemented for a ``GeoDataFrame``:
|
||||
that column, otherwise calls ``GeoSeries.plot()`` on the
|
||||
``geometry`` column. Wraps the ``plot_dataframe()`` function.
|
||||
|
||||
.. attribute:: GeoDataFrame.__geo_interface__
|
||||
|
||||
Implements the `geo_interface`_. Returns a python data structure
|
||||
to represent the ``GeoDataFrame`` as a GeoJSON-like ``FeatureCollection``.
|
||||
|
||||
All pandas ``DataFrame`` methods are also available, although they may
|
||||
not operate in a meaningful way on the ``geometry`` column and may not
|
||||
return a ``GeoDataFrame`` result even when it would be appropriate to
|
||||
@@ -480,6 +491,7 @@ borough that are in the holes:
|
||||
.. _matplotlib: http://matplotlib.org
|
||||
.. _fiona: http://toblerity.github.io/fiona
|
||||
.. _geopy: https://github.com/geopy/geopy
|
||||
.. _geo_interface: https://gist.github.com/sgillies/2217756
|
||||
.. _file containing the boroughs of New York City: http://www.nyc.gov/html/dcp/download/bytes/nybb_14aav.zip
|
||||
|
||||
.. toctree::
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
try:
|
||||
from geopandas.version import version as __version__
|
||||
except ImportError:
|
||||
__version__ = '0.1.0.dev-unknown'
|
||||
__version__ = '0.2.0.dev-unknown'
|
||||
|
||||
from geopandas.geoseries import GeoSeries
|
||||
from geopandas.geodataframe import GeoDataFrame
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -106,6 +106,13 @@ class GeoSeries(GeoPandasBase, Series):
|
||||
g.crs = crs
|
||||
return g
|
||||
|
||||
@property
|
||||
def __geo_interface__(self):
|
||||
"""Returns a GeoSeries as a python feature collection
|
||||
"""
|
||||
from geopandas import GeoDataFrame
|
||||
return GeoDataFrame({'geometry': self}).__geo_interface__
|
||||
|
||||
def to_file(self, filename, driver="ESRI Shapefile", **kwargs):
|
||||
from geopandas import GeoDataFrame
|
||||
data = GeoDataFrame({"geometry": self,
|
||||
|
||||
+4
-3
@@ -3,9 +3,9 @@ import binascii
|
||||
from pandas import read_sql
|
||||
import shapely.wkb
|
||||
|
||||
|
||||
from geopandas import GeoSeries, GeoDataFrame
|
||||
|
||||
|
||||
def read_postgis(sql, con, geom_col='geom', crs=None, index_col=None,
|
||||
coerce_float=True, params=None):
|
||||
"""
|
||||
@@ -19,7 +19,7 @@ def read_postgis(sql, con, geom_col='geom', crs=None, index_col=None,
|
||||
Parameters
|
||||
----------
|
||||
sql: string
|
||||
con: DB connection object
|
||||
con: DB connection object or SQLAlchemy engine
|
||||
geom_col: string, default 'geom'
|
||||
column name to convert to shapely geometries
|
||||
crs: optional
|
||||
@@ -30,8 +30,9 @@ def read_postgis(sql, con, geom_col='geom', crs=None, index_col=None,
|
||||
index_col, coerce_float, params
|
||||
|
||||
"""
|
||||
df = read_sql(sql, con, index_col=index_col, coerce_float=coerce_float,
|
||||
df = read_sql(sql, con, index_col=index_col, coerce_float=coerce_float,
|
||||
params=params)
|
||||
|
||||
if geom_col not in df:
|
||||
raise ValueError("Query missing geometry column '{0}'".format(
|
||||
geom_col))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
psycopg2>=2.5.1
|
||||
SQLAlchemy>=0.8.3
|
||||
geopy==0.99
|
||||
matplotlib>=1.2.1
|
||||
descartes>=1.0
|
||||
|
||||
@@ -367,8 +367,6 @@ class TestDataFrame(unittest.TestCase):
|
||||
{'a': 2, 'b': np.nan}])
|
||||
assert_frame_equal(expected, result)
|
||||
|
||||
@unittest.skipIf(PANDAS_NEW_SQL_API, 'Development version of pandas '
|
||||
'not yet supported in SQL API.')
|
||||
def test_from_postgis_default(self):
|
||||
con = connect('test_geopandas')
|
||||
if con is None or not create_db(self.df):
|
||||
@@ -378,12 +376,13 @@ class TestDataFrame(unittest.TestCase):
|
||||
sql = "SELECT * FROM nybb;"
|
||||
df = GeoDataFrame.from_postgis(sql, con)
|
||||
finally:
|
||||
if PANDAS_NEW_SQL_API:
|
||||
# It's not really a connection, it's an engine
|
||||
con = con.connect()
|
||||
con.close()
|
||||
|
||||
validate_boro_df(self, df)
|
||||
|
||||
@unittest.skipIf(PANDAS_NEW_SQL_API, 'Development version of pandas '
|
||||
'not yet supported in SQL API.')
|
||||
def test_from_postgis_custom_geom_col(self):
|
||||
con = connect('test_geopandas')
|
||||
if con is None or not create_db(self.df):
|
||||
@@ -396,6 +395,9 @@ class TestDataFrame(unittest.TestCase):
|
||||
FROM nybb;"""
|
||||
df = GeoDataFrame.from_postgis(sql, con, geom_col='__geometry__')
|
||||
finally:
|
||||
if PANDAS_NEW_SQL_API:
|
||||
# It's not really a connection, it's an engine
|
||||
con = con.connect()
|
||||
con.close()
|
||||
|
||||
validate_boro_df(self, df)
|
||||
@@ -425,3 +427,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])
|
||||
|
||||
|
||||
@@ -146,5 +146,10 @@ class TestSeries(unittest.TestCase):
|
||||
self.assertTrue(geom_equals(self.g3[[True, False]], self.g3.cx[0.9:, :0.1]))
|
||||
self.assertTrue(geom_equals(self.g3[[False, True]], self.g3.cx[0:0.1, 0.9:1.0]))
|
||||
|
||||
def test_geoseries_geointerface(self):
|
||||
self.assertEqual(self.g1.__geo_interface__['type'], 'FeatureCollection')
|
||||
self.assertEqual(len(self.g1.__geo_interface__['features']),
|
||||
self.g1.shape[0])
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
+6
-4
@@ -16,8 +16,6 @@ class TestIO(unittest.TestCase):
|
||||
with fiona.open(path, vfs=vfs) as f:
|
||||
self.crs = f.crs
|
||||
|
||||
@unittest.skipIf(PANDAS_NEW_SQL_API, 'Development version of pandas '
|
||||
'not yet supported in SQL API.')
|
||||
def test_read_postgis_default(self):
|
||||
con = tests.util.connect('test_geopandas')
|
||||
if con is None or not tests.util.create_db(self.df):
|
||||
@@ -27,12 +25,13 @@ class TestIO(unittest.TestCase):
|
||||
sql = "SELECT * FROM nybb;"
|
||||
df = read_postgis(sql, con)
|
||||
finally:
|
||||
if PANDAS_NEW_SQL_API:
|
||||
# It's not really a connection, it's an engine
|
||||
con = con.connect()
|
||||
con.close()
|
||||
|
||||
tests.util.validate_boro_df(self, df)
|
||||
|
||||
@unittest.skipIf(PANDAS_NEW_SQL_API, 'Development version of pandas '
|
||||
'not yet supported in SQL API.')
|
||||
def test_read_postgis_custom_geom_col(self):
|
||||
con = tests.util.connect('test_geopandas')
|
||||
if con is None or not tests.util.create_db(self.df):
|
||||
@@ -45,6 +44,9 @@ class TestIO(unittest.TestCase):
|
||||
FROM nybb;"""
|
||||
df = read_postgis(sql, con, geom_col='__geometry__')
|
||||
finally:
|
||||
if PANDAS_NEW_SQL_API:
|
||||
# It's not really a connection, it's an engine
|
||||
con = con.connect()
|
||||
con.close()
|
||||
|
||||
tests.util.validate_boro_df(self, df)
|
||||
|
||||
Reference in New Issue
Block a user