Skip to content
Commits on Source (5)
python-pyproj (2.3.1+ds-1~exp1) experimental; urgency=medium
* New upstream release.
* Drop patches.
-- Bas Couwenberg <sebastic@debian.org> Sun, 01 Sep 2019 07:27:23 +0200
python-pyproj (2.3.0+ds-1) unstable; urgency=medium
* Move from experimental to unstable.
......
Description: reduce precision constrants on geodesic tests
Author: "Alan D. Snow" <alansnow21@gmail.com>
Origin: https://github.com/pyproj4/pyproj/commit/2fe0630d399f6647215031b2e07c03448f61947a
Bug: https://github.com/pyproj4/pyproj/pull/405
--- a/pyproj/geod.py
+++ b/pyproj/geod.py
@@ -396,8 +396,8 @@ class Geod(_Geod):
>>> lons = [-74, -102, -102, -131, -163, 163, 172, 140, 113,
... 88, 59, 25, -4, -14, -33, -46, -61]
>>> poly_area, poly_perimeter = geod.polygon_area_perimeter(lons, lats)
- >>> "{:.3f} {:.3f}".format(poly_area, poly_perimeter)
- '13376856682207.406 14710425.407'
+ >>> "{:.1f} {:.1f}".format(poly_area, poly_perimeter)
+ '13376856682207.4 14710425.4'
Parameters
--- a/test/test_geod.py
+++ b/test/test_geod.py
@@ -183,7 +183,7 @@ def test_geometry_length__linestring():
assert_almost_equal(
geod.geometry_length(LineString([Point(1, 2), Point(3, 4)])),
313588.39721259556,
- decimal=3,
+ decimal=2,
)
@@ -201,7 +201,7 @@ def test_geometry_length__linestring__ra
radians=True,
),
313588.39721259556,
- decimal=3,
+ decimal=2,
)
@@ -213,7 +213,7 @@ def test_geometry_length__linearring():
LinearRing(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
1072185.2103813463,
- decimal=3,
+ decimal=2,
)
@@ -225,7 +225,7 @@ def test_geometry_length__polygon():
Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
1072185.2103813463,
- decimal=3,
+ decimal=2,
)
@@ -246,7 +246,7 @@ def test_geometry_length__polygon__radia
radians=True,
),
1072185.2103813463,
- decimal=3,
+ decimal=2,
)
@@ -257,7 +257,7 @@ def test_geometry_length__multipolygon()
assert_almost_equal(
geod.geometry_length(MultiPolygon([polygon, polygon])),
2 * 1072185.2103813463,
- decimal=3,
+ decimal=2,
)
@@ -276,7 +276,7 @@ def test_geometry_length__multipolygon__
assert_almost_equal(
geod.geometry_length(MultiPolygon([polygon, polygon]), radians=True),
2 * 1072185.2103813463,
- decimal=3,
+ decimal=2,
)
@@ -287,7 +287,7 @@ def test_geometry_length__multilinestrin
assert_almost_equal(
geod.geometry_length(MultiLineString([line_string, line_string])),
1254353.5888503822,
- decimal=3,
+ decimal=2,
)
@@ -311,7 +311,7 @@ def test_geometry_area_perimeter__linest
assert_almost_equal(
geod.geometry_area_perimeter(LineString([Point(1, 2), Point(3, 4)])),
(0.0, 627176.7944251911),
- decimal=3,
+ decimal=2,
)
@@ -329,7 +329,7 @@ def test_geometry_area_perimeter__linest
radians=True,
),
(0.0, 627176.7944251911),
- decimal=3,
+ decimal=2,
)
@@ -341,7 +341,7 @@ def test_geometry_area_perimeter__linear
LinearRing(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
(-49187690467.58623, 1072185.2103813463),
- decimal=3,
+ decimal=2,
)
@@ -353,7 +353,7 @@ def test_geometry_area_perimeter__polygo
Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
(-49187690467.58623, 1072185.2103813463),
- decimal=3,
+ decimal=2,
)
@@ -374,7 +374,7 @@ def test_geometry_area_perimeter__polygo
radians=True,
),
(-49187690467.58623, 1072185.2103813463),
- decimal=3,
+ decimal=2,
)
@@ -389,6 +389,7 @@ def test_geometry_area_perimeter__polygo
)
),
(-944373881400.3394, 3979008.0359657984),
+ decimal=2,
)
@@ -399,7 +400,7 @@ def test_geometry_area_perimeter__multip
assert_almost_equal(
geod.geometry_area_perimeter(MultiPolygon([polygon, polygon])),
(-98375380935.17245, 2144370.4207626926),
- decimal=3,
+ decimal=2,
)
@@ -418,7 +419,7 @@ def test_geometry_area_perimeter__multip
assert_almost_equal(
geod.geometry_area_perimeter(MultiPolygon([polygon, polygon]), radians=True),
(-98375380935.17245, 2144370.4207626926),
- decimal=3,
+ decimal=2,
)
@@ -429,7 +430,7 @@ def test_geometry_area_perimeter__multil
assert_almost_equal(
geod.geometry_area_perimeter(MultiLineString([line_string, line_string])),
(-98375380935.17245, 2144370.4207626926),
- decimal=3,
+ decimal=2,
)
Description: use mock for changing os.environ and sys.prefix in data directory tests
Author: "Alan D. Snow" <alansnow21@gmail.com>
Origin: https://github.com/pyproj4/pyproj/commit/288c149f5306e8b62ee2652bfe0ac5efe555f681
Bug: https://github.com/pyproj4/pyproj/pull/404
--- a/test/test_datadir.py
+++ b/test/test_datadir.py
@@ -27,16 +27,9 @@ def proj_env():
"""
Ensure environment variable the same at the end of the test.
"""
- proj_lib = os.environ.get("PROJ_LIB")
try:
yield
finally:
- if proj_lib is not None:
- # add it back if it used to be there
- os.environ["PROJ_LIB"] = proj_lib
- else:
- # remove it if it wasn't there previously
- os.environ.pop("PROJ_LIB", None)
# make sure the data dir is cleared
set_data_dir(None)
@@ -53,72 +46,101 @@ def temporary_directory():
shutil.rmtree(temp_dir)
-@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
+_INVALID_PATH = "/invalid/path/to/nowhere"
+
+
+def setup_os_mock(os_mock, abspath_return=_INVALID_PATH, proj_dir=None):
+ os_mock.path.abspath.return_value = abspath_return
+ os_mock.path.join = os.path.join
+ os_mock.path.dirname = os.path.dirname
+ os_mock.path.exists = os.path.exists
+ os_mock.pathsep = os.pathsep
+ if proj_dir is None:
+ os_mock.environ = {}
+ else:
+ os_mock.environ = {"PROJ_LIB": proj_dir}
+
+
def test_get_data_dir__missing():
with proj_env(), pytest.raises(DataDirError), patch(
- "pyproj.datadir.os.path.abspath", return_value="INVALID"
- ), patch("pyproj.datadir.find_executable", return_value=None):
+ "pyproj.datadir.find_executable", return_value=None
+ ), patch("pyproj.datadir.os") as os_mock, patch("pyproj.datadir.sys") as sys_mock:
+ sys_mock.prefix = _INVALID_PATH
+ setup_os_mock(os_mock)
unset_data_dir()
- os.environ.pop("PROJ_LIB", None)
assert get_data_dir() is None
def test_get_data_dir__from_user():
- with proj_env(), temporary_directory() as tmpdir, temporary_directory() as tmpdir_env: # noqa: E501
+ with proj_env(), temporary_directory() as tmpdir, patch(
+ "pyproj.datadir.os"
+ ) as os_mock, patch(
+ "pyproj.datadir.sys"
+ ) as sys_mock, temporary_directory() as tmpdir_env: # noqa: E501
+ setup_os_mock(
+ os_mock,
+ abspath_return=os.path.join(tmpdir, "randomfilename.py"),
+ proj_dir=tmpdir_env,
+ )
+ sys_mock.prefix = tmpdir_env
create_projdb(tmpdir)
- os.environ["PROJ_LIB"] = tmpdir_env
create_projdb(tmpdir_env)
set_data_dir(tmpdir)
internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj")
os.makedirs(internal_proj_dir)
create_projdb(internal_proj_dir)
- with patch("pyproj.datadir.os.path.abspath") as abspath_mock:
- abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py")
- assert get_data_dir() == tmpdir
+ assert get_data_dir() == tmpdir
def test_get_data_dir__internal():
- with proj_env(), temporary_directory() as tmpdir:
+ with proj_env(), temporary_directory() as tmpdir, patch(
+ "pyproj.datadir.os"
+ ) as os_mock, temporary_directory() as tmpdir_fake, patch(
+ "pyproj.datadir.sys"
+ ) as sys_mock:
+ setup_os_mock(
+ os_mock,
+ abspath_return=os.path.join(tmpdir, "randomfilename.py"),
+ proj_dir=tmpdir_fake,
+ )
+ sys_mock.prefix = tmpdir_fake
unset_data_dir()
- os.environ["PROJ_LIB"] = tmpdir
create_projdb(tmpdir)
+ create_projdb(tmpdir_fake)
internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj")
os.makedirs(internal_proj_dir)
create_projdb(internal_proj_dir)
- with patch("pyproj.datadir.os.path.abspath") as abspath_mock:
- abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py")
- assert get_data_dir() == internal_proj_dir
+ assert get_data_dir() == internal_proj_dir
-@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_env_var():
with proj_env(), temporary_directory() as tmpdir, patch(
- "pyproj.datadir.os.path.abspath", return_value="INVALID"
- ):
+ "pyproj.datadir.os"
+ ) as os_mock, patch("pyproj.datadir.sys") as sys_mock:
+ setup_os_mock(os_mock, proj_dir=tmpdir)
+ sys_mock.prefix = _INVALID_PATH
unset_data_dir()
- os.environ["PROJ_LIB"] = tmpdir
create_projdb(tmpdir)
assert get_data_dir() == tmpdir
-@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_env_var__multiple():
with proj_env(), temporary_directory() as tmpdir, patch(
- "pyproj.datadir.os.path.abspath", return_value="INVALID"
- ):
+ "pyproj.datadir.os"
+ ) as os_mock, patch("pyproj.datadir.sys") as sys_mock:
+ setup_os_mock(os_mock, proj_dir=os.pathsep.join([tmpdir, tmpdir, tmpdir]))
+ sys_mock.prefix = _INVALID_PATH
unset_data_dir()
- os.environ["PROJ_LIB"] = os.pathsep.join([tmpdir, tmpdir, tmpdir])
create_projdb(tmpdir)
assert get_data_dir() == os.pathsep.join([tmpdir, tmpdir, tmpdir])
-@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_prefix():
with proj_env(), temporary_directory() as tmpdir, patch(
- "pyproj.datadir.os.path.abspath", return_value="INVALID"
- ), patch("pyproj.datadir.sys") as sys_mock:
+ "pyproj.datadir.os"
+ ) as os_mock, patch("pyproj.datadir.sys") as sys_mock:
+ setup_os_mock(os_mock)
unset_data_dir()
- os.environ.pop("PROJ_LIB", None)
sys_mock.prefix = tmpdir
proj_dir = os.path.join(tmpdir, "share", "proj")
os.makedirs(proj_dir)
@@ -126,13 +148,15 @@ def test_get_data_dir__from_prefix():
assert get_data_dir() == proj_dir
-@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_path():
with proj_env(), temporary_directory() as tmpdir, patch(
- "pyproj.datadir.os.path.abspath", return_value="INVALID"
- ), patch("pyproj.datadir.find_executable") as find_exe:
+ "pyproj.datadir.os"
+ ) as os_mock, patch("pyproj.datadir.sys") as sys_mock, patch(
+ "pyproj.datadir.find_executable"
+ ) as find_exe:
+ setup_os_mock(os_mock)
+ sys_mock.prefix = _INVALID_PATH
unset_data_dir()
- os.environ.pop("PROJ_LIB", None)
find_exe.return_value = os.path.join(tmpdir, "bin", "proj")
proj_dir = os.path.join(tmpdir, "share", "proj")
os.makedirs(proj_dir)
@@ -141,18 +165,18 @@ def test_get_data_dir__from_path():
def test_append_data_dir__internal():
- with proj_env(), temporary_directory() as tmpdir:
+ with proj_env(), temporary_directory() as tmpdir, patch(
+ "pyproj.datadir.os"
+ ) as os_mock:
+ setup_os_mock(os_mock, os.path.join(tmpdir, "randomfilename.py"))
unset_data_dir()
- os.environ["PROJ_LIB"] = tmpdir
create_projdb(tmpdir)
internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj")
os.makedirs(internal_proj_dir)
create_projdb(internal_proj_dir)
extra_datadir = str(os.path.join(tmpdir, "extra_datumgrids"))
- with patch("pyproj.datadir.os.path.abspath") as abspath_mock:
- abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py")
- append_data_dir(extra_datadir)
- assert get_data_dir() == os.pathsep.join([internal_proj_dir, extra_datadir])
+ append_data_dir(extra_datadir)
+ assert get_data_dir() == os.pathsep.join([internal_proj_dir, extra_datadir])
def test_creating_multiple_crs_without_file_limit():
0001-use-mock-for-changing-os.environ-and-sys.prefix-in-d.patch
0001-reduce-precision-constrants-on-geodesic-tests-405.patch
......@@ -47,7 +47,7 @@ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """
__version__ = "2.3.0"
__version__ = "2.3.1"
__all__ = [
"Proj",
"Geod",
......@@ -66,6 +66,7 @@ __all__ = [
]
import sys
from pyproj._datadir import PYPROJ_CONTEXT
from pyproj._list import ( # noqa: F401
get_angular_units_map,
get_ellps_map,
......@@ -80,6 +81,8 @@ from pyproj.geod import Geod, geodesic_version_str, pj_ellps # noqa: F401
from pyproj.proj import Proj, pj_list, proj_version_str # noqa: F401
from pyproj.transformer import Transformer, itransform, transform # noqa: F401
PYPROJ_CONTEXT.set_search_paths()
def test(**kwargs):
"""run the examples in the docstrings using the doctest module"""
......
......@@ -91,7 +91,9 @@ cdef _to_wkt(PJ* projobj, version=WktVersion.WKT2_2018, pretty=False):
PROJ_CONTEXT.context,
projobj,
wkt_out_type,
options_wkt)
options_wkt,
)
CRSError.clear()
return cstrdecode(proj_string)
......@@ -122,14 +124,15 @@ cdef _to_proj4(PJ* projobj, version):
PROJ_CONTEXT.context,
projobj,
proj_out_type,
NULL)
NULL,
)
CRSError.clear()
return cstrdecode(proj_string)
cdef PJ* _from_authority(
auth_name, code, PJ_CATEGORY category, int use_proj_alternative_grid_names=False
):
CRSError.clear()
b_auth_name = cstrencode(auth_name)
cdef char *c_auth_name = b_auth_name
b_code = cstrencode(str(code))
......@@ -145,7 +148,6 @@ cdef PJ* _from_authority(
cdef PJ* _from_string(proj_string, expected_types):
CRSError.clear()
cdef PJ* base_pj = proj_create(
PROJ_CONTEXT.context,
cstrencode(proj_string)
......@@ -404,6 +406,7 @@ cdef class CoordinateSystem(Base):
coord_system.name = _COORD_SYSTEM_TYPE_MAP[cs_type]
except KeyError:
raise CRSError("Not a coordinate system.")
CRSError.clear()
return coord_system
@property
......@@ -458,19 +461,18 @@ cdef class Ellipsoid(Base):
cdef Ellipsoid ellips = Ellipsoid()
ellips.projobj = ellipsoid_pj
cdef int is_semi_minor_computed = 0
try:
proj_ellipsoid_get_parameters(
PROJ_CONTEXT.context,
ellips.projobj,
&ellips._semi_major_metre,
&ellips._semi_minor_metre,
&is_semi_minor_computed,
&ellips._inv_flattening)
&ellips._inv_flattening,
)
ellips.ellipsoid_loaded = True
ellips.is_semi_minor_computed = is_semi_minor_computed == 1
except Exception:
pass
ellips._set_name()
CRSError.clear()
return ellips
@staticmethod
......@@ -498,6 +500,7 @@ cdef class Ellipsoid(Base):
raise CRSError(
"Invalid authority or code ({0}, {1})".format(auth_name, code)
)
CRSError.clear()
return Ellipsoid.create(ellipsoid_pj)
@staticmethod
......@@ -546,7 +549,7 @@ cdef class Ellipsoid(Base):
pystrdecode(ellipsoid_string)
)
)
CRSError.clear()
return Ellipsoid.create(ellipsoid_pj)
@property
......@@ -620,6 +623,7 @@ cdef class PrimeMeridian(Base):
)
prime_meridian.unit_name = decode_or_undefined(unit_name)
prime_meridian._set_name()
CRSError.clear()
return prime_meridian
@staticmethod
......@@ -647,6 +651,7 @@ cdef class PrimeMeridian(Base):
raise CRSError(
"Invalid authority or code ({0}, {1})".format(auth_name, code)
)
CRSError.clear()
return PrimeMeridian.create(prime_meridian_pj)
@staticmethod
......@@ -665,7 +670,6 @@ cdef class PrimeMeridian(Base):
"""
return PrimeMeridian.from_authority("EPSG", code)
@staticmethod
def from_string(prime_meridian_string):
"""
......@@ -696,7 +700,7 @@ cdef class PrimeMeridian(Base):
pystrdecode(prime_meridian_string)
)
)
CRSError.clear()
return PrimeMeridian.create(prime_meridian_pj)
......@@ -746,6 +750,7 @@ cdef class Datum(Base):
raise CRSError(
"Invalid authority or code ({0}, {1})".format(auth_name, code)
)
CRSError.clear()
return Datum.create(datum_pj)
@staticmethod
......@@ -801,7 +806,7 @@ cdef class Datum(Base):
pystrdecode(datum_string)
)
)
CRSError.clear()
return Datum.create(datum_pj)
@property
......@@ -817,6 +822,7 @@ cdef class Datum(Base):
PROJ_CONTEXT.context,
self.projobj,
)
CRSError.clear()
if ellipsoid_pj == NULL:
self._ellipsoid = False
return None
......@@ -836,6 +842,7 @@ cdef class Datum(Base):
PROJ_CONTEXT.context,
self.projobj,
)
CRSError.clear()
if prime_meridian_pj == NULL:
self._prime_meridian = False
return None
......@@ -999,6 +1006,7 @@ cdef class Grid:
grid.direct_download = direct_download == 1
grid.open_license = open_license == 1
grid.available = available == 1
CRSError.clear()
return grid
def __str__(self):
......@@ -1085,7 +1093,7 @@ cdef class CoordinateOperation(Base):
PROJ_CONTEXT.context,
coord_operation.projobj
) == 1
CRSError.clear()
return coord_operation
@staticmethod
......@@ -1116,6 +1124,7 @@ cdef class CoordinateOperation(Base):
raise CRSError(
"Invalid authority or code ({0}, {1})".format(auth_name, code)
)
CRSError.clear()
return CoordinateOperation.create(coord_operation_pj)
@staticmethod
......@@ -1170,7 +1179,7 @@ cdef class CoordinateOperation(Base):
pystrdecode(coordinate_operation_string)
)
)
CRSError.clear()
return CoordinateOperation.create(coord_operation_pj)
@property
......@@ -1195,6 +1204,7 @@ cdef class CoordinateOperation(Base):
param_idx
)
)
CRSError.clear()
return self._params
@property
......@@ -1219,6 +1229,7 @@ cdef class CoordinateOperation(Base):
grid_idx
)
)
CRSError.clear()
return self._grids
@property
......@@ -1331,6 +1342,7 @@ cdef class _CRS(Base):
self._type = proj_get_type(self.projobj)
self.type_name = _CRS_TYPE_MAP[self._type]
self._set_name()
CRSError.clear()
@property
def axis_info(self):
......@@ -1366,6 +1378,7 @@ cdef class _CRS(Base):
PROJ_CONTEXT.context,
self.projobj
)
CRSError.clear()
if ellipsoid_pj == NULL:
self._ellipsoid = False
return None
......@@ -1385,6 +1398,7 @@ cdef class _CRS(Base):
PROJ_CONTEXT.context,
self.projobj,
)
CRSError.clear()
if prime_meridian_pj == NULL:
self._prime_meridian = False
return None
......@@ -1406,6 +1420,7 @@ cdef class _CRS(Base):
PROJ_CONTEXT.context,
self.projobj,
)
CRSError.clear()
if datum_pj == NULL:
self._datum = False
return None
......@@ -1426,6 +1441,7 @@ cdef class _CRS(Base):
PROJ_CONTEXT.context,
self.projobj
)
CRSError.clear()
if coord_system_pj == NULL:
self._coordinate_system = False
return None
......@@ -1447,6 +1463,7 @@ cdef class _CRS(Base):
PROJ_CONTEXT.context,
self.projobj
)
CRSError.clear()
if coord_pj == NULL:
self._coordinate_operation = False
return None
......@@ -1465,6 +1482,7 @@ cdef class _CRS(Base):
return None if self._source_crs is False else self._source_crs
cdef PJ * projobj
projobj = proj_get_source_crs(PROJ_CONTEXT.context, self.projobj)
CRSError.clear()
if projobj == NULL:
self._source_crs = False
return None
......@@ -1485,6 +1503,7 @@ cdef class _CRS(Base):
return None if self._target_crs is False else self._target_crs
cdef PJ * projobj
projobj = proj_get_target_crs(PROJ_CONTEXT.context, self.projobj)
CRSError.clear()
if projobj == NULL:
self._target_crs = False
return None
......@@ -1519,7 +1538,7 @@ cdef class _CRS(Base):
proj_destroy(projobj) # deallocate temp proj
iii += 1
projobj = proj_crs_get_sub_crs(PROJ_CONTEXT.context, self.projobj, iii)
CRSError.clear()
return self._sub_crs_list
@property
......@@ -1533,6 +1552,7 @@ cdef class _CRS(Base):
return self._geodetic_crs if self. _geodetic_crs is not False else None
cdef PJ * projobj
projobj = proj_crs_get_geodetic_crs(PROJ_CONTEXT.context, self.projobj)
CRSError.clear()
if projobj == NULL:
self._geodetic_crs = False
return None
......@@ -1667,6 +1687,7 @@ cdef class _CRS(Base):
finally:
if out_confidence_list != NULL:
proj_int_list_destroy(out_confidence_list)
CRSError.clear()
# check to make sure that the projection found is valid
if proj_list == NULL or num_proj_objects <= 0 or out_confidence < min_confidence:
......@@ -1680,6 +1701,7 @@ cdef class _CRS(Base):
proj = proj_list_get(PROJ_CONTEXT.context, proj_list, 0)
finally:
proj_list_destroy(proj_list)
CRSError.clear()
if proj == NULL:
return None
......@@ -1693,6 +1715,7 @@ cdef class _CRS(Base):
return pystrdecode(out_auth_name), pystrdecode(code)
finally:
proj_destroy(proj)
CRSError.clear()
return None
......@@ -1728,7 +1751,6 @@ cdef class _CRS(Base):
is_property = self._type in property_types
return is_property
@property
def is_geographic(self):
"""
......
......@@ -4,3 +4,4 @@ cdef ContextManager PROJ_CONTEXT
cdef class ContextManager:
cdef PJ_CONTEXT *context
cdef object _set_search_paths
\ No newline at end of file
......@@ -13,7 +13,6 @@ cdef void pyproj_log_function(void *user_data, int level, const char *error_msg)
if level == PJ_LOG_ERROR:
ProjError.internal_proj_error = pystrdecode(error_msg)
cdef class ContextManager:
def __cinit__(self):
self.context = NULL
......@@ -25,24 +24,28 @@ cdef class ContextManager:
def __init__(self):
self.context = proj_context_create()
self.set_search_paths()
self._set_search_paths = False
proj_context_use_proj4_init_rules(self.context, 1)
proj_log_func(self.context, NULL, pyproj_log_function)
def set_search_paths(self):
def set_search_paths(self, reset=False):
"""
This method sets the search paths
based on pyproj.datadir.get_data_dir()
"""
if self._set_search_paths and not reset:
return
data_dir_list = get_data_dir().split(os.pathsep)
cdef char **c_data_dir = <char **>malloc(len(data_dir_list) * sizeof(char*))
try:
for iii in range(len(data_dir_list)):
b_data_dir = cstrencode(data_dir_list[iii])
c_data_dir[iii] = b_data_dir
proj_context_set_search_paths(NULL, len(data_dir_list), c_data_dir)
proj_context_set_search_paths(self.context, len(data_dir_list), c_data_dir)
finally:
free(c_data_dir)
self._set_search_paths = True
cdef ContextManager PROJ_CONTEXT = ContextManager()
......
include "proj.pxi"
cdef class Proj:
cdef PJ * projpj
cdef PJ_PROJ_INFO projpj_info
cdef PJ * projobj
cdef PJ_PROJ_INFO projobj_info
cdef readonly srs
......@@ -18,30 +18,31 @@ proj_version_str = "{0}.{1}.{2}".format(
cdef class Proj:
def __cinit__(self):
self.projpj = NULL
self.projobj = NULL
def __init__(self, const char *projstring):
self.srs = pystrdecode(projstring)
# initialize projection
self.projpj = proj_create(PROJ_CONTEXT.context, projstring)
if self.projpj is NULL:
self.projobj = proj_create(PROJ_CONTEXT.context, projstring)
if self.projobj is NULL:
raise ProjError("Invalid projection {}.".format(projstring))
self.projpj_info = proj_pj_info(self.projpj)
self.projobj_info = proj_pj_info(self.projobj)
ProjError.clear()
def __dealloc__(self):
"""destroy projection definition"""
if self.projpj is not NULL:
proj_destroy(self.projpj)
self.projpj = NULL
if self.projobj is not NULL:
proj_destroy(self.projobj)
self.projobj = NULL
@property
def definition(self):
return self.projpj_info.definition
return self.projobj_info.definition
@property
def has_inverse(self):
"""Returns true if this projection has an inverse"""
return self.projpj_info.has_inverse == 1
return self.projobj_info.has_inverse == 1
def __reduce__(self):
"""special method that allows pyproj.Proj instance to be pickled"""
......@@ -63,18 +64,19 @@ cdef class Proj:
cdef double *latsdata
cdef void *londata
cdef void *latdata
cdef int err
cdef int errno
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(lons, &londata, &buflenx) <> 0:
raise ProjError
raise ProjError("object does not provide the python buffer writeable interface")
if PyObject_AsWriteBuffer(lats, &latdata, &bufleny) <> 0:
raise ProjError
raise ProjError("object does not provide the python buffer writeable interface")
# process data in buffer
if buflenx != bufleny:
raise ProjError("Buffer lengths not the same")
ndim = buflenx//_DOUBLESIZE
lonsdata = <double *>londata
latsdata = <double *>latdata
proj_errno_reset(self.projobj)
for iii in range(ndim):
# if inputs are nan's, return big number.
if lonsdata[iii] != lonsdata[iii] or latsdata[iii] != latsdata[iii]:
......@@ -82,17 +84,19 @@ cdef class Proj:
if errcheck:
raise ProjError("projection_undefined")
continue
if proj_angular_input(self.projpj, PJ_FWD):
if proj_angular_input(self.projobj, PJ_FWD):
projlonlatin.uv.u = _DG2RAD * lonsdata[iii]
projlonlatin.uv.v = _DG2RAD * latsdata[iii]
else:
projlonlatin.uv.u = lonsdata[iii]
projlonlatin.uv.v = latsdata[iii]
projxyout = proj_trans(self.projpj, PJ_FWD, projlonlatin)
if errcheck:
err = proj_errno(self.projpj)
if err != 0:
raise ProjError(pystrdecode(proj_errno_string(err)))
projxyout = proj_trans(self.projobj, PJ_FWD, projlonlatin)
errno = proj_errno(self.projobj)
if errcheck and errno:
raise ProjError("proj error: {}".format(
pystrdecode(proj_errno_string(errno))))
elif errcheck and ProjError.internal_proj_error is not None:
raise ProjError("proj error")
# since HUGE_VAL can be 'inf',
# change it to a real (but very large) number.
# also check for NaNs.
......@@ -104,12 +108,13 @@ cdef class Proj:
raise ProjError("projection_undefined")
lonsdata[iii] = 1.e30
latsdata[iii] = 1.e30
elif proj_angular_output(self.projpj, PJ_FWD):
elif proj_angular_output(self.projobj, PJ_FWD):
lonsdata[iii] = _RAD2DG * projxyout.xy.x
latsdata[iii] = _RAD2DG * projxyout.xy.y
else:
lonsdata[iii] = projxyout.xy.x
latsdata[iii] = projxyout.xy.y
ProjError.clear()
@cython.boundscheck(False)
......@@ -131,13 +136,13 @@ cdef class Proj:
cdef void *ydata
cdef double *xdatab
cdef double *ydatab
cdef int err
cdef int errno
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(x, &xdata, &buflenx) <> 0:
raise ProjError
raise ProjError("object does not provide the python buffer writeable interface")
if PyObject_AsWriteBuffer(y, &ydata, &bufleny) <> 0:
raise ProjError
raise ProjError("object does not provide the python buffer writeable interface")
# process data in buffer
# (for numpy/regular python arrays).
if buflenx != bufleny:
......@@ -145,6 +150,9 @@ cdef class Proj:
ndim = buflenx//_DOUBLESIZE
xdatab = <double *>xdata
ydatab = <double *>ydata
# reset errors potentially left over
proj_errno_reset(self.projobj)
for iii in range(ndim):
# if inputs are nan's, return big number.
if xdatab[iii] != xdatab[iii] or ydatab[iii] != ydatab[iii]:
......@@ -152,17 +160,19 @@ cdef class Proj:
if errcheck:
raise ProjError("projection_undefined")
continue
if proj_angular_input(self.projpj, PJ_INV):
if proj_angular_input(self.projobj, PJ_INV):
projxyin.uv.u = _DG2RAD * xdatab[iii]
projxyin.uv.v = _DG2RAD * ydatab[iii]
else:
projxyin.uv.u = xdatab[iii]
projxyin.uv.v = ydatab[iii]
projlonlatout = proj_trans(self.projpj, PJ_INV, projxyin)
if errcheck:
err = proj_errno(self.projpj)
if err != 0:
raise ProjError(pystrdecode(proj_errno_string(err)))
projlonlatout = proj_trans(self.projobj, PJ_INV, projxyin)
errno = proj_errno(self.projobj)
if errcheck and errno:
raise ProjError("proj error: {}".format(
pystrdecode(proj_errno_string(errno))))
elif errcheck and ProjError.internal_proj_error is not None:
raise ProjError("proj error")
# since HUGE_VAL can be 'inf',
# change it to a real (but very large) number.
# also check for NaNs.
......@@ -174,23 +184,25 @@ cdef class Proj:
raise ProjError("projection_undefined")
xdatab[iii] = 1.e30
ydatab[iii] = 1.e30
elif proj_angular_output(self.projpj, PJ_INV):
elif proj_angular_output(self.projobj, PJ_INV):
xdatab[iii] = _RAD2DG * projlonlatout.uv.u
ydatab[iii] = _RAD2DG * projlonlatout.uv.v
else:
xdatab[iii] = projlonlatout.uv.u
ydatab[iii] = projlonlatout.uv.v
ProjError.clear()
def __repr__(self):
return "Proj('{srs}', preserve_units=True)".format(srs=self.srs)
def _is_exact_same(self, Proj other):
return proj_is_equivalent_to(
self.projpj, other.projpj, PJ_COMP_STRICT) == 1
self.projobj, other.projobj, PJ_COMP_STRICT) == 1
def _is_equivalent(self, Proj other):
return proj_is_equivalent_to(
self.projpj, other.projpj, PJ_COMP_EQUIVALENT) == 1
self.projobj, other.projobj, PJ_COMP_EQUIVALENT) == 1
def __eq__(self, other):
if not isinstance(other, Proj):
......
......@@ -67,7 +67,6 @@ def transformer_list_from_crs(
cdef int is_instantiable = 0
cdef CoordinateOperation coordinate_operation
cdef double west_lon_degree, south_lat_degree, east_lon_degree, north_lat_degree
operations = []
try:
operation_factory_context = proj_create_operation_factory_context(
......@@ -142,6 +141,8 @@ def transformer_list_from_crs(
if pj_operations != NULL:
proj_list_destroy(pj_operations)
pj_operations = NULL
ProjError.clear()
return operations
......@@ -183,10 +184,10 @@ cdef class _Transformer(Base):
def _initialize_from_projobj(self):
self.proj_info = proj_pj_info(self.projobj)
if self.proj_info.id == NULL:
ProjError.clear()
raise ProjError("Input is not a transformation.")
cdef PJ_TYPE transformer_type = proj_get_type(self.projobj)
self.type_name = _TRANSFORMER_TYPE_MAP[transformer_type]
ProjError.clear()
@property
def id(self):
......@@ -228,7 +229,6 @@ cdef class _Transformer(Base):
always_xy=False,
area_of_interest=None
):
ProjError.clear()
cdef PJ_AREA *pj_area_of_interest = NULL
cdef double west_lon_degree, south_lat_degree, east_lon_degree, north_lat_degree
if area_of_interest is not None:
......@@ -299,7 +299,6 @@ cdef class _Transformer(Base):
@staticmethod
def from_pipeline(const char *proj_pipeline):
ProjError.clear()
cdef _Transformer transformer = _Transformer()
# initialize projection
transformer.projobj = proj_create(PROJ_CONTEXT.context, proj_pipeline)
......@@ -329,17 +328,15 @@ cdef class _Transformer(Base):
cdef Py_ssize_t buflenx, bufleny, buflenz, buflent, npts, iii
cdef int err
if PyObject_AsWriteBuffer(inx, &xdata, &buflenx) <> 0:
raise ProjError
raise ProjError("object does not provide the python buffer writeable interface")
if PyObject_AsWriteBuffer(iny, &ydata, &bufleny) <> 0:
raise ProjError
if inz is not None:
if PyObject_AsWriteBuffer(inz, &zdata, &buflenz) <> 0:
raise ProjError
raise ProjError("object does not provide the python buffer writeable interface")
if inz is not None and PyObject_AsWriteBuffer(inz, &zdata, &buflenz) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
else:
buflenz = bufleny
if intime is not None:
if PyObject_AsWriteBuffer(intime, &tdata, &buflent) <> 0:
raise ProjError
if intime is not None and PyObject_AsWriteBuffer(intime, &tdata, &buflent) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
else:
buflent = bufleny
......@@ -371,7 +368,6 @@ cdef class _Transformer(Base):
xx[iii] = xx[iii]*_RAD2DG
yy[iii] = yy[iii]*_RAD2DG
ProjError.clear()
proj_errno_reset(self.projobj)
proj_trans_generic(
self.projobj,
......@@ -401,6 +397,7 @@ cdef class _Transformer(Base):
for iii in range(npts):
xx[iii] = xx[iii]*_DG2RAD
yy[iii] = yy[iii]*_DG2RAD
ProjError.clear()
@cython.boundscheck(False)
@cython.wraparound(False)
......@@ -421,7 +418,6 @@ cdef class _Transformer(Base):
double *z
double *tt
Py_ssize_t buflen, npts, iii, jjj
int err
if stride < 2:
raise ProjError("coordinates must contain at least 2 values")
......@@ -467,7 +463,6 @@ cdef class _Transformer(Base):
else:
tt = NULL
ProjError.clear()
proj_errno_reset(self.projobj)
proj_trans_generic (
self.projobj,
......@@ -500,3 +495,5 @@ cdef class _Transformer(Base):
jjj = stride * iii
coords[jjj] *= _DG2RAD
coords[jjj + 1] *= _DG2RAD
ProjError.clear()
......@@ -24,7 +24,7 @@ def set_data_dir(proj_data_dir):
# reset search paths
from pyproj._datadir import PYPROJ_CONTEXT
PYPROJ_CONTEXT.set_search_paths()
PYPROJ_CONTEXT.set_search_paths(reset=True)
def append_data_dir(proj_data_dir):
......
......@@ -396,8 +396,8 @@ class Geod(_Geod):
>>> lons = [-74, -102, -102, -131, -163, 163, 172, 140, 113,
... 88, 59, 25, -4, -14, -33, -46, -61]
>>> poly_area, poly_perimeter = geod.polygon_area_perimeter(lons, lats)
>>> "{:.3f} {:.3f}".format(poly_area, poly_perimeter)
'13376856682207.406 14710425.407'
>>> "{:.1f} {:.1f}".format(poly_area, poly_perimeter)
'13376856682207.4 14710425.4'
Parameters
......
import os
import shutil
import tempfile
import unittest
from contextlib import contextmanager
import pytest
from mock import patch
from pyproj import CRS
from pyproj._datadir import ContextManager
from pyproj.datadir import DataDirError, append_data_dir, get_data_dir, set_data_dir
......@@ -27,16 +27,9 @@ def proj_env():
"""
Ensure environment variable the same at the end of the test.
"""
proj_lib = os.environ.get("PROJ_LIB")
try:
yield
finally:
if proj_lib is not None:
# add it back if it used to be there
os.environ["PROJ_LIB"] = proj_lib
else:
# remove it if it wasn't there previously
os.environ.pop("PROJ_LIB", None)
# make sure the data dir is cleared
set_data_dir(None)
......@@ -53,72 +46,108 @@ def temporary_directory():
shutil.rmtree(temp_dir)
@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
_INVALID_PATH = "/invalid/path/to/nowhere"
def setup_os_mock(os_mock, abspath_return=_INVALID_PATH, proj_dir=None):
os_mock.path.abspath.return_value = abspath_return
os_mock.path.join = os.path.join
os_mock.path.dirname = os.path.dirname
os_mock.path.exists = os.path.exists
os_mock.pathsep = os.pathsep
if proj_dir is None:
os_mock.environ = {}
else:
os_mock.environ = {"PROJ_LIB": proj_dir}
def test_get_data_dir__missing():
with proj_env(), pytest.raises(DataDirError), patch(
"pyproj.datadir.os.path.abspath", return_value="INVALID"
), patch("pyproj.datadir.find_executable", return_value=None):
"pyproj.datadir.find_executable", return_value=None
), patch("pyproj.datadir.os") as os_mock, patch("pyproj.datadir.sys") as sys_mock:
sys_mock.prefix = _INVALID_PATH
setup_os_mock(os_mock)
unset_data_dir()
os.environ.pop("PROJ_LIB", None)
assert get_data_dir() is None
def test_condext_manager_datadir_missing():
with proj_env(), pytest.raises(DataDirError), patch(
"pyproj._datadir.get_data_dir", side_effect=DataDirError("test")
):
ContextManager().set_search_paths()
def test_get_data_dir__from_user():
with proj_env(), temporary_directory() as tmpdir, temporary_directory() as tmpdir_env: # noqa: E501
with proj_env(), temporary_directory() as tmpdir, patch(
"pyproj.datadir.os"
) as os_mock, patch(
"pyproj.datadir.sys"
) as sys_mock, temporary_directory() as tmpdir_env: # noqa: E501
setup_os_mock(
os_mock,
abspath_return=os.path.join(tmpdir, "randomfilename.py"),
proj_dir=tmpdir_env,
)
sys_mock.prefix = tmpdir_env
create_projdb(tmpdir)
os.environ["PROJ_LIB"] = tmpdir_env
create_projdb(tmpdir_env)
set_data_dir(tmpdir)
internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj")
os.makedirs(internal_proj_dir)
create_projdb(internal_proj_dir)
with patch("pyproj.datadir.os.path.abspath") as abspath_mock:
abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py")
assert get_data_dir() == tmpdir
def test_get_data_dir__internal():
with proj_env(), temporary_directory() as tmpdir:
with proj_env(), temporary_directory() as tmpdir, patch(
"pyproj.datadir.os"
) as os_mock, temporary_directory() as tmpdir_fake, patch(
"pyproj.datadir.sys"
) as sys_mock:
setup_os_mock(
os_mock,
abspath_return=os.path.join(tmpdir, "randomfilename.py"),
proj_dir=tmpdir_fake,
)
sys_mock.prefix = tmpdir_fake
unset_data_dir()
os.environ["PROJ_LIB"] = tmpdir
create_projdb(tmpdir)
create_projdb(tmpdir_fake)
internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj")
os.makedirs(internal_proj_dir)
create_projdb(internal_proj_dir)
with patch("pyproj.datadir.os.path.abspath") as abspath_mock:
abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py")
assert get_data_dir() == internal_proj_dir
@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_env_var():
with proj_env(), temporary_directory() as tmpdir, patch(
"pyproj.datadir.os.path.abspath", return_value="INVALID"
):
"pyproj.datadir.os"
) as os_mock, patch("pyproj.datadir.sys") as sys_mock:
setup_os_mock(os_mock, proj_dir=tmpdir)
sys_mock.prefix = _INVALID_PATH
unset_data_dir()
os.environ["PROJ_LIB"] = tmpdir
create_projdb(tmpdir)
assert get_data_dir() == tmpdir
@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_env_var__multiple():
with proj_env(), temporary_directory() as tmpdir, patch(
"pyproj.datadir.os.path.abspath", return_value="INVALID"
):
"pyproj.datadir.os"
) as os_mock, patch("pyproj.datadir.sys") as sys_mock:
setup_os_mock(os_mock, proj_dir=os.pathsep.join([tmpdir, tmpdir, tmpdir]))
sys_mock.prefix = _INVALID_PATH
unset_data_dir()
os.environ["PROJ_LIB"] = os.pathsep.join([tmpdir, tmpdir, tmpdir])
create_projdb(tmpdir)
assert get_data_dir() == os.pathsep.join([tmpdir, tmpdir, tmpdir])
@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_prefix():
with proj_env(), temporary_directory() as tmpdir, patch(
"pyproj.datadir.os.path.abspath", return_value="INVALID"
), patch("pyproj.datadir.sys") as sys_mock:
"pyproj.datadir.os"
) as os_mock, patch("pyproj.datadir.sys") as sys_mock:
setup_os_mock(os_mock)
unset_data_dir()
os.environ.pop("PROJ_LIB", None)
sys_mock.prefix = tmpdir
proj_dir = os.path.join(tmpdir, "share", "proj")
os.makedirs(proj_dir)
......@@ -126,13 +155,15 @@ def test_get_data_dir__from_prefix():
assert get_data_dir() == proj_dir
@unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.")
def test_get_data_dir__from_path():
with proj_env(), temporary_directory() as tmpdir, patch(
"pyproj.datadir.os.path.abspath", return_value="INVALID"
), patch("pyproj.datadir.find_executable") as find_exe:
"pyproj.datadir.os"
) as os_mock, patch("pyproj.datadir.sys") as sys_mock, patch(
"pyproj.datadir.find_executable"
) as find_exe:
setup_os_mock(os_mock)
sys_mock.prefix = _INVALID_PATH
unset_data_dir()
os.environ.pop("PROJ_LIB", None)
find_exe.return_value = os.path.join(tmpdir, "bin", "proj")
proj_dir = os.path.join(tmpdir, "share", "proj")
os.makedirs(proj_dir)
......@@ -141,16 +172,16 @@ def test_get_data_dir__from_path():
def test_append_data_dir__internal():
with proj_env(), temporary_directory() as tmpdir:
with proj_env(), temporary_directory() as tmpdir, patch(
"pyproj.datadir.os"
) as os_mock:
setup_os_mock(os_mock, os.path.join(tmpdir, "randomfilename.py"))
unset_data_dir()
os.environ["PROJ_LIB"] = tmpdir
create_projdb(tmpdir)
internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj")
os.makedirs(internal_proj_dir)
create_projdb(internal_proj_dir)
extra_datadir = str(os.path.join(tmpdir, "extra_datumgrids"))
with patch("pyproj.datadir.os.path.abspath") as abspath_mock:
abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py")
append_data_dir(extra_datadir)
assert get_data_dir() == os.pathsep.join([internal_proj_dir, extra_datadir])
......
......@@ -3,6 +3,7 @@ This is a wrapper for the doctests in lib/pyproj/__init__.py so that
pytest can conveniently run all the tests in a single command line.
"""
import os
import platform
import pyproj
......@@ -15,7 +16,7 @@ def test_doctests():
try:
import shapely # noqa
except ImportError:
if os.name == "nt":
if os.name == "nt" or platform.uname()[4] != "x86_64":
expected_failure_count = 6
# if the below line fails, doctests have failed
......
import math
import os
import pickle
import platform
import shutil
import tempfile
from contextlib import contextmanager
......@@ -26,8 +27,9 @@ except ImportError:
SHAPELY_LOADED = False
skip_shapely_windows = pytest.mark.skipif(
not SHAPELY_LOADED and os.name == "nt", reason="Missing shapely wheels for Windows."
skip_shapely = pytest.mark.skipif(
not SHAPELY_LOADED and (os.name == "nt" or platform.uname()[4] != "x86_64"),
reason="Missing shapely wheels for Windows.",
)
......@@ -171,23 +173,23 @@ def test_polygon_area_perimeter__single_point():
assert perimeter == 0
@skip_shapely_windows
@skip_shapely
def test_geometry_length__point():
geod = Geod(ellps="WGS84")
assert geod.geometry_length(Point(1, 2)) == 0
@skip_shapely_windows
@skip_shapely
def test_geometry_length__linestring():
geod = Geod(ellps="WGS84")
assert_almost_equal(
geod.geometry_length(LineString([Point(1, 2), Point(3, 4)])),
313588.39721259556,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__linestring__radians():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -201,11 +203,11 @@ def test_geometry_length__linestring__radians():
radians=True,
),
313588.39721259556,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__linearring():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -213,11 +215,11 @@ def test_geometry_length__linearring():
LinearRing(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
1072185.2103813463,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__polygon():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -225,11 +227,11 @@ def test_geometry_length__polygon():
Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
1072185.2103813463,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__polygon__radians():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -246,22 +248,22 @@ def test_geometry_length__polygon__radians():
radians=True,
),
1072185.2103813463,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__multipolygon():
geod = Geod(ellps="WGS84")
polygon = Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
assert_almost_equal(
geod.geometry_length(MultiPolygon([polygon, polygon])),
2 * 1072185.2103813463,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__multipolygon__radians():
geod = Geod(ellps="WGS84")
polygon = Polygon(
......@@ -276,22 +278,22 @@ def test_geometry_length__multipolygon__radians():
assert_almost_equal(
geod.geometry_length(MultiPolygon([polygon, polygon]), radians=True),
2 * 1072185.2103813463,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__multilinestring():
geod = Geod(ellps="WGS84")
line_string = LineString([Point(1, 2), Point(3, 4), Point(5, 2)])
assert_almost_equal(
geod.geometry_length(MultiLineString([line_string, line_string])),
1254353.5888503822,
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_length__multipoint():
geod = Geod(ellps="WGS84")
assert (
......@@ -299,23 +301,23 @@ def test_geometry_length__multipoint():
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__point():
geod = Geod(ellps="WGS84")
assert geod.geometry_area_perimeter(Point(1, 2)) == (0, 0)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__linestring():
geod = Geod(ellps="WGS84")
assert_almost_equal(
geod.geometry_area_perimeter(LineString([Point(1, 2), Point(3, 4)])),
(0.0, 627176.7944251911),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__linestring__radians():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -329,11 +331,11 @@ def test_geometry_area_perimeter__linestring__radians():
radians=True,
),
(0.0, 627176.7944251911),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__linearring():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -341,11 +343,11 @@ def test_geometry_area_perimeter__linearring():
LinearRing(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
(-49187690467.58623, 1072185.2103813463),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__polygon():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -353,11 +355,11 @@ def test_geometry_area_perimeter__polygon():
Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
),
(-49187690467.58623, 1072185.2103813463),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__polygon__radians():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -374,11 +376,11 @@ def test_geometry_area_perimeter__polygon__radians():
radians=True,
),
(-49187690467.58623, 1072185.2103813463),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__polygon__holes():
geod = Geod(ellps="WGS84")
assert_almost_equal(
......@@ -389,21 +391,22 @@ def test_geometry_area_perimeter__polygon__holes():
)
),
(-944373881400.3394, 3979008.0359657984),
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__multipolygon():
geod = Geod(ellps="WGS84")
polygon = Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)]))
assert_almost_equal(
geod.geometry_area_perimeter(MultiPolygon([polygon, polygon])),
(-98375380935.17245, 2144370.4207626926),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__multipolygon__radians():
geod = Geod(ellps="WGS84")
polygon = Polygon(
......@@ -418,22 +421,22 @@ def test_geometry_area_perimeter__multipolygon__radians():
assert_almost_equal(
geod.geometry_area_perimeter(MultiPolygon([polygon, polygon]), radians=True),
(-98375380935.17245, 2144370.4207626926),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__multilinestring():
geod = Geod(ellps="WGS84")
line_string = LineString([Point(1, 2), Point(3, 4), Point(5, 2)])
assert_almost_equal(
geod.geometry_area_perimeter(MultiLineString([line_string, line_string])),
(-98375380935.17245, 2144370.4207626926),
decimal=3,
decimal=2,
)
@skip_shapely_windows
@skip_shapely
def test_geometry_area_perimeter__multipoint():
geod = Geod(ellps="WGS84")
assert geod.geometry_area_perimeter(
......
......@@ -403,5 +403,13 @@ def test_is_exact_same_different_type():
assert not Proj("epsg:4326").is_exact_same(None)
def test_reset_errno():
proj = Proj(
{"proj": "laea", "lat_0": -90, "lon_0": 0, "a": 6371228.0, "units": "m"}
)
assert not proj.crs.is_geographic
assert proj(0, 0, inverse=True, errcheck=True) == (0.0, -90.0)
if __name__ == "__main__":
unittest.main()
from pkg_resources import parse_version
import numpy as np
import pytest
from numpy.testing import assert_almost_equal
......@@ -93,7 +95,9 @@ def test_equivalent_proj():
def test_equivalent_proj__disabled():
transformer = Transformer.from_proj(3857, pyproj.Proj(3857).crs.to_proj4())
assert not transformer._transformer.skip_equivalent
assert not transformer._transformer.projections_equivalent
assert transformer._transformer.projections_equivalent == (
parse_version(pyproj.proj_version_str) >= parse_version("6.2.0")
)
assert not transformer._transformer.projections_exact_same
......