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 test_set_vector_file_wrong_fail(self):
        """Test set_vector_file with wrong centroids"""
        shp_file = shapereader.natural_earth(resolution='110m',
                                             category='cultural',
                                             name='populated_places_simple')
        centr = Centroids()
        inten = centr.set_vector_file(shp_file, ['pop_min', 'pop_max'])

        self.assertEqual(CRS.from_user_input(centr.geometry.crs),
                         CRS.from_epsg(u_coord.NE_EPSG))
        self.assertEqual(centr.geometry.size, centr.lat.size)
        self.assertEqual(CRS.from_user_input(centr.geometry.crs),
                         CRS.from_epsg(u_coord.NE_EPSG))
        self.assertAlmostEqual(centr.lon[0], 12.453386544971766)
        self.assertAlmostEqual(centr.lon[-1], 114.18306345846304)
        self.assertAlmostEqual(centr.lat[0], 41.903282179960115)
        self.assertAlmostEqual(centr.lat[-1], 22.30692675357551)

        self.assertEqual(inten.shape, (2, 243))
        # population min
        self.assertEqual(inten[0, 0], 832)
        self.assertEqual(inten[0, -1], 4551579)
        # population max
        self.assertEqual(inten[1, 0], 832)
        self.assertEqual(inten[1, -1], 7206000)

        shp_file = shapereader.natural_earth(resolution='10m',
                                             category='cultural',
                                             name='populated_places_simple')
        with self.assertRaises(ValueError):
            centr.set_vector_file(shp_file, ['pop_min', 'pop_max'])
async def get_wms_image(tile, source, session):
    bounds = list(mercantile.bounds(tile))
    if "available_projections" not in source["properties"]:
        return None
    available_projections = source["properties"]["available_projections"]
    url = source["properties"]["url"]

    proj = None
    if "EPSG:4326" in available_projections:
        proj = "EPSG:4326"
    elif "EPSG:3857" in available_projections:
        proj = "EPSG:3857"
    else:
        for proj in sorted(available_projections):
            try:
                CRS.from_string(proj)
            except:
                continue
            break
    if proj is None:
        return None

    wms_version = wms_version_from_url(url)
    bbox = _get_bbox(proj, bounds, wms_version)
    if bbox is None:
        return None

    formatted_url = url.format(proj=proj, width=256, height=256, bbox=bbox)

    return formatted_url
Exemple #4
0
def _get_bbox(proj, bounds, wms_version):
    """ Build wms bbox parameter for GetMap request"""
    if proj in {"EPSG:4326", "CRS:84"}:
        if proj == "EPSG:4326" and wms_version == "1.3.0":
            bbox = ",".join(
                map(str, [bounds[1], bounds[0], bounds[3], bounds[2]]))
        else:
            bbox = ",".join(map(str, bounds))
    else:
        try:
            crs_from = CRS.from_string("epsg:4326")
            crs_to = CRS.from_string(proj)
            transformer = get_transformer(crs_from, crs_to)
            bounds = list(transformer.transform(bounds[0], bounds[1])) + list(
                transformer.transform(bounds[2], bounds[3]))
        except:
            return None

        # WMS < 1.3.0 assumes x,y coordinate ordering.
        # WMS 1.3.0 expects coordinate ordering defined in CRS.
        #
        if crs_to.axis_info[0].direction == "north" and wms_version == "1.3.0":
            bbox = ",".join(
                map(str, [bounds[1], bounds[0], bounds[3], bounds[2]]))
        else:
            bbox = ",".join(map(str, bounds))
    return bbox
    def test_to_crs_user_input(self):
        pcrs = PCRS.from_epsg(4326)
        rcrs = RCRS.from_epsg(4326)

        # are they the default?
        self.assertTrue(
            pcrs == PCRS.from_user_input(to_crs_user_input(DEF_CRS)))
        self.assertEqual(rcrs,
                         RCRS.from_user_input(to_crs_user_input(DEF_CRS)))

        # can they be understood from the provider?
        for arg in ['epsg:4326', b'epsg:4326', DEF_CRS, 4326]:
            self.assertEqual(pcrs,
                             PCRS.from_user_input(to_crs_user_input(arg)))
            self.assertEqual(rcrs,
                             RCRS.from_user_input(to_crs_user_input(arg)))

        # can they be misunderstood from the provider?
        for arg in [{
                'init': 'epsg:4326',
                'no_defs': True
        }, b'{"init": "epsg:4326", "no_defs": True}']:
            self.assertFalse(
                pcrs == PCRS.from_user_input(to_crs_user_input(arg)))
            self.assertEqual(rcrs,
                             RCRS.from_user_input(to_crs_user_input(arg)))

        # are they noticed?
        for arg in [4326.0, [4326]]:
            with self.assertRaises(ValueError):
                to_crs_user_input(arg)
        with self.assertRaises(SyntaxError):
            to_crs_user_input('{init: epsg:4326, no_defs: True}')
    def __init__(self,
                 *args,
                 local_crs: int = None,
                 x_col: str = None,
                 y_col: str = None,
                 z_col: str = None,
                 time_col: str = None,
                 time_sort: bool = True,
                 **kwargs) -> '_GpsBase':

        # Get data
        data = kwargs.get("data", None)
        if data is None and len(args) > 0:
            data = args[0]
        if isinstance(data,
                      (_GpsBase, pd.core.internals.managers.BlockManager)):
            is_base = True
        else:
            is_base = False

        # Create a GeoDataFrame
        df = gpd.GeoDataFrame(*args, **kwargs)

        # Set CRS
        if df.crs is None:
            try:
                df.crs = data.crs
            except AttributeError:
                df.crs = self._default_input_crs

        if not is_base:
            # Get default values
            x_col = x_col if x_col is not None else self._default_x_col
            y_col = y_col if y_col is not None else self._default_y_col
            z_col = z_col if z_col is not None else self._default_z_col
            time_col = time_col if time_col is not None else self._default_time_col

            # Format data
            self._format_data(
                df,
                x_col,
                y_col,
                z_col,
                time_col,
                time_sort,
            )

        # Project data
        if local_crs is not None:
            self_crs = CRS(df.crs)
            local_crs = CRS(local_crs)
            if local_crs != self_crs:
                df.to_crs(local_crs, inplace=True)

        # Compute normalized data
        if not is_base and self._has_time:
            self._normalize_data(df)

        super(_GpsBase, self).__init__(df, crs=df.crs)
