Repository: geopandas/geopandas

Issue:
ValueError when saving geodataframe with pandas timestamps to shapefile
Is there any proper way to fix this error inside geopandas (not fiona)?

(Or maybe I'm trying to do the wrong thing and for example should convert my timestamps into strings before writing?)

```
C:\Users\kkrasnoschekov\_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\geopandas-0.1.0.dev_6163bc9-py3.4.egg\geopandas\geodataframe.py in to_file(self, filename, driver, schema, **kwargs)
    326         """
    327         from geopandas.io.file import to_file
--> 328         to_file(self, filename, driver, schema, **kwargs)
    329 
    330     def to_crs(self, crs=None, epsg=None, inplace=False):

C:\Users\kkrasnoschekov\_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\geopandas-0.1.0.dev_6163bc9-py3.4.egg\geopandas\io\file.py in to_file(df, filename, driver, schema, **kwargs)
     60                     schema=schema, **kwargs) as c:
     61         for feature in df.iterfeatures():
---> 62             c.write(feature)
     63 
     64 

C:\Users\kkrasnoschekov\_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\fiona\collection.py in write(self, record)
    323     def write(self, record):
    324         """Stages a record for writing to disk."""
--> 325         self.writerecords([record])
    326 
    327     def validate_record(self, record):

C:\Users\kkrasnoschekov\_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\fiona\collection.py in writerecords(self, records)
    317         if self.mode not in ('a', 'w'):
    318             raise IOError("collection not open for writing")
--> 319         self.session.writerecs(records, self)
    320         self._len = self.session.get_length()
    321         self._bounds = self.session.get_extent()

fiona/ogrext.pyx in fiona.ogrext.WritingSession.writerecs (fiona/ogrext.c:15333)()

fiona/ogrext.pyx in fiona.ogrext.OGRFeatureBuilder.build (fiona/ogrext.c:5751)()

ValueError: Invalid field type <class 'pandas.tslib.Timestamp'>
```



Discussion:
Yes, you would need to convert your timestamp values to strings. GeoPandas is very flexible about what kinds of data you can store in columns, but output formats are more limited. Timestamps are a special case, that may be worth handling.

On a similar note, I'm having issues exporting geopandas dataframes  that have columns with data types'float64' and 'int64'.  This was my last error using 'int64' column:

`OverflowError: value too large to convert to int`

Should I convert them to strings as well?

N.
On May 5, 2015 10:39 AM, "Kirill Krasnoschekov" notifications@github.com
wrote:

> Is there any proper way to fix this error inside geopandas (not fiona)?
> 
> (Or maybe I'm trying to do the wrong thing and for example should convert
> my timestamps into strings before writing?)
> 
> C:\Users\kkrasnoschekov_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\geopandas-0.1.0.dev_6163bc9-py3.4.egg\geopandas\geodataframe.py
> in to_file(self, filename, driver, schema, *_kwargs)
>     326         """
>     327         from geopandas.io.file import to_file
> --> 328         to_file(self, filename, driver, schema, *_kghbbnnn.
> wargs)
>     329
>     330     def to_crs(self, crs=None, epsg=None, inplace=False):
> 
> C:\Users\kkrasnoschekov_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\geopandas-0.1.0.dev_6163bc9-py3.4.egg\geopandas\io\file.py
> in to_file(df, filename, driver, schema, *_kwargs)
>      60                     schema=schema, *_kwargs) as c:
>      61         for feature in df.iterfeatures():
> ---> 62             c.write(feature)
>      63
>      64
> 
> C:\Users\kkrasnoschekov_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\fiona\collection.py
> in write(self, record)
>     323     def write(self, record):
>     324         """Stages a record for writing to disk."""
> --> 325         self.writerecords([record])
>     326
>     327     def validate_record(self, record):
> 
> C:\Users\kkrasnoschekov_soft\WinPython-64bit-3.4.3.2_1\python-3.4.3.amd64\lib\site-packages\fiona\collection.py
> in writerecords(self, records)
>     317         if self.mode not in ('a', 'w'):
>     318             raise IOError("collection not open for writing")
> --> 319         self.session.writerecs(records, self)
>     320         self._len = self.session.get_length()
>     321         self._bounds = self.session.get_extent()
> 
> fiona/ogrext.pyx in fiona.ogrext.WritingSession.writerecs
> (fiona/ogrext.c:15333)()
> 
> fiona/ogrext.pyx in fiona.ogrext.OGRFeatureBuilder.build
> (fiona/ogrext.c:5751)()
> 
> ValueError: Invalid field type <class 'pandas.tslib.Timestamp'>
> 
> —
> Reply to this email directly or view it on GitHub.


Resolving patch:
diff --git a/geopandas/io/file.py b/geopandas/io/file.py
--- a/geopandas/io/file.py
+++ b/geopandas/io/file.py
@@ -140,6 +140,9 @@ def infer_schema(df):
     def convert_type(column, in_type):
         if in_type == object:
             return 'str'
+        if in_type.name.startswith('datetime64'):
+            # numpy datetime type regardless of frequency
+            return 'datetime'
         out_type = type(np.zeros(1, in_type).item()).__name__
         if out_type == 'long':
             out_type = 'int'


Test patch:
diff --git a/geopandas/io/tests/test_file.py b/geopandas/io/tests/test_file.py
--- a/geopandas/io/tests/test_file.py
+++ b/geopandas/io/tests/test_file.py
@@ -1,8 +1,10 @@
 from __future__ import absolute_import
 
 from collections import OrderedDict
+import datetime
 from distutils.version import LooseVersion
 import os
+import sys
 
 import numpy as np
 
@@ -97,6 +99,22 @@ def test_to_file_bool(tmpdir, driver, ext):
         assert_geodataframe_equal(result, df, check_column_type=False)
 
 
+@pytest.mark.skipif(
+        (sys.version_info < (3, 0)) and sys.platform.startswith('win'),
+        reason="GPKG tests failing on AppVeyor for Python 2.7")
+def test_to_file_datetime(tmpdir):
+    """Test writing a data file with the datetime column type"""
+    tempfilename = os.path.join(str(tmpdir), 'test_datetime.gpkg')
+    point = Point(0, 0)
+    now = datetime.datetime.now()
+    df = GeoDataFrame(
+        {'a': [1, 2], 'b': [now, now]},
+        geometry=[point, point], crs={})
+    df.to_file(tempfilename, driver='GPKG')
+    df_read = read_file(tempfilename)
+    assert_geoseries_equal(df.geometry, df_read.geometry)
+
+
 @pytest.mark.parametrize(
     'ext, driver', [('shp', 'ESRI Shapefile'), ('geojson', 'GeoJSON')])
 def test_to_file_with_point_z(tmpdir, ext, driver):