Пример #1
0
def test_from_cf_transverse_mercator(towgs84_test):
    crs = CRS.from_cf({
        "grid_mapping_name": "transverse_mercator",
        "latitude_of_projection_origin": 0,
        "longitude_of_central_meridian": 15,
        "false_easting": 2520000,
        "false_northing": 0,
        "reference_ellipsoid_name": "intl",
        "towgs84": towgs84_test,
        "unit": "m",
    })
    expected_cf = {
        "semi_major_axis": 6378388.0,
        "semi_minor_axis": crs.ellipsoid.semi_minor_metre,
        "inverse_flattening": 297.0,
        "reference_ellipsoid_name": "International 1909 (Hayford)",
        "longitude_of_prime_meridian": 0.0,
        "prime_meridian_name": "Greenwich",
        "grid_mapping_name": "transverse_mercator",
        "latitude_of_projection_origin": 0.0,
        "longitude_of_central_meridian": 15.0,
        "false_easting": 2520000.0,
        "false_northing": 0.0,
        "scale_factor_at_central_meridian": 1.0,
    }
    cf_dict = crs.to_cf()
    assert cf_dict.pop("crs_wkt").startswith("BOUNDCRS[")
    assert_almost_equal(cf_dict.pop("towgs84"),
                        _try_list_if_string(towgs84_test))
    assert cf_dict == expected_cf
    # test roundtrip
    expected_cf["towgs84"] = _try_list_if_string(towgs84_test)
    _test_roundtrip(expected_cf, "BOUNDCRS[")
Пример #2
0
 def parse(val):
     if val.lower() == "true":
         return True
     elif val.lower() == "false":
         return False
     try:
         return int(val)
     except ValueError:
         pass
     try:
         return float(val)
     except ValueError:
         pass
     return _try_list_if_string(val)
