diff --git a/.all-contributorsrc b/.all-contributorsrc index b269ff2..0755e4c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -24,7 +24,8 @@ "review", "question", "maintenance", - "infra" + "infra", + "bug" ] }, { @@ -41,7 +42,8 @@ "infra", "ideas", "review", - "question" + "question", + "bug" ] }, { @@ -56,7 +58,8 @@ "maintenance", "infra", "review", - "question" + "question", + "bug" ] }, { @@ -69,7 +72,9 @@ "code", "ideas", "review", - "question" + "question", + "bug", + "test" ] }, { @@ -290,7 +295,8 @@ "contributions": [ "platform", "question", - "bug" + "bug", + "test" ] }, { @@ -342,6 +348,18 @@ "ideas", "test" ] + }, + { + "login": "mraspaud", + "name": "Martin Raspaud", + "avatar_url": "https://avatars1.githubusercontent.com/u/167802?v=4", + "profile": "https://github.com/mraspaud", + "contributions": [ + "bug", + "code", + "test", + "ideas" + ] } ], "contributorsPerLine": 7 diff --git a/.isort.cfg b/.isort.cfg index fa2e0d7..746d310 100644 --- a/.isort.cfg +++ b/.isort.cfg @@ -1,5 +1,6 @@ [settings] line_length=88 multi_line_output=3 -known_third_party=mock,numpy,pkg_resources,pytest,setuptools,test +known_third_party=mock,numpy,pkg_resources,pytest,setuptools +known_first_party=pyproj,test include_trailing_comma=true diff --git a/.travis.yml b/.travis.yml index c30961c..d011a2c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,12 @@ - python: 3.6 - python: 3.6 env: + - PROJ_NETWORK=ON + - python: 3.6 + env: + - PROJSYNC=ALL + - python: 3.6 + env: - PROJSOURCE=6.2.0 - python: 3.6 env: @@ -40,6 +46,16 @@ - python: 3.6 env: - PROJSOURCE=6.3.1 + - python: 3.6 + env: + - PROJSOURCE=6.3.2 + - python: 3.6 + env: + - PROJSOURCE=7.0.1 + - python: 3.6 + env: + - PROJSOURCE=7.0.1 + - PROJ_NETWORK=ON - python: 3.7 env: - DOC=true @@ -108,6 +124,10 @@ ci/travis/proj-dl-and-compile "$PROJSOURCE" fi - export PROJ_LIB=$PROJ_DIR/share/proj + - | + if [ "$PROJSYNC" = "ALL" ]; then + $PROJ_DIR/bin/projsync --quiet --bbox -175,0,-50,85 + fi install: # coverage report requires a local install diff --git a/README.md b/README.md index b73b590..6f948cc 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,10 @@ - - - - + + + + @@ -69,7 +69,7 @@ - + @@ -77,6 +77,7 @@ +
Jeff Whitaker
Jeff Whitaker

📖 ⚠️ 💻 💡 🤔 👀 💬 🚧 🚇
Alan D. Snow
Alan D. Snow

📖 ⚠️ 💻 💡 🚧 🚇 🤔 👀 💬
Micah Cochran
Micah Cochran

📖 ⚠️ 💻 🚧 🚇 👀 💬
Joris Van den Bossche
Joris Van den Bossche

📖 💻 🤔 👀 💬
Jeff Whitaker
Jeff Whitaker

📖 ⚠️ 💻 💡 🤔 👀 💬 🚧 🚇 🐛
Alan D. Snow
Alan D. Snow

📖 ⚠️ 💻 💡 🚧 🚇 🤔 👀 💬 🐛
Micah Cochran
Micah Cochran

📖 ⚠️ 💻 🚧 🚇 👀 💬 🐛
Joris Van den Bossche
Joris Van den Bossche

📖 💻 🤔 👀 💬 🐛 ⚠️
Chris Mayo
Chris Mayo

⚠️
Charles Karney
Charles Karney

💻 ⚠️
Justin Dearing
Justin Dearing

🚇
Christopher H. Barker
Christopher H. Barker

💻
Kristian Evers
Kristian Evers

💬 🤔 📖
Even Rouault
Even Rouault

💬
Christoph Gohlke
Christoph Gohlke

📦 💬 🐛
Christoph Gohlke
Christoph Gohlke

📦 💬 🐛 ⚠️
Chris Willoughby
Chris Willoughby

💻
Eduard Popov
Eduard Popov

📖
Joe Ranalli
Joe Ranalli

🐛 💻 ⚠️
Greg Berardinelli
Greg Berardinelli

🐛 💻 🤔 ⚠️
Martin Raspaud
Martin Raspaud