Exemple #7
0
 def _transform_to_coordinates(self, x, y):
     if self.file.crs == CRS("EPSG:4326"):
         return Point(y, x)
     transformer = Transformer.from_proj(self.file.crs, CRS("EPSG:4326"))
     lat, lon = transformer.transform(x, y)
     lon = abs(lon + 90)
     if abs(lon - 90) > abs(lon - 180):
         if abs(lon - 180) > abs(lon - 270):
             lon = abs(270 - lon) + 90
         else:
             lon = lon - 90
     return Point(lat, lon)
Exemple #8
0
 def test_proj(proj):
     if proj == 'CRS:84':
         return True
     if 'AUTO' in proj:
         return False
     if 'EPSG' in proj:
         try:
             CRS.from_string(proj)
             return True
         except:
             return False
     return False
Exemple #9
0
def test_bound_crs_crs__from_methods():
    crs_str = "+proj=latlon +towgs84=0,0,0"
    with pytest.raises(CRSError, match="Invalid type"):
        BoundCRS.from_epsg(4326)
    assert_maker_inheritance_valid(BoundCRS.from_string(crs_str), BoundCRS)
    assert_maker_inheritance_valid(BoundCRS.from_proj4(crs_str), BoundCRS)
    assert_maker_inheritance_valid(
        BoundCRS.from_user_input(BoundCRS.from_string(crs_str)), BoundCRS)
    assert_maker_inheritance_valid(BoundCRS.from_json(CRS(crs_str).to_json()),
                                   BoundCRS)
    assert_maker_inheritance_valid(
        BoundCRS.from_json_dict(CRS(crs_str).to_json_dict()), BoundCRS)
Exemple #10
0
def test_vertical_crs__from_methods():
    assert_maker_inheritance_valid(VerticalCRS.from_epsg(5703), VerticalCRS)
    assert_maker_inheritance_valid(VerticalCRS.from_string("EPSG:5703"),
                                   VerticalCRS)
    with pytest.raises(CRSError, match="Invalid type"):
        VerticalCRS.from_proj4("+proj=latlon")
    assert_maker_inheritance_valid(
        VerticalCRS.from_user_input(VerticalCRS.from_string("EPSG:5703")),
        VerticalCRS)
    assert_maker_inheritance_valid(VerticalCRS.from_json(CRS(5703).to_json()),
                                   VerticalCRS)
    assert_maker_inheritance_valid(
        VerticalCRS.from_json_dict(CRS(5703).to_json_dict()), VerticalCRS)
