geopandas: BUG: to_file(driver='GPKG') tests fail with GDAL 3.3.0

  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of geopandas.
  • (optional) I have confirmed this bug exists on the master branch of geopandas.

Problem description

test_to_file_datetime (which uses GPKG) and test_to_file_bool[GPKG-gpkg] both fail with GDAL 3.3.0, as the data read back has a CRS, but the originally written data does not:

_________________________ test_to_file_bool[GPKG-gpkg] _________________________
tmpdir = local('/tmp/pytest-of-mockbuild/pytest-4/test_to_file_bool_GPKG_gpkg_0')
driver = 'GPKG', ext = 'gpkg'
    @pytest.mark.parametrize("driver,ext", driver_ext_pairs)
    def test_to_file_bool(tmpdir, driver, ext):
        """Test error raise when writing with a boolean column (GH #437)."""
        tempfilename = os.path.join(str(tmpdir), "temp.{0}".format(ext))
        df = GeoDataFrame(
            {
                "a": [1, 2, 3],
                "b": [True, False, True],
                "geometry": [Point(0, 0), Point(1, 1), Point(2, 2)],
            }
        )
    
        df.to_file(tempfilename, driver=driver)
        result = read_file(tempfilename)
        if driver == "GeoJSON":
            # geojson by default assumes epsg:4326
            result.crs = None
        if driver == "ESRI Shapefile":
            # Shapefile does not support boolean, so is read back as int
            df["b"] = df["b"].astype("int64")
>       assert_geodataframe_equal(result, df)
geopandas/io/tests/test_file.py:120: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
left =    a      b                 geometry
0  1   True  POINT (0.00000 0.00000)
1  2  False  POINT (1.00000 1.00000)
2  3   True  POINT (2.00000 2.00000)
right =    a      b                 geometry
0  1   True  POINT (0.00000 0.00000)
1  2  False  POINT (1.00000 1.00000)
2  3   True  POINT (2.00000 2.00000)
check_dtype = True, check_index_type = 'equiv', check_column_type = 'equiv'
check_frame_type = True, check_like = False, check_less_precise = False
check_geom_type = False, check_crs = True, normalize = False
    def assert_geodataframe_equal(
        left,
        right,
        check_dtype=True,
        check_index_type="equiv",
        check_column_type="equiv",
        check_frame_type=True,
        check_like=False,
        check_less_precise=False,
        check_geom_type=False,
        check_crs=True,
        normalize=False,
    ):
        """
        Check that two GeoDataFrames are equal/
    
        Parameters
        ----------
        left, right : two GeoDataFrames
        check_dtype : bool, default True
            Whether to check the DataFrame dtype is identical.
        check_index_type, check_column_type : bool, default 'equiv'
            Check that index types are equal.
        check_frame_type : bool, default True
            Check that both are same type (*and* are GeoDataFrames). If False,
            will attempt to convert both into GeoDataFrame.
        check_like : bool, default False
            If true, ignore the order of rows & columns
        check_less_precise : bool, default False
            If True, use geom_almost_equals. if False, use geom_equals.
        check_geom_type : bool, default False
            If True, check that all the geom types are equal.
        check_crs: bool, default True
            If `check_frame_type` is True, then also check that the
            crs matches.
        normalize: bool, default False
            If True, normalize the geometries before comparing equality.
            Typically useful with ``check_less_precise=True``, which uses
            ``geom_almost_equals`` and requires exact coordinate order.
        """
        try:
            # added from pandas 0.20
            from pandas.testing import assert_frame_equal, assert_index_equal
        except ImportError:
            from pandas.util.testing import assert_frame_equal, assert_index_equal
    
        # instance validation
        if check_frame_type:
            assert isinstance(left, GeoDataFrame)
            assert isinstance(left, type(right))
    
            if check_crs:
                # no crs can be either None or {}
                if not left.crs and not right.crs:
                    pass
                else:
>                   assert left.crs == right.crs
E                   AssertionError
geopandas/testing.py:246: AssertionError
____________________________ test_to_file_datetime _____________________________
tmpdir = local('/tmp/pytest-of-mockbuild/pytest-4/test_to_file_datetime0')
    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)
geopandas/io/tests/test_file.py:131: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
left = 0    POINT (0.00000 0.00000)
1    POINT (0.00000 0.00000)
Name: geometry, dtype: geometry
right = 0    POINT (0.00000 0.00000)
1    POINT (0.00000 0.00000)
Name: geometry, dtype: geometry
check_dtype = True, check_index_type = False, check_series_type = True
check_less_precise = False, check_geom_type = False, check_crs = True
normalize = False
    def assert_geoseries_equal(
        left,
        right,
        check_dtype=True,
        check_index_type=False,
        check_series_type=True,
        check_less_precise=False,
        check_geom_type=False,
        check_crs=True,
        normalize=False,
    ):
        """
        Test util for checking that two GeoSeries are equal.
    
        Parameters
        ----------
        left, right : two GeoSeries
        check_dtype : bool, default False
            If True, check geo dtype [only included so it's a drop-in replacement
            for assert_series_equal].
        check_index_type : bool, default False
            Check that index types are equal.
        check_series_type : bool, default True
            Check that both are same type (*and* are GeoSeries). If False,
            will attempt to convert both into GeoSeries.
        check_less_precise : bool, default False
            If True, use geom_almost_equals. if False, use geom_equals.
        check_geom_type : bool, default False
            If True, check that all the geom types are equal.
        check_crs: bool, default True
            If `check_series_type` is True, then also check that the
            crs matches.
        normalize: bool, default False
            If True, normalize the geometries before comparing equality.
            Typically useful with ``check_less_precise=True``, which uses
            ``geom_almost_equals`` and requires exact coordinate order.
        """
        assert len(left) == len(right), "%d != %d" % (len(left), len(right))
    
        if check_dtype:
            msg = "dtype should be a GeometryDtype, got {0}"
            assert isinstance(left.dtype, GeometryDtype), msg.format(left.dtype)
            assert isinstance(right.dtype, GeometryDtype), msg.format(left.dtype)
    
        if check_index_type:
            assert isinstance(left.index, type(right.index))
    
        if check_series_type:
            assert isinstance(left, GeoSeries)
            assert isinstance(left, type(right))
    
            if check_crs:
>               assert left.crs == right.crs
E               AssertionError
geopandas/testing.py:114: AssertionError

It looks like this affected CI, but hasn’t been reported yet?

Expected Output

Tests pass.

Output of geopandas.show_versions()

https://github.com/geopandas/geopandas/runs/2844417430?check_suite_focus=true#step:5:18

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 15 (15 by maintainers)

Most upvoted comments

I would be fine with such a solution (probably using WKT rather than a simple name). We should just make a note in docs.