Ejemplo n.º 1
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'])
Ejemplo n.º 2
0
    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}')
Ejemplo n.º 3
0
def _get_proj_data(projection: Any) -> CRS:
    """Take projection information and returns a proj CRS.

    Takes projection information in any format understood by
    :func:`pyproj.crs.CRS.from_user_input`.  There is special
    handling for the "EPSG:XXXX" case where "XXXX" is an EPSG
    number code. It can be provided as a string `"EPSG:XXXX"` or
    as a dictionary (when provided via YAML) as `{'EPSG': XXXX}`.
    If it is passed as a string ("EPSG:XXXX") then the rules of
    :func:`~pyresample.utils._proj.proj4_str_to_dict` are followed.  If a
    dictionary and pyproj 2.0+ is installed then the string `"EPSG:XXXX"`
    is passed to ``proj4_str_to_dict``. If pyproj<2.0 is installed then
    the string ``+init=EPSG:XXXX`` is passed to ``proj4_str_to_dict``
    which provides limited information to area config operations.
    """
    if isinstance(projection, dict) and 'EPSG' in projection:
        projection = "EPSG:{}".format(projection['EPSG'])
    return CRS.from_user_input(projection)
    def write_hdf5(self, file_data):
        """Write centroids attributes into hdf5 format.

        Parameters
        ----------
        file_data : str or h5
            If string, path to write data. If h5 object, the datasets will be generated there.
        """
        if isinstance(file_data, str):
            LOGGER.info('Writting %s', file_data)
            data = h5py.File(file_data, 'w')
        else:
            data = file_data
        str_dt = h5py.special_dtype(vlen=str)
        for centr_name, centr_val in self.__dict__.items():
            if isinstance(centr_val, np.ndarray):
                data.create_dataset(centr_name,
                                    data=centr_val,
                                    compression="gzip")
            if centr_name == 'meta' and centr_val:
                centr_meta = data.create_group(centr_name)
                for key, value in centr_val.items():
                    if key not in ('crs', 'transform'):
                        if not isinstance(value, str):
                            centr_meta.create_dataset(key, (1, ),
                                                      data=value,
                                                      dtype=type(value))
                        else:
                            hf_str = centr_meta.create_dataset(key, (1, ),
                                                               dtype=str_dt)
                            hf_str[0] = value
                    elif key == 'transform':
                        centr_meta.create_dataset(key, (6, ),
                                                  data=[
                                                      value.a, value.b,
                                                      value.c, value.d,
                                                      value.e, value.f
                                                  ],
                                                  dtype=float)
        hf_str = data.create_dataset('crs', (1, ), dtype=str_dt)
        hf_str[0] = CRS.from_user_input(self.crs).to_wkt()

        if isinstance(file_data, str):
            data.close()
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
def subset_shape(
    ds: Union[xarray.DataArray, xarray.Dataset],
    shape: Union[str, Path, gpd.GeoDataFrame],
    vectorize: bool = True,
    raster_crs: Optional[Union[str, int]] = None,
    shape_crs: Optional[Union[str, int]] = None,
    buffer: Optional[Union[int, float]] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
) -> Union[xarray.DataArray, xarray.Dataset]:
    """Subset a DataArray or Dataset spatially (and temporally) using a vector shape and date selection.

    Return a subset of a DataArray or Dataset for grid points falling within the area of a Polygon and/or
    MultiPolygon shape, or grid points along the path of a LineString and/or MultiLineString.

    Parameters
    ----------
    ds : Union[xarray.DataArray, xarray.Dataset]
      Input values.
    shape : Union[str, Path, gpd.GeoDataFrame]
      Path to shape file, or directly a geodataframe. Supports formats compatible with geopandas.
    vectorize: bool
      Whether to use the spatialjoin or vectorize backend.
    raster_crs : Optional[Union[str, int]]
      EPSG number or PROJ4 string.
    shape_crs : Optional[Union[str, int]]
      EPSG number or PROJ4 string.
    buffer : Optional[Union[int, float]]
      Buffer the shape in order to select a larger region stemming from it. Units are based on the shape degrees/metres.
    start_date : Optional[str]
      Start date of the subset.
      Date string format -- can be year ("%Y"), year-month ("%Y-%m") or year-month-day("%Y-%m-%d").
      Defaults to first day of input data-array.
    end_date : Optional[str]
      End date of the subset.
      Date string format -- can be year ("%Y"), year-month ("%Y-%m") or year-month-day("%Y-%m-%d").
      Defaults to last day of input data-array.

    Returns
    -------
    Union[xarray.DataArray, xarray.Dataset]
      A subset of `ds`

    Examples
    --------
    >>> import xarray as xr  # doctest: +SKIP
    >>> from xclim.subset import subset_shape  # doctest: +SKIP
    >>> pr = xr.open_dataset(path_to_pr_file).pr  # doctest: +SKIP
    ...
    # Subset data array by shape
    >>> prSub = subset_shape(pr, shape=path_to_shape_file)  # doctest: +SKIP
    ...
    # Subset data array by shape and single year
    >>> prSub = subset_shape(pr, shape=path_to_shape_file, start_date='1990-01-01', end_date='1990-12-31')  # doctest: +SKIP
    ...
    # Subset multiple variables in a single dataset
    >>> ds = xr.open_mfdataset([path_to_tasmin_file, path_to_tasmax_file])  # doctest: +SKIP
    >>> dsSub = subset_shape(ds, shape=path_to_shape_file)  # doctest: +SKIP
    """
    wgs84 = CRS(4326)
    # PROJ4 definition for WGS84 with longitudes ranged between -180/+180.
    wgs84_wrapped = CRS.from_string(
        "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs lon_wrap=180")

    if isinstance(ds, xarray.DataArray):
        ds_copy = ds._to_temp_dataset()
    else:
        ds_copy = ds.copy()

    if isinstance(shape, gpd.GeoDataFrame):
        poly = shape.copy()
    else:
        poly = gpd.GeoDataFrame.from_file(shape)

    if buffer is not None:
        poly.geometry = poly.buffer(buffer)

    # Get the shape's bounding box.
    minx, miny, maxx, maxy = poly.total_bounds
    lon_bnds = (minx, maxx)
    lat_bnds = (miny, maxy)

    # If polygon doesn't cross prime meridian, subset bbox first to reduce processing time
    # Only case not implemented is when lon_bnds cross the 0 deg meridian but dataset grid has all positive lons
    try:
        ds_copy = subset_bbox(ds_copy, lon_bnds=lon_bnds, lat_bnds=lat_bnds)
    except NotImplementedError:
        pass

    if ds_copy.lon.size == 0 or ds_copy.lat.size == 0:
        raise ValueError(
            "No grid cell centroids found within provided polygon bounding box. "
            'Try using the "buffer" option to create an expanded area.')

    if start_date or end_date:
        ds_copy = subset_time(ds_copy,
                              start_date=start_date,
                              end_date=end_date)

    # Determine whether CRS types are the same between shape and raster
    if shape_crs is not None:
        try:
            shape_crs = CRS.from_user_input(shape_crs)
        except ValueError:
            raise
    else:
        shape_crs = CRS(poly.crs)

    wrap_lons = False
    if raster_crs is not None:
        try:
            raster_crs = CRS.from_user_input(raster_crs)
        except ValueError:
            raise
    else:
        if np.min(lat_bnds) < -90 or np.max(lat_bnds) > 90:
            raise ValueError(
                "Latitudes exceed domain of WGS84 coordinate system.")
        if np.min(lon_bnds) < -180 or np.max(lon_bnds) > 180:
            raise ValueError(
                "Longitudes exceed domain of WGS84 coordinate system.")

        try:
            # Extract CF-compliant CRS_WKT from crs variable.
            raster_crs = CRS.from_cf(ds_copy.crs.attrs)
        except AttributeError:
            if np.min(ds_copy.lon) >= 0 and np.max(ds_copy.lon) <= 360:
                wrap_lons = True
                raster_crs = wgs84_wrapped
            else:
                raster_crs = wgs84
    _check_crs_compatibility(shape_crs=shape_crs, raster_crs=raster_crs)

    # Create mask using the vectorize or spatial join methods.
    if vectorize:
        mask_2d = create_mask_vectorize(x_dim=ds_copy.lon,
                                        y_dim=ds_copy.lat,
                                        poly=poly,
                                        wrap_lons=wrap_lons)
    else:
        mask_2d = create_mask(x_dim=ds_copy.lon,
                              y_dim=ds_copy.lat,
                              poly=poly,
                              wrap_lons=wrap_lons)

    if np.all(mask_2d.isnull()):
        raise ValueError(
            f"No grid cell centroids found within provided polygon bounds ({poly.bounds}). "
            'Try using the "buffer" option to create an expanded areas or verify polygon.'
        )

    # loop through variables
    for v in ds_copy.data_vars:
        if set.issubset(set(mask_2d.dims), set(ds_copy[v].dims)):
            ds_copy[v] = ds_copy[v].where(mask_2d.notnull())

    # Remove coordinates where all values are outside of region mask
    for dim in mask_2d.dims:
        mask_2d = mask_2d.dropna(dim, how="all")
    ds_copy = ds_copy.sel({dim: mask_2d[dim] for dim in mask_2d.dims})

    # Add a CRS definition using CF conventions and as a global attribute in CRS_WKT for reference purposes
    ds_copy.attrs["crs"] = raster_crs.to_string()
    ds_copy["crs"] = 1
    ds_copy["crs"].attrs.update(raster_crs.to_cf())

    for v in ds_copy.variables:
        if {"lat", "lon"}.issubset(set(ds_copy[v].dims)):
            ds_copy[v].attrs["grid_mapping"] = "crs"

    if isinstance(ds, xarray.DataArray):
        return ds._from_temp_dataset(ds_copy)
    return ds_copy
