def test_to_xy(): """ This method checks to_xy method. """ dsr_x_exm = -575834 dsr_y_exm = 66564 test_dir = Path(tempfile.mkdtemp()) valid_desc = [ "B4, central wavelength 665 nm", "B3, central wavelength 560 nm", "B2, central wavelength 490 nm", "B8, central wavelength 842 nm", ] transform = from_origin(1470996, 6914001, 10.0, 10.0) test_img, _ = SyntheticImage(20, 18, 4, "uint16", test_dir, 32640).create(seed=45, transform=transform, band_desc=valid_desc) # dsr = rasterio.open(test_img) data_file_path_test = "/test/a.SAFE" dsr_x, dsr_y = DATA_UTILS(data_file_path_test).to_xy(lon=1, lat=40, data=test_img) assert dsr_x == dsr_x_exm assert dsr_y == dsr_y_exm
def create_flood_multipolygon(self,zoom_flooded): """ Create multipolygons for the regions that flood. Input: zoom_flooded = grid showing where on DEM grid flooding occurred. Output: flood_pgon_gdf = geodataframe with multipolygon geometry for the flooding. """ # Create affine transformation matrix. x = self.zoom_x[0,:].ravel() y = self.zoom_y[:,0].ravel() res = (x[1] - x[0]) transform = from_origin(x[0],y[0], res, res) # Create multipolygon, store in geodataframe. flood_pgons = [] for geom, val in features.shapes(zoom_flooded.astype('int32'),transform=transform): if val > 0: pgon_coords = Polygon(geom['coordinates'][0]) flood_pgons.append(pgon_coords) flood_pgons = MultiPolygon(flood_pgons) flood_pgon_gdf = gpd.GeoDataFrame(pd.DataFrame({'geometry': flood_pgons})) return flood_pgon_gdf
def _affine(self): """Constructs the affine transformation, used for plotting and exporting polygons and rasters.""" from rasterio.transform import from_origin affine = from_origin(self.grid.cloud.data.min[0], self.grid.cloud.data.max[1], self.grid.cell_size, self.grid.cell_size) return affine
def rasterize(result_array, result_raster): #result_array = the prediction result in the form of Numpy array #result_raster = 'the path of the' a = result_array.astype(np.uint8) #reshape into 2D b = np.reshape(a, (-1,3057)) c = np.flipud(b) #flip vertically #because rasterio writes from bottom to top #the origin of Rasterio is the coordinate of the Southwest edge of the raster file #this should be based on the source raster that is used #transform = from_origin(longitude, latitude, X resolution, Y resolution) #feel free to modify the long, lat, and resolutions transform = from_origin(110.0363020639564269, -7.8701315292535803, 0.000271658, -0.000271658) new_dataset = rasterio.open(result_raster, 'w', driver='GTiff', height = b.shape[0], width = c.shape[1], count=1, dtype=c.dtype, crs='+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs', transform=transform) new_dataset.write(c, 1) new_dataset.close()
def array2raster(pixel_size, xmin, ymax, crs, array, output_path, raster_name='raster.tif'): """ Function that exports a numpy array into a raster. Inputs: pixel_size: (int). Pixel Size. X,Y dimensions must be the same. xmin, ymax: (float). Coordinates of the bounding box of the output raster. crs: (string). coordinate system of the raster. output_path: (string). path to store raster file. raster_name: (string). Name of the raster. Output: None. The raster will be stored in the path specified. """ transform = from_origin(xmin, ymax, pixel_size, pixel_size) new_dataset = rasterio.open(output_path + raster_name, 'w', driver='GTiff', height=array.shape[0], width=array.shape[1], count=1, dtype=str(array.dtype), crs=crs, transform=transform) new_dataset.write(array, 1) new_dataset.close()
def to_terrain(self, dx, dy=None, resampling=warp.Resampling.bilinear): """Load geospatial raster data and reproject onto specified grid Usage ===== dx,dy : float Grid spacings [m]. If dy is not specified, then uniform spacing is assumed. resampling : warp.Resampling value, optional See `list(warp.Resampling)`. """ if dy is None: dy = dx # load raster if not os.path.isfile(self.tiffdata): raise FileNotFoundError('Need to download()') dem_raster = rasterio.open(self.tiffdata) # get source coordinate reference system, transform west, south, east, north = self.bounds src_height, src_width = dem_raster.shape src_crs = dem_raster.crs src_transform = transform.from_bounds(*self.bounds, src_width, src_height) src = dem_raster.read(1) # calculate destination coordinate reference system, transform dst_crs = self.utm_crs print('Projecting from', src_crs, 'to', dst_crs) # - get origin (the _upper_ left corner) from bounds orix, oriy = self.to_xy(north, west) origin = (orix, oriy) self.origin = origin dst_transform = transform.from_origin(*origin, dx, dy) # - get extents from lower right corner SE_x, SE_y = self.to_xy(south, east) Lx = SE_x - orix Ly = oriy - SE_y Nx = int(Lx / dx) Ny = int(Ly / dy) # reproject to uniform grid in the UTM CRS dem_array = np.empty((Ny, Nx)) warp.reproject(src, dem_array, src_transform=src_transform, src_crs=src_crs, dst_transform=dst_transform, dst_crs=dst_crs, resampling=resampling) utmx = orix + np.arange(0, Nx * dx, dx) utmy = oriy + np.arange((-Ny + 1) * dy, dy, dy) self.x, self.y = np.meshgrid(utmx, utmy, indexing='ij') self.z = np.flipud(dem_array).T self.zfun = RectBivariateSpline(utmx, utmy, self.z) self.have_terrain = True return self.x, self.y, self.z
def test_to_xy(): """ This method checks to_xy method. """ params = {"roi_x_y": [5, 5, 15, 15]} s_2 = Superresolution(params) dsr_x_exm = -575834 dsr_y_exm = 66564 test_dir = Path(tempfile.mkdtemp()) valid_desc = [ "B4, central wavelength 665 nm", "B3, central wavelength 560 nm", "B2, central wavelength 490 nm", "B8, central wavelength 842 nm", ] transform = from_origin(1470996, 6914001, 10.0, 10.0) test_img, _ = FakeGeoImage(20, 18, 4, "uint16", test_dir, 32640).create(seed=45, transform=transform, band_desc=valid_desc) # dsr = rasterio.open(test_img) dsr_x, dsr_y = s_2.to_xy(lon=1, lat=40, data=test_img) assert dsr_x == dsr_x_exm assert dsr_y == dsr_y_exm
def read_raster(file, static=False): """ Method to read a raster. All rasterio types are accepted, plus IDF: in that case the iMod-package is used to read the IDF raster (IDF is cusomary for MODFLOW/SIMGRO models.) Parameters ---------- file : raster static : BOOL, optional If static than no time information needs to be deduced. Returns ------- rasterio grid and an affine object. """ if not static: time = pd.Timestamp(os.path.split(file)[1].split('_')[1].split('.')[0]) if file.lower().endswith('idf'): dataset = imod.idf.open(file) header = imod.idf.header(file,pattern=None) grid = dataset[0,0,:,:].values affine =from_origin(header['xmin'], header['ymax'], header['dx'], header['dx']) else: dataset = rasterio.open(file) affine = dataset.transform grid = dataset.read(1) if static: return grid, affine else: return grid, affine, time
def test_non_rectilinear(self): from rasterio.transform import from_origin # Create a geotiff file with 2d coordinates with create_tmp_geotiff( transform=from_origin(0, 3, 1, 1).rotation(45), crs=None ) as (tmp_file, _): # Default is to not parse coords with xr.open_rasterio(tmp_file) as rioda: assert "x" not in rioda.coords assert "y" not in rioda.coords assert "crs" not in rioda.attrs assert rioda.attrs["scales"] == (1.0, 1.0, 1.0) assert rioda.attrs["offsets"] == (0.0, 0.0, 0.0) assert rioda.attrs["descriptions"] == ("d1", "d2", "d3") assert rioda.attrs["units"] == ("u1", "u2", "u3") assert isinstance(rioda.attrs["res"], tuple) assert isinstance(rioda.attrs["is_tiled"], np.uint8) assert isinstance(rioda.attrs["transform"], tuple) assert len(rioda.attrs["transform"]) == 6 # See if a warning is raised if we force it with pytest.warns(Warning, match="transformation isn't rectilinear"): with xr.open_rasterio(tmp_file, parse_coordinates=True) as rioda: assert "x" not in rioda.coords assert "y" not in rioda.coords
def test_from_origin(): with rasterio.open('tests/data/RGB.byte.tif') as src: w, n = src.xy(0, 0, offset='ul') xs, ys = src.res tr = transform.from_origin(w, n, xs, ys) assert [round(v, 7) for v in tr] == [round(v, 7) for v in src.transform]
def create_grid(geom, dst_crs, dst_res): """Create a raster grid for a given area of interest. Parameters ---------- geom : shapely geometry Area of interest. dst_crs : CRS Target CRS as a rasterio CRS object. dst_res : int or float Spatial resolution (in `dst_crs` units). Returns ------- transform: Affine Output affine transform object. shape : tuple of int Output shape (height, width). bounds : tuple of float Output bounds. """ bounds = transform_bounds(CRS.from_epsg(4326), dst_crs, *geom.bounds) xmin, ymin, xmax, ymax = bounds transform = from_origin(xmin, ymax, dst_res, dst_res) ncols = (xmax - xmin) / dst_res nrows = (ymax - ymin) / dst_res transform, ncols, nrows = aligned_target(transform, ncols, nrows, dst_res) log.info(f"Created raster grid of shape ({nrows}, {ncols}).") return transform, (nrows, ncols), bounds
def gridmet_nc_to_geotiff(ds, time_index, path, filename, dsname): # collect data to describe geotransform lonmin = float(ds.attrs['geospatial_lon_min']) latmax = float(ds.attrs['geospatial_lat_max']) lonres = float(ds.attrs['geospatial_lon_resolution']) latres = float(ds.attrs['geospatial_lon_resolution']) # get data shape ts = ds.sizes dayshape = ts['day'] lonshape = ts['lon'] latshape = ts['lat'] # get transform transform = from_origin(lonmin, latmax, lonres, latres) # create geodiff from netcdf data file = path + filename new_dataset = rasterio.open(file, 'w', driver='GTiff', height=lonshape, width=latshape, count=1, dtype=str(ds.dtype), crs={'init': 'epsg:4326'}, transform=transform) vals = ds[dsname].values[dayshape - time_index, :, :] ud = np.flipud(vals) new_dataset.write(ud, 1) new_dataset.close()
def rasterize(result_array, result_raster): a = result_array.astype(np.uint8) #reshape into 2D b = np.reshape(a, (-1, 3057)) c = np.flipud(b) #flip vertically #because rasterio writes from bottom to top #transform = from_origin(110....<--dari origin, -7....<--bukan dari origin, 0.000271658, -0.000271658) transform = from_origin(110.0363020639564269, -7.8701315292535803, 0.000271658, -0.000271658) new_dataset = rasterio.open( result_raster, 'w', driver='GTiff', height=b.shape[0], width=c.shape[1], count=1, dtype=c.dtype, crs='+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs', transform=transform) new_dataset.write(c, 1) new_dataset.close()
def to_geotiff(in_path, out_path, srid: int = None, delimiter: str = ','): """Converts single CityCAT results file to GeoTIFF Args: in_path: path where CityCAT results file is located out_path: path to create GeoTIFF file srid: EPSG Spatial Reference System Identifier of results file delimiter: Delimiter to use when reading the results file """ from rasterio.transform import from_origin df = pd.read_csv(in_path, delimiter=delimiter) res, unique_x, unique_y, x_index, y_index = get_transform(df.XCen, df.YCen) width = len(unique_x) height = len(unique_y) depth = np.full((height, width), fill_value) depth[y_index, x_index] = df.Depth.values with rio.open(out_path, 'w', driver='GTiff', height=height, width=width, count=1, dtype=depth.dtype, crs=f'EPSG:{srid}' if srid is not None else None, transform=from_origin(unique_x.min() - res / 2, unique_y.max() + res / 2, res, res), nodata=fill_value, compress='lzw') as dst: dst.write(depth, 1)
def save_file(save_path, data, bound, dst_crs='epsg:4326'): """ 每次运行脚本时,将生成的数据存储到一个临时位置,通过commit方式,将这个文件夹上传入库 按照给出的影像信息,将影像数据保存为本地文件 :param name: str, 保存的文件名称 :param data: numpy.arr 影像数据 shape:(band, height, width) :param bound: [w, s, e, n] :param dst_crs: 输出影像的坐标系 :return: bool 创建成功,返回 True; 创建失败,返回 False. """ isfolder(save_path) try: if len(data.shape) == 2: data = np.expand_dims(data, axis=0) height_res = abs(bound[3] - bound[1]) / data.shape[1] width_res = abs(bound[2] - bound[0]) / data.shape[2] transform = from_origin(bound[0], bound[3], height_res, width_res) with rasterio.open(save_path, 'w', driver='GTiff', height=data.shape[1], width=data.shape[2], count=data.shape[0], dtype=data.dtype, crs=CRS({'init': dst_crs}), transform=transform) as dst: dst.write(data) except Exception as err: print(err) return False else: return True
def _calculate_transform(geom, res): west, south, east, north = geom.bounds dst_height, dst_width = tuple( int(np.ceil(diff / res)) for diff in [north - south, east - west]) dst_transform = transform.from_origin(west, north, res, res) return dst_transform, (dst_height, dst_width)
def test_get_max_min(): """ This method checks the get_min_max method. """ dsr_xmin_exm, dsr_ymin_exm, dsr_xmax_exm, dsr_ymax_exm, dsr_area_exm = ( 0, 0, 5, 5, 36, ) test_dir = Path(tempfile.mkdtemp()) valid_desc = [ "B4, central wavelength 665 nm", "B3, central wavelength 560 nm", "B2, central wavelength 490 nm", "B8, central wavelength 842 nm", ] transform = from_origin(1470996, 6914001, 10.0, 10.0) test_img, _ = SyntheticImage(40, 40, 4, "uint16", test_dir, 32640).create(seed=45, transform=transform, band_desc=valid_desc) # dsr = rasterio.open(test_img) dsr_xmin, dsr_ymin, dsr_xmax, dsr_ymax, dsr_area = DATA_UTILS.get_max_min( 0, 0, 10, 10, test_img) assert dsr_xmin == dsr_xmin_exm assert dsr_ymin == dsr_ymin_exm assert dsr_xmax == dsr_xmax_exm assert dsr_ymax == dsr_ymax_exm assert dsr_area == dsr_area_exm
def test_get_band_short_name(): """ This method checks the functionality of get_short_name methods. """ short_desc_exm = ["B4", "B3", "B2", "B8"] test_dir = Path(tempfile.mkdtemp()) valid_desc = [ "B4, central wavelength 665 nm", "B3, central wavelength 560 nm", "B2, central wavelength 490 nm", "B8, central wavelength 842 nm", ] transform = from_origin(1470996, 6914001, 10.0, 10.0) test_img, _ = SyntheticImage(20, 18, 4, "uint16", test_dir).create(seed=45, transform=transform, band_desc=valid_desc) dsr = rasterio.open(test_img) short_desc = [] for i in range(dsr.count): desc = DATA_UTILS.validate_description(dsr.descriptions[i]) short_desc.append(DATA_UTILS.get_band_short_name(desc)) assert set(short_desc) == set(short_desc_exm)
def test_validate_description(): """ this method checks the validate_description methods. """ valid_desc_exm = [ "B4 (665 nm)", "B3 (560 nm)", "B2 (490 nm)", "B8 (842 nm)" ] test_dir = Path(tempfile.mkdtemp()) valid_desc = [ "B4, central wavelength 665 nm", "B3, central wavelength 560 nm", "B2, central wavelength 490 nm", "B8, central wavelength 842 nm", ] transform = from_origin(1470996, 6914001, 10.0, 10.0) test_img, _ = SyntheticImage(20, 18, 4, "uint16", test_dir).create(seed=45, transform=transform, band_desc=valid_desc) dsr = rasterio.open(test_img) valid_desc = [] print(dsr.count) for i in range(dsr.count): valid_desc.append(DATA_UTILS.validate_description(dsr.descriptions[i])) assert set(valid_desc) == set(valid_desc_exm)
def test_validate(): """ This method check whether validate function defined in the s2_tiles_supres file produce the correct results. """ params = {"roi_x_y": [5, 5, 15, 15]} s_2 = Superresolution(params) test_dir = Path(tempfile.mkdtemp()) valid_desc_10 = [ "B4, central wavelength 665 nm", "B3, central wavelength 560 nm", "B2, central wavelength 490 nm", "B8, central wavelength 842 nm", ] transform = from_origin(1470996, 6914001, 10.0, 10.0) test_img_10, _ = FakeGeoImage(20, 18, 4, "uint16", test_dir).create(seed=45, transform=transform, band_desc=valid_desc_10) validated_10m_indices_exm = [0, 1, 2, 3] validated_10m_bands_exm = ["B2", "B3", "B4", "B8"] validated_10m_bands, validated_10m_indices, _ = s_2.validate( data=test_img_10) assert set(validated_10m_bands) == set(validated_10m_bands_exm) assert validated_10m_indices == validated_10m_indices_exm
def test_validate(): """ This method check whether validate function defined in the s2_tiles_supres file produce the correct results. """ test_dir = Path(tempfile.mkdtemp()) valid_desc_10 = [ "B4, central wavelength 665 nm", "B3, central wavelength 560 nm", "B2, central wavelength 490 nm", "B8, central wavelength 842 nm", ] transform = from_origin(1470996, 6914001, 10.0, 10.0) test_img_10, _ = SyntheticImage(20, 18, 4, "uint16", test_dir).create(seed=45, transform=transform, band_desc=valid_desc_10) validated_10m_indices_exm = [0, 1, 2, 3] validated_10m_bands_exm = ["B2", "B3", "B4", "B8"] data_file_path_test = "/test/a.SAFE" validated_10m_bands, validated_10m_indices, _ = DATA_UTILS( data_file_path_test).validate(data=test_img_10) assert set(validated_10m_bands) == set(validated_10m_bands_exm) assert validated_10m_indices == validated_10m_indices_exm
def downscale(ddir, area, time, postfix='', dt=-1): # parse time t = pd.to_datetime(time) # read regions info sdir = dirname(realpath(__file__)) fn_regions = join(sdir, 'map', 'hires', 'location.txt') click.echo(fn_regions) regions = pd.read_csv(fn_regions, delim_whitespace=True, index_col=0).T \ .set_index('area').astype(float).to_dict(orient='index') # read nc fn_nc = join(ddir, 'flddph*.nc') ds = xr.open_mfdataset(fn_nc, chunks={'time': 10}) if dt != 0: ds['time'] = ds.time.to_index() + timedelta(days=dt) data = ds.flddph.sel(time=time).data data = np.where(np.isnan(data), 1e+20, data) # mv = 1e20 # write to bin datestr = '{:04d}{:02d}{:02d}'.format(t.year, t.month, t.day) fn_out_bin = join(sdir, basename(fn_nc).replace('*.nc', datestr)) click.echo(fn_out_bin) with open(fn_out_bin, 'w') as fid: fid.write(data.astype('f4').tobytes()) # downscale click.echo('downscaling...') msg = ['./downscale_flddph', str(area), basename(fn_out_bin), '1'] click.echo(' '.join(msg)) subprocess.call(msg, cwd=sdir, stderr=subprocess.STDOUT) # open binary output fn_fld = join(sdir, '{:s}.flood'.format(area)) ny, nx = int(regions[area]['ny']), int(regions[area]['nx']) with open(fn_fld, 'r') as fid: data = np.fromfile(fid, 'f4').reshape(ny, nx) # write to geotiff fn_out_tif = join(ddir, basename(fn_out_bin) + postfix + '.tif') click.echo('writing to ' + fn_out_tif) west, north, csize = regions[area]['west'], regions[area][ 'north'], regions[area]['csize'] transform = from_origin(west, north, csize, csize) with rasterio.open(fn_out_tif, 'w', driver='GTiff', height=data.shape[0], compress='lzw', width=data.shape[1], count=1, dtype=str(data.dtype), crs='+proj=latlong', transform=transform, nodata=-9999) as dst: dst.write(data, 1) # remove binary output os.unlink(fn_out_bin) os.unlink(fn_fld)
def test_ENVI_tags(self): rasterio = pytest.importorskip("rasterio", minversion="1.0a") from rasterio.transform import from_origin # Create an ENVI file with some tags in the ENVI namespace # this test uses a custom driver, so we can't use create_tmp_geotiff with create_tmp_file(suffix=".dat") as tmp_file: # data nx, ny, nz = 4, 3, 3 data = np.arange(nx * ny * nz, dtype=rasterio.float32).reshape(nz, ny, nx) transform = from_origin(5000, 80000, 1000, 2000.0) with rasterio.open( tmp_file, "w", driver="ENVI", height=ny, width=nx, count=nz, crs={ "units": "m", "no_defs": True, "ellps": "WGS84", "proj": "utm", "zone": 18, }, transform=transform, dtype=rasterio.float32, ) as s: s.update_tags( ns="ENVI", description="{Tagged file}", wavelength="{123.000000, 234.234000, 345.345678}", fwhm="{1.000000, 0.234000, 0.000345}", ) s.write(data) dx, dy = s.res[0], -s.res[1] # Tests coords = { "band": [1, 2, 3], "y": -np.arange(ny) * 2000 + 80000 + dy / 2, "x": np.arange(nx) * 1000 + 5000 + dx / 2, "wavelength": ("band", np.array([123, 234.234, 345.345678])), "fwhm": ("band", np.array([1, 0.234, 0.000345])), } expected = DataArray(data, dims=("band", "y", "x"), coords=coords) with xr.open_rasterio(tmp_file) as rioda: assert_allclose(rioda, expected) assert isinstance(rioda.attrs["crs"], str) assert isinstance(rioda.attrs["res"], tuple) assert isinstance(rioda.attrs["is_tiled"], np.uint8) assert isinstance(rioda.attrs["transform"], tuple) assert len(rioda.attrs["transform"]) == 6 # from ENVI tags assert isinstance(rioda.attrs["description"], str) assert isinstance(rioda.attrs["map_info"], str) assert isinstance(rioda.attrs["samples"], str)
def test_nonintersecting_window_index(): """See gh-2378""" t = from_origin(0, 0, 1, 1) w = from_bounds(-3, -3, -1, -1, t) data = np.arange(25).reshape(5, 5) selection = data[window_index(w, height=5, width=5)] assert selection.shape == (2, 0) assert selection.flatten().tolist() == []
def get_transform(self): x = self[self.x_column].values y = self[self.y_column].values xres, yres = self.res x_origin = min(x) - xres // 2 y_origin = max(y) + yres // 2 return from_origin(x_origin, y_origin, xres, yres)
def get_dtm_hawaii(path_out, minlong, maxlong, minlat, maxlat): step_out = 0 minxll = int(((minlong + 180) * 120) - step_out) maxxll = int(((maxlong + 180) * 120) + step_out) minyll = int(((minlat + 90) * 120) - step_out) maxyll = int(((maxlat + 90) * 120) + step_out) sizex = round(maxxll - minxll + 1) sizey = round(maxyll - minyll + 1) minxll = str(minxll) maxxll = str(maxxll) minyll = str(minyll) maxyll = str(maxyll) bbox = "[" + minyll + ":1:" + maxyll + "][" + minxll + ":1:" + maxxll + "]" link = "https://pae-paha.pacioos.hawaii.edu/thredds/dodsC/srtm30plus_v11_land.ascii?elev" + bbox print(link) f = urlopen(link) myfile = f.read() myfile2 = myfile.decode("utf-8") data = myfile2.split("---------------------------------------------") #import re grid = re.sub('\[.*\]', '', data[1]).replace(",", "").replace( "elev.elev", "").replace("\n", " ").replace(" ", " ") #print(grid) grid = grid.split(" ") grid = grid[2:(sizex * sizey) + 2] #OPeNDAP = np.ones((sizey,sizex), dtype='int16') #k=0 #for j in range (0, sizey, 1): # for i in range (0, sizex, 1): # OPeNDAP[sizey-1-j][i]=int(float(grid[k])) # k+=1 OPeNDAP = np.asarray(grid, dtype=np.float16).reshape(sizey, sizex) OPeNDAP = OPeNDAP.astype('int16') OPeNDAP = np.flipud(OPeNDAP) transform = from_origin(minlong, maxlat, 0.008333333, 0.008333333) new_dataset = rasterio.open(path_out, 'w', driver='GTiff', height=OPeNDAP.shape[0], width=OPeNDAP.shape[1], count=1, dtype=str(OPeNDAP.dtype), crs='+proj=longlat', transform=transform) new_dataset.write(OPeNDAP, 1) new_dataset.close() print("dtm geotif saved as", path_out)
def __init__(self, array, grid): from rasterio.transform import from_origin self.grid = grid self.cell_size = self.grid.cell_size self.array = array self._affine = from_origin(self.grid.cloud.data.min[0], self.grid.cloud.data.max[1], self.grid.cell_size, self.grid.cell_size)
def create_raster_transform(bounds, pixel_size, snap_extent_to_pixel=True, buffer_by_pixels=0): """Create parameters required for creating a new raster file based on a known extent and pixel size. snap_extent_to_pixel can be used to ensure the bounding coordinates are a divisible of the pixel size. Args: bounds (float, float, float, float): the bounding box coordinates (xmin, ymin, xmax, ymax) pixel_size (int, float): the required pixel size snap_extent_to_pixel (bool): round the extent coordinates to be divisible by the pixel size buffer_by_pixels (int): The number of pixels to buffer the input bounding box by. Returns: affine.Affine: the Rasterio Transformation object int: the width or number of columns int: the height or number of rows. [float, float, float, float]: new bounding box coordinates updated if snapping was used. """ if not isinstance(bounds, (tuple, list)): raise TypeError( 'Bounds should be a tuple or list for xmin, ymin, xmax, ymax') if not isinstance(pixel_size, six.integer_types + (float, )): raise TypeError('pixel_size must be numeric number.') if not isinstance(snap_extent_to_pixel, (int, bool)): raise TypeError('snap_extent_to_pixel must be boolean.') # adjust values to an area slightly larger than the bounds if buffer_by_pixels > 0: bounds = (bounds[0] - (pixel_size * buffer_by_pixels), bounds[1] - (pixel_size * buffer_by_pixels), bounds[2] + (pixel_size * buffer_by_pixels), bounds[3] + (pixel_size * buffer_by_pixels)) # We may want to snap the output grids to a multiple of the grid size, allowing # adjacent blocks to align nicely. if snap_extent_to_pixel: x_min, y_min, x_max, y_max = raster_snap_extent(*bounds, pixel_size=pixel_size) else: x_min, y_min, x_max, y_max = bounds width = int((x_max - x_min) / pixel_size) # columns height = int((y_max - y_min) / pixel_size) # rows # create an affine transformation matrix to associate the array to the coordinates. from rasterio.transform import from_origin transform = from_origin(x_min, y_max, pixel_size, pixel_size) return transform, width, height, (x_min, y_min, x_max, y_max)
def rasterize(img_path, result_array, result_raster): #img_path = the path of the source raster #result_array = the prediction result in the form of Numpy array #result_raster = 'the path of the output raster' a = result_array.astype(np.uint8) #the origin of Rasterio is the coordinate of the Southwest edge of the raster file #this should be based on the source raster that is used #transform = from_origin(longitude, latitude, X resolution, Y resolution) #feel free to modify the long, lat, and resolutions #get the source raster origin (= the southwest corner of the raster) img = gdal.Open(img_path, gdal.GA_ReadOnly) trans = img.GetGeoTransform() xRes = trans[1] yRes = trans[5] xOrigin = trans[0] yOrigin = trans[3] + (img.RasterYSize) * yRes xSize = img.RasterXSize #close gdal dataset img = None #hence the raster origin transform = from_origin(xOrigin, yOrigin, xRes, yRes) #reshape Array into 2D b = np.reshape(a, (-1, xSize)) c = np.flipud(b) #flip vertically #because rasterio writes from bottom to top #now define the CRS in rasterio (because GDAL's CRS is of different format, and IDK how to convert it w/o # including another library) imgras = rasterio.open(img_path) #take the CRS proj_init = imgras.crs #close the raster imgras.close() new_dataset = rasterio.open(result_raster, 'w', driver='GTiff', height=c.shape[0], width=c.shape[1], count=1, dtype=c.dtype, crs=proj_init, transform=transform) ##from the old code, the CRS is in the PROJ4 format """ crs='+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs', """ new_dataset.write(c, 1) new_dataset.close()
def test_ENVI_tags(): # Create an ENVI file with some tags in the ENVI namespace # this test uses a custom driver, so we can't use create_tmp_geotiff with create_tmp_file(suffix=".dat") as tmp_file: # data nx, ny, nz = 4, 3, 3 data = np.arange(nx * ny * nz, dtype=rasterio.float32).reshape(nz, ny, nx) transform = from_origin(5000, 80000, 1000, 2000.0) with rasterio.open( tmp_file, "w", driver="ENVI", height=ny, width=nx, count=nz, crs={ "units": "m", "no_defs": True, "ellps": "WGS84", "proj": "utm", "zone": 18, }, transform=transform, dtype=rasterio.float32, ) as s: s.update_tags( ns="ENVI", description="{Tagged file}", wavelength="{123.000000, 234.234000, 345.345678}", fwhm="{1.000000, 0.234000, 0.000345}", ) s.write(data) dx, dy = s.res[0], -s.res[1] crs_wkt = s.crs.to_wkt() # Tests coords = { "band": [1, 2, 3], "y": -np.arange(ny) * 2000 + 80000 + dy / 2, "x": np.arange(nx) * 1000 + 5000 + dx / 2, "wavelength": ("band", np.array([123, 234.234, 345.345678])), "fwhm": ("band", np.array([1, 0.234, 0.000345])), } expected = DataArray(data, dims=("band", "y", "x"), coords=coords) expected.coords[DEFAULT_GRID_MAP] = xr.Variable((), 0) expected.coords[DEFAULT_GRID_MAP].attrs["crs_wkt"] = crs_wkt with rioxarray.open_rasterio(tmp_file) as rioda: assert_allclose(rioda, expected) assert rioda.rio.crs == crs_wkt assert isinstance(rioda.rio._cached_transform(), Affine) # from ENVI tags assert isinstance(rioda.attrs["description"], str) assert isinstance(rioda.attrs["map_info"], str) assert isinstance(rioda.attrs["samples"], str)
def test_from_origin(): with rasterio.open('tests/data/RGB.byte.tif') as src: w, n = src.xy(0, 0, offset='ul') xs, ys = src.res tr = transform.from_origin(w, n, xs, ys) assert [round(v, 7) for v in tr] == [round(v, 7) for v in src.transform]
def test_from_origin(): with rasterio.open('tests/data/RGB.byte.tif') as src: w, n = src.ul(0, 0) xs, ys = src.res tr = transform.from_origin(w, n, xs, ys) assert [round(v, 7) for v in tr] == [round(v, 7) for v in src.affine]
def convert_from_shapefile(shapefile, rgb_color): """ :param shp: :param rgb_color: :return: """ shp = shapefile # alias # get coordinates coords_1 = shp.bounds[1], shp.bounds[0] # coordinate 2 to get height coords_2 = shp.bounds[3], shp.bounds[0] height = geopy.distance.vincenty(coords_1, coords_2).km # coordinate 2 to get width coords_2 = shp.bounds[1], shp.bounds[2] width = geopy.distance.vincenty(coords_1, coords_2).km res_x = (shp.bounds[2] - shp.bounds[0]) / width res_y = (shp.bounds[3] - shp.bounds[1]) / height out_shape = int(height), int(width) transform = from_origin( shp.bounds[0] - res_x / 2, shp.bounds[3] + res_y / 2, res_x, res_y ) shapes = [ [(geometry['geometry'], color)] for k, geometry in shp.items() for color in rgb_color ] # creates raster file dtype = rasterio.float64 fill = np.nan raster_args = dict( out_shape=out_shape, fill=fill, transform=transform, dtype=dtype, all_touched=True ) rasters = [rasterize(shape, **raster_args) for shape in shapes] geotiff_path = '/tmp/%s.tif' % np.random.randint(100000, 999999) with rasterio.open( geotiff_path, mode='w', crs=shp.crs, driver='GTiff', # profile='GeoTIFF', dtype=dtype, count=3, width=width, height=height, nodata=np.nan, transform=transform, photometric='RGB' ) as dst: for i in range(1, 4): dst.write_band(i, rasters[i - 1]) with open(geotiff_path, 'rb') as f: result = f.read() os.remove(geotiff_path) return result
with rasterio.drivers(): # Consider a 512 x 512 raster centered on 0 degrees E and 0 degrees N # with each pixel covering 15". rows, cols = src_shape = (512, 512) dpp = 1.0/240 # decimal degrees per pixel west, south, east, north = -cols*dpp/2, -rows*dpp/2, cols*dpp/2, rows*dpp/2 src_transform = transform.from_bounds(west, south, east, north, cols, rows) src_crs = {'init': 'EPSG:4326'} source = numpy.ones(src_shape, numpy.uint8)*255 # Prepare to reproject this rasters to a 1024 x 1024 dataset in # Web Mercator (EPSG:3857) with origin at -237481.5, 237536.4. dst_shape = (1024, 1024) dst_transform = transform.from_origin(-237481.5, 237536.4, 425.0, 425.0) dst_crs = {'init': 'EPSG:3857'} destination = numpy.zeros(dst_shape, numpy.uint8) reproject( source, destination, src_transform=src_transform, src_crs=src_crs, dst_transform=dst_transform, dst_crs=dst_crs, resampling=RESAMPLING.nearest) # Assert that the destination is only partly filled. assert destination.any() assert not destination.all()