def test_crop_image_fails_empty_list(basic_image_tif, basic_geometry): """If users provide empty list as arg, crop_image fails.""" with pytest.raises(AttributeError): es.crop_image(list(), basic_geometry) with rio.open(basic_image_tif) as src: with pytest.raises(ValueError): es.crop_image(src, list())
def test_crop_image_when_poly_bounds_image_extent(basic_image_tif): """When an image is fully contained in a larger polygon, dont crop.""" big_polygon = Polygon([(-1, -1), (11, -1), (11, 11), (-1, 11), (-1, -1)]) with rio.open(basic_image_tif) as src: img, meta = es.crop_image(src, [big_polygon]) src_array = src.read() assert np.array_equal(img, src_array)
def crop_image_by_shp(imm, shp): currentDirectory = os.getcwd() crop_extent = gpd.read_file(shp) imm_or = rasterio.open(imm, 'r') metadatas_imm_or = imm_or.meta imm_crop, imm_crop_meta = es.crop_image(imm_or, crop_extent, all_touched=True) with fiona.open(shp, "r") as shapefile: geoms = [feature["geometry"] for feature in shapefile] out_image, out_transform = mask(imm_or, geoms, all_touched=True, crop=True) imm_crop_affine = imm_crop_meta["transform"] # Create spatial plotting extent for the cropped layer #imm_extent = plotting_extent(imm_crop[0], imm_crop_affine) metadatas_imm_or.update({ 'transform': imm_crop_affine, 'height': imm_crop.shape[1], 'width': imm_crop.shape[2], 'nodata': 0 }) #imm_crop=imm_crop[0,:,:] # out_image, out_transform = mask(imm_crop, geoms,invert=True) # wkspFldr = os.path.dirname(imm) base = os.path.basename(imm) ext = os.path.splitext(base)[1] name_file = os.path.splitext(base)[0] metadatas_imm_or['driver'] = "GTiff" path_out = currentDirectory + '/' + name_file + '_rep' + '.tif' #path_out = imm#"data/colorado-flood/spatial/outputs/lidar_chm_cropped.tif" # with rio.open(path_out, 'w', **metadatas_imm_or) as ff: # ff.write(out_image[0], 1) return out_image, metadatas_imm_or
def _pre_crop(self, src_tif, shape_file): _no_data = 0 crop_extent = gpd.read_file(shape_file) with rio.open(src_tif) as clim_data: _no_data = clim_data.nodata clim_data, clim_metadata = es.crop_image(clim_data, crop_extent) clim_data[0][clim_data[0] == _no_data] = self.no_data_default # NOTE: set no data return clim_data, clim_metadata
def test_crop_image_with_gdf(basic_image_tif, basic_geometry_gdf): """Cropping with a GeoDataFrame works when all_touched=True. Cropping basic_image_tif file with the basic geometry fixture returns all of the cells that have the value 1 in the basic_image_tif fixture These fixtures are described in conftest.py """ with rio.open(basic_image_tif) as src: img, meta = es.crop_image(src, basic_geometry_gdf, all_touched=True) assert np.sum(img) == 9
def crop_ras_to_shpfile(raster_path, shpfile_path, output_path, no_data_val): shpfile = gpd.read_file(shpfile_path) with rio.open(raster_path) as ras: ras_crop, ras_crop_meta = es.crop_image(ras, shpfile) ras_crop_aff = ras_crop_meta["transform"] ras_crop_meta.update({'transform': ras_crop_aff, 'height': ras_crop.shape[1], 'width': ras_crop.shape[2], 'nodata': no_data_val}) with rio.open(output_path, 'w', **ras_crop_meta) as ff: ff.write(ras_crop[0], 1) print('done cropping raster to shapefile')
def test_crop_image_with_geometry(basic_image_tif, basic_geometry): """Cropping with a geometry works with all_touched=True.""" with rio.open(basic_image_tif) as src: img, meta = es.crop_image(src, [basic_geometry], all_touched=True) assert np.sum(img) == 9
crop_bound_utm13N = crop_bound.to_crs(crop_raster_profile["crs"]) ############################################################################# # Crop Each Band # -------------- # This step crops all of the bands one by one. It uses enumerate to implement dynamic naming # of raster outputs. The ``i`` variable will be an integer that counts up one with every # loop that is completed, and ``bands`` will be the raster bands in the folder. # It crops the rasters one at a time and writes them to an output directory. os.chdir(os.path.join(et.io.HOME, "earth-analytics")) for i, bands in enumerate(stack_band_paths): outpath = "data/outputs/outputraster" + str(i) with rio.open(bands) as currband: crop, meta = es.crop_image(currband, crop_bound_utm13N) with rio.open(outpath, "w", **meta) as dest: dest.write(crop) ############################################################################# # Stack All Bands # --------------- # Once the data are cropped, you are ready to create a new stack. os.chdir(os.path.join(et.io.HOME, "earth-analytics")) stack = glob("data/outputs/outputraster*") cropped_array, array_raster = es.stack(stack, nodata=-9999) crop_extent = plotting_extent(crop[0], meta["transform"]) # Plotting the cropped image
def test_crop_image_swapped_args(basic_image_tif, basic_geometry): """If users provide a polygon instead of raster raise an error.""" with pytest.raises(AttributeError): es.crop_image(basic_geometry, basic_image_tif) with pytest.raises(AttributeError): es.crop_image(basic_geometry, basic_geometry)
def test_crop_image_fails_two_rasters(basic_image_tif, basic_geometry): """crop_image should raise an error if provided two rasters.""" with rio.open(basic_image_tif) as src: with pytest.raises(TypeError): es.crop_image(src, src)
def test_crop_image_with_1d_extent_raises_error(basic_image_tif): """Cropping with a horizontal or vertical line raises an error.""" line = LineString([(1, 1), (2, 1), (3, 1)]) with rio.open(basic_image_tif) as src: with pytest.raises(ValueError, match="width and height must be > 0"): es.crop_image(src, [line])
def test_crop_image_with_one_point_raises_error(basic_image_tif): """Cropping an image with one point should raise an error.""" point = Point([(1, 1)]) with rio.open(basic_image_tif) as src: with pytest.raises(ValueError, match="width and height must be > 0"): es.crop_image(src, [point])
print("*******************************************") print("VECTOR INFO ") print("*******************************************") vector = gp.read_file(vfp) print(vector) print(vector.crs) print() print() vector = vector.to_crs(raster.crs) # our crop_extent is the vector crop_extent = vector raster_crop, raster_crop_meta = es.crop_image(raster, crop_extent) raster_crop_affine = raster_crop_meta["transform"] # Create spatial plotting extent for the cropped layer raster_extent = plotting_extent(raster_crop[0], raster_crop_affine) print(crop_extent) plot_crop_extent() plot_crop_overlayed_on_raster() plot_cropped_raster() raster_meta = raster.profile raster_meta.update({
def test_crop_image_with_geojson_touch_false(basic_image_tif, basic_geometry): """Cropping with GeoJSON works when all_touched=False.""" geojson = basic_geometry.__geo_interface__ with rio.open(basic_image_tif) as src: img, meta = es.crop_image(src, [geojson], all_touched=False) assert np.sum(img) == 4
dir_crop = dir_iii + '\\crop' if not os.path.exists(dir_crop): os.mkdir(dir_crop) dir_crop = dir_iii + '\\crop' list_iii = glob.glob('*.tif') # iii = list_iii[1] for iii in list_iii: with rio.open(iii) as iii_tif: iii_tif_crop, iii_tif_crop_meta = es.crop_image( iii_tif, crop_extent) iii_tif_crop_affine = iii_tif_crop_meta['transform'] # Create spatial plotting extent for the cropped layer iii_tif_extent = plotting_extent(iii_tif_crop[0], iii_tif_crop_affine) # Plot your data ''' ep.plot_bands(iii_tif_crop[0], extent = iii_tif_extent, cmap = 'Greys', title = "Cropped Raster Dataset", scale = False) plt.show()
def test_crop_image_with_gdf_touch_false(basic_image_tif, basic_geometry_gdf): """Cropping with a GeoDataFrame works when all_touched=False.""" with rio.open(basic_image_tif) as src: img, meta = es.crop_image(src, basic_geometry_gdf, all_touched=False) assert np.sum(img) == 4
plt.show() ############################################################################# # Crop Individual Bands # --------------------- # If you only need to crop one raster image, you can use EarthPy's # ``es.crop_image()`` function. # This function takes a Rasterio object and crops it to the provided # spatial extent. # Open Landsat image as a Rasterio object in order to crop it os.chdir(os.path.join(et.io.HOME, "earth-analytics")) with rio.open(stack_band_paths[0]) as src: single_cropped_image, single_cropped_meta = es.crop_image( src, crop_bound_utm13N ) # Create the extent object single_crop_extent = plotting_extent( single_cropped_image[0], single_cropped_meta["transform"] ) # Plot the newly cropped image fig, ax = plt.subplots(figsize=(12, 6)) crop_bound_utm13N.boundary.plot(ax=ax, color="red", zorder=10) ep.plot_bands( single_cropped_image, ax=ax, extent=single_crop_extent, title="Single Cropped Raster and Fire Boundary",
# -------------- # # clip files by polygon ramsar = gpd.read_file(ramsarshp_fn) for image_dir in os.listdir(dos_img_dir): # print(image_dir) path = os.path.join(clipped_img_dir, image_dir) try: os.mkdir(path) for image_band in os.listdir(dos_img_dir + '\\' + image_dir): # print(os.path.join(path, image_band)) # clip flow acc by shapefile with rasterio.open( r'C:\Users\Clare\Documents\MscDiss\Images\6_Classified\MT_seasonal_2.tif' ) as src_raster: cropped_raster, cropped_meta = spatial.crop_image( src_raster, ramsar) crop_affine = cropped_meta["transform"] cropped_meta.update({ 'transform': crop_affine, 'height': cropped_raster.shape[1], 'width': cropped_raster.shape[2], 'nodata': -999.99 }) # write tif file of clipped bit with rasterio.open(os.path.join(path, image_band), 'w', **cropped_meta) as ff: ff.write(cropped_raster[0], 1) except: pass
def polygonize_by_extent(bounding_polygon): with rasterio.open(lulc_path) as lulc: out_img, out_meta = es.crop_image(lulc, bounding_polygon) features_gen = ( { 'properties': { 'DN': v, 'feature_name': features[v]["name"], 'feature_color': features[v]["color"], 'feature_type': 'land cover', 'feature_desc': 'N/A', 'feature_date': '' # 'feature_area':calculate_area(s) / 10000 }, 'geometry': s } for i, (s, v) in enumerate( rasterio.features.shapes( out_img, None, transform=out_meta["transform"]))) geometries = list(features_gen) with rasterio.open(settlements_path) as path: out_img, out_meta = es.crop_image(path, bounding_polygon) features_gen = ( { 'properties': { 'DN': v, 'feature_name': "Building Cluster", 'feature_color': "#000", 'feature_type': 'Settlement Density', 'feature_desc': 'N/A', 'feature_date': '' # 'feature_area':calculate_area(s) / 10000 }, 'geometry': s } for i, (s, v) in enumerate( rasterio.features.shapes( out_img, None, transform=out_meta["transform"]))) geometries = geometries + list(features_gen) bounds = list(bounding_polygon.bounds.values[0]) possible_matches_index = list(osm_land_use_idx.intersection(bounds)) possible_matches = osm_land_use.loc[possible_matches_index] features_gen = ({ 'properties': { 'DN': v["code"], 'feature_name': v["fclass"], 'feature_color': "#ccc", 'feature_type': 'Land Use', 'feature_desc': 'N/A', 'feature_date': '' }, 'geometry': v["geometry"] } for i, v in possible_matches.iterrows()) geometries = geometries + list(features_gen) possible_matches_index = list(osm_roads_idx.intersection(bounds)) possible_matches = osm_roads.loc[possible_matches_index] features_gen = ({ 'properties': { 'DN': v["code"], 'feature_name': v["fclass"], 'feature_color': "#f00", 'feature_type': 'Terrain', 'feature_desc': 'N/A', 'feature_date': '' }, 'geometry': v["geometry"] } for i, v in possible_matches.iterrows()) geometries = geometries + list(features_gen) possible_matches_index = list(osm_waterways_idx.intersection(bounds)) possible_matches = osm_waterways.loc[possible_matches_index] features_gen = ({ 'properties': { 'DN': v["code"], 'feature_name': v["fclass"], 'feature_color': "#00f", 'feature_type': 'Water Way', 'feature_desc': 'N/A', 'feature_date': '' }, 'geometry': v["geometry"] } for i, v in possible_matches.iterrows()) geometries = geometries + list(features_gen) possible_matches_index = list(osm_water_idx.intersection(bounds)) possible_matches = osm_water.loc[possible_matches_index] features_gen = ({ 'properties': { 'DN': v["code"], 'feature_name': v["fclass"], 'feature_color': "#00002f", 'feature_type': 'Water Body', 'feature_desc': 'N/A', 'feature_date': '' }, 'geometry': v["geometry"] } for i, v in possible_matches.iterrows()) geometries = geometries + list(features_gen) possible_matches_index = list(osm_transport_idx.intersection(bounds)) possible_matches = osm_transport.loc[possible_matches_index] features_gen = ({ 'properties': { 'DN': v["code"], 'feature_name': v["fclass"], 'feature_color': "#34ff5c", 'feature_type': 'Public Transport', 'feature_desc': 'N/A', 'feature_date': '' }, 'geometry': v["geometry"] } for i, v in possible_matches.iterrows()) geometries = geometries + list(features_gen) possible_matches_index = list(osm_traffic_idx.intersection(bounds)) possible_matches = osm_traffic.loc[possible_matches_index] features_gen = ({ 'properties': { 'DN': v["code"], 'feature_name': v["fclass"], 'feature_color': "#003ccc", 'feature_type': 'Urban Traffic', 'feature_desc': 'N/A', 'feature_date': '' }, 'geometry': v["geometry"] } for i, v in possible_matches.iterrows()) geometries = geometries + list(features_gen) possible_matches_index = list(acled_idx.intersection(bounds)) possible_matches = acled.loc[possible_matches_index] # print(list(possible_matches)) features_gen = ({ 'properties': { 'DN': v["EVENT_ID_C"], 'feature_name': v["SUB_EVENT_"], 'feature_color': "#ffccee", 'feature_type': 'OSINT Event', 'feature_desc': v["NOTES"], 'feature_date': v["EVENT_DATE"] }, 'geometry': v["geometry"] } for i, v in possible_matches.iterrows()) geometries = geometries + list(features_gen) polygonized_features = gpd.GeoDataFrame.from_features(geometries) return polygonized_features