Exemple #11
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 #12
0
def pyproj_crs_to_osgeo(proj_crs: Union[CRS, int]):
    """
    Convert from the pyproj CRS object to osgeo SpatialReference

    See https://pyproj4.github.io/pyproj/stable/crs_compatibility.html

    Parameters
    ----------
    proj_crs
        pyproj CRS or an integer epsg code

    Returns
    -------
    SpatialReference
        converted SpatialReference
    """

    if isinstance(proj_crs, int):
        proj_crs = CRS.from_epsg(proj_crs)
    osr_crs = SpatialReference()
    if osgeo.version_info.major < 3:
        osr_crs.ImportFromWkt(proj_crs.to_wkt(WktVersion.WKT1_GDAL))
    else:
        osr_crs.ImportFromWkt(proj_crs.to_wkt())
    return osr_crs
Exemple #13
0
def test_projected_crs__from_methods():
    assert_maker_inheritance_valid(ProjectedCRS.from_epsg(6933), ProjectedCRS)
    assert_maker_inheritance_valid(ProjectedCRS.from_string("EPSG:6933"),
                                   ProjectedCRS)
    assert_maker_inheritance_valid(
        ProjectedCRS.from_proj4("+proj=aea +lat_1=1"), ProjectedCRS)
    assert_maker_inheritance_valid(
        ProjectedCRS.from_user_input(ProjectedCRS.from_string("EPSG:6933")),
        ProjectedCRS,
    )
    assert_maker_inheritance_valid(ProjectedCRS.from_json(CRS(6933).to_json()),
                                   ProjectedCRS)
    assert_maker_inheritance_valid(
        ProjectedCRS.from_json_dict(CRS(6933).to_json_dict()), ProjectedCRS)
    with pytest.raises(CRSError, match="Invalid type"):
        ProjectedCRS.from_epsg(4326)
Exemple #14
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 #15
0
def test_geographic_crs__from_methods():
    assert_maker_inheritance_valid(GeographicCRS.from_epsg(4326),
                                   GeographicCRS)
    assert_maker_inheritance_valid(GeographicCRS.from_string("EPSG:4326"),
                                   GeographicCRS)
    assert_maker_inheritance_valid(GeographicCRS.from_proj4("+proj=latlon"),
                                   GeographicCRS)
    assert_maker_inheritance_valid(
        GeographicCRS.from_user_input(GeographicCRS.from_string("EPSG:4326")),
        GeographicCRS,
    )
    assert_maker_inheritance_valid(
        GeographicCRS.from_json(CRS(4326).to_json()), GeographicCRS)
    assert_maker_inheritance_valid(
        GeographicCRS.from_json_dict(CRS(4326).to_json_dict()), GeographicCRS)
    with pytest.raises(CRSError, match="Invalid type"):
        GeographicCRS.from_epsg(6933)
Exemple #16
0
def split_linestring_df(df: Union[pd.DataFrame, gpd.GeoDataFrame],
                        max_length: float,
                        pool: Pool = None,
                        **kwargs) -> gpd.GeoDataFrame:
    """
    Splits the LineString existing in a data frame based on the provided `max_length`. All the other columns are
    retpeated untouched.

    :param df: The input `DataFrame` or `GeoDataFrame`

    :param max_length: The maximum length that each LineString is allowed to have. Has not effect on other geometry t
                       types.

    :param pool: A pool of parallel workers to speed up processing large data frames.

    :param kwargs: Extra keywords controlling the behavior of this function. Currently available keywords are:

                   - 'length_epsg`: the EPSG that the max_length is provided. The default is EPSG:3857 hence, the
                     `max_length` is assumed to be meter.
                   - `geom_field`: The name of the column containing the geometry. Default is 'geometry'.
                   - `part_id_field`: The name of the columns to be added to the output which identifies different parts
                     of the same geometry. Default is `part_id`.

    :return: a new `GeoDataFrame` where LineString or MultiLineStrings do not exceed the `max_length`
    """
    length_epsg = kwargs.get('length_epsg', 3857)
    length_crs = CRS(length_epsg)
    original_crs = None if length_crs.name == df.crs.name else df.crs
    df = df if length_crs.name == df.crs.name else df.to_crs(length_crs)

    geom_field = kwargs.get('geom_field', 'geometry')
    split_geometry = split_linestring(geometry=df[geom_field],
                                      max_length=max_length,
                                      pool=pool)

    part_id_field = kwargs.get('part_id_field', 'part_id')
    output = pd.concat([
        gpd.GeoDataFrame(
            data={
                key: (
                    [row[1][key]] * len(split_geometry[row[0]]) \
                    if key != part_id_field \
                    else list(range(len(split_geometry[row[0]])))
                )
                for key in list(row[1].keys()) + [part_id_field] if key != geom_field
            },
            geometry=split_geometry[row[0]]
        )
        for row in df.iterrows()
    ])

    output.reset_index(drop=True, inplace=True)
    output.crs = length_crs

    if original_crs is not None:
        output = output.to_crs(original_crs)

    return output