Пример #3
0
    def from_cf(in_cf: dict, errcheck=False) -> "CRS":
        """
        .. versionadded:: 2.2.0

        This converts a Climate and Forecast (CF) Grid Mapping Version 1.8
        dict to a :obj:`pyproj.crs.CRS` object.

        .. warning:: Parameters may be lost if a mapping
            from the CF parameter is not found. For best results
            store the WKT of the projection in the crs_wkt attribute.

        Parameters
        ----------
        in_cf: dict
            CF version of the projection.
        errcheck: bool, optional
            This parameter is for backwards compatibility with the old version.
            It currently does nothing when True or False.

        Returns
        -------
        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
            return CRS(in_cf["spatial_ref"])

        grid_mapping_name = in_cf.get("grid_mapping_name")
        if grid_mapping_name is None:
            raise CRSError(
                "CF projection parameters missing 'grid_mapping_name'")

        # build datum if possible
        datum = _horizontal_datum_from_params(in_cf)

        # build geographic CRS
        try:
            geographic_conversion_method = _GEOGRAPHIC_GRID_MAPPING_NAME_MAP[
                grid_mapping_name]  # type: Optional[Callable]
        except KeyError:
            geographic_conversion_method = None

        geographic_crs_name = in_cf.get("geographic_crs_name")
        if datum:
            geographic_crs = GeographicCRS(
                name=geographic_crs_name or "undefined",
                datum=datum,
            )  # type: CRS
        elif geographic_crs_name and geographic_crs_name not in unknown_names:
            geographic_crs = CRS(geographic_crs_name)
        else:
            geographic_crs = GeographicCRS()
        if grid_mapping_name == "latitude_longitude":
            return geographic_crs
        if geographic_conversion_method is not None:
            return DerivedGeographicCRS(
                base_crs=geographic_crs,
                conversion=geographic_conversion_method(in_cf),
            )

        # build projected CRS
        try:
            conversion_method = _GRID_MAPPING_NAME_MAP[grid_mapping_name]
        except KeyError:
            raise CRSError(
                "Unsupported grid mapping name: {}".format(grid_mapping_name))
        projected_crs = ProjectedCRS(
            name=in_cf.get("projected_crs_name", "undefined"),
            conversion=conversion_method(in_cf),
            geodetic_crs=geographic_crs,
        )

        # build bound CRS if exists
        bound_crs = None
        if "towgs84" in in_cf:
            bound_crs = BoundCRS(
                source_crs=projected_crs,
                target_crs="WGS 84",
                transformation=ToWGS84Transformation(
                    projected_crs.geodetic_crs,
                    *_try_list_if_string(in_cf["towgs84"])),
            )
        if "geopotential_datum_name" not in in_cf:
            return bound_crs or projected_crs

        # build Vertical CRS
        vertical_crs = VerticalCRS(
            name="undefined",
            datum=in_cf["geopotential_datum_name"],
            geoid_model=in_cf.get("geoid_name"),
        )

        # build compound CRS
        return CompoundCRS(
            name="undefined",
            components=[bound_crs or projected_crs, vertical_crs])
Пример #4
0
    def from_cf(
        in_cf: dict,
        ellipsoidal_cs: Any = None,
        cartesian_cs: Any = None,
        vertical_cs: Any = None,
        errcheck=False,
    ) -> "CRS":
        """
        .. versionadded:: 2.2.0

        .. versionadded:: 3.0.0 ellipsoidal_cs, cartesian_cs, vertical_cs

        This converts a Climate and Forecast (CF) Grid Mapping Version 1.8
        dict to a :obj:`pyproj.crs.CRS` object.

        :ref:`build_crs_cf`

        Parameters
        ----------
        in_cf: dict
            CF version of the projection.
        ellipsoidal_cs: Any, optional
            Input to create an Ellipsoidal Coordinate System.
            Anything accepted by :meth:`pyproj.crs.CoordinateSystem.from_user_input`
            or an Ellipsoidal Coordinate System created from :ref:`coordinate_system`.
        cartesian_cs: Any, optional
            Input to create a Cartesian Coordinate System.
            Anything accepted by :meth:`pyproj.crs.CoordinateSystem.from_user_input`
            or :class:`pyproj.crs.coordinate_system.Cartesian2DCS`.
        vertical_cs: Any, optional
            Input to create a Vertical Coordinate System accepted by
            :meth:`pyproj.crs.CoordinateSystem.from_user_input`
            or :class:`pyproj.crs.coordinate_system.VerticalCS`
        errcheck: bool, optional
            This parameter is for backwards compatibility with the old version.
            It currently does nothing when True or False.

        Returns
        -------
        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
            return CRS(in_cf["spatial_ref"])

        grid_mapping_name = in_cf.get("grid_mapping_name")
        if grid_mapping_name is None:
            raise CRSError(
                "CF projection parameters missing 'grid_mapping_name'")

        # build datum if possible
        datum = _horizontal_datum_from_params(in_cf)

        # build geographic CRS
        try:
            geographic_conversion_method = _GEOGRAPHIC_GRID_MAPPING_NAME_MAP[
                grid_mapping_name]  # type: Optional[Callable]
        except KeyError:
            geographic_conversion_method = None

        geographic_crs_name = in_cf.get("geographic_crs_name")
        if datum:
            geographic_crs = GeographicCRS(
                name=geographic_crs_name or "undefined",
                datum=datum,
                ellipsoidal_cs=ellipsoidal_cs,
            )  # type: CRS
        elif geographic_crs_name and geographic_crs_name not in unknown_names:
            geographic_crs = CRS(geographic_crs_name)
            if ellipsoidal_cs is not None:
                geographic_crs_json = geographic_crs.to_json_dict()
                geographic_crs_json[
                    "coordinate_system"] = CoordinateSystem.from_user_input(
                        ellipsoidal_cs).to_json_dict()
                geographic_crs = CRS(geographic_crs_json)
        else:
            geographic_crs = GeographicCRS(ellipsoidal_cs=ellipsoidal_cs)
        if grid_mapping_name == "latitude_longitude":
            return geographic_crs
        if geographic_conversion_method is not None:
            return DerivedGeographicCRS(
                base_crs=geographic_crs,
                conversion=geographic_conversion_method(in_cf),
                ellipsoidal_cs=ellipsoidal_cs,
            )

        # build projected CRS
        try:
            conversion_method = _GRID_MAPPING_NAME_MAP[grid_mapping_name]
        except KeyError:
            raise CRSError(
                f"Unsupported grid mapping name: {grid_mapping_name}")
        projected_crs = ProjectedCRS(
            name=in_cf.get("projected_crs_name", "undefined"),
            conversion=conversion_method(in_cf),
            geodetic_crs=geographic_crs,
            cartesian_cs=cartesian_cs,
        )

        # build bound CRS if exists
        bound_crs = None
        if "towgs84" in in_cf:
            bound_crs = BoundCRS(
                source_crs=projected_crs,
                target_crs="WGS 84",
                transformation=ToWGS84Transformation(
                    projected_crs.geodetic_crs,
                    *_try_list_if_string(in_cf["towgs84"])),
            )
        if "geopotential_datum_name" not in in_cf:
            return bound_crs or projected_crs

        # build Vertical CRS
        vertical_crs = VerticalCRS(
            name="undefined",
            datum=in_cf["geopotential_datum_name"],
            geoid_model=in_cf.get("geoid_name"),
            vertical_cs=vertical_cs,
        )

        # build compound CRS
        return CompoundCRS(
            name="undefined",
            components=[bound_crs or projected_crs, vertical_crs])