Module rok4.raster
Provide functions to read information on raster data
The module contains the following class :
Classes
class Raster
-
A structure describing raster data
Attributes
path
:str
- path to the file/object (ex: file:///path/to/image.tif or s3://bucket/path/to/image.tif)
bbox
:Tuple[float, float, float, float]
- bounding rectange in the data projection
bands
:int
- number of color bands (or channels) format (ColorFormat). Numeric variable format for color values. Bit depth, as bits per channel, can be derived from it.
mask
:str
- path to the associated mask file or object, if any, or None (same path as the image, but with a ".msk" extension and TIFF format. Ex: file:///path/to/image.msk or s3://bucket/path/to/image.msk)
dimensions
:Tuple[int, int]
- image width and height, in pixels
Expand source code
class Raster: """A structure describing raster data Attributes: path (str): path to the file/object (ex: file:///path/to/image.tif or s3://bucket/path/to/image.tif) bbox (Tuple[float, float, float, float]): bounding rectange in the data projection bands (int): number of color bands (or channels) format (ColorFormat). Numeric variable format for color values. Bit depth, as bits per channel, can be derived from it. mask (str): path to the associated mask file or object, if any, or None (same path as the image, but with a ".msk" extension and TIFF format. Ex: file:///path/to/image.msk or s3://bucket/path/to/image.msk) dimensions (Tuple[int, int]): image width and height, in pixels """ def __init__(self) -> None: self.bands = None self.bbox = (None, None, None, None) self.dimensions = (None, None) self.format = None self.mask = None self.path = None @classmethod def from_file(cls, path: str) -> "Raster": """Creates a Raster object from an image Args: path (str): path to the image file/object Examples: Loading informations from a file stored raster TIFF image from rok4.raster import Raster try: raster = Raster.from_file( "file:///data/SC1000/0040_6150_L93.tif" ) except Exception as e: print(f"Cannot load information from image : {e}") Raises: FormatError: MASK file is not a TIFF RuntimeError: raised by OGR/GDAL if anything goes wrong NotImplementedError: Storage type not handled FileNotFoundError: File or object does not exists Returns: Raster: a Raster instance """ if not exists(path): raise FileNotFoundError(f"No file or object found at path '{path}'.") self = cls() work_image_path = get_osgeo_path(path) image_datasource = gdal.Open(work_image_path) self.path = path path_pattern = re.compile("(/[^/]+?)[.][a-zA-Z0-9_-]+$") mask_path = path_pattern.sub("\\1.msk", path) if exists(mask_path): work_mask_path = get_osgeo_path(mask_path) mask_driver = gdal.IdentifyDriver(work_mask_path).ShortName if "GTiff" != mask_driver: message = f"Mask file '{mask_path}' use GDAL driver : '{mask_driver}'" raise FormatError("TIFF", mask_path, message) self.mask = mask_path else: self.mask = None self.bbox = compute_bbox(image_datasource) self.bands = image_datasource.RasterCount self.format = compute_format(image_datasource, path) self.dimensions = (image_datasource.RasterXSize, image_datasource.RasterYSize) return self @classmethod def from_parameters( cls, path: str, bands: int, bbox: Tuple[float, float, float, float], dimensions: Tuple[int, int], format: ColorFormat, mask: str = None, ) -> "Raster": """Creates a Raster object from parameters Args: path (str): path to the file/object (ex: file:///path/to/image.tif or s3://bucket/image.tif) bands (int): number of color bands (or channels) bbox (Tuple[float, float, float, float]): bounding rectange in the data projection dimensions (Tuple[int, int]): image width and height expressed in pixels format (ColorFormat): numeric format for color values. Bit depth, as bits per channel, can be derived from it. mask (str, optionnal): path to the associated mask, if any, or None (same path as the image, but with a ".msk" extension and TIFF format. ex: file:///path/to/image.msk or s3://bucket/image.msk) Examples: Loading informations from parameters, related to a TIFF main image coupled to a TIFF mask image from rok4.raster import Raster try: raster = Raster.from_parameters( path="file:///data/SC1000/_0040_6150_L93.tif", mask="file:///data/SC1000/0040_6150_L93.msk", bands=3, format=ColorFormat.UINT8, dimensions=(2000, 2000), bbox=(40000.000, 5950000.000, 240000.000, 6150000.000) ) except Exception as e: print( f"Cannot load information from parameters : {e}" ) Raises: KeyError: a mandatory argument is missing Returns: Raster: a Raster instance """ self = cls() self.path = path self.bands = bands self.bbox = bbox self.dimensions = dimensions self.format = format self.mask = mask return self
Static methods
def from_file(path: str) ‑> Raster
-
Creates a Raster object from an image
Args
path
:str
- path to the image file/object
Examples
Loading informations from a file stored raster TIFF image
from rok4.raster import Raster try: raster = Raster.from_file( "file:///data/SC1000/0040_6150_L93.tif" ) except Exception as e: print(f"Cannot load information from image : {e}")
Raises
FormatError
- MASK file is not a TIFF
RuntimeError
- raised by OGR/GDAL if anything goes wrong
NotImplementedError
- Storage type not handled
FileNotFoundError
- File or object does not exists
Returns
Raster
- a Raster instance
def from_parameters(path: str, bands: int, bbox: Tuple[float, float, float, float], dimensions: Tuple[int, int], format: ColorFormat, mask: str = None) ‑> Raster
-
Creates a Raster object from parameters
Args
path
:str
- path to the file/object (ex: file:///path/to/image.tif or s3://bucket/image.tif)
bands
:int
- number of color bands (or channels)
bbox
:Tuple[float, float, float, float]
- bounding rectange in the data projection
dimensions
:Tuple[int, int]
- image width and height expressed in pixels
format
:ColorFormat
- numeric format for color values. Bit depth, as bits per channel, can be derived from it.
mask
:str, optionnal
- path to the associated mask, if any, or None (same path as the image, but with a ".msk" extension and TIFF format. ex: file:///path/to/image.msk or s3://bucket/image.msk)
Examples
Loading informations from parameters, related to a TIFF main image coupled to a TIFF mask image
from rok4.raster import Raster try: raster = Raster.from_parameters( path="file:///data/SC1000/_0040_6150_L93.tif", mask="file:///data/SC1000/0040_6150_L93.msk", bands=3, format=ColorFormat.UINT8, dimensions=(2000, 2000), bbox=(40000.000, 5950000.000, 240000.000, 6150000.000) ) except Exception as e: print( f"Cannot load information from parameters : {e}" )
Raises
KeyError
- a mandatory argument is missing
Returns
Raster
- a Raster instance
class RasterSet
-
A structure describing a set of raster data
Attributes
raster_list
:List[Raster]
- List of Raster instances in the set
colors
:Set[Tuple[int, ColorFormat]]
- Set (distinct values) of color properties (bands and format) found in the raster set.
srs
:str
- Name of the set's spatial reference system
bbox
:Tuple[float, float, float, float]
- bounding rectange in the data projection, enclosing the whole set
Expand source code
class RasterSet: """A structure describing a set of raster data Attributes: raster_list (List[Raster]): List of Raster instances in the set colors (Set[Tuple[int, ColorFormat]]): Set (distinct values) of color properties (bands and format) found in the raster set. srs (str): Name of the set's spatial reference system bbox (Tuple[float, float, float, float]): bounding rectange in the data projection, enclosing the whole set """ def __init__(self) -> None: self.bbox = (None, None, None, None) self.colors = set() self.raster_list = [] self.srs = None @classmethod def from_list(cls, path: str, srs: str) -> "RasterSet": """Instanciate a RasterSet from an images list path and a srs Args: path (str): path to the images list file or object (each line in this list contains the path to an image file or object in the set) srs (str): images' coordinates system Examples: Loading informations from a file stored list from rok4.raster import RasterSet try: raster_set = RasterSet.from_list( path="file:///data/SC1000.list", srs="EPSG:3857" ) except Exception as e: print( f"Cannot load information from list file : {e}" ) Raises: RuntimeError: raised by OGR/GDAL if anything goes wrong NotImplementedError: Storage type not handled Returns: RasterSet: a RasterSet instance """ self = cls() self.srs = srs # Chargement de la liste des images (la liste peut être un fichier ou un objet) list_obj = tempfile.NamedTemporaryFile(mode="r", delete=False) list_file = list_obj.name copy(path, f"file://{list_file}") list_obj.close() image_list = [] with open(list_file) as listin: for line in listin: image_path = line.strip(" \t\n\r") image_list.append(image_path) remove(f"file://{list_file}") bbox = [None, None, None, None] for image_path in image_list: raster = Raster.from_file(image_path) self.raster_list.append(raster) # Mise à jour de la bbox globale if bbox == [None, None, None, None]: bbox = list(raster.bbox) else: if bbox[0] > raster.bbox[0]: bbox[0] = raster.bbox[0] if bbox[1] > raster.bbox[1]: bbox[1] = raster.bbox[1] if bbox[2] < raster.bbox[2]: bbox[2] = raster.bbox[2] if bbox[3] < raster.bbox[3]: bbox[3] = raster.bbox[3] # Inventaire des colors distinctes self.colors.add((raster.bands, raster.format)) self.bbox = tuple(bbox) return self @classmethod def from_descriptor(cls, path: str) -> "RasterSet": """Creates a RasterSet object from a descriptor file or object Args: path (str): path to the descriptor file or object Examples: Loading informations from a file stored descriptor from rok4.raster import RasterSet try: raster_set = RasterSet.from_descriptor( "file:///data/images/descriptor.json" ) except Exception as e: message = ("Cannot load information from descriptor file : {e}") print(message) Raises: RuntimeError: raised by OGR/GDAL if anything goes wrong NotImplementedError: Storage type not handled Returns: RasterSet: a RasterSet instance """ self = cls() try: serialization = json.loads(get_data_str(path)) except JSONDecodeError as e: raise FormatError("JSON", path, e) self.srs = serialization["srs"] self.raster_list = [] for raster_dict in serialization["raster_list"]: parameters = deepcopy(raster_dict) parameters["bbox"] = tuple(raster_dict["bbox"]) parameters["dimensions"] = tuple(raster_dict["dimensions"]) parameters["format"] = ColorFormat[raster_dict["format"]] self.raster_list.append(Raster.from_parameters(**parameters)) self.bbox = tuple(serialization["bbox"]) for color_dict in serialization["colors"]: self.colors.add((color_dict["bands"], ColorFormat[color_dict["format"]])) return self @property def serializable(self) -> Dict: """Get the dict version of the raster set, descriptor compliant Returns: Dict: descriptor structured object description """ serialization = {"bbox": list(self.bbox), "srs": self.srs, "colors": [], "raster_list": []} for color in self.colors: color_serial = {"bands": color[0], "format": color[1].name} serialization["colors"].append(color_serial) for raster in self.raster_list: raster_dict = { "path": raster.path, "dimensions": list(raster.dimensions), "bbox": list(raster.bbox), "bands": raster.bands, "format": raster.format.name, } if raster.mask is not None: raster_dict["mask"] = raster.mask serialization["raster_list"].append(raster_dict) return serialization def write_descriptor(self, path: str = None) -> None: """Print raster set's descriptor as JSON Args: path (str, optional): Complete path (file or object) where to print the raster set's JSON. Defaults to None, JSON is printed to standard output. """ content = json.dumps(self.serializable, sort_keys=True) if path is None: print(content) else: put_data_str(content, path)
Static methods
def from_descriptor(path: str) ‑> RasterSet
-
Creates a RasterSet object from a descriptor file or object
Args
path
:str
- path to the descriptor file or object
Examples
Loading informations from a file stored descriptor
from rok4.raster import RasterSet try: raster_set = RasterSet.from_descriptor( "file:///data/images/descriptor.json" ) except Exception as e: message = ("Cannot load information from descriptor file : {e}") print(message)
Raises
RuntimeError
- raised by OGR/GDAL if anything goes wrong
NotImplementedError
- Storage type not handled
Returns
RasterSet
- a RasterSet instance
def from_list(path: str, srs: str) ‑> RasterSet
-
Instanciate a RasterSet from an images list path and a srs
Args
path
:str
- path to the images list file or object (each line in this list contains the path to an image file or object in the set)
srs
:str
- images' coordinates system
Examples
Loading informations from a file stored list
from rok4.raster import RasterSet try: raster_set = RasterSet.from_list( path="file:///data/SC1000.list", srs="EPSG:3857" ) except Exception as e: print( f"Cannot load information from list file : {e}" )
Raises
RuntimeError
- raised by OGR/GDAL if anything goes wrong
NotImplementedError
- Storage type not handled
Returns
RasterSet
- a RasterSet instance
Instance variables
prop serializable : Dict[~KT, ~VT]
-
Get the dict version of the raster set, descriptor compliant
Returns
Dict
- descriptor structured object description
Expand source code
@property def serializable(self) -> Dict: """Get the dict version of the raster set, descriptor compliant Returns: Dict: descriptor structured object description """ serialization = {"bbox": list(self.bbox), "srs": self.srs, "colors": [], "raster_list": []} for color in self.colors: color_serial = {"bands": color[0], "format": color[1].name} serialization["colors"].append(color_serial) for raster in self.raster_list: raster_dict = { "path": raster.path, "dimensions": list(raster.dimensions), "bbox": list(raster.bbox), "bands": raster.bands, "format": raster.format.name, } if raster.mask is not None: raster_dict["mask"] = raster.mask serialization["raster_list"].append(raster_dict) return serialization
Methods
def write_descriptor(self, path: str = None) ‑> None
-
Print raster set's descriptor as JSON
Args
path
:str
, optional- Complete path (file or object) where to print the raster set's JSON. Defaults to None, JSON is printed to standard output.