Exemple #17
0
    def __init__(self, code):
        crs = _CRS.from_epsg(code)
        if not crs.is_projected:
            raise ValueError('EPSG code does not define a projection')
        if not crs.area_of_use:
            raise ValueError("Area of use not defined.")

        self.epsg_code = code
        super().__init__(crs.to_wkt())
Exemple #18
0
 def test_proj(proj):
     if proj == "CRS:84":
         return True
     if "AUTO" in proj:
         return False
     # 'EPSG:102067' is not valid, should be ESRI:102067: https://epsg.io/102067
     if proj == "EPSG:102067":
         return False
     # 'EPSG:102066' is not valid, should be ESRI:102066: https://epsg.io/102066
     if proj == "EPSG:102066":
         return False
     if "EPSG" in proj:
         try:
             CRS.from_string(proj)
             return True
         except:
             return False
     return False
Exemple #19
0
def from_rasterio(crs):
    """Converts from rasterio CRS to the workflow CRS standard.

    Parameters
    ----------
    crs : rasterio-crs-object
        Input rasterio crs.

    Returns
    -------
    out : crs-type
        Equivalent workflow CRS.

    """
    try:
        # from authority seems to get better results with bounds?
        return CRS.from_authority(*crs.to_authority())
    except Exception:
        return CRS.from_user_input(crs)
Exemple #20
0
def build_valid_vert_crs(crs: pyproj_VerticalCRS, regions: [str],
                         datum_data: object) -> (pyproj_VerticalCRS, str, str):
    """
    Add the regions and pipeline to the remarks section of the wkt for the
    provided pyproj VerticalCRS object.

    Parameters
    ----------
    crs : pyproj.crs.VerticalCRS
        The vertical crs object to add the pipeline and region into.
    regions : [str]
        The regions to add into the crs remarks.
    vdatum_version_string
        version of vdatum, used in the geoid/region lookup

    Returns
    -------
    result (pyproj.crs.VerticalCRS, str)
        First value is the vertical crs object with the remarks updated to add the region and
        pipeline.  The second value is the vyperdatum.pipeline datum identifier. The third
        value is the pipeline string.

    """
    datum = guess_vertical_datum_from_string(crs.name)
    pipeline = None
    new_crs = VerticalPipelineCRS(datum_data=datum_data)
    new_crs.from_wkt(crs.to_wkt())
    if datum:
        for region in regions:
            if datum == 'ellipse':
                new_pipeline = '[]'
            else:
                geoid_name = datum_data.get_geoid_name(region)
                new_pipeline = get_regional_pipeline('ellipse', datum, region,
                                                     geoid_name)
            if new_pipeline:
                new_crs.add_pipeline(new_pipeline, region)
        pipeline = new_crs.pipeline_string
        if datum == 'geoid':
            geoids = [
                gd for gd in geoid_possibilities if pipeline.find(gd) != -1
            ]
            if len(geoids) > 1:
                raise NotImplementedError(
                    f'Found multiple geoids in the pipeline string, only one geoid per pipeline supported at this time: {geoids}'
                )
            elif len(geoids) == 0:
                raise ValueError(
                    f'No geoid found in given pipeline string: {pipeline}')
            newdatum = geoids[0]
            new_crs.datum_name = newdatum
        valid_vert_crs = CRS.from_wkt(new_crs.to_wkt())
    else:
        valid_vert_crs = None
    return valid_vert_crs, datum, pipeline
