mirror of
https://github.com/wassname/geopandas.git
synced 2026-09-23 13:20:36 +08:00
Add always_xy for pyproj>=2.2.0; skip transformations when CRS exact same (#1122)
This commit is contained in:
committed by
Joris Van den Bossche
parent
0f0556a457
commit
d2020b299b
+24
-7
@@ -18,7 +18,8 @@ from geopandas.plotting import plot_series
|
||||
from .array import GeometryDtype, from_shapely
|
||||
from .base import is_geometry_type
|
||||
|
||||
_PYPROJ2 = LooseVersion(pyproj.__version__) >= LooseVersion("2.1.0")
|
||||
|
||||
_PYPROJ_VERSION = LooseVersion(pyproj.__version__)
|
||||
|
||||
|
||||
_SERIES_WARNING_MSG = """\
|
||||
@@ -389,22 +390,38 @@ class GeoSeries(GeoPandasBase, Series):
|
||||
"""
|
||||
from fiona.crs import from_epsg
|
||||
|
||||
if crs is None and epsg is None:
|
||||
raise TypeError("Must set either crs or epsg for output.")
|
||||
|
||||
if self.crs is None:
|
||||
raise ValueError(
|
||||
"Cannot transform naive geometries. "
|
||||
"Please set a crs on the object first."
|
||||
)
|
||||
|
||||
if crs is None:
|
||||
try:
|
||||
crs = from_epsg(epsg)
|
||||
except TypeError:
|
||||
raise TypeError("Must set either crs or epsg for output.")
|
||||
proj_in = pyproj.Proj(self.crs, preserve_units=True)
|
||||
proj_out = pyproj.Proj(crs, preserve_units=True)
|
||||
if _PYPROJ2:
|
||||
transformer = pyproj.Transformer.from_proj(proj_in, proj_out)
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError("Invalid epsg: {}".format(epsg))
|
||||
|
||||
# skip transformation if the input CRS and output CRS are the exact same
|
||||
if _PYPROJ_VERSION >= LooseVersion("2.1.2") and pyproj.CRS.from_user_input(
|
||||
self.crs
|
||||
).is_exact_same(pyproj.CRS.from_user_input(crs)):
|
||||
return self
|
||||
|
||||
if _PYPROJ_VERSION >= LooseVersion("2.2.0"):
|
||||
# if availale, use always_xy=True to preserve GIS axis order
|
||||
transformer = pyproj.Transformer.from_crs(self.crs, crs, always_xy=True)
|
||||
project = transformer.transform
|
||||
elif _PYPROJ_VERSION >= LooseVersion("2.1.0"):
|
||||
# use transformer for repeated transformations
|
||||
transformer = pyproj.Transformer.from_crs(self.crs, crs)
|
||||
project = transformer.transform
|
||||
else:
|
||||
proj_in = pyproj.Proj(self.crs, preserve_units=True)
|
||||
proj_out = pyproj.Proj(crs, preserve_units=True)
|
||||
project = partial(pyproj.transform, proj_in, proj_out)
|
||||
result = self.apply(lambda geom: transform(project, geom))
|
||||
result.__class__ = GeoSeries
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
import numpy as np
|
||||
|
||||
from shapely.geometry import Point
|
||||
|
||||
from geopandas import GeoDataFrame, points_from_xy
|
||||
from geopandas.geoseries import _PYPROJ_VERSION
|
||||
|
||||
from geopandas.testing import assert_geodataframe_equal
|
||||
import pytest
|
||||
@@ -94,3 +99,22 @@ def test_transform2(epsg4326, epsg26918):
|
||||
# can't check for CRS equality, as the formats differ although representing
|
||||
# the same CRS
|
||||
assert_geodataframe_equal(df, utm, check_less_precise=True, check_crs=False)
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
_PYPROJ_VERSION < LooseVersion("2.2.0"),
|
||||
reason="EPSG strings without +init= won't work on previous versions of pyproj.",
|
||||
)
|
||||
def test_crs_axis_order__always_xy():
|
||||
df = GeoDataFrame(geometry=[Point(-1683723, 6689139)], crs="epsg:26918")
|
||||
lonlat = df.to_crs("epsg:4326")
|
||||
test_lonlat = GeoDataFrame(
|
||||
geometry=[Point(-110.1399901, 55.1350011)], crs="epsg:4326"
|
||||
)
|
||||
assert_geodataframe_equal(lonlat, test_lonlat, check_less_precise=True)
|
||||
|
||||
|
||||
def test_skip_exact_same():
|
||||
df = df_epsg26918()
|
||||
utm = df.to_crs(df.crs)
|
||||
assert_geodataframe_equal(df, utm, check_less_precise=True)
|
||||
|
||||
Reference in New Issue
Block a user