0

The following code clips the TIFF images based on the GeoJson file. However, when clipping the tiles that has half image and half nothing (white area in QGIS), the nothing half changes to black, which is what I want but the half that has the real image turns to white. How can I get the half that has the real image to have the same thing (data) while the half that has nothing to turn to the black color?

import os
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from shapely.geometry import mapping
import geopandas as gpd
import rasterio as rio
from rasterio.plot import plotting_extent
from rasterio.mask import mask
import earthpy as et
import earthpy.spatial as es
import earthpy.plot as ep

shape_file = '/.../abc.geojson' crop_extent = gpd.read_file(shape_file)

lidar_chm_path = '/.../reprojected.tif' output = '/.../Data/' if not os.path.exists(output): os.mkdir(output) i, j = 0, 0 while i < crop_extent.shape[0]: with rio.open(lidar_chm_path) as lidar_chm: try: lidar_chm_crop, lidar_chm_crop_meta = es.crop_image(lidar_chm,[crop_extent.iloc[i]['geometry']]) lidar_chm_crop_affine = lidar_chm_crop_meta["transform"] j += 1 lidar_chm_crop_meta.update({'transform': lidar_chm_crop_affine, 'height': lidar_chm_crop.shape[1], 'width': lidar_chm_crop.shape[2], 'nodata': -999.99}) name = output + str(crop_extent.iloc[1][2]) + 'image' + str(j) + '.tif' with rio.open(name, 'w', **lidar_chm_crop_meta) as ff: ff.write(lidar_chm_crop[0], 1) except: None i += 1

  • Is your CHM a 32 bit floating point raster? Your NoData is -999.99 which would only be valid in a floating point context, as for this question I don't know enough about rasterio specifically, I work with GDAL which is similar, have a read of the documentation on the update method and see if there's a fill value parameter then check that the NoData value of the output raster is set to the specified -999.99. – Michael Stimson Aug 05 '20 at 05:08
  • Thank you very much for the answer! The No data value is -999.989990234375. The data I am opening through rasterio is a TIF image, I do not know if it is a floating point raster or not. How can I know whether it is a floating point raster or not? Also, how would you do the same task through GDAL? – Rohullah Najibi Aug 05 '20 at 05:30
  • What software are you using to view the data? This information should be in the layers information tab in QGIS or ArcGIS. As for how to do this in GDAL, have a read of https://gis.stackexchange.com/questions/262021/how-to-replicate-gdalwarp-cutline-in-python-to-cut-out-tif-image-based-on-the-e accepted answer, very simple and elegant cutline code. I think gdal.Warp fills the output with the specified NoData value and sets the output raster NoData value to match as such the ephemera isn't black or white it's set transparent. – Michael Stimson Aug 05 '20 at 06:07
  • I am using QGIS to view the data. Thank you very much for the link. – Rohullah Najibi Aug 05 '20 at 06:39
  • On the layer properties, information tab Data type should read Float32 - Thirty two bit floating point for a floating point raster; 64 bit floating point is also possible but not very common. For a Canopy Height Model I would expect the pixel type to be float as that is what I produce from LiDAR data but your CHM could be integer if the units are inches or centimetres in which case you need to pick a different NoData value that is in range, for unsigned 16 bit integer I use 65535, signed 16 bit -9999 and unsigned 8 bit I use 255. – Michael Stimson Aug 05 '20 at 07:08
  • I just checked it. It is Float32. Thank you very much! So, -999.99 no data value should be correct, right? – Rohullah Najibi Aug 05 '20 at 07:25
  • It's not about being correct or not, it must only be in range (see https://stackoverflow.com/questions/13484475/what-are-the-upper-and-lower-limits-and-types-of-pixel-values-in-opencv/13490111 for values) and not a value that is even remotely possible to see legitimately in your valid data, which makes unsigned 8 bit a little concerning as 255 could legitimately exist in your valid data. Many years ago I was working with a company that mandated -99 as the NoData value and then we had a project where the mine site was more than 100 metres below sea level, so -999.99 is probably good enough. – Michael Stimson Aug 05 '20 at 07:32
  • Oh, I see. It is about being in range as you mentioned. Thank you very much! – Rohullah Najibi Aug 05 '20 at 07:44

0 Answers0