Exemple #21
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 #22
0
    def _handler(self, request, response):

        shape_url = request.inputs["shape"][0].file
        projected_crs = request.inputs["projected_crs"][0].data

        extensions = [".gml", ".shp", ".gpkg", ".geojson", ".json"]
        vector_file = single_file_check(
            archive_sniffer(shape_url,
                            working_dir=self.workdir,
                            extensions=extensions))
        shape_crs = crs_sniffer(vector_file)

        try:
            projection = CRS.from_epsg(projected_crs)
            if projection.is_geographic:
                msg = (
                    f"Desired CRS {projection.to_epsg()} is geographic. "
                    "Areal analysis values will be in decimal-degree units.")
                LOGGER.warning(msg)
        except Exception as e:
            msg = f"{e}: Failed to parse CRS definition. Exiting."
            LOGGER.error(msg)
            raise Exception(msg)

        # TODO: It would be good to one day refactor this to make use of RavenPy utils and gis utilities
        properties = list()
        try:
            for i, layer_name in enumerate(fiona.listlayers(vector_file)):
                with fiona.open(vector_file, "r", crs=shape_crs,
                                layer=i) as src:
                    for feature in src:
                        geom = shape(feature["geometry"])

                        multipolygon_check(geom)

                        transformed = geom_transform(geom,
                                                     source_crs=shape_crs,
                                                     target_crs=projection)
                        prop = {"id": feature["id"]}
                        prop.update(feature["properties"])
                        prop.update(geom_prop(transformed))

                        # Recompute the centroid location using the original projection
                        prop["centroid"] = geom_prop(geom)["centroid"]

                        properties.append(prop)

        except Exception as e:
            msg = f"{e}: Failed to extract features from shape {vector_file}."
            LOGGER.error(msg)
            raise Exception(msg)

        response.outputs["properties"].data = json.dumps(properties)

        return response
Exemple #23
0
def test_derived_geographic_crs__from_methods():
    crs_str = "+proj=ob_tran +o_proj=longlat +o_lat_p=0 +o_lon_p=0 +lon_0=0"
    with pytest.raises(CRSError, match="Invalid type Geographic 2D CRS"):
        DerivedGeographicCRS.from_epsg(4326)
    assert_maker_inheritance_valid(DerivedGeographicCRS.from_string(crs_str),
                                   DerivedGeographicCRS)
    assert_maker_inheritance_valid(DerivedGeographicCRS.from_proj4(crs_str),
                                   DerivedGeographicCRS)
    assert_maker_inheritance_valid(
        DerivedGeographicCRS.from_user_input(
            DerivedGeographicCRS.from_string(crs_str)),
        DerivedGeographicCRS,
    )
    assert_maker_inheritance_valid(
        DerivedGeographicCRS.from_json(CRS(crs_str).to_json()),
        DerivedGeographicCRS)
    assert_maker_inheritance_valid(
        DerivedGeographicCRS.from_json_dict(CRS(crs_str).to_json_dict()),
        DerivedGeographicCRS,
    )
Exemple #24
0
def _is_longlat(crs):
    '''Test if CRS is in lat/long coordinates'''
    try:
        return crs['proj'] == 'longlat'
    except (KeyError, TypeError, AttributeError):
        pass

    projection = CRS(crs)

    try:
        return projection.is_geographic
    except AttributeError:
        return crs.to_dict().get('proj') == 'longlat'
    def test_read_vector_pass(self):
        """Test one columns data"""
        shp_file = shapereader.natural_earth(resolution='110m',
                                             category='cultural',
                                             name='populated_places_simple')
        lat, lon, geometry, intensity = read_vector(shp_file,
                                                    ['pop_min', 'pop_max'])

        self.assertEqual(PCRS.from_user_input(geometry.crs),
                         PCRS.from_epsg(NE_EPSG))
        self.assertEqual(geometry.size, lat.size)
        self.assertAlmostEqual(lon[0], 12.453386544971766)
        self.assertAlmostEqual(lon[-1], 114.18306345846304)
        self.assertAlmostEqual(lat[0], 41.903282179960115)
        self.assertAlmostEqual(lat[-1], 22.30692675357551)

        self.assertEqual(intensity.shape, (2, 243))
        # population min
        self.assertEqual(intensity[0, 0], 832)
        self.assertEqual(intensity[0, -1], 4551579)
        # population max
        self.assertEqual(intensity[1, 0], 832)
        self.assertEqual(intensity[1, -1], 7206000)
