Exemple #1
0
    def _proj4_str_to_dict(self, proj4_string):
        """
        Converts PROJ4 compatible string to dictionary.

        Parameters
        ----------
        proj4_string : str
            PROJ4 parameters as a string (e.g., '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs').

        Returns
        -------
        dict
            Dictionary containing PROJ4 parameters.

        Notes
        -----
        Key only parameters will be assigned a value of `True`.
        EPSG codes should be provided as "EPSG:XXXX" where "XXXX"
        is the EPSG code number. It can also be provided as
        "+init=EPSG:XXXX" as long as the underlying PROJ library
        supports it (deprecated in PROJ 6.0+).

        """

        # convert EPSG codes to equivalent PROJ4 string definition
        if proj4_string.lower().startswith('epsg:'):
            crs = CRS(proj4_string)
            return crs.to_dict()
        else:
            proj4_pairs = (x.split('=', 1)
                           for x in proj4_string.replace('+', '').split(" "))
            return self.__convert_proj4_pairs_to_dict(proj4_pairs)
Exemple #2
0
def _convert_units(var,
                   name: str,
                   units: str,
                   p: Proj,
                   crs: CRS,
                   inverse: bool = False,
                   center=None):
    """Converts units from lon/lat to projection coordinates (meters).

    If `inverse` it True then the inverse calculation is done.

    """
    if var is None:
        return None
    if isinstance(var, DataArray):
        units = var.units
        var = tuple(var.data.tolist())
    if crs.is_geographic and not ('deg' == units or 'degrees' == units):
        raise ValueError(
            'latlon/latlong projection cannot take {0} as units: {1}'.format(
                units, name))
    # Check if units are an angle.
    is_angle = ('deg' == units or 'degrees' == units)
    if ('deg' in units) and not is_angle:
        logging.warning('units provided to {0} are incorrect: {1}'.format(
            name, units))
    # Convert from var projection units to projection units given by projection from user.
    if not is_angle:
        if units == 'meters' or units == 'metres':
            units = 'm'
        if _get_proj_units(crs) != units:
            tmp_proj_dict = crs.to_dict()
            tmp_proj_dict['units'] = units
            transformer = Transformer.from_crs(tmp_proj_dict, p.crs)
            var = transformer.transform(*var)
    if name == 'center':
        var = _round_poles(var, units, p)
    # Return either degrees or meters depending on if the inverse is true or not.
    # Don't convert if inverse is True: Want degrees.
    # Converts list-like from degrees to meters.
    if is_angle and not inverse:
        if name in ('radius', 'resolution'):
            var = _distance_from_center_forward(var, center, p)
        elif not crs.is_geographic:
            # only convert to meters
            # this allows geographic projections to use coordinates outside
            # normal lon/lat ranges (ex. -90/90)
            var = p(*var, errcheck=True)
    # Don't convert if inverse is False: Want meters.
    elif not is_angle and inverse:
        # Converts list-like from meters to degrees.
        var = p(*var, inverse=True, errcheck=True)
    if name in ['radius', 'resolution']:
        var = (abs(var[0]), abs(var[1]))
    return var
Exemple #3
0
def proj4_radius_parameters(proj4_dict):
    """Calculate 'a' and 'b' radius parameters.

    Arguments:
        proj4_dict (str or dict): PROJ.4 parameters

    Returns:
        a (float), b (float): equatorial and polar radius
    """
    if CRS is not None:
        import math
        crs = CRS(proj4_dict)
        a = crs.ellipsoid.semi_major_metre
        b = crs.ellipsoid.semi_minor_metre
        if not math.isnan(b):
            return a, b
        # older versions of pyproj didn't always have a valid minor radius
        proj4_dict = crs.to_dict()

    if isinstance(proj4_dict, str):
        new_info = proj4_str_to_dict(proj4_dict)
    else:
        new_info = proj4_dict.copy()

    # load information from PROJ.4 about the ellipsis if possible

    from pyproj import Geod

    if 'ellps' in new_info:
        geod = Geod(**new_info)
        new_info['a'] = geod.a
        new_info['b'] = geod.b
    elif 'a' not in new_info or 'b' not in new_info:

        if 'rf' in new_info and 'f' not in new_info:
            new_info['f'] = 1. / float(new_info['rf'])

        if 'a' in new_info and 'f' in new_info:
            new_info['b'] = float(new_info['a']) * (1 - float(new_info['f']))
        elif 'b' in new_info and 'f' in new_info:
            new_info['a'] = float(new_info['b']) / (1 - float(new_info['f']))
        elif 'R' in new_info:
            new_info['a'] = new_info['R']
            new_info['b'] = new_info['R']
        else:
            geod = Geod(**{'ellps': 'WGS84'})
            new_info['a'] = geod.a
            new_info['b'] = geod.b

    return float(new_info['a']), float(new_info['b'])
Exemple #4
0
 def _proj4_str_to_dict(self, proj4_str):
     """Convert PROJ.4 compatible string definition to dict
     EPSG codes should be provided as "EPSG:XXXX" where "XXXX"
     is the EPSG number code. It can also be provided as
     ``"+init=EPSG:XXXX"`` as long as the underlying PROJ library
     supports it (deprecated in PROJ 6.0+).
     Note: Key only parameters will be assigned a value of `True`.
     """
     # TODO: @shahn I would got for one solution, i.e. PyProj > 2.2
     # TODO: test if this can be simplified
     # # convert EPSG codes to equivalent PROJ4 string definition
     if proj4_str.startswith('EPSG:'):
         crs = CRS(proj4_str)
         return crs.to_dict()
     else:
         proj4_pairs = (x.split('=', 1) for x in proj4_str.replace('+', '').split(" "))
         return self.__convert_proj4_pairs_to_dict(proj4_pairs)
Exemple #5
0
def proj4_str_to_dict(proj4_str):
    """Convert PROJ.4 compatible string definition to dict

    EPSG codes should be provided as "EPSG:XXXX" where "XXXX"
    is the EPSG number code. It can also be provided as
    ``"+init=EPSG:XXXX"`` as long as the underlying PROJ library
    supports it (deprecated in PROJ 6.0+).

    Note: Key only parameters will be assigned a value of `True`.
    """
    # convert EPSG codes to equivalent PROJ4 string definition
    if proj4_str.startswith('EPSG:') and CRS is not None:
        crs = CRS(proj4_str)
        if hasattr(crs, 'to_dict'):
            # pyproj 2.2+
            return crs.to_dict()
        proj4_str = crs.to_proj4()
    elif proj4_str.startswith('EPSG:'):
        # legacy +init= PROJ4 string and no pyproj 2.0+ to help convert
        proj4_str = "+init={}".format(proj4_str)

    pairs = (x.split('=', 1) for x in proj4_str.replace('+', '').split(" "))
    return convert_proj_floats(pairs)