Ejemplo n.º 8
0
    def __init__(self, projparams=None, preserve_units=True, **kwargs):
        """
        initialize a Proj class instance.

        See the PROJ documentation (https://proj.org)
        for more information about projection parameters.

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


        Example usage:

        >>> from pyproj import Proj
        >>> p = Proj(proj='utm',zone=10,ellps='WGS84', preserve_units=False)
        >>> 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)
        >>> 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)

        projstring = self.crs.to_proj4() or self.crs.srs
        projstring = re.sub(r"\s\+?type=crs", "", projstring)
        super(Proj, self).__init__(cstrencode(projstring.strip()))
import numpy as np
import pandas as pd
from pyproj.crs import CRS
import rasterio
from rasterio.warp import Resampling
from scipy import sparse
from shapely.geometry.point import Point

from climada.util.constants import (DEF_CRS, ONE_LAT_KM, NATEARTH_CENTROIDS)
import climada.util.coordinates as u_coord
import climada.util.hdf5_handler as u_hdf5
import climada.util.plot as u_plot

__all__ = ['Centroids']

PROJ_CEA = CRS.from_user_input({'proj': 'cea'})

DEF_VAR_MAT = {
    'field_names': ['centroids', 'hazard'],
    'var_name': {
        'lat': 'lat',
        'lon': 'lon',
        'dist_coast': 'distance2coast_km',
        'admin0_name': 'admin0_name',
        'admin0_iso3': 'admin0_ISO3',
        'comment': 'comment',
        'region_id': 'NatId'
    }
}
"""MATLAB variable names"""
Ejemplo n.º 10
0
    def __init__(
        self,
        projparams: Any = None,
        preserve_units: bool = True,
        network=None,
        **kwargs,
    ) -> None:
        """
        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.

        .. versionadded:: 3.0.0 network

        Parameters
        ----------
        projparams: int, str, dict, pyproj.CRS
            A PROJ or WKT string, PROJ dict, EPSG integer, or a pyproj.CRS instance.
        preserve_units: bool
            If false, will ensure +units=m.
        network: bool, optional
            Default is None, which uses the system defaults for networking.
            If True, it will force the use of network for grids regardless of
            any other network setting. If False, it will force disable use of
            network for grids regardless of any other network setting.
        **kwargs:
            PROJ projection parameters.


        Example usage:

        >>> from pyproj import Proj
        >>> p = Proj(proj='utm',zone=10,ellps='WGS84', preserve_units=False)
        >>> 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)
        >>> x,y = p2(-120.108, 34.36116666)
        >>> 'x=%9.3f y=%11.3f' % (x,y)
        'x=765975.641 y=3805993.134'
        >>> p = Proj("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("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("epsg:4214")
        >>> x1, y1 = p1(116.366, 39.867)
        >>> f'{x1:.3f} {y1:.3f}'
        '116.366 39.867'
        >>> x2, y2 = p1(x1, y1, inverse=True)
        >>> f'{x2:.3f} {y2:.3f}'
        '116.366 39.867'
        """
        self.crs = CRS.from_user_input(projparams, **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:
            # ignore export to PROJ string deprecation warning
            with warnings.catch_warnings():
                warnings.filterwarnings(
                    "ignore",
                    "You will likely lose important projection information",
                    UserWarning,
                )
                projstring = self.crs.to_proj4(4)
            projstring = re.sub(r"\s\+units=[\w-]+", "", projstring)
            projstring += " +units=m"
            self.crs = CRS(projstring)

        # ignore export to PROJ string deprecation warning
        with warnings.catch_warnings():
            warnings.filterwarnings(
                "ignore",
                "You will likely lose important projection information",
                UserWarning,
            )
            projstring = self.crs.to_proj4() or self.crs.srs

        self.srs = re.sub(r"\s\+?type=crs", "", projstring).strip()
        super().__init__(
            _Transformer.from_pipeline(cstrencode(self.srs), network=network)
        )
Ejemplo n.º 11
0
    def _handler(self, request, response):

        # Process inputs
        # ---------------
        shape_url = request.inputs["shape"][0].file
        destination_crs = request.inputs["projected_crs"][0].data
        touches = request.inputs["select_all_touching"][0].data

        # Checks for valid CRS and that CRS is projected
        # -----------------------------------------------
        projection = CRS.from_user_input(destination_crs)
        if not projection.is_projected:
            msg = f"Destination CRS {projection.to_epsg()} is not projected. Terrain analysis values will not be valid."
            LOGGER.error(ValueError(msg))
            raise ValueError(msg)

        # Collect and process the shape
        # -----------------------------
        vectors = [".gml", ".shp", ".gpkg", ".geojson", ".json"]
        vector_file = single_file_check(
            archive_sniffer(shape_url,
                            working_dir=self.workdir,
                            extensions=vectors))
        vec_crs = crs_sniffer(vector_file)

        # Check that boundaries within 60N and 60S
        boundary_check(vector_file)

        if "raster" in request.inputs:
            raster_url = request.inputs["raster"][0].file
            rasters = [".tiff", ".tif"]
            raster_file = single_file_check(
                archive_sniffer(raster_url,
                                working_dir=self.workdir,
                                extensions=rasters))

        else:
            # Assuming that the shape coordinate are in WGS84
            raster_file = gather_dem_tile(vector_file, self.workdir)

        ras_crs = crs_sniffer(raster_file)

        # Reproject raster
        # ----------------
        if ras_crs != projection.to_epsg():
            msg = f"CRS for {raster_file} is not {projection}. Reprojecting raster..."
            LOGGER.warning(msg)
            warped_fn = tempfile.NamedTemporaryFile(prefix="warped_",
                                                    suffix=".tiff",
                                                    delete=False,
                                                    dir=self.workdir).name
            generic_raster_warp(raster_file, warped_fn, projection)

        else:
            warped_fn = raster_file

        # Perform the terrain analysis
        # ----------------------------
        rpj = tempfile.NamedTemporaryFile(prefix="reproj_",
                                          suffix=".json",
                                          delete=False,
                                          dir=self.workdir).name
        generic_vector_reproject(vector_file,
                                 rpj,
                                 source_crs=vec_crs,
                                 target_crs=projection.to_epsg())
        with open(rpj) as src:
            geo = json.load(src)

        features = [sgeo.shape(feat["geometry"]) for feat in geo["features"]]
        union = ops.unary_union(features)

        clipped_fn = tempfile.NamedTemporaryFile(prefix="clipped_",
                                                 suffix=".tiff",
                                                 delete=False,
                                                 dir=self.workdir).name
        # Ensure that values for regions outside of clip are kept
        generic_raster_clip(
            raster=warped_fn,
            output=clipped_fn,
            geometry=union,
            touches=touches,
            fill_with_nodata=True,
            padded=True,
        )

        # Compute DEM properties for each feature.
        properties = []
        for i in range(len(features)):
            properties.append(
                dem_prop(clipped_fn, geom=features[i], directory=self.workdir))
        properties.append(dem_prop(clipped_fn, directory=self.workdir))

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

        return response
Ejemplo n.º 12
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()
            )
        )