Exemple #26
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)
Exemple #27
0
def from_fiona(crs):
    """Converts a fiona CRS to the workflow CRS standard.

    Parameters
    ----------
    crs : fiona-crs-dict
        Input fiona CRS, which is a dictionary containing an EPSG
        code.

    Returns
    -------
    out : crs-type
        Equivalent workflow CRS.

    """
    # if 'datum' in crs and crs['datum'] == 'WGS84' and 'epsg' not in crs and 'ellps' not in crs:
    #     logging.warning('Old-style datum WGS84, moving to ellipse')
    #     crs['ellps'] = crs.pop('datum')
    if 'init' in crs and crs['init'].startswith('epsg:'):
        epsg, code = crs['init'].split(':')
        return CRS.from_epsg(code)
    else:
        return CRS.from_dict(crs)
Exemple #28
0
def find_inlet_nodes(nodes, inlets_shp, gdobj):
    """
    Load inlets from a shapefile.

    Loads the user-defined inlet nodes point shapefile and uses it to identify
    the inlet nodes within the network.

    Parameters
    ----------
    links : dict
        stores the network's links and their properties
    inlets_shp : str
        path to the shapefile of inlet locations (point shapefile)
    gdobj : osgeo.gdal.Dataset
        gdal object corresponding to the georeferenced input binary channel
        mask

    Returns
    -------
    nodes : dict
        nodes dictionary with 'inlets' key containing list of inlet node ids

    """

    # Check that CRSs match; reproject inlet points if not
    inlets_gpd = gpd.read_file(inlets_shp)
    mask_crs = CRS(gdobj.GetProjection())
    if inlets_gpd.crs != mask_crs:
        inlets_gpd = inlets_gpd.to_crs(mask_crs)
        logger.info(
            'Provided inlet points file does not have the same CRS as provided mask. Reprojecting.'
        )

    # Convert all nodes to xy coordinates for distance search
    nodes_xy = gu.idx_to_coords(nodes['idx'], gdobj)

    # Map provided inlet nodes to actual network nodes
    inlets = []
    for inlet_geom in inlets_gpd.geometry.values:
        # Distances between inlet node and all nodes in network
        xy = inlet_geom.xy
        dists = np.sqrt((xy[0][0] - nodes_xy[0])**2 +
                        (xy[1][0] - nodes_xy[1])**2)
        inlets.append(nodes['id'][np.argmin(dists)])

    # Append inlets to nodes dict
    nodes['inlets'] = inlets

    return nodes
Exemple #29
0
def from_epsg(epsg):
    """Converts from an EPSG code to a workflow CRS.

    Parameters
    ----------
    epsg : int
        An EPSG code. (see `https://epsg.io`_)

    Returns
    -------
    out : crs-type
        Equivalent workflow CRS.

    """
    return CRS.from_epsg(epsg)
Exemple #30
0
def from_cartopy(crs):
    """Converts a cartopy CRS to a workflow CRS.

    Parameters
    ----------
    epsg : int
        An EPSG code. (see `https://epsg.io`_)

    Returns
    -------
    out : crs-type
        Equivalent workflow CRS.

    """
    return CRS.from_dict(crs.proj4_params)
