def _ssebop(url_stamped): dt, url = url_stamped resp = session.get(url) zfile = zipfile.ZipFile(io.BytesIO(resp.content)) content = zfile.read(zfile.filelist[0].filename) ds = geoutils.gtiff2xarray({"eta": content}, _geometry, DEF_CRS) return dt, ds.expand_dims({"time": [dt]})
def nlcd( geometry: Union[Polygon, MultiPolygon, Tuple[float, float, float, float]], resolution: float, years: Optional[Dict[str, Optional[int]]] = None, geo_crs: str = DEF_CRS, crs: str = DEF_CRS, ) -> xr.Dataset: """Get data from NLCD database (2016). Download land use/land cover data from NLCD (2016) database within a given geometry in epsg:4326. Parameters ---------- geometry : Polygon, MultiPolygon, or tuple of length 4 The geometry or bounding box (west, south, east, north) for extracting the data. resolution : float The data resolution in meters. The width and height of the output are computed in pixel based on the geometry bounds and the given resolution. years : dict, optional The years for NLCD data as a dictionary, defaults to {'impervious': 2016, 'cover': 2016, 'canopy': 2016}. Set the value of a layer to None, to ignore it. geo_crs : str, optional The CRS of the input geometry, defaults to epsg:4326. crs : str, optional The spatial reference system to be used for requesting the data, defaults to epsg:4326. Returns ------- xarray.DataArray NLCD within a geometry """ years = {"impervious": 2016, "cover": 2016, "canopy": 2016} if years is None else years layers = _nlcd_layers(years) _geometry = geoutils.geo2polygon(geometry, geo_crs, crs) wms = WMS(ServiceURL().wms.mrlc, layers=layers, outformat="image/geotiff", crs=crs) r_dict = wms.getmap_bybox(_geometry.bounds, resolution, box_crs=crs) ds = geoutils.gtiff2xarray(r_dict, _geometry, crs) if isinstance(ds, xr.DataArray): ds = ds.to_dataset() for n in ds.keys(): if "cover" in n.lower(): ds = ds.rename({n: "cover"}) ds.cover.attrs["units"] = "classes" elif "canopy" in n.lower(): ds = ds.rename({n: "canopy"}) ds.canopy.attrs["units"] = "%" elif "impervious" in n.lower(): ds = ds.rename({n: "impervious"}) ds.impervious.attrs["units"] = "%" return ds
def test_gtiff2array(geometry_nat): url_wms = "https://www.fws.gov/wetlands/arcgis/services/Wetlands_Raster/ImageServer/WMSServer" wms = WMS( url_wms, layers="0", outformat="image/tiff", crs="epsg:3857", ) r_dict = wms.getmap_bybox( geometry_nat.bounds, 1e3, box_crs=DEF_CRS, ) wetlands_box = geoutils.gtiff2xarray(r_dict, geometry_nat.bounds, DEF_CRS) wetlands_msk = geoutils.xarray_geomask(wetlands_box, geometry_nat, DEF_CRS) wetlands = geoutils.gtiff2xarray(r_dict, geometry_nat, DEF_CRS) assert (abs(wetlands_msk.isel(band=0).mean().values.item() - 17.208) < 1e-3 and abs(wetlands.isel(band=0).mean().values.item() - 16.542) < 1e-3)
def get_map( layers: Union[str, List[str]], geometry: Union[Polygon, Tuple[float, float, float, float]], resolution: float, geo_crs: str = DEF_CRS, crs: str = DEF_CRS, ) -> xr.DataArray: """Access to `3DEP <https://www.usgs.gov/core-science-systems/ngp/3dep>`__ service. The 3DEP service has multi-resolution sources so depending on the user provided resolution the data is resampled on server-side based on all the available data sources. The following layers are available: - "DEM" - "Hillshade Gray" - "Aspect Degrees" - "Aspect Map" - "GreyHillshade_elevationFill" - "Hillshade Multidirectional" - "Slope Map" - "Slope Degrees" - "Hillshade Elevation Tinted" - "Height Ellipsoidal" - "Contour 25" - "Contour Smoothed 25" Parameters ---------- layers : str or list A valid 3DEP layer or a list of them geometry : Polygon, MultiPolygon, or tuple A shapely Polygon or a bounding box (west, south, east, north) resolution : float The data resolution in meters. The width and height of the output are computed in pixel based on the geometry bounds and the given resolution. geo_crs : str, optional The spatial reference system of the input geometry, defaults to epsg:4326. crs : str, optional The spatial reference system to be used for requesting the data, defaults to epsg:4326. Returns ------- xarray.DataArray The requeted data within the geometry """ if not isinstance(geometry, (Polygon, MultiPolygon, tuple)): raise InvalidInputType("geometry", "Polygon or tuple of length 4") _geometry = geoutils.geo2polygon(geometry, geo_crs, crs) _layers = layers if isinstance(layers, list) else [layers] if "DEM" in _layers: _layers[_layers.index("DEM")] = "None" _layers = [f"3DEPElevation:{lyr}" for lyr in _layers] wms = WMS(ServiceURL().wms.nm_3dep, layers=_layers, outformat="image/tiff", crs=crs) r_dict = wms.getmap_bybox(_geometry.bounds, resolution, box_crs=crs) ds = geoutils.gtiff2xarray(r_dict, _geometry, crs) valid_layers = wms.get_validlayers() rename = {lyr: lyr.split(":")[-1].replace(" ", "_").lower() for lyr in valid_layers} rename.update({"3DEPElevation:None": "elevation"}) if isinstance(ds, xr.DataArray): ds.name = rename[ds.name] else: ds = ds.rename({n: rename[n] for n in ds.keys()}) return ds