🐛 💻 ⚠️ 🤔
diff --git a/pyproj/__init__.py b/pyproj/__init__.py index 885377c..a072c27 100644 --- a/pyproj/__init__.py +++ b/pyproj/__init__.py @@ -28,7 +28,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -__version__ = "2.6.0" +__version__ = "2.6.1rc0" __all__ = [ "Proj", "Geod", @@ -45,7 +45,6 @@ "get_units_map", "show_versions", ] - import warnings from pyproj import _datadir @@ -65,6 +64,9 @@ from pyproj.proj import Proj, pj_list, proj_version_str # noqa: F401 from pyproj.transformer import Transformer, itransform, transform # noqa: F401 +__proj_version__ = proj_version_str + + try: _datadir.pyproj_global_context_initialize() except DataDirError as err: diff --git a/pyproj/__main__.py b/pyproj/__main__.py index b3d3a0d..cc2f8bb 100644 --- a/pyproj/__main__.py +++ b/pyproj/__main__.py @@ -7,7 +7,7 @@ import argparse -from pyproj import __version__, _show_versions, proj_version_str +from pyproj import __proj_version__, __version__, _show_versions parser = argparse.ArgumentParser() parser.add_argument( @@ -20,5 +20,5 @@ if args.verbose: _show_versions.show_versions() else: - print("pyproj version: {} [PROJ version: {}]".format(__version__, proj_version_str)) + print("pyproj version: {} [PROJ version: {}]".format(__version__, __proj_version__)) parser.print_help() diff --git a/pyproj/_list.pyx b/pyproj/_list.pyx index 699308d..fd59f9d 100644 --- a/pyproj/_list.pyx +++ b/pyproj/_list.pyx @@ -2,6 +2,7 @@ from collections import namedtuple from enum import IntEnum +import warnings from pyproj.compat import cstrencode, pystrdecode from pyproj.enums import PJType @@ -74,6 +75,12 @@ dict: Units supported by PROJ """ + warnings.warn( + "The behavior of 'pyproj.get_units_map' is deprecated " + "and will change in version 3.0.0.", + DeprecationWarning, + stacklevel=2, + ) cdef PJ_UNITS *proj_units = proj_list_units() cdef int iii = 0 units_map = {} @@ -95,6 +102,13 @@ dict: Angular units supported by PROJ """ + warnings.warn( + "'pyproj.get_angular_units_map' is deprecated. " + "Angular units will be available " + "in 'pyproj.get_units_map' in version 3.0.0.", + DeprecationWarning, + stacklevel=2, + ) cdef PJ_UNITS *proj_units = proj_list_angular_units() cdef int iii = 0 units_map = {} diff --git a/pyproj/_proj.pyx b/pyproj/_proj.pyx index b4d16f3..70426e6 100644 --- a/pyproj/_proj.pyx +++ b/pyproj/_proj.pyx @@ -258,7 +258,7 @@ Equivalent to `proj -S` command line. """ cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(longitude) - cdef PyBuffWriteManager latbuff = PyBuffWriteManager(longitude) + cdef PyBuffWriteManager latbuff = PyBuffWriteManager(latitude) if not lonbuff.len or not (lonbuff.len == latbuff.len): raise ProjError('longitude and latitude must be same size') diff --git a/pyproj/_show_versions.py b/pyproj/_show_versions.py index 486f0e8..3683c49 100644 --- a/pyproj/_show_versions.py +++ b/pyproj/_show_versions.py @@ -43,7 +43,7 @@ blob = [ ("pyproj", pyproj.__version__), - ("PROJ", pyproj.proj_version_str), + ("PROJ", pyproj.__proj_version__), ("data dir", data_dir), ] diff --git a/pyproj/crs/_cf1x8.py b/pyproj/crs/_cf1x8.py index 8f33d2a..62eb854 100644 --- a/pyproj/crs/_cf1x8.py +++ b/pyproj/crs/_cf1x8.py @@ -53,9 +53,9 @@ prime_meridian = None prime_meridian_name = cf_params.get("prime_meridian_name") try: - ellipsoid = CustomPrimeMeridian( + prime_meridian = CustomPrimeMeridian( name=prime_meridian_name or "undefined", - longitude=cf_params["prime_meridian_longitude"], + longitude=cf_params["longitude_of_prime_meridian"], ) except KeyError: if prime_meridian_name: diff --git a/pyproj/crs/coordinate_operation.py b/pyproj/crs/coordinate_operation.py index 5a347db..a9ba7ae 100644 --- a/pyproj/crs/coordinate_operation.py +++ b/pyproj/crs/coordinate_operation.py @@ -1136,7 +1136,7 @@ """ Parameters ---------- - longitude_natural_origin: float, optional + latitude_natural_origin: float, optional Latitude of natural origin (lat_0). Defaults to 0.0. longitude_natural_origin: float, optional Longitude of natural origin (lon_0). Defaults to 0.0. diff --git a/pyproj/crs/crs.py b/pyproj/crs/crs.py index f50870f..12979a3 100644 --- a/pyproj/crs/crs.py +++ b/pyproj/crs/crs.py @@ -44,9 +44,9 @@ if isinstance(value, (list, tuple)): value = ",".join([str(val) for val in value]) # issue 183 (+ no_rot) - if value is None or value is True: + if value is None or str(value) == "True": pjargs.append("+{key}".format(key=key)) - elif str(value) == str(False): + elif str(value) == "False": pass else: pjargs.append("+{key}={value}".format(key=key, value=value)) @@ -580,7 +580,6 @@ CF-1.8 version of the projection. """ - unknown_names = ("unknown", "undefined") cf_dict = {"crs_wkt": self.to_wkt(wkt_version)} # type: Dict[str, Any] # handle bound CRS @@ -608,7 +607,7 @@ vert_json = self.to_json_dict() if "geoid_model" in vert_json: cf_dict["geoid_name"] = vert_json["geoid_model"]["name"] - if self.datum and self.datum.name not in unknown_names: + if self.datum: cf_dict["geopotential_datum_name"] = self.datum.name return cf_dict @@ -619,15 +618,13 @@ semi_minor_axis=self.ellipsoid.semi_minor_metre, inverse_flattening=self.ellipsoid.inverse_flattening, ) - if self.ellipsoid.name not in unknown_names: - cf_dict["reference_ellipsoid_name"] = self.ellipsoid.name + cf_dict["reference_ellipsoid_name"] = self.ellipsoid.name if self.prime_meridian: cf_dict["longitude_of_prime_meridian"] = self.prime_meridian.longitude - if self.prime_meridian.name not in unknown_names: - cf_dict["prime_meridian_name"] = self.prime_meridian.name + cf_dict["prime_meridian_name"] = self.prime_meridian.name # handle geographic CRS - if self.geodetic_crs and self.geodetic_crs.name not in unknown_names: + if self.geodetic_crs: cf_dict["geographic_crs_name"] = self.geodetic_crs.name if self.is_geographic: @@ -637,20 +634,19 @@ self.coordinate_operation.method_name.lower() ](self.coordinate_operation) ) - if self.datum and self.datum.name not in unknown_names: + if self.datum: cf_dict["horizontal_datum_name"] = self.datum.name else: cf_dict["grid_mapping_name"] = "latitude_longitude" return cf_dict # handle projected CRS - if self.is_projected and self.datum and self.datum.name not in unknown_names: + if self.is_projected and self.datum: cf_dict["horizontal_datum_name"] = self.datum.name coordinate_operation = None if not self.is_bound and self.is_projected: coordinate_operation = self.coordinate_operation - if self.name not in unknown_names: - cf_dict["projected_crs_name"] = self.name + cf_dict["projected_crs_name"] = self.name coordinate_operation_name = ( None if not coordinate_operation @@ -700,6 +696,7 @@ ------- CRS """ + unknown_names = ("unknown", "undefined") if "crs_wkt" in in_cf: return CRS(in_cf["crs_wkt"]) elif "spatial_ref" in in_cf: # for previous supported WKT key @@ -725,7 +722,7 @@ geographic_crs = GeographicCRS( name=geographic_crs_name or "undefined", datum=datum, ) # type: CRS - elif geographic_crs_name: + elif geographic_crs_name and geographic_crs_name not in unknown_names: geographic_crs = CRS(geographic_crs_name) else: geographic_crs = GeographicCRS() @@ -907,6 +904,9 @@ def __eq__(self, other: Any) -> bool: return self.equals(other) + + def __ne__(self, other: Any) -> bool: + return not self == other def __reduce__(self) -> Tuple[Type["CRS"], Tuple[str]]: """special method that allows CRS instance to be pickled""" diff --git a/pyproj/proj.py b/pyproj/proj.py index 774607f..048af0c 100644 --- a/pyproj/proj.py +++ b/pyproj/proj.py @@ -29,30 +29,9 @@ class Proj(_Proj): """ - Performs cartographic transformations (converts from - longitude,latitude to native map projection x,y coordinates and - vice versa) using PROJ (https://proj.org). - - A Proj class instance is initialized with proj map projection - control parameter key/value pairs. The key/value pairs can - either be passed in a dictionary, or as keyword arguments, - or as a PROJ string (compatible with the proj command). See - https://proj.org/operations/projections/index.html for examples of - key/value pairs defining different map projections. - - Calling a Proj class instance with the arguments lon, lat will - convert lon/lat (in degrees) to x/y native map projection - coordinates (in meters). If optional keyword 'inverse' is True - (default is False), the inverse transformation from x/y to - lon/lat is performed. If optional keyword 'errcheck' is True (default is - False) an exception is raised if the transformation is invalid. - If errcheck=False and the transformation is invalid, no - exception is raised and 'inf' is returned. If the optional keyword - 'preserve_units' is True, the units in map projection coordinates - are not forced to be meters. - - Works with numpy and regular python array objects, python - sequences and scalars. + Performs cartographic transformations. Converts from + longitude, latitude to native map projection x,y coordinates and + vice versa using PROJ (https://proj.org). Attributes ---------- @@ -67,10 +46,12 @@ self, projparams: Any = None, preserve_units: bool = True, **kwargs ) -> None: """ - initialize a Proj class instance. - - See the PROJ documentation (https://proj.org) - for more information about projection parameters. + A Proj class instance is initialized with proj map projection + control parameter key/value pairs. The key/value pairs can + either be passed in a dictionary, or as keyword arguments, + or as a PROJ string (compatible with the proj command). See + https://proj.org/operations/projections/index.html for examples of + key/value pairs defining different map projections. Parameters ---------- @@ -150,30 +131,45 @@ projstring = re.sub(r"\s\+?type=crs", "", projstring) super().__init__(cstrencode(projstring.strip())) - def __call__(self, *args, **kw) -> Tuple[Any, Any]: - # ,lon,lat,inverse=False,errcheck=False): + def __call__( + self, + longitude: Any, + latitude: Any, + inverse: bool = False, + errcheck: bool = False, + ) -> Tuple[Any, Any]: """ Calling a Proj class instance with the arguments lon, lat will convert lon/lat (in degrees) to x/y native map projection - coordinates (in meters). If optional keyword 'inverse' is True - (default is False), the inverse transformation from x/y to - lon/lat is performed. If optional keyword 'errcheck' is True (default is - False) an exception is raised if the transformation is invalid. - If errcheck=False and the transformation is invalid, no - exception is raised and 'inf' is returned. + coordinates (in meters). Inputs should be doubles (they will be cast to doubles if they are not, causing a slight performance hit). Works with numpy and regular python array objects, python sequences and scalars, but is fastest for array objects. - """ - inverse = kw.get("inverse", False) - errcheck = kw.get("errcheck", False) - lon, lat = args + + Parameters + ---------- + longitude: scalar or array (numpy or python) + Input longitude coordinate(s). + latitude: scalar or array (numpy or python) + Input latitude coordinate(s). + inverse: boolean, optional + If inverse is True the inverse transformation from x/y to + lon/lat is performed. Default is False. + errcheck: boolean, optional + If True an exception is raised if the errors are found in the process. + By default errcheck=False and ``inf`` is returned. + + Returns + ------- + Tuple[Any, Any]: + The transformed coordinates. + """ # process inputs, making copies that support buffer API. - inx, xisfloat, xislist, xistuple = _copytobuffer(lon) - iny, yisfloat, yislist, yistuple = _copytobuffer(lat) + inx, xisfloat, xislist, xistuple = _copytobuffer(longitude) + iny, yisfloat, yislist, yistuple = _copytobuffer(latitude) # call PROJ functions. inx and iny modified in place. if inverse: self._inv(inx, iny, errcheck=errcheck) @@ -210,7 +206,7 @@ radians: boolean, optional If True, will expect input data to be in radians. Default is False (degrees). - errcheck: boolean, optional (default False) + errcheck: boolean, optional If True an exception is raised if the errors are found in the process. By default errcheck=False and ``inf`` is returned. diff --git a/pyproj/transformer.py b/pyproj/transformer.py index 87611eb..3d9e1d5 100644 --- a/pyproj/transformer.py +++ b/pyproj/transformer.py @@ -9,6 +9,7 @@ "TransformerGroup", "AreaOfInterest", ] +import warnings from array import array from itertools import chain, islice from typing import Any, Iterable, Iterator, List, Optional, Tuple, Union @@ -68,16 +69,6 @@ The area of interest to help order the transformations based on the best operation for the area. - - Example: - - >>> from pyproj.transformer import TransformerGroup - >>> trans_group = TransformerGroup(4326, 2964) - >>> trans_group - - - transformers: 8 - - unavailable_operations: 1 - """ super().__init__( CRS.from_user_input(crs_from), @@ -373,7 +364,7 @@ If True, will expect input data to be in radians and will return radians if the projection is geographic. Default is False (degrees). Ignored for pipeline transformations. - errcheck: boolean, optional (default False) + errcheck: boolean, optional If True an exception is raised if the transformation is invalid. By default errcheck=False and an invalid transformation returns ``inf`` and no exception is raised. @@ -487,7 +478,7 @@ If True, will expect input data to be in radians and will return radians if the projection is geographic. Default is False (degrees). Ignored for pipeline transformations. - errcheck: boolean, optional (default False) + errcheck: boolean, optional If True an exception is raised if the transformation is invalid. By default errcheck=False and an invalid transformation returns ``inf`` and no exception is raised. @@ -685,6 +676,8 @@ .. versionadded:: 2.1.2 skip_equivalent .. versionadded:: 2.2.0 always_xy + .. warning:: This function is deprecated. See: :ref:`upgrade_transformer` + x2, y2, z2 = transform(p1, p2, x1, y1, z1) Transform points between two coordinate systems defined by the @@ -754,6 +747,15 @@ >>> '%8.3f %8.3f %8.3f %5.3f %5.3f %5.3f' % xy ' -92.220 -94.720 -90.370 38.830 39.320 38.750' """ + warnings.warn( + ( + "This function is deprecated. " + "See: https://pyproj4.github.io/pyproj/stable/" + "gotchas.html#upgrading-to-pyproj-2-from-pyproj-1" + ), + DeprecationWarning, + stacklevel=2, + ) return Transformer.from_proj( p1, p2, skip_equivalent=skip_equivalent, always_xy=always_xy ).transform(xx=x, yy=y, zz=z, tt=tt, radians=radians, errcheck=errcheck) @@ -773,6 +775,8 @@ """ .. versionadded:: 2.1.2 skip_equivalent .. versionadded:: 2.2.0 always_xy + + .. warning:: This function is deprecated. See: :ref:`upgrade_transformer` points2 = itransform(p1, p2, points1) Iterator/generator version of the function pyproj.transform. @@ -827,6 +831,15 @@ '30 60' """ + warnings.warn( + ( + "This function is deprecated. " + "See: https://pyproj4.github.io/pyproj/stable/" + "gotchas.html#upgrading-to-pyproj-2-from-pyproj-1" + ), + DeprecationWarning, + stacklevel=2, + ) return Transformer.from_proj( p1, p2, skip_equivalent=skip_equivalent, always_xy=always_xy ).itransform( diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/conftest.py b/test/conftest.py index 8c53da3..fe19634 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -1,28 +1,16 @@ import os -import shutil -import tempfile +from pathlib import Path -import pytest - -import pyproj +from pyproj.datadir import get_data_dir -@pytest.fixture(scope="session") -def aoi_data_directory(): +def grids_available(*grid_names): """ - This is to ensure that the ntv2_0.gsb file is actually - missing for the AOI tests. + Check if the grids are available """ - data_dir = pyproj.datadir.get_data_dir() - with tempfile.TemporaryDirectory() as tmpdir: - tmp_data_dir = os.path.join(tmpdir, "proj") - shutil.copytree(data_dir, tmp_data_dir) - try: - os.remove(os.path.join(str(tmp_data_dir), "ntv2_0.gsb")) - except OSError: - pass - try: - pyproj.datadir.set_data_dir(str(tmp_data_dir)) - yield - finally: - pyproj.datadir.set_data_dir(data_dir) + if os.environ.get("PROJ_NETWORK") == "ON": + return True + for grid_name in grid_names: + if Path(get_data_dir(), grid_name).exists(): + return True + return False diff --git a/test/crs/test_crs.py b/test/crs/test_crs.py index a055abd..9ea5a7d 100644 --- a/test/crs/test_crs.py +++ b/test/crs/test_crs.py @@ -1,9 +1,10 @@ import json from distutils.version import LooseVersion +import numpy import pytest -from pyproj import CRS, Transformer, proj_version_str +from pyproj import CRS, __proj_version__ from pyproj.crs import ( CoordinateOperation, CoordinateSystem, @@ -14,6 +15,7 @@ from pyproj.crs.enums import CoordinateOperationType, DatumType from pyproj.enums import ProjVersion, WktVersion from pyproj.exceptions import CRSError +from pyproj.transformer import TransformerGroup class CustomCRS(object): @@ -537,11 +539,18 @@ def test_coordinate_operation_grids(): cc = CoordinateOperation.from_epsg(1312) - assert ( - repr(cc.grids) - == "[Grid(short_name=NTv1_0.gsb, full_name=, package_name=, url=, " - "direct_download=False, open_license=False, available=False)]" - ) + if not cc.grids[0].full_name: + assert ( + repr(cc.grids) + == "[Grid(short_name=NTv1_0.gsb, full_name=, package_name=, url=, " + "direct_download=False, open_license=False, available=False)]" + ) + else: + assert ( + repr(cc.grids) + == "[Grid(short_name=NTv1_0.gsb, full_name=NTv1_0.gsb, package_name=, " + "url=, direct_download=False, open_license=False, available=False)]" + ) def test_coordinate_operation_grids__alternative_grid_name(): @@ -551,9 +560,11 @@ assert grid.direct_download is True assert grid.open_license is True assert grid.available is True - if LooseVersion(proj_version_str) >= LooseVersion("7.0.0"): + if LooseVersion(__proj_version__) >= LooseVersion("7.0.0"): assert grid.short_name == "ca_nrc_ntv1_can.tif" - assert grid.full_name.endswith("ntv1_can.dat") + assert grid.full_name.endswith("ntv1_can.dat") or grid.full_name.endswith( + grid.short_name + ) assert grid.package_name == "" assert grid.url == "https://cdn.proj.org/ca_nrc_ntv1_can.tif" else: @@ -1103,6 +1114,13 @@ def test_equals_different_type(): assert CRS("epsg:4326") != "" + assert not CRS("epsg:4326") == "" + + assert CRS("epsg:4326") != 27700 + assert not CRS("epsg:4326") == 27700 + + assert not CRS("epsg:4326") != 4326 + assert CRS("epsg:4326") == 4326 def test_is_exact_same_different_type(): @@ -1186,7 +1204,7 @@ "proj": "ob_tran", } ) - if LooseVersion(proj_version_str) >= LooseVersion("6.3.0"): + if LooseVersion(__proj_version__) >= LooseVersion("6.3.0"): with pytest.warns(UserWarning): assert crs.to_dict() == { "R": 6371229, @@ -1237,13 +1255,14 @@ def test_operations(): - transformer = Transformer.from_crs(28356, 7856) + transformer = TransformerGroup(28356, 7856).transformers[0] coord_op = CoordinateOperation.from_string(transformer.to_wkt()) assert coord_op.operations == transformer.operations def test_operations__scope_remarks(): - transformer = Transformer.from_crs(28356, 7856) + + transformer = TransformerGroup(28356, 7856).transformers[0] coord_op = CoordinateOperation.from_string(transformer.to_wkt()) assert coord_op.operations == transformer.operations # scope does not transfer for some reason @@ -1280,3 +1299,21 @@ @pytest.mark.parametrize("crs_input", ["+proj=tmerc", "epsg:4326"]) def test_utm_zone__none(crs_input): assert CRS(crs_input).utm_zone is None + + +def test_numpy_bool_kwarg_false(): + # Issue 564 + south = numpy.array(50) < 0 + crs = CRS( + proj="utm", zone=32, ellipsis="WGS84", datum="WGS84", units="m", south=south + ) + assert "south" not in crs.srs + + +def test_numpy_bool_kwarg_true(): + # Issue 564 + south = numpy.array(50) > 0 + crs = CRS( + proj="utm", zone=32, ellipsis="WGS84", datum="WGS84", units="m", south=south + ) + assert "+south " in crs.srs diff --git a/test/crs/test_crs_cf.py b/test/crs/test_crs_cf.py index a635f60..aa86769 100644 --- a/test/crs/test_crs_cf.py +++ b/test/crs/test_crs_cf.py @@ -3,7 +3,7 @@ import pytest from numpy.testing import assert_almost_equal -from pyproj import CRS, proj_version_str +from pyproj import CRS, __proj_version__ from pyproj.crs import ProjectedCRS from pyproj.crs._cf1x8 import _try_list_if_string from pyproj.crs.coordinate_operation import ( @@ -73,6 +73,8 @@ "false_easting": 2520000.0, "false_northing": 0.0, "scale_factor_at_central_meridian": 0.9996, + "geographic_crs_name": "unknown", + "projected_crs_name": "unknown", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("BOUNDCRS[") @@ -129,6 +131,9 @@ "false_easting": 2520000.0, "false_northing": 0.0, "scale_factor_at_central_meridian": 1.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", + "horizontal_datum_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("BOUNDCRS[") @@ -154,6 +159,8 @@ "longitude_of_prime_meridian": 0.0, "prime_meridian_name": "Greenwich", "grid_mapping_name": "latitude_longitude", + "geographic_crs_name": "undefined", + "reference_ellipsoid_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("GEOGCRS[") @@ -253,6 +260,7 @@ "grid_north_pole_latitude": 32.5, "grid_north_pole_longitude": 170.0, "north_pole_grid_longitude": 0.0, + "geographic_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("GEOGCRS[") @@ -261,7 +269,7 @@ _test_roundtrip(expected_cf, "GEOGCRS[") with pytest.warns(UserWarning): proj_dict = crs.to_dict() - if LooseVersion(proj_version_str) >= LooseVersion("6.3.0"): + if LooseVersion(__proj_version__) >= LooseVersion("6.3.0"): assert proj_dict == { "proj": "ob_tran", "o_proj": "longlat", @@ -287,7 +295,7 @@ ) with pytest.warns(UserWarning): proj_dict = crs.to_dict() - if LooseVersion(proj_version_str) >= LooseVersion("6.3.0"): + if LooseVersion(__proj_version__) >= LooseVersion("6.3.0"): assert proj_dict == { "proj": "ob_tran", "o_proj": "longlat", @@ -324,6 +332,8 @@ "false_easting": 0.0, "false_northing": 0.0, "standard_parallel": 25.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -372,6 +382,8 @@ "longitude_of_central_meridian": 265.0, "false_easting": 0.0, "false_northing": 0.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -422,6 +434,9 @@ "scale_factor_at_projection_origin": 1.0, "false_easting": 0.0, "false_northing": 0.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", + "horizontal_datum_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -494,6 +509,8 @@ "longitude_of_projection_origin": 0.0, "false_easting": 0.0, "false_northing": 0.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -525,6 +542,8 @@ "longitude_of_projection_origin": 0.0, "false_easting": 0.0, "false_northing": 0.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -548,6 +567,10 @@ "longitude_of_projection_origin": 0.0, "false_easting": 0.0, "false_northing": 0.0, + "geographic_crs_name": "unknown", + "horizontal_datum_name": "unknown", + "projected_crs_name": "unknown", + "reference_ellipsoid_name": "unknown", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -587,6 +610,8 @@ "longitude_of_projection_origin": 10.0, "false_easting": 0.0, "false_northing": 0.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } with pytest.warns(UserWarning): assert crs.to_dict() == { @@ -664,7 +689,7 @@ @pytest.mark.skipif( - LooseVersion(proj_version_str) < LooseVersion("6.3.0"), + LooseVersion(__proj_version__) < LooseVersion("6.3.0"), reason="geoid model does not work in PROJ < 6.3.0", ) def test_geoid_model_name(): @@ -811,6 +836,8 @@ "longitude_of_projection_origin": 2.0, "false_easting": 3.0, "false_northing": 4.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -834,6 +861,8 @@ "longitude_of_central_meridian": 2.0, "false_easting": 3.0, "false_northing": 4.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -858,6 +887,8 @@ "false_easting": 3.0, "false_northing": 4.0, "scale_factor_at_projection_origin": 1.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -881,6 +912,8 @@ "longitude_of_projection_origin": 2.0, "false_easting": 3.0, "false_northing": 4.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -905,6 +938,8 @@ "false_easting": 2.0, "false_northing": 3.0, "scale_factor_at_projection_origin": 1.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -928,6 +963,8 @@ "straight_vertical_longitude_from_pole": 1.0, "false_easting": 2.0, "false_northing": 3.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -952,6 +989,8 @@ "false_easting": 2.0, "false_northing": 3.0, "scale_factor_at_projection_origin": 1.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -974,6 +1013,8 @@ "longitude_of_projection_origin": 0.0, "false_easting": 1.0, "false_northing": 2.0, + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", } cf_dict = crs.to_cf() assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") @@ -998,9 +1039,71 @@ "longitude_of_projection_origin": 1.0, "false_easting": 2.0, "false_northing": 3.0, - } - cf_dict = crs.to_cf() - assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") - assert cf_dict == expected_cf - # test roundtrip - _test_roundtrip(expected_cf, "PROJCRS[") + "geographic_crs_name": "undefined", + "projected_crs_name": "undefined", + } + cf_dict = crs.to_cf() + assert cf_dict.pop("crs_wkt").startswith("PROJCRS[") + assert cf_dict == expected_cf + # test roundtrip + _test_roundtrip(expected_cf, "PROJCRS[") + + +def test_build_custom_datum(): + cf_dict = { + "semi_major_axis": 6370997.0, + "semi_minor_axis": 6370997.0, + "inverse_flattening": 0.0, + "reference_ellipsoid_name": "Normal Sphere (r=6370997)", + "longitude_of_prime_meridian": 1.0, + "grid_mapping_name": "oblique_mercator", + "latitude_of_projection_origin": 0.0, + "longitude_of_projection_origin": 13.809602948622212, + "azimuth_of_central_line": 8.998112717187938, + "scale_factor_at_projection_origin": 1.0, + "false_easting": 0.0, + "false_northing": 0.0, + } + crs = CRS.from_cf(cf_dict) + assert crs.datum.name == "undefined" + assert crs.ellipsoid.name == "Normal Sphere (r=6370997)" + assert crs.prime_meridian.name == "undefined" + assert crs.prime_meridian.longitude == 1 + + +def test_build_custom_datum__default_prime_meridian(): + cf_dict = { + "semi_major_axis": 6370997.0, + "semi_minor_axis": 6370997.0, + "inverse_flattening": 0.0, + "grid_mapping_name": "oblique_mercator", + "latitude_of_projection_origin": 0.0, + "longitude_of_projection_origin": 13.809602948622212, + "azimuth_of_central_line": 8.998112717187938, + "scale_factor_at_projection_origin": 1.0, + "false_easting": 0.0, + "false_northing": 0.0, + } + crs = CRS.from_cf(cf_dict) + assert crs.datum.name == "undefined" + assert crs.ellipsoid.name == "undefined" + assert crs.prime_meridian.name == "Greenwich" + assert crs.prime_meridian.longitude == 0 + + +def test_build_custom_datum__default_ellipsoid(): + cf_dict = { + "prime_meridian_name": "Paris", + "grid_mapping_name": "oblique_mercator", + "latitude_of_projection_origin": 0.0, + "longitude_of_projection_origin": 13.809602948622212, + "azimuth_of_central_line": 8.998112717187938, + "scale_factor_at_projection_origin": 1.0, + "false_easting": 0.0, + "false_northing": 0.0, + } + crs = CRS.from_cf(cf_dict) + assert crs.datum.name == "undefined" + assert crs.ellipsoid.name == "WGS 84" + assert crs.prime_meridian.name == "Paris" + assert str(crs.prime_meridian.longitude).startswith("2.") diff --git a/test/crs/test_crs_coordinate_operation.py b/test/crs/test_crs_coordinate_operation.py index bf87de8..28c6274 100644 --- a/test/crs/test_crs_coordinate_operation.py +++ b/test/crs/test_crs_coordinate_operation.py @@ -3,7 +3,7 @@ import pytest from numpy.testing import assert_almost_equal -from pyproj import proj_version_str +from pyproj import __proj_version__ from pyproj.crs import GeographicCRS from pyproj.crs.coordinate_operation import ( AlbersEqualAreaConversion, @@ -617,7 +617,7 @@ def test_lambert_cylindrical_equal_area_scale_operation__defaults(): lceaop = LambertCylindricalEqualAreaScaleConversion() - if LooseVersion(proj_version_str) >= LooseVersion("6.3.1"): + if LooseVersion(__proj_version__) >= LooseVersion("6.3.1"): assert lceaop.name == "unknown" assert lceaop.method_name == "Lambert Cylindrical Equal Area" assert _to_dict(lceaop) == { @@ -642,7 +642,7 @@ false_northing=4, scale_factor_natural_origin=0.999, ) - if LooseVersion(proj_version_str) >= LooseVersion("6.3.1"): + if LooseVersion(__proj_version__) >= LooseVersion("6.3.1"): assert lceaop.name == "unknown" assert lceaop.method_name == "Lambert Cylindrical Equal Area" op_dict = _to_dict(lceaop) diff --git a/test/crs/test_crs_maker.py b/test/crs/test_crs_maker.py index dffabbc..0c469f6 100644 --- a/test/crs/test_crs_maker.py +++ b/test/crs/test_crs_maker.py @@ -2,7 +2,7 @@ import pytest -from pyproj import proj_version_str +from pyproj import __proj_version__ from pyproj.crs import ( BoundCRS, CompoundCRS, @@ -62,7 +62,7 @@ assert vc.name == "NAVD88 height" assert vc.type_name == "Vertical CRS" assert vc.coordinate_system == VerticalCS() - if LooseVersion(proj_version_str) >= LooseVersion("6.3.0"): + if LooseVersion(__proj_version__) >= LooseVersion("6.3.0"): assert vc.to_json_dict()["geoid_model"]["name"] == "GEOID12B" diff --git a/test/test_awips221.py b/test/test_awips221.py index 8423a4e..522d063 100644 --- a/test/test_awips221.py +++ b/test/test_awips221.py @@ -3,7 +3,7 @@ import numpy from numpy.testing import assert_allclose -from pyproj import Proj, proj_version_str +from pyproj import Proj, __proj_version__ try: from time import perf_counter @@ -26,7 +26,7 @@ # awips221 = Proj(params) # or keyword args awips221 = Proj(proj="lcc", R=6371200, lat_1=50, lat_2=50, lon_0=-107) - print("proj4 library version = ", proj_version_str) + print("proj4 library version = ", __proj_version__) # AWIPS grid 221 parameters # (from http://www.nco.ncep.noaa.gov/pmb/docs/on388/tableb.html) llcrnrx, llcrnry = awips221(-145.5, 1.0) diff --git a/test/test_datum.py b/test/test_datum.py index 4eb930a..aef63aa 100644 --- a/test/test_datum.py +++ b/test/test_datum.py @@ -3,18 +3,25 @@ import pytest from numpy.testing import assert_almost_equal -from pyproj import CRS, Proj, proj_version_str, transform +from pyproj import CRS, Proj, __proj_version__, transform +from test.conftest import grids_available @pytest.mark.parametrize("proj_class", [Proj, CRS]) -def test_datum(proj_class, aoi_data_directory): +def test_datum(proj_class): p1 = proj_class(proj="latlong", datum="WGS84") s_1 = -111.5 s_2 = 45.25919444444 p2 = proj_class(proj="utm", zone=10, datum="NAD27") - x2, y2 = transform(p1, p2, s_1, s_2) - if LooseVersion(proj_version_str) < LooseVersion("6.3.0"): - assert_almost_equal((x2, y2), (1402291.0833290431, 5076289.591846835)) + with pytest.warns(DeprecationWarning): + x2, y2 = transform(p1, p2, s_1, s_2) + if LooseVersion(__proj_version__) < LooseVersion("6.3.0"): + assert_almost_equal( + (x2, y2), (1402291.0833290431, 5076289.591846835), decimal=2 + ) else: - # https://github.com/OSGeo/PROJ/issues/1808 - assert_almost_equal((x2, y2), (1402285.9829252, 5076292.4212746)) + if grids_available("ca_nrc_ntv2_0.tif"): + assert_almost_equal((x2, y2), (1402286.3333203, 5076292.2955777), decimal=2) + else: + # https://github.com/OSGeo/PROJ/issues/1808 + assert_almost_equal((x2, y2), (1402285.9829252, 5076292.4212746), decimal=2) diff --git a/test/test_datum_shift.py b/test/test_datum_shift.py index bb0b463..bf15a6f 100644 --- a/test/test_datum_shift.py +++ b/test/test_datum_shift.py @@ -1,7 +1,7 @@ import pytest from numpy.testing import assert_almost_equal -from pyproj import Proj, proj_version_str, transform +from pyproj import Proj, transform # illustrates the use of the transform function to # perform coordinate transformations with datum shifts. @@ -33,28 +33,33 @@ GAUSSSB_PROJ = Proj( init="epsg:3004", towgs84="-122.74,-34.27,-22.83,-1.884,-3.400,-3.030,-15.62" ) -print("proj4 library version = ", proj_version_str) def test_shift_wgs84_to_utm33(): - xutm33, yutm33, zutm33 = transform( - WGS84_PROJ, UTM_33_PROJ, WGS84_lon, WGS84_lat, WGS84_z - ) + with pytest.warns(DeprecationWarning): + xutm33, yutm33, zutm33 = transform( + WGS84_PROJ, UTM_33_PROJ, WGS84_lon, WGS84_lat, WGS84_z + ) assert_almost_equal((xutm33, yutm33, zutm33), (UTM_x, UTM_y, UTM_z)) def test_shift_utm33_to_wgs84(): - back_lon, back_lat, back_z = transform(UTM_33_PROJ, WGS84_PROJ, UTM_x, UTM_y, UTM_z) + with pytest.warns(DeprecationWarning): + back_lon, back_lat, back_z = transform( + UTM_33_PROJ, WGS84_PROJ, UTM_x, UTM_y, UTM_z + ) assert_almost_equal((back_lon, back_lat, back_z), (WGS84_lon, WGS84_lat, WGS84_z)) def test_shift_wgs84_to_gaussb_no_ellisoidal_height(): - xgb, ygb, zgb = transform(WGS84_PROJ, GAUSSSB_PROJ, WGS84_lon, WGS84_lat, 0) + with pytest.warns(DeprecationWarning): + xgb, ygb, zgb = transform(WGS84_PROJ, GAUSSSB_PROJ, WGS84_lon, WGS84_lat, 0) assert_almost_equal((xgb, ygb, zgb), (GB_x, 5055619.899, 0), decimal=2) def test_shift_gaussb_to_wgs84_no_ellisoidal_height(): - back_lon, back_lat, back_z = transform(GAUSSSB_PROJ, WGS84_PROJ, GB_x, GB_y, 0) + with pytest.warns(DeprecationWarning): + back_lon, back_lat, back_z = transform(GAUSSSB_PROJ, WGS84_PROJ, GB_x, GB_y, 0) assert_almost_equal( (back_lon, back_lat, back_z), (WGS84_lon, WGS84_lat, 0), decimal=3 ) diff --git a/test/test_doctest_wrapper.py b/test/test_doctest_wrapper.py index 2e940e2..0d0b7ea 100644 --- a/test/test_doctest_wrapper.py +++ b/test/test_doctest_wrapper.py @@ -1,6 +1,5 @@ """ -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. +This is a wrapper for the doctests in pyproj """ import doctest import os @@ -8,10 +7,12 @@ import sys import warnings +import pytest + import pyproj -def test_doctests(aoi_data_directory): +def test_doctests(): """run the examples in the docstrings using the doctest module""" with warnings.catch_warnings(): @@ -24,9 +25,10 @@ failure_count_proj, test_count = doctest.testmod(pyproj.proj, verbose=True) failure_count_crs, test_count_crs = doctest.testmod(pyproj.crs, verbose=True) failure_count_geod, test_count_geod = doctest.testmod(pyproj.geod, verbose=True) - failure_count_transform, test_count_transform = doctest.testmod( - pyproj.transformer, verbose=True - ) + with pytest.warns(DeprecationWarning): + failure_count_transform, test_count_transform = doctest.testmod( + pyproj.transformer, verbose=True + ) failure_count = ( failure_count_proj diff --git a/test/test_list.py b/test/test_list.py index 328f3b1..3d1fd9c 100644 --- a/test/test_list.py +++ b/test/test_list.py @@ -15,14 +15,16 @@ def test_units_map(): - units_map = get_units_map() + with pytest.warns(DeprecationWarning): + units_map = get_units_map() assert isinstance(units_map["m"], Unit) assert units_map["m"].id == "m" assert units_map["m"].name == "Meter" def test_angular_units_map(): - ang_map = get_angular_units_map() + with pytest.warns(DeprecationWarning): + ang_map = get_angular_units_map() assert isinstance(ang_map["deg"], Unit) assert ang_map["deg"].id == "deg" assert ang_map["deg"].name == "Degree" diff --git a/test/test_proj.py b/test/test_proj.py index 5632d6a..3bac6ac 100644 --- a/test/test_proj.py +++ b/test/test_proj.py @@ -125,13 +125,13 @@ def test_tranform_none_1st_parmeter(self): # test should raise Type error if projections are not of Proj classes # version 1.9.4 produced AttributeError, now should raise TypeError - with self.assertRaises(CRSError): + with pytest.warns(DeprecationWarning), pytest.raises(CRSError): transform(None, self.p, -74, 39) def test_tranform_none_2nd_parmeter(self): # test should raise Type error if projections are not of Proj classes # version 1.9.4 has a Segmentation Fault, now should raise TypeError - with self.assertRaises(CRSError): + with pytest.warns(DeprecationWarning), pytest.raises(CRSError): transform(self.p, None, -74, 39) @@ -150,7 +150,8 @@ p = Proj("+proj=stere +lon_0=-39 +lat_0=90 +lat_ts=71.0 +ellps=WGS84") self.assertTrue(isinstance(p, Proj)) # if not patched this line raises a "TypeError: p2 must be a Proj class" - lon, lat = transform(p, p.to_latlong(), 200000, 400000) + with pytest.warns(DeprecationWarning): + lon, lat = transform(p, p.to_latlong(), 200000, 400000) @unittest.skipIf( @@ -432,24 +433,24 @@ longitude=longitude, latitude=latitude, radians=radians ) assert_almost_equal( - factors.meridional_scale, [[1.0, 1.00015233], [1.00060954, 1.00137235]], - ) - assert_almost_equal( - factors.parallel_scale, [[1.0, 1.00015233], [1.00060954, 1.00137235]], - ) - assert_almost_equal( - factors.areal_scale, [[1.0, 1.00030468], [1.00121946, 1.00274658]], + factors.meridional_scale, [[1.0001523, 1.0006095], [1.0013723, 1.0024419]], + ) + assert_almost_equal( + factors.parallel_scale, [[1.0001523, 1.0006095], [1.0013723, 1.0024419]], + ) + assert_almost_equal( + factors.areal_scale, [[1.00030468, 1.00121946], [1.00274658, 1.00488976]], ) assert_almost_equal(factors.angular_distortion, [[0, 0], [0, 0]], decimal=5) assert_almost_equal( - factors.meridian_parallel_angle, [[90, 90], [90, 90]], + factors.meridian_parallel_angle, [[89.99, 90], [90, 90]], decimal=2 ) assert_almost_equal(factors.meridian_convergence, [[0, 0], [0, 0]]) assert_almost_equal( - factors.tissot_semimajor, [[1.0, 1.00015233], [1.00060955, 1.00137235]], - ) - assert_almost_equal( - factors.tissot_semiminor, [[1.0, 1.00015233], [1.00060953, 1.00137235]], + factors.tissot_semimajor, [[1.00015234, 1.00060955], [1.00137235, 1.0024419]], + ) + assert_almost_equal( + factors.tissot_semiminor, [[1.00015232, 1.00060953], [1.00137235, 1.0024419]], ) assert_almost_equal( factors.dx_dlam, [[1, 1], [1, 1]], @@ -457,8 +458,25 @@ assert_almost_equal(factors.dx_dphi, [[0, 0], [0, 0]]) assert_almost_equal(factors.dy_dlam, [[0, 0], [0, 0]]) assert_almost_equal( - factors.dy_dphi, [[1.0, 1.00015233], [1.00060954, 1.00137235]], - ) + factors.dy_dphi, [[1.00015233, 1.00060954], [1.00137235, 1.0024419]], + ) + + +def test_get_factors(): + transformer = Proj(3717) + factors = transformer.get_factors(-120, 34) + assert_almost_equal(factors.meridional_scale, 1.0005466) + assert_almost_equal(factors.parallel_scale, 1.0005466) + assert_almost_equal(factors.areal_scale, 1.00109349) + assert_almost_equal(factors.angular_distortion, 0) + assert_almost_equal(factors.meridian_parallel_angle, 90) + assert_almost_equal(factors.meridian_convergence, 1.67864770) + assert_almost_equal(factors.tissot_semimajor, 1.00055, decimal=5) + assert_almost_equal(factors.tissot_semiminor, 1.00055, decimal=5) + assert_almost_equal(factors.dx_dlam, 0.8300039) + assert_almost_equal(factors.dx_dphi, -0.0292052) + assert_almost_equal(factors.dy_dlam, 0.0243244) + assert_almost_equal(factors.dy_dphi, 0.9965495) def test_get_factors__nan_inf(): @@ -466,18 +484,20 @@ factors = transformer.get_factors( longitude=[0, np.nan, np.inf, 0], latitude=[np.nan, 2, 2, np.inf] ) - assert_almost_equal(factors.meridional_scale, [1, np.inf, np.inf, 1]) - assert_almost_equal(factors.parallel_scale, [1, np.inf, np.inf, 1]) - assert_almost_equal(factors.areal_scale, [1, np.inf, np.inf, 1]) - assert_almost_equal(factors.angular_distortion, [0, np.inf, np.inf, 0]) - assert_almost_equal(factors.meridian_parallel_angle, [90, np.inf, np.inf, 90]) - assert_almost_equal(factors.meridian_convergence, [0.0, np.inf, np.inf, 0.0]) - assert_almost_equal(factors.tissot_semimajor, [1, np.inf, np.inf, 1]) - assert_almost_equal(factors.tissot_semiminor, [1, np.inf, np.inf, 1]) - assert_almost_equal(factors.dx_dlam, [1, np.inf, np.inf, 1]) - assert_almost_equal(factors.dx_dphi, [0.0, np.inf, np.inf, 0.0]) - assert_almost_equal(factors.dy_dlam, [0.0, np.inf, np.inf, 0.0]) - assert_almost_equal(factors.dy_dphi, [1, np.inf, np.inf, 1]) + assert_almost_equal(factors.meridional_scale, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.parallel_scale, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.areal_scale, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.angular_distortion, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal( + factors.meridian_parallel_angle, [np.inf, np.inf, np.inf, np.inf] + ) + assert_almost_equal(factors.meridian_convergence, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.tissot_semimajor, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.tissot_semiminor, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.dx_dlam, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.dx_dphi, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.dy_dlam, [np.inf, np.inf, np.inf, np.inf]) + assert_almost_equal(factors.dy_dphi, [np.inf, np.inf, np.inf, np.inf]) def test_get_factors__errcheck(): @@ -486,10 +506,19 @@ transformer.get_factors(longitude=40, latitude=70, errcheck=True, radians=True) -def test_numpy_bool_kwarg(): - # Issue 546 +def test_numpy_bool_kwarg_false(): + # Issue 564 south = np.array(50) < 0 proj = Proj( proj="utm", zone=32, ellipsis="WGS84", datum="WGS84", units="m", south=south ) assert "south" not in proj.srs + + +def test_numpy_bool_kwarg_true(): + # Issue 564 + south = np.array(50) > 0 + proj = Proj( + proj="utm", zone=32, ellipsis="WGS84", datum="WGS84", units="m", south=south + ) + assert "+south " in proj.srs diff --git a/test/test_transform.py b/test/test_transform.py index bb223cc..57879f7 100644 --- a/test/test_transform.py +++ b/test/test_transform.py @@ -1,7 +1,8 @@ import numpy +import pytest from numpy.testing import assert_allclose -from pyproj import Proj, proj_version_str, transform +from pyproj import Proj, __proj_version__, transform def test_transform(): @@ -12,7 +13,7 @@ dx = 12190.58 dy = dx awips221 = Proj(proj="lcc", R=6371200, lat_1=50, lat_2=50, lon_0=-107) - print("proj4 library version = ", proj_version_str) + print("proj4 library version = ", __proj_version__) llcrnrx, llcrnry = awips221(-145.5, 1) awips221 = Proj( proj="lcc", @@ -35,11 +36,13 @@ print("max/min x and y for awips218 grid") print(numpy.minimum.reduce(numpy.ravel(x1)), numpy.maximum.reduce(numpy.ravel(x1))) print(numpy.minimum.reduce(numpy.ravel(y1)), numpy.maximum.reduce(numpy.ravel(y1))) - x2, y2 = transform(awips218, awips221, x1, y1) + with pytest.warns(DeprecationWarning): + x2, y2 = transform(awips218, awips221, x1, y1) print("max/min x and y for awips218 grid in awips221 coordinates") print(numpy.minimum.reduce(numpy.ravel(x2)), numpy.maximum.reduce(numpy.ravel(x2))) print(numpy.minimum.reduce(numpy.ravel(y2)), numpy.maximum.reduce(numpy.ravel(y2))) - x3, y3 = transform(awips221, awips218, x2, y2) + with pytest.warns(DeprecationWarning): + x3, y3 = transform(awips221, awips218, x2, y2) print("error for reverse transformation back to awips218 coords") print("(should be close to zero)") assert_allclose(numpy.minimum.reduce(numpy.ravel(x3 - x1)), 0, atol=1e-4) @@ -49,5 +52,6 @@ def test_skip_equivalent(): - xeq, yeq = transform(4326, 4326, 30, 60, skip_equivalent=True) + with pytest.warns(DeprecationWarning): + xeq, yeq = transform(4326, 4326, 30, 60, skip_equivalent=True) assert (xeq, yeq) == (30, 60) diff --git a/test/test_transformer.py b/test/test_transformer.py index 03ecf2c..85314a9 100644 --- a/test/test_transformer.py +++ b/test/test_transformer.py @@ -5,10 +5,13 @@ from numpy.testing import assert_almost_equal import pyproj -from pyproj import Proj, Transformer, itransform, transform +from pyproj import Proj, Transformer, __proj_version__, itransform, transform from pyproj.enums import TransformDirection from pyproj.exceptions import ProjError from pyproj.transformer import AreaOfInterest, TransformerGroup +from test.conftest import grids_available + +_PROJ_gte_701 = LooseVersion(__proj_version__) >= LooseVersion("7.0.1") def test_tranform_wgs84_to_custom(): @@ -18,7 +21,8 @@ ) wgs84 = pyproj.Proj("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs") lat, lon = 51.04715, 3.23406 - xx, yy = pyproj.transform(wgs84, custom_proj, lon, lat) + with pytest.warns(DeprecationWarning): + xx, yy = pyproj.transform(wgs84, custom_proj, lon, lat) assert "{:.3f} {:.3f}".format(xx, yy) == "212.623 4604.975" @@ -27,7 +31,8 @@ lat_lon_proj = pyproj.Proj(init="epsg:4326", preserve_units=False) alaska_aea_proj = pyproj.Proj(init="epsg:2964", preserve_units=False) test = (-179.72638, 49.752533) - xx, yy = pyproj.transform(lat_lon_proj, alaska_aea_proj, *test) + with pytest.warns(DeprecationWarning): + xx, yy = pyproj.transform(lat_lon_proj, alaska_aea_proj, *test) assert "{:.3f} {:.3f}".format(xx, yy) == "-1824924.495 330822.800" @@ -36,12 +41,13 @@ with pytest.warns(FutureWarning): p1 = pyproj.Proj(init="epsg:4326") p2 = pyproj.Proj(init="epsg:3857") - xx, yy = pyproj.transform( - p1, p2, (-180, -180, 180, 180, -180), (-90, 90, 90, -90, -90) - ) + with pytest.warns(DeprecationWarning): + xx, yy = pyproj.transform( + p1, p2, (-180, -180, 180, 180, -180), (-90, 90, 90, -90, -90) + ) assert np.all(np.isinf(xx)) assert np.all(np.isinf(yy)) - with pytest.raises(ProjError): + with pytest.warns(DeprecationWarning), pytest.raises(ProjError): pyproj.transform( p1, p2, (-180, -180, 180, 180, -180), (-90, 90, 90, -90, -90), errcheck=True ) @@ -56,8 +62,8 @@ E = 567623.931 N = 256422.787 h = 1341.467 - - Long1, Lat1, H1 = pyproj.transform(Midelt, WGS84, E, N, h, radians=False) + with pytest.warns(DeprecationWarning): + Long1, Lat1, H1 = pyproj.transform(Midelt, WGS84, E, N, h, radians=False) assert_almost_equal((Long1, Lat1, H1), (-4.6753456, 32.902199, 1341.467), decimal=5) @@ -148,10 +154,13 @@ def test_4d_transform_orginal_crs_obs1(): - assert_almost_equal( - transform(7789, 8401, x=3496737.2679, y=743254.4507, z=5264462.9620, tt=2019.0), - (3496737.757717311, 743253.9940103051, 5264462.701132784, 2019.0), - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + transform( + 7789, 8401, x=3496737.2679, y=743254.4507, z=5264462.9620, tt=2019.0 + ), + (3496737.757717311, 743253.9940103051, 5264462.701132784, 2019.0), + ) def test_4d_transform_crs_obs2(): @@ -173,10 +182,11 @@ def test_2d_with_time_transform_original_crs_obs2(): - assert_almost_equal( - transform(4896, 7930, x=3496737.2679, y=743254.4507, tt=2019.0), - (3496737.4105305015, 743254.1014318303, 2019.0), - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + transform(4896, 7930, x=3496737.2679, y=743254.4507, tt=2019.0), + (3496737.4105305015, 743254.1014318303, 2019.0), + ) def test_4d_itransform(): @@ -204,26 +214,34 @@ def test_4d_itransform_orginal_crs_obs1(): - assert_almost_equal( - list( - itransform(7789, 8401, [(3496737.2679, 743254.4507, 5264462.9620, 2019.0)]) - ), - [(3496737.757717311, 743253.9940103051, 5264462.701132784, 2019.0)], - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + list( + itransform( + 7789, 8401, [(3496737.2679, 743254.4507, 5264462.9620, 2019.0)] + ) + ), + [(3496737.757717311, 743253.9940103051, 5264462.701132784, 2019.0)], + ) def test_2d_with_time_itransform_original_crs_obs2(): - assert_almost_equal( - list( - itransform(4896, 7930, [(3496737.2679, 743254.4507, 2019.0)], time_3rd=True) - ), - [(3496737.4105305015, 743254.1014318303, 2019.0)], - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + list( + itransform( + 4896, 7930, [(3496737.2679, 743254.4507, 2019.0)], time_3rd=True + ) + ), + [(3496737.4105305015, 743254.1014318303, 2019.0)], + ) def test_itransform_time_3rd_invalid(): - with pytest.raises(ValueError, match="'time_3rd' is only valid for 3 coordinates."): + with pytest.warns(DeprecationWarning), pytest.raises( + ValueError, match="'time_3rd' is only valid for 3 coordinates." + ): list( itransform( 7789, @@ -232,7 +250,9 @@ time_3rd=True, ) ) - with pytest.raises(ValueError, match="'time_3rd' is only valid for 3 coordinates."): + with pytest.warns(DeprecationWarning), pytest.raises( + ValueError, match="'time_3rd' is only valid for 3 coordinates." + ): list(itransform(7789, 8401, [(3496737.2679, 743254.4507)], time_3rd=True)) @@ -240,14 +260,16 @@ with pytest.warns(FutureWarning): pj = Proj(init="epsg:4555") pjx, pjy = pj(116.366, 39.867) - transform(pj, Proj(4326), pjx, pjy, radians=True, errcheck=True) + with pytest.warns(DeprecationWarning): + transform(pj, Proj(4326), pjx, pjy, radians=True, errcheck=True) def test_itransform_no_error(): with pytest.warns(FutureWarning): pj = Proj(init="epsg:4555") pjx, pjy = pj(116.366, 39.867) - list(itransform(pj, Proj(4326), [(pjx, pjy)], radians=True, errcheck=True)) + with pytest.warns(DeprecationWarning): + list(itransform(pj, Proj(4326), [(pjx, pjy)], radians=True, errcheck=True)) def test_transform_no_exception(): @@ -261,7 +283,7 @@ def test_transform__out_of_bounds(): with pytest.warns(FutureWarning): transformer = Transformer.from_proj("+init=epsg:4326", "+init=epsg:27700") - if LooseVersion(pyproj.proj_version_str) >= LooseVersion("7.0.0"): + if LooseVersion(pyproj.__proj_version__) >= LooseVersion("7.0.0"): with pytest.raises(pyproj.exceptions.ProjError): transformer.transform(100000, 100000, errcheck=True) else: @@ -272,50 +294,55 @@ with pytest.warns(FutureWarning): WGS84 = pyproj.Proj("+init=EPSG:4326") ECEF = pyproj.Proj(proj="geocent", ellps="WGS84", datum="WGS84") - assert_almost_equal( - pyproj.transform( - ECEF, WGS84, -2704026.010, -4253051.810, 3895878.820, radians=True - ), - (-2.137113493845668, 0.6613203738996222, -20.531156923621893), - ) - - assert_almost_equal( - pyproj.transform( - WGS84, - ECEF, - -2.137113493845668, - 0.6613203738996222, - -20.531156923621893, - radians=True, - ), - (-2704026.010, -4253051.810, 3895878.820), - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + pyproj.transform( + ECEF, WGS84, -2704026.010, -4253051.810, 3895878.820, radians=True + ), + (-2.137113493845668, 0.6613203738996222, -20.531156923621893), + ) + + assert_almost_equal( + pyproj.transform( + WGS84, + ECEF, + -2.137113493845668, + 0.6613203738996222, + -20.531156923621893, + radians=True, + ), + (-2704026.010, -4253051.810, 3895878.820), + ) def test_itransform_radians(): with pytest.warns(FutureWarning): WGS84 = pyproj.Proj("+init=EPSG:4326") ECEF = pyproj.Proj(proj="geocent", ellps="WGS84", datum="WGS84") - assert_almost_equal( - list( - pyproj.itransform( - ECEF, WGS84, [(-2704026.010, -4253051.810, 3895878.820)], radians=True - ) - ), - [(-2.137113493845668, 0.6613203738996222, -20.531156923621893)], - ) - - assert_almost_equal( - list( - pyproj.itransform( - WGS84, - ECEF, - [(-2.137113493845668, 0.6613203738996222, -20.531156923621893)], - radians=True, - ) - ), - [(-2704026.010, -4253051.810, 3895878.820)], - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + list( + pyproj.itransform( + ECEF, + WGS84, + [(-2704026.010, -4253051.810, 3895878.820)], + radians=True, + ) + ), + [(-2.137113493845668, 0.6613203738996222, -20.531156923621893)], + ) + + assert_almost_equal( + list( + pyproj.itransform( + WGS84, + ECEF, + [(-2.137113493845668, 0.6613203738996222, -20.531156923621893)], + radians=True, + ) + ), + [(-2704026.010, -4253051.810, 3895878.820)], + ) def test_4d_transform__inverse(): @@ -354,17 +381,19 @@ def test_always_xy__transform(): - assert_almost_equal( - transform(2193, 4326, 1625350, 5504853, always_xy=True), - (173.29964730317386, -40.60674802693758), - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + transform(2193, 4326, 1625350, 5504853, always_xy=True), + (173.29964730317386, -40.60674802693758), + ) def test_always_xy__itransform(): - assert_almost_equal( - list(itransform(2193, 4326, [(1625350, 5504853)], always_xy=True)), - [(173.29964730317386, -40.60674802693758)], - ) + with pytest.warns(DeprecationWarning): + assert_almost_equal( + list(itransform(2193, 4326, [(1625350, 5504853)], always_xy=True)), + [(173.29964730317386, -40.60674802693758)], + ) def test_transform_direction__string(): @@ -423,28 +452,44 @@ assert str(Transformer.from_crs(4326, 3857)).startswith("proj=pipeline") -def test_repr(): - assert repr(Transformer.from_crs(7789, 8401)) == ( - "\n" - "Description: ITRF2014 to ETRF2014 (1)\n" - "Area of Use:\n" - "- name: Europe - ETRS89\n" - "- bounds: (-16.1, 32.88, 40.18, 84.17)" - ) - - assert repr(Transformer.from_crs(4326, 3857)) == ( - "\n" - "Description: Popular Visualisation Pseudo-Mercator\n" - "Area of Use:\n" - "- name: World\n" - "- bounds: (-180.0, -90.0, 180.0, 90.0)" - ) - - assert repr(Transformer.from_crs(4326, 26917)) == ( - "\n" - "Description: unavailable until proj_trans is called\n" - "Area of Use:\n- undefined" - ) +@pytest.mark.parametrize( + "from_crs, to_crs, expected_repr", + [ + ( + 7789, + 8401, + ( + "\n" + "Description: ITRF2014 to ETRF2014 (1)\n" + "Area of Use:\n" + "- name: Europe - {}\n" + "- bounds: (-16.1, 32.88, 40.18, 84.17)" + ).format("ETRF by country" if _PROJ_gte_701 else "ETRS89"), + ), + ( + 4326, + 3857, + ( + "\n" + "Description: Popular Visualisation Pseudo-Mercator\n" + "Area of Use:\n" + "- name: World\n" + "- bounds: (-180.0, -90.0, 180.0, 90.0)" + ), + ), + ( + 4326, + 26917, + ( + "\n" + "Description: unavailable until proj_trans is called\n" + "Area of Use:\n- undefined" + ), + ), + ], +) +def test_repr(from_crs, to_crs, expected_repr): + assert repr(Transformer.from_crs(from_crs, to_crs)) == expected_repr def test_to_json_dict(): @@ -475,7 +520,7 @@ def test_transformer__operations(): - transformer = Transformer.from_crs(28356, 7856) + transformer = TransformerGroup(28356, 7856).transformers[0] assert [op.name for op in transformer.operations] == [ "Inverse of Map Grid of Australia zone 56", "GDA94 to GDA2020 (1)", @@ -488,7 +533,7 @@ def test_transformer__operations__scope_remarks(): - transformer = Transformer.from_crs(28356, 7856) + transformer = TransformerGroup(28356, 7856).transformers[0] assert transformer.scope is None assert [op.scope for op in transformer.operations] == [ None, @@ -512,83 +557,143 @@ assert trans_group.best_available -def test_transformer_group__unavailable(aoi_data_directory): +def test_transformer_group__unavailable(): trans_group = TransformerGroup(4326, 2964) - assert len(trans_group.unavailable_operations) == 1 - assert ( - trans_group.unavailable_operations[0].name - == "Inverse of NAD27 to WGS 84 (33) + Alaska Albers" - ) - assert len(trans_group.transformers) == 8 - assert trans_group.best_available - - -def test_transform_group__missing_best(aoi_data_directory): + if not grids_available("ntv2_0.gsb", "ca_nrc_ntv2_0.tif"): + assert len(trans_group.unavailable_operations) == 1 + assert ( + trans_group.unavailable_operations[0].name + == "Inverse of NAD27 to WGS 84 (33) + Alaska Albers" + ) + if _PROJ_gte_701: + assert len(trans_group.transformers) == 9 + else: + assert len(trans_group.transformers) == 8 + assert trans_group.best_available + else: + assert len(trans_group.unavailable_operations) == 0 + if _PROJ_gte_701: + assert len(trans_group.transformers) == 10 + else: + assert len(trans_group.transformers) == 9 + assert trans_group.best_available + + +def test_transform_group__missing_best(): with pytest.warns(FutureWarning): lat_lon_proj = pyproj.Proj(init="epsg:4326", preserve_units=False) alaska_aea_proj = pyproj.Proj(init="epsg:2964", preserve_units=False) - with pytest.warns( - UserWarning, match="Best transformation is not available due to missing Grid" - ): + if not grids_available("ntv2_0.gsb", "ca_nrc_ntv2_0.tif"): + with pytest.warns( + UserWarning, + match="Best transformation is not available due to missing Grid", + ): + trans_group = pyproj.transformer.TransformerGroup( + lat_lon_proj.crs, alaska_aea_proj.crs + ) + + assert not trans_group.best_available + assert len(trans_group.transformers) == 37 + assert len(trans_group.unavailable_operations) == 41 + else: + # assuming all grids avaiable or PROJ_NETWORK=ON trans_group = pyproj.transformer.TransformerGroup( lat_lon_proj.crs, alaska_aea_proj.crs ) - - assert not trans_group.best_available - assert len(trans_group.transformers) == 37 - assert len(trans_group.unavailable_operations) == 41 - - -def test_transform_group__area_of_interest(aoi_data_directory): - with pytest.warns( - UserWarning, match="Best transformation is not available due to missing Grid" - ): - trans_group = TransformerGroup( - 4326, 2964, area_of_interest=AreaOfInterest(-136.46, 49.0, -60.72, 83.17) - ) - assert ( - trans_group.transformers[0].description - == "Inverse of NAD27 to WGS 84 (13) + Alaska Albers" - ) + assert trans_group.best_available + assert len(trans_group.transformers) == 78 + assert len(trans_group.unavailable_operations) == 0 + + +def test_transform_group__area_of_interest(): + if not grids_available("ntv2_0.gsb", "ca_nrc_ntv2_0.tif"): + with pytest.warns( + UserWarning, + match="Best transformation is not available due to missing Grid", + ): + trans_group = pyproj.transformer.TransformerGroup( + 4326, + 2964, + area_of_interest=pyproj.transformer.AreaOfInterest( + -136.46, 49.0, -60.72, 83.17 + ), + ) + assert ( + trans_group.transformers[0].description + == "Inverse of NAD27 to WGS 84 (13) + Alaska Albers" + ) + else: + trans_group = pyproj.transformer.TransformerGroup( + 4326, + 2964, + area_of_interest=pyproj.transformer.AreaOfInterest( + -136.46, 49.0, -60.72, 83.17 + ), + ) + assert trans_group.best_available + assert ( + trans_group.transformers[0].description + == "Inverse of NAD27 to WGS 84 (33) + Alaska Albers" + ) def test_transformer_group__get_transform_crs(): tg = TransformerGroup("epsg:4258", "epsg:7415") - if LooseVersion(pyproj.proj_version_str) >= LooseVersion("6.3.1"): - assert len(tg.transformers) == 1 + if LooseVersion(pyproj.__proj_version__) >= LooseVersion("6.3.1"): + if not grids_available("nl_nsgi_rdtrans2018.tif"): + assert len(tg.transformers) == 1 + else: + assert len(tg.transformers) == 2 else: assert len(tg.transformers) == 4 -def test_transformer__area_of_interest(aoi_data_directory): +def test_transformer__area_of_interest(): transformer = Transformer.from_crs( 4326, 2964, area_of_interest=AreaOfInterest(-136.46, 49.0, -60.72, 83.17) ) - assert transformer.description == "Inverse of NAD27 to WGS 84 (13) + Alaska Albers" - - -def test_transformer_proj__area_of_interest(aoi_data_directory): + if not grids_available("ntv2_0.gsb", "ca_nrc_ntv2_0.tif"): + assert ( + transformer.description == "Inverse of NAD27 to WGS 84 (13) + Alaska Albers" + ) + else: + assert ( + transformer.description == "Inverse of NAD27 to WGS 84 (33) + Alaska Albers" + ) + + +def test_transformer_proj__area_of_interest(): transformer = Transformer.from_proj( 4326, 2964, area_of_interest=AreaOfInterest(-136.46, 49.0, -60.72, 83.17) ) - assert transformer.description == "Inverse of NAD27 to WGS 84 (13) + Alaska Albers" - - -def test_transformer__area_of_interest__invalid(aoi_data_directory): + if not grids_available("ntv2_0.gsb", "ca_nrc_ntv2_0.tif"): + assert ( + transformer.description == "Inverse of NAD27 to WGS 84 (13) + Alaska Albers" + ) + else: + assert ( + transformer.description == "Inverse of NAD27 to WGS 84 (33) + Alaska Albers" + ) + + +def test_transformer__area_of_interest__invalid(): with pytest.raises(ProjError): Transformer.from_crs( 4326, 2964, area_of_interest=(-136.46, 49.0, -60.72, 83.17) ) -def test_transformer_group__area_of_interest__invalid(aoi_data_directory): +def test_transformer_group__area_of_interest__invalid(): with pytest.raises(ProjError): TransformerGroup(4326, 2964, area_of_interest=(-136.46, 49.0, -60.72, 83.17)) def test_transformer_equals(): - assert Transformer.from_crs(28356, 7856) == Transformer.from_crs(28356, 7856) + assert ( + TransformerGroup(28356, 7856).transformers[0] + == TransformerGroup(28356, 7856).transformers[0] + ) @pytest.mark.parametrize(