Exemple #31
0
    def __init__(self, projparams=None, preserve_units=True, **kwargs):
        """
        initialize a Proj class instance.

        See the proj documentation (https://github.com/OSGeo/proj.4/wiki)
        for more information about projection parameters.

        Parameters
        ----------
        projparams: int, str, dict, pyproj.CRS
            A proj.4 or WKT string, proj.4 dict, EPSG integer, or a pyproj.CRS instnace.
        preserve_units: bool
            If false, will ensure +units=m.
        **kwargs:
            proj.4 projection parameters.


        Example usage:

        >>> from pyproj import Proj
        >>> p = Proj(proj='utm',zone=10,ellps='WGS84', preserve_units=False) # use kwargs
        >>> x,y = p(-120.108, 34.36116666)
        >>> 'x=%9.3f y=%11.3f' % (x,y)
        'x=765975.641 y=3805993.134'
        >>> 'lon=%8.3f lat=%5.3f' % p(x,y,inverse=True)
        'lon=-120.108 lat=34.361'
        >>> # do 3 cities at a time in a tuple (Fresno, LA, SF)
        >>> lons = (-119.72,-118.40,-122.38)
        >>> lats = (36.77, 33.93, 37.62 )
        >>> x,y = p(lons, lats)
        >>> 'x: %9.3f %9.3f %9.3f' % x
        'x: 792763.863 925321.537 554714.301'
        >>> 'y: %9.3f %9.3f %9.3f' % y
        'y: 4074377.617 3763936.941 4163835.303'
        >>> lons, lats = p(x, y, inverse=True) # inverse transform
        >>> 'lons: %8.3f %8.3f %8.3f' % lons
        'lons: -119.720 -118.400 -122.380'
        >>> 'lats: %8.3f %8.3f %8.3f' % lats
        'lats:   36.770   33.930   37.620'
        >>> p2 = Proj('+proj=utm +zone=10 +ellps=WGS84', preserve_units=False) # use proj4 string
        >>> x,y = p2(-120.108, 34.36116666)
        >>> 'x=%9.3f y=%11.3f' % (x,y)
        'x=765975.641 y=3805993.134'
        >>> p = Proj(init="epsg:32667", preserve_units=False)
        >>> 'x=%12.3f y=%12.3f (meters)' % p(-114.057222, 51.045)
        'x=-1783506.250 y= 6193827.033 (meters)'
        >>> p = Proj("+init=epsg:32667")
        >>> 'x=%12.3f y=%12.3f (feet)' % p(-114.057222, 51.045)
        'x=-5851386.754 y=20320914.191 (feet)'
        >>> # test data with radian inputs
        >>> p1 = Proj(init="epsg:4214")
        >>> x1, y1 = p1(116.366, 39.867)
        >>> '{:.3f} {:.3f}'.format(x1, y1)
        '2.031 0.696'
        >>> x2, y2 = p1(x1, y1, inverse=True)
        >>> '{:.3f} {:.3f}'.format(x2, y2)
        '116.366 39.867'
        """
        self.crs = CRS.from_user_input(projparams if projparams is not None else kwargs)
        # make sure units are meters if preserve_units is False.
        if not preserve_units and "foot" in self.crs.axis_info[0].unit_name:
            projstring = self.crs.to_proj4(4)
            projstring = re.sub(r"\s\+units=[\w-]+", "", projstring)
            projstring += " +units=m"
            self.crs = CRS(projstring)
        super(Proj, self).__init__(
            cstrencode(
                (self.crs.to_proj4() or self.crs.srs).replace("+type=crs", "").strip()
            )
        )
Exemple #32
0
class Proj(_proj.Proj):
    """
    performs cartographic transformations (converts from
    longitude,latitude to native map projection x,y coordinates and
    vice versa) using proj (https://github.com/OSGeo/proj.4/wiki).

    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 proj4 string (compatible with the proj command). See
    http://www.remotesensing.org/geotiff/proj_list 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 1.e30 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.

    Attributes
    ----------
    srs: str
        The string form of the user input used to create the Proj.
    crs: ~pyproj.crs.CRS
        The CRS object associated with the Proj.
    proj_version: int
        The major version number for PROJ.

    """

    def __init__(self, projparams=None, preserve_units=True, **kwargs):
        """
        initialize a Proj class instance.

        See the proj documentation (https://github.com/OSGeo/proj.4/wiki)
        for more information about projection parameters.

        Parameters
        ----------
        projparams: int, str, dict, pyproj.CRS
            A proj.4 or WKT string, proj.4 dict, EPSG integer, or a pyproj.CRS instnace.
        preserve_units: bool
            If false, will ensure +units=m.
        **kwargs:
            proj.4 projection parameters.


        Example usage:

        >>> from pyproj import Proj
        >>> p = Proj(proj='utm',zone=10,ellps='WGS84', preserve_units=False) # use kwargs
        >>> x,y = p(-120.108, 34.36116666)
        >>> 'x=%9.3f y=%11.3f' % (x,y)
        'x=765975.641 y=3805993.134'
        >>> 'lon=%8.3f lat=%5.3f' % p(x,y,inverse=True)
        'lon=-120.108 lat=34.361'
        >>> # do 3 cities at a time in a tuple (Fresno, LA, SF)
        >>> lons = (-119.72,-118.40,-122.38)
        >>> lats = (36.77, 33.93, 37.62 )
        >>> x,y = p(lons, lats)
        >>> 'x: %9.3f %9.3f %9.3f' % x
        'x: 792763.863 925321.537 554714.301'
        >>> 'y: %9.3f %9.3f %9.3f' % y
        'y: 4074377.617 3763936.941 4163835.303'
        >>> lons, lats = p(x, y, inverse=True) # inverse transform
        >>> 'lons: %8.3f %8.3f %8.3f' % lons
        'lons: -119.720 -118.400 -122.380'
        >>> 'lats: %8.3f %8.3f %8.3f' % lats
        'lats:   36.770   33.930   37.620'
        >>> p2 = Proj('+proj=utm +zone=10 +ellps=WGS84', preserve_units=False) # use proj4 string
        >>> x,y = p2(-120.108, 34.36116666)
        >>> 'x=%9.3f y=%11.3f' % (x,y)
        'x=765975.641 y=3805993.134'
        >>> p = Proj(init="epsg:32667", preserve_units=False)
        >>> 'x=%12.3f y=%12.3f (meters)' % p(-114.057222, 51.045)
        'x=-1783506.250 y= 6193827.033 (meters)'
        >>> p = Proj("+init=epsg:32667")
        >>> 'x=%12.3f y=%12.3f (feet)' % p(-114.057222, 51.045)
        'x=-5851386.754 y=20320914.191 (feet)'
        >>> # test data with radian inputs
        >>> p1 = Proj(init="epsg:4214")
        >>> x1, y1 = p1(116.366, 39.867)
        >>> '{:.3f} {:.3f}'.format(x1, y1)
        '2.031 0.696'
        >>> x2, y2 = p1(x1, y1, inverse=True)
        >>> '{:.3f} {:.3f}'.format(x2, y2)
        '116.366 39.867'
        """
        self.crs = CRS.from_user_input(projparams if projparams is not None else kwargs)
        # make sure units are meters if preserve_units is False.
        if not preserve_units and "foot" in self.crs.axis_info[0].unit_name:
            projstring = self.crs.to_proj4(4)
            projstring = re.sub(r"\s\+units=[\w-]+", "", projstring)
            projstring += " +units=m"
            self.crs = CRS(projstring)
        super(Proj, self).__init__(
            cstrencode(
                (self.crs.to_proj4() or self.crs.srs).replace("+type=crs", "").strip()
            )
        )

    def __call__(self, *args, **kw):
        # ,lon,lat,inverse=False,errcheck=False):
        """
        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 1.e30 is returned.

        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)
        # if len(args) == 1:
        #    latlon = np.array(args[0], copy=True,
        #                      order='C', dtype=float, ndmin=2)
        #    if inverse:
        #        _proj.Proj._invn(self, latlon, radians=radians, errcheck=errcheck)
        #    else:
        #        _proj.Proj._fwdn(self, latlon, radians=radians, errcheck=errcheck)
        #    return latlon
        lon, lat = args
        # process inputs, making copies that support buffer API.
        inx, xisfloat, xislist, xistuple = _copytobuffer(lon)
        iny, yisfloat, yislist, yistuple = _copytobuffer(lat)
        # call proj4 functions. inx and iny modified in place.
        if inverse:
            self._inv(inx, iny, errcheck=errcheck)
        else:
            self._fwd(inx, iny, errcheck=errcheck)
        # if inputs were lists, tuples or floats, convert back.
        outx = _convertback(xisfloat, xislist, xistuple, inx)
        outy = _convertback(yisfloat, yislist, xistuple, iny)
        return outx, outy

    def is_latlong(self):
        """
        Returns
        -------
        bool: True if projection in geographic (lon/lat) coordinates.
        """
        warnings.warn(
            "'is_latlong()' is deprecated and will be removed in version 2.2.0. "
            "Please use 'crs.is_geographic'."
        )
        return self.crs.is_geographic

    def is_geocent(self):
        """
        Returns
        -------
        bool: True if projection in geocentric (x/y) coordinates
        """
        warnings.warn(
            "'is_geocent()' is deprecated and will be removed in version 2.2.0. "
            "Please use 'crs.is_geocent'."
        )
        return self.is_geocent

    def definition_string(self):
        """Returns formal definition string for projection

        >>> Proj('+init=epsg:4326').definition_string()
        'proj=longlat datum=WGS84 no_defs ellps=WGS84 towgs84=0,0,0'
        >>>
        """
        return pystrdecode(self.definition)

    def to_latlong_def(self):
        """return the definition string of the geographic (lat/lon)
        coordinate version of the current projection"""
        # This is a little hacky way of getting a latlong proj object
        # Maybe instead of this function the __cinit__ function can take a
        # Proj object and a type (where type = "geographic") as the libproj
        # java wrapper
        return self.crs.to_geodetic().to_proj4(4)

    # deprecated : using in transform raised a TypeError in release 1.9.5.1
    # reported in issue #53, resolved in #73.
    def to_latlong(self):
        """return a new Proj instance which is the geographic (lat/lon)
        coordinate version of the current projection"""
        return Proj(self.crs.to_geodetic())