Module losanalyst.functions.checks
Expand source code
from osgeo import ogr
import warnings
from typing import Union
from gdalhelpers.checks import layer_checks, values_checks
from gdalhelpers.classes.DEM import DEM
import losanalyst.functions.los_field_names as field_names
from losanalyst.functions import helpers
def check_los_layer(layer: ogr.Layer) -> None:
"""
Checks that the `layer` is LoS layer.
Parameters
----------
layer : ogr.Layer
Layer to perform the check on.
Raises
------
ValueError
If the `layer` is not LoS.
"""
if not is_los_layer(layer):
raise ValueError("The provided LoS layer does not provide the necessary attributes. "
"It cannot be correctly processed.")
def is_los_layer(layer: ogr.Layer) -> bool:
"""
Verify, based on presence of specific fields, that the given `layer` contains LoS data.
Parameters
----------
layer : ogr.Layer
Layer to perform the check on.
Returns
-------
bool
"""
result1 = layer_checks.does_field_exist(layer, field_names.observer_id_field_name) and \
layer_checks.does_field_exist(layer, field_names.target_id_field_name)
result2 = layer_checks.does_field_exist(layer, field_names.observer_offset_field_name) and \
layer_checks.does_field_exist(layer, field_names.target_offset_field_name)
return result1 and result2
def is_global_los_layer(layer: ogr.Layer) -> bool:
"""
Verify that the given `layer` contain global LoS data.
Parameters
----------
layer : ogr.Layer
Layer to perform the check on.
Returns
-------
bool
"""
is_global = helpers.get_los_type(layer) == "global"
result = layer_checks.does_field_exist(layer, field_names.tp_x_field_name) and \
layer_checks.does_field_exist(layer, field_names.tp_y_field_name) and \
is_global
return result
def is_los_without_target(layer: ogr.Layer) -> bool:
"""
Verify that the given `layer` contain LoS without target data.
Parameters
----------
layer : ogr.Layer
Layer to perform the check on.
Returns
-------
bool
"""
if helpers.get_los_type(layer) == "without target":
return True
else:
return False
def check_return_sampling_distance(sampling_distance: Union[int, float], dsm: DEM) -> float:
"""
Checks that the provided sampling distance value is valid one, if it is `None` then estimates it based on pixel size
of `dsm`.
Parameters
----------
sampling_distance : int or float
Value of LoS sampling distance. Should be positive number.
dsm : DEM
If the `sampling_distance` is not provided, it is estimated as pixel size of `dsm`.
Returns
-------
float
Sampling distance.
"""
if sampling_distance is not None:
values_checks.check_value_is_zero_or_positive(sampling_distance, "sampling_distance")
return float(sampling_distance)
else:
sampling_distance = dsm.get_min_pixel_size()
return sampling_distance
def check_return_id_field(layer: ogr.Layer,
layer_name: str,
field_name: str) -> str:
"""
Checks if the provided field (`field_name`) exists in `layer`. If it does not or it is not `Integer` data type
outputs warning and sets return value as `None`.
Parameters
----------
layer : ogr.Layer
Layer to verify.
layer_name : str
Layer name for warning messages.
field_name : str
Name of the field to look for.
Returns
-------
str
Either the name of the field or value `None` if does not exists or if it is of incorrect type.
Warns
-------
UserWarning
If the field does not exist or if it is not Integer type.
"""
if field_name is not None:
if not layer_checks.does_field_exist(layer, field_name):
warnings.warn(
"The field `{0}` does not exist in `{1}`, the default gdal FID will be used instead."
.format(field_name, layer_name),
UserWarning
)
field_name = None
elif not layer_checks.is_field_of_type(layer, field_name, ogr.OFTInteger):
warnings.warn(
"The field `{0}` in observers is not an `Integer` type, the default gdal FID will be used instead."
.format(field_name),
UserWarning
)
field_name = None
return field_name
def check_return_set_offset(offset: Union[str, int, float],
offset_name: str,
layer: ogr.Layer,
layer_name: str,
default_offset: float = 1.75):
"""
Checks that `offset` is usable. The `offset` is either `str`, which specifies field name in `layer` from which the
value is obtained, or `float` and `int` which are used directly.
Parameters
----------
offset : str or int or float
Either numerical value or string specifying field name of `layer`.
offset_name : str
Name of the offset for warning messages.
layer : ogr.Layer
Layer to work with.
layer_name : str
Name of the layer for warning messages.
default_offset : float, optional
Offset value to use if the field does not exist. Default value is `1.75`.
Returns
-------
str or float
Either verified name of the field from `layer` or numerical value.
Raises
------
ValueError
If some of the values is not valid.
Warns
-------
UserWarning
If the field does not exist or if it is of non-numerical type.
"""
if not isinstance(default_offset, (float, int)):
raise ValueError("The `default_offset` variable is not either `int` or `float`. It is: `{0}`."
.format(type(default_offset).__name__))
if isinstance(offset, str):
if not layer_checks.does_field_exist(layer, offset):
warnings.warn(
"`{0}` `{1}` does not exist in `{2}` layer, the default value of offset `{3}` will be used."
.format(offset_name, offset, layer_name, default_offset),
UserWarning
)
return default_offset
elif not (layer_checks.is_field_of_type(layer, offset, ogr.OFTInteger) or
layer_checks.is_field_of_type(layer, offset, ogr.OFTReal)):
warnings.warn(
"`{0}` field `{1}` is not either `Integer` or `Real` in `{2}` layer, "
"the default value of offset `{3}` will be used."
.format(offset_name, offset, layer_name, default_offset),
UserWarning
)
return default_offset
else:
return offset
elif isinstance(offset, (int, float)):
return offset
else:
raise ValueError("The `{0}` is not either string or number.".format(offset_name))
Functions
def check_los_layer(layer)
-
Checks that the
layer
is LoS layer.Parameters
layer
:ogr.Layer
- Layer to perform the check on.
Raises
ValueError
- If the
layer
is not LoS.
Expand source code
def check_los_layer(layer: ogr.Layer) -> None: """ Checks that the `layer` is LoS layer. Parameters ---------- layer : ogr.Layer Layer to perform the check on. Raises ------ ValueError If the `layer` is not LoS. """ if not is_los_layer(layer): raise ValueError("The provided LoS layer does not provide the necessary attributes. " "It cannot be correctly processed.")
def check_return_id_field(layer, layer_name, field_name)
-
Checks if the provided field (
field_name
) exists inlayer
. If it does not or it is notInteger
data type outputs warning and sets return value asNone
.Parameters
layer
:ogr.Layer
- Layer to verify.
layer_name
:str
- Layer name for warning messages.
field_name
:str
- Name of the field to look for.
Returns
str
- Either the name of the field or value
None
if does not exists or if it is of incorrect type.
Warns
UserWarning
- If the field does not exist or if it is not Integer type.
Expand source code
def check_return_id_field(layer: ogr.Layer, layer_name: str, field_name: str) -> str: """ Checks if the provided field (`field_name`) exists in `layer`. If it does not or it is not `Integer` data type outputs warning and sets return value as `None`. Parameters ---------- layer : ogr.Layer Layer to verify. layer_name : str Layer name for warning messages. field_name : str Name of the field to look for. Returns ------- str Either the name of the field or value `None` if does not exists or if it is of incorrect type. Warns ------- UserWarning If the field does not exist or if it is not Integer type. """ if field_name is not None: if not layer_checks.does_field_exist(layer, field_name): warnings.warn( "The field `{0}` does not exist in `{1}`, the default gdal FID will be used instead." .format(field_name, layer_name), UserWarning ) field_name = None elif not layer_checks.is_field_of_type(layer, field_name, ogr.OFTInteger): warnings.warn( "The field `{0}` in observers is not an `Integer` type, the default gdal FID will be used instead." .format(field_name), UserWarning ) field_name = None return field_name
def check_return_sampling_distance(sampling_distance, dsm)
-
Checks that the provided sampling distance value is valid one, if it is
None
then estimates it based on pixel size ofdsm
.Parameters
sampling_distance
:int
orfloat
- Value of LoS sampling distance. Should be positive number.
dsm
:DEM
- If the
sampling_distance
is not provided, it is estimated as pixel size ofdsm
.
Returns
float
- Sampling distance.
Expand source code
def check_return_sampling_distance(sampling_distance: Union[int, float], dsm: DEM) -> float: """ Checks that the provided sampling distance value is valid one, if it is `None` then estimates it based on pixel size of `dsm`. Parameters ---------- sampling_distance : int or float Value of LoS sampling distance. Should be positive number. dsm : DEM If the `sampling_distance` is not provided, it is estimated as pixel size of `dsm`. Returns ------- float Sampling distance. """ if sampling_distance is not None: values_checks.check_value_is_zero_or_positive(sampling_distance, "sampling_distance") return float(sampling_distance) else: sampling_distance = dsm.get_min_pixel_size() return sampling_distance
def check_return_set_offset(offset, offset_name, layer, layer_name, default_offset=1.75)
-
Checks that
offset
is usable. Theoffset
is eitherstr
, which specifies field name inlayer
from which the value is obtained, orfloat
andint
which are used directly.Parameters
offset
:str
orint
orfloat
- Either numerical value or string specifying field name of
layer
. offset_name
:str
- Name of the offset for warning messages.
layer
:ogr.Layer
- Layer to work with.
layer_name
:str
- Name of the layer for warning messages.
default_offset
:float
, optional- Offset value to use if the field does not exist. Default value is
1.75
.
Returns
str
orfloat
- Either verified name of the field from
layer
or numerical value.
Raises
ValueError
- If some of the values is not valid.
Warns
UserWarning
- If the field does not exist or if it is of non-numerical type.
Expand source code
def check_return_set_offset(offset: Union[str, int, float], offset_name: str, layer: ogr.Layer, layer_name: str, default_offset: float = 1.75): """ Checks that `offset` is usable. The `offset` is either `str`, which specifies field name in `layer` from which the value is obtained, or `float` and `int` which are used directly. Parameters ---------- offset : str or int or float Either numerical value or string specifying field name of `layer`. offset_name : str Name of the offset for warning messages. layer : ogr.Layer Layer to work with. layer_name : str Name of the layer for warning messages. default_offset : float, optional Offset value to use if the field does not exist. Default value is `1.75`. Returns ------- str or float Either verified name of the field from `layer` or numerical value. Raises ------ ValueError If some of the values is not valid. Warns ------- UserWarning If the field does not exist or if it is of non-numerical type. """ if not isinstance(default_offset, (float, int)): raise ValueError("The `default_offset` variable is not either `int` or `float`. It is: `{0}`." .format(type(default_offset).__name__)) if isinstance(offset, str): if not layer_checks.does_field_exist(layer, offset): warnings.warn( "`{0}` `{1}` does not exist in `{2}` layer, the default value of offset `{3}` will be used." .format(offset_name, offset, layer_name, default_offset), UserWarning ) return default_offset elif not (layer_checks.is_field_of_type(layer, offset, ogr.OFTInteger) or layer_checks.is_field_of_type(layer, offset, ogr.OFTReal)): warnings.warn( "`{0}` field `{1}` is not either `Integer` or `Real` in `{2}` layer, " "the default value of offset `{3}` will be used." .format(offset_name, offset, layer_name, default_offset), UserWarning ) return default_offset else: return offset elif isinstance(offset, (int, float)): return offset else: raise ValueError("The `{0}` is not either string or number.".format(offset_name))
def is_global_los_layer(layer)
-
Verify that the given
layer
contain global LoS data.Parameters
layer
:ogr.Layer
- Layer to perform the check on.
Returns
bool
Expand source code
def is_global_los_layer(layer: ogr.Layer) -> bool: """ Verify that the given `layer` contain global LoS data. Parameters ---------- layer : ogr.Layer Layer to perform the check on. Returns ------- bool """ is_global = helpers.get_los_type(layer) == "global" result = layer_checks.does_field_exist(layer, field_names.tp_x_field_name) and \ layer_checks.does_field_exist(layer, field_names.tp_y_field_name) and \ is_global return result
def is_los_layer(layer)
-
Verify, based on presence of specific fields, that the given
layer
contains LoS data.Parameters
layer
:ogr.Layer
- Layer to perform the check on.
Returns
bool
Expand source code
def is_los_layer(layer: ogr.Layer) -> bool: """ Verify, based on presence of specific fields, that the given `layer` contains LoS data. Parameters ---------- layer : ogr.Layer Layer to perform the check on. Returns ------- bool """ result1 = layer_checks.does_field_exist(layer, field_names.observer_id_field_name) and \ layer_checks.does_field_exist(layer, field_names.target_id_field_name) result2 = layer_checks.does_field_exist(layer, field_names.observer_offset_field_name) and \ layer_checks.does_field_exist(layer, field_names.target_offset_field_name) return result1 and result2
def is_los_without_target(layer)
-
Verify that the given
layer
contain LoS without target data.Parameters
layer
:ogr.Layer
- Layer to perform the check on.
Returns
bool
Expand source code
def is_los_without_target(layer: ogr.Layer) -> bool: """ Verify that the given `layer` contain LoS without target data. Parameters ---------- layer : ogr.Layer Layer to perform the check on. Returns ------- bool """ if helpers.get_los_type(layer) == "without target": return True else: return False