#! /usr/bin/env python

'''
Python Interface to SAGA Tools Library
----------
- Category : Terrain Analysis
- Name     : Lighting, Visibility
- ID       : ta_lighting

Description
----------
Lighting and visibility calculations for digital terrain models.
'''

from PySAGA.helper import Tool_Wrapper

def Run_Analytical_Hillshading(ELEVATION=None, SHADE=None, METHOD=None, POSITION=None, AZIMUTH=None, DECLINATION=None, DATE=None, TIME=None, EXAGGERATION=None, UNIT=None, SHADOW=None, NDIRS=None, RADIUS=None, Verbose=2):
    '''
    Analytical Hillshading
    ----------
    [ta_lighting.0]\n
    This tool performs an analytical hillshade computation for an elevation grid. The 'Standard' method simply calculates the angle at which light coming from the position of the light source would hit the surface. This method can produce angles greater than 90 degree. With the second method all values are kept within the range of 0-90 degree. It can be enhanced with shadowing effects, where shadowed cells will be marked with a value of exactly 90 degree. 'Shadows Only' creates a mask for the shadowed areas and sets all other cells to no-data. 'Combined Shading' takes the values of the standard method and multiplies these with the normalized slope. 'Ambient Occlusion' is based on the concepts of Tarini et al. (2006), but only the northern half-space is considered here.\n
    Arguments
    ----------
    - ELEVATION [`input grid`] : Elevation
    - SHADE [`output grid`] : Analytical Hillshading. The angle between the surface and the incoming light beams, measured in radians.
    - METHOD [`choice`] : Shading Method. Available Choices: [0] Standard [1] Limited Maximum [2] With Shadows [3] Shadows Only [4] Ambient Occlusion [5] Combined Shading Default: 0
    - POSITION [`choice`] : Sun's Position. Available Choices: [0] azimuth and height [1] date and time Default: 0
    - AZIMUTH [`floating point number`] : Azimuth. Minimum: 0.000000 Maximum: 360.000000 Default: 315.000000 Direction of the light source, measured in degree clockwise from the North direction.
    - DECLINATION [`floating point number`] : Height. Minimum: 0.000000 Maximum: 90.000000 Default: 45.000000 Height of the light source, measured in degree above the horizon.
    - DATE [`date`] : Day. Default: 2023-10-06
    - TIME [`floating point number`] : Hour. Minimum: 0.000000 Maximum: 24.000000 Default: 12.000000
    - EXAGGERATION [`floating point number`] : Exaggeration. Default: 1.000000 The terrain exaggeration factor allows one to increase the shading contrasts in flat areas.
    - UNIT [`choice`] : Unit. Available Choices: [0] radians [1] degree Default: 0
    - SHADOW [`choice`] : Shadow. Available Choices: [0] slim [1] fat Default: 1 Choose 'slim' to trace grid node's shadow, 'fat' to trace the whole cell's shadow. The first is slightly faster but might show some artifacts.
    - NDIRS [`integer number`] : Number of Directions. Minimum: 2 Default: 8 Number of sample directions for ambient occlusion. Divides azimuth range (270 to 0 to 90 degree) into sectors. Declination (0 to 90 degree) is divided in (Number of Directions / 4) sectors.
    - RADIUS [`floating point number`] : Search Radius. Minimum: 0.001000 Default: 10.000000 Radius used to trace for shadows (ambient occlusion) [map units].

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_lighting', '0', 'Analytical Hillshading')
    if Tool.is_Okay():
        Tool.Set_Input ('ELEVATION', ELEVATION)
        Tool.Set_Output('SHADE', SHADE)
        Tool.Set_Option('METHOD', METHOD)
        Tool.Set_Option('POSITION', POSITION)
        Tool.Set_Option('AZIMUTH', AZIMUTH)
        Tool.Set_Option('DECLINATION', DECLINATION)
        Tool.Set_Option('DATE', DATE)
        Tool.Set_Option('TIME', TIME)
        Tool.Set_Option('EXAGGERATION', EXAGGERATION)
        Tool.Set_Option('UNIT', UNIT)
        Tool.Set_Option('SHADOW', SHADOW)
        Tool.Set_Option('NDIRS', NDIRS)
        Tool.Set_Option('RADIUS', RADIUS)
        return Tool.Execute(Verbose)
    return False

def Run_Potential_Incoming_Solar_Radiation(GRD_DEM=None, GRD_SVF=None, GRD_VAPOUR=None, GRD_LINKE=None, GRD_DIRECT=None, GRD_DIFFUS=None, GRD_TOTAL=None, GRD_RATIO=None, GRD_FLAT=None, GRD_DURATION=None, GRD_SUNRISE=None, GRD_SUNSET=None, GRD_VAPOUR_DEFAULT=None, GRD_LINKE_DEFAULT=None, SOLARCONST=None, LOCALSVF=None, UNITS=None, SHADOW=None, LOCATION=None, LATITUDE=None, PERIOD=None, DAY=None, DAY_STOP=None, DAYS_STEP=None, MOMENT=None, HOUR_RANGE=None, HOUR_STEP=None, METHOD=None, ATMOSPHERE=None, PRESSURE=None, WATER=None, DUST=None, LUMPED=None, Verbose=2):
    '''
    Potential Incoming Solar Radiation
    ----------
    [ta_lighting.2]\n
    Calculation of potential incoming solar radiation (insolation). Times of sunrise/sunset will only be calculated if time span is set to single day.\n
    Most options should do well, but TAPES-G based diffuse irradiance calculation ('Atmospheric Effects' methods 2 and 3) needs further revision!\n
    Arguments
    ----------
    - GRD_DEM [`input grid`] : Elevation
    - GRD_SVF [`optional input grid`] : Sky View Factor
    - GRD_VAPOUR [`optional input grid`] : Water Vapour Pressure [mbar]
    - GRD_LINKE [`optional input grid`] : Linke Turbidity Coefficient
    - GRD_DIRECT [`output grid`] : Direct Insolation
    - GRD_DIFFUS [`output grid`] : Diffuse Insolation
    - GRD_TOTAL [`output grid`] : Total Insolation
    - GRD_RATIO [`output grid`] : Direct to Diffuse Ratio
    - GRD_FLAT [`output grid`] : Compare to Flat Terrain
    - GRD_DURATION [`output grid`] : Duration of Insolation
    - GRD_SUNRISE [`output grid`] : Sunrise
    - GRD_SUNSET [`output grid`] : Sunset
    - GRD_VAPOUR_DEFAULT [`floating point number`] : Default. Minimum: 0.000000 Default: 10.000000 default value if no grid has been selected
    - GRD_LINKE_DEFAULT [`floating point number`] : Default. Minimum: 0.000000 Default: 3.000000 default value if no grid has been selected
    - SOLARCONST [`floating point number`] : Solar Constant [W/m²]. Minimum: 0.000000 Default: 1367.000000
    - LOCALSVF [`boolean`] : Local Sky View Factor. Default: 1 Use sky view factor based on local slope (after Oke 1988), if no sky viev factor grid is given.
    - UNITS [`choice`] : Units. Available Choices: [0] [kWh/m²] [1] [kJ/m²] [2] [J/cm²] Default: 0 Units for output radiation values.
    - SHADOW [`choice`] : Shadow. Available Choices: [0] slim [1] fat [2] none Default: 1 Choose 'slim' to trace grid node's shadow, 'fat' to trace the whole cell's shadow, or ignore shadowing effects. The first is slightly faster but might show some artifacts.
    - LOCATION [`choice`] : Location. Available Choices: [0] constant latitude [1] calculate from grid system Default: 0
    - LATITUDE [`degree`] : Latitude. Minimum: -90.000000 Maximum: 90.000000 Default: 53.000000
    - PERIOD [`choice`] : Time Period. Available Choices: [0] moment [1] day [2] range of days Default: 1
    - DAY [`date`] : Day. Default: 2023-10-06
    - DAY_STOP [`date`] : Last Day. Default: 2023-10-06
    - DAYS_STEP [`integer number`] : Resolution [d]. Minimum: 1 Default: 5 Time step size for a range of days calculation given in days.
    - MOMENT [`floating point number`] : Moment [h]. Minimum: 0.000000 Maximum: 24.000000 Default: 12.000000
    - HOUR_RANGE [`value range`] : Time Span [h]. Time span used for the calculation of daily radiation sums.
    - HOUR_STEP [`floating point number`] : Resolution [h]. Minimum: 0.000000 Maximum: 24.000000 Default: 0.500000 Time step size for a day's calculation given in hours.
    - METHOD [`choice`] : Atmospheric Effects. Available Choices: [0] Height of Atmosphere and Vapour Pressure [1] Air Pressure, Water and Dust Content [2] Lumped Atmospheric Transmittance [3] Hofierka and Šúri Default: 2
    - ATMOSPHERE [`floating point number`] : Height of Atmosphere [m]. Minimum: 0.000000 Default: 12000.000000
    - PRESSURE [`floating point number`] : Barometric Pressure [mbar]. Minimum: 0.000000 Default: 1013.000000
    - WATER [`floating point number`] : Water Content [cm]. Minimum: 0.000000 Default: 1.680000 Water content of a vertical slice of atmosphere in cm: 1.5 to 1.7, average=1.68
    - DUST [`floating point number`] : Dust [ppm]. Minimum: 0.000000 Default: 100.000000 Dust factor: 100 ppm (standard)
    - LUMPED [`floating point number`] : Lumped Atmospheric Transmittance [Percent]. Minimum: 0.000000 Maximum: 100.000000 Default: 70.000000 The transmittance of the atmosphere, usually between 60 and 80 percent.

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_lighting', '2', 'Potential Incoming Solar Radiation')
    if Tool.is_Okay():
        Tool.Set_Input ('GRD_DEM', GRD_DEM)
        Tool.Set_Input ('GRD_SVF', GRD_SVF)
        Tool.Set_Input ('GRD_VAPOUR', GRD_VAPOUR)
        Tool.Set_Input ('GRD_LINKE', GRD_LINKE)
        Tool.Set_Output('GRD_DIRECT', GRD_DIRECT)
        Tool.Set_Output('GRD_DIFFUS', GRD_DIFFUS)
        Tool.Set_Output('GRD_TOTAL', GRD_TOTAL)
        Tool.Set_Output('GRD_RATIO', GRD_RATIO)
        Tool.Set_Output('GRD_FLAT', GRD_FLAT)
        Tool.Set_Output('GRD_DURATION', GRD_DURATION)
        Tool.Set_Output('GRD_SUNRISE', GRD_SUNRISE)
        Tool.Set_Output('GRD_SUNSET', GRD_SUNSET)
        Tool.Set_Option('GRD_VAPOUR_DEFAULT', GRD_VAPOUR_DEFAULT)
        Tool.Set_Option('GRD_LINKE_DEFAULT', GRD_LINKE_DEFAULT)
        Tool.Set_Option('SOLARCONST', SOLARCONST)
        Tool.Set_Option('LOCALSVF', LOCALSVF)
        Tool.Set_Option('UNITS', UNITS)
        Tool.Set_Option('SHADOW', SHADOW)
        Tool.Set_Option('LOCATION', LOCATION)
        Tool.Set_Option('LATITUDE', LATITUDE)
        Tool.Set_Option('PERIOD', PERIOD)
        Tool.Set_Option('DAY', DAY)
        Tool.Set_Option('DAY_STOP', DAY_STOP)
        Tool.Set_Option('DAYS_STEP', DAYS_STEP)
        Tool.Set_Option('MOMENT', MOMENT)
        Tool.Set_Option('HOUR_RANGE', HOUR_RANGE)
        Tool.Set_Option('HOUR_STEP', HOUR_STEP)
        Tool.Set_Option('METHOD', METHOD)
        Tool.Set_Option('ATMOSPHERE', ATMOSPHERE)
        Tool.Set_Option('PRESSURE', PRESSURE)
        Tool.Set_Option('WATER', WATER)
        Tool.Set_Option('DUST', DUST)
        Tool.Set_Option('LUMPED', LUMPED)
        return Tool.Execute(Verbose)
    return False

def Run_Sky_View_Factor(DEM=None, VISIBLE=None, SVF=None, SIMPLE=None, TERRAIN=None, DISTANCE=None, RADIUS=None, NDIRS=None, METHOD=None, DLEVEL=None, Verbose=2):
    '''
    Sky View Factor
    ----------
    [ta_lighting.3]\n
    Calculation of visible sky, sky view factor (SVF) and related parameters.\n
    Arguments
    ----------
    - DEM [`input grid`] : Elevation
    - VISIBLE [`output grid`] : Visible Sky. The unobstructed hemisphere given as percentage.
    - SVF [`output grid`] : Sky View Factor
    - SIMPLE [`output grid`] : Sky View Factor (Simplified)
    - TERRAIN [`output grid`] : Terrain View Factor
    - DISTANCE [`output grid`] : Average View Distance. Average distance to horizon.
    - RADIUS [`floating point number`] : Maximum Search Radius. Minimum: 0.000000 Default: 10000.000000 The maximum search radius [map units]. This value is ignored if set to zero.
    - NDIRS [`integer number`] : Number of Sectors. Minimum: 3 Default: 8
    - METHOD [`choice`] : Method. Available Choices: [0] cell size [1] multi scale Default: 0
    - DLEVEL [`floating point number`] : Multi Scale Factor. Minimum: 1.250000 Default: 3.000000

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_lighting', '3', 'Sky View Factor')
    if Tool.is_Okay():
        Tool.Set_Input ('DEM', DEM)
        Tool.Set_Output('VISIBLE', VISIBLE)
        Tool.Set_Output('SVF', SVF)
        Tool.Set_Output('SIMPLE', SIMPLE)
        Tool.Set_Output('TERRAIN', TERRAIN)
        Tool.Set_Output('DISTANCE', DISTANCE)
        Tool.Set_Option('RADIUS', RADIUS)
        Tool.Set_Option('NDIRS', NDIRS)
        Tool.Set_Option('METHOD', METHOD)
        Tool.Set_Option('DLEVEL', DLEVEL)
        return Tool.Execute(Verbose)
    return False

def Run_Topographic_Openness(DEM=None, POS=None, NEG=None, RADIUS=None, DIRECTIONS=None, DIRECTION=None, NDIRS=None, METHOD=None, DLEVEL=None, UNIT=None, NADIR=None, Verbose=2):
    '''
    Topographic Openness
    ----------
    [ta_lighting.5]\n
    Topographic openness expresses the dominance (positive) or enclosure (negative) of a landscape location. See Yokoyama et al. (2002) for a precise definition. Openness has been related to how wide a landscape can be viewed from any position. It has been proven to be a meaningful input for computer aided geomorphological mapping.\n
    Arguments
    ----------
    - DEM [`input grid`] : Elevation
    - POS [`output grid`] : Positive Openness
    - NEG [`output grid`] : Negative Openness
    - RADIUS [`floating point number`] : Radial Limit. Minimum: 0.000000 Default: 10000.000000 Maximum search distance [map units].
    - DIRECTIONS [`choice`] : Directions. Available Choices: [0] single [1] all Default: 1
    - DIRECTION [`floating point number`] : Direction. Minimum: -360.000000 Maximum: 360.000000 Default: 315.000000 Single direction given as degree measured clockwise from the North direction.
    - NDIRS [`integer number`] : Number of Sectors. Minimum: 4 Default: 8
    - METHOD [`choice`] : Method. Available Choices: [0] multi scale [1] line tracing Default: 1
    - DLEVEL [`floating point number`] : Multi Scale Factor. Minimum: 1.250000 Default: 3.000000
    - UNIT [`choice`] : Unit. Available Choices: [0] Radians [1] Degree Default: 0
    - NADIR [`boolean`] : Difference from Nadir. Default: 1 If set, output angles are the mean difference from nadir, or else from a plane.

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_lighting', '5', 'Topographic Openness')
    if Tool.is_Okay():
        Tool.Set_Input ('DEM', DEM)
        Tool.Set_Output('POS', POS)
        Tool.Set_Output('NEG', NEG)
        Tool.Set_Option('RADIUS', RADIUS)
        Tool.Set_Option('DIRECTIONS', DIRECTIONS)
        Tool.Set_Option('DIRECTION', DIRECTION)
        Tool.Set_Option('NDIRS', NDIRS)
        Tool.Set_Option('METHOD', METHOD)
        Tool.Set_Option('DLEVEL', DLEVEL)
        Tool.Set_Option('UNIT', UNIT)
        Tool.Set_Option('NADIR', NADIR)
        return Tool.Execute(Verbose)
    return False

def Run_Visibility_Analysis(ELEVATION=None, POINTS=None, VISIBILITY=None, METHOD=None, UNIT=None, CUMULATIVE=None, NODATA=None, HEIGHT=None, HEIGHT_DEFAULT=None, Verbose=2):
    '''
    Visibility Analysis
    ----------
    [ta_lighting.6]\n
    This tool performs a visibility analysis using light source or observer points from a points layer.\n
    Arguments
    ----------
    - ELEVATION [`input grid`] : Elevation
    - POINTS [`input shapes`] : Points. Observer points.
    - VISIBILITY [`output grid`] : Visibility
    - METHOD [`choice`] : Output. Available Choices: [0] Visibility [1] Shade [2] Distance [3] Size Default: 3
    - UNIT [`choice`] : Unit. Available Choices: [0] radians [1] degree Default: 1
    - CUMULATIVE [`boolean`] : Cumulative. Default: 0 If not set, output is the maximum size, or the cumulated sizes otherwise.
    - NODATA [`boolean`] : Ignore No-Data. Default: 0 Ignore elevations that have been marked as no-data.
    - HEIGHT [`table field`] : Height. Height of the light source or observer above ground.
    - HEIGHT_DEFAULT [`floating point number`] : Default. Minimum: 0.000000 Default: 10.000000 default value if no attribute has been selected

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_lighting', '6', 'Visibility Analysis')
    if Tool.is_Okay():
        Tool.Set_Input ('ELEVATION', ELEVATION)
        Tool.Set_Input ('POINTS', POINTS)
        Tool.Set_Output('VISIBILITY', VISIBILITY)
        Tool.Set_Option('METHOD', METHOD)
        Tool.Set_Option('UNIT', UNIT)
        Tool.Set_Option('CUMULATIVE', CUMULATIVE)
        Tool.Set_Option('NODATA', NODATA)
        Tool.Set_Option('HEIGHT', HEIGHT)
        Tool.Set_Option('HEIGHT_DEFAULT', HEIGHT_DEFAULT)
        return Tool.Execute(Verbose)
    return False

def Run_Potential_Annual_Insolation(DEM=None, INSOLATION=None, STEPS=None, UNITS=None, HOUR_STEP=None, YEAR=None, Verbose=2):
    '''
    Potential Annual Insolation
    ----------
    [ta_lighting.7]\n
    Calculates the annual potential total insolation for given time steps and stores resulting time series in a grid collection.\n
    Arguments
    ----------
    - DEM [`input grid`] : Elevation
    - INSOLATION [`output grid collection`] : Annual Insolation
    - STEPS [`integer number`] : Number of Steps. Minimum: 2 Maximum: 365 Default: 14 Number of time steps per year.
    - UNITS [`choice`] : Units. Available Choices: [0] kWh / m2 [1] kJ / m2 [2] J / cm2 Default: 0 Units for output radiation values.
    - HOUR_STEP [`floating point number`] : Resolution [h]. Minimum: 0.000000 Maximum: 24.000000 Default: 0.500000 Time step size for a day's calculation given in hours.
    - YEAR [`integer number`] : Reference Year. Default: 2000

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_lighting', '7', 'Potential Annual Insolation')
    if Tool.is_Okay():
        Tool.Set_Input ('DEM', DEM)
        Tool.Set_Output('INSOLATION', INSOLATION)
        Tool.Set_Option('STEPS', STEPS)
        Tool.Set_Option('UNITS', UNITS)
        Tool.Set_Option('HOUR_STEP', HOUR_STEP)
        Tool.Set_Option('YEAR', YEAR)
        return Tool.Execute(Verbose)
    return False

def Run_Geomorphons(DEM=None, GEOMORPHONS=None, THRESHOLD=None, RADIUS=None, METHOD=None, DLEVEL=None, Verbose=2):
    '''
    Geomorphons
    ----------
    [ta_lighting.8]\n
    This tool derives so called geomorphons, which represent categories of terrain forms, from a digital elevation model using a machine vision approach.\n
    Arguments
    ----------
    - DEM [`input grid`] : Elevation
    - GEOMORPHONS [`output grid`] : Geomorphons
    - THRESHOLD [`floating point number`] : Threshold Angle. Minimum: 0.000000 Default: 1.000000 Flatness threshold angle (degrees).
    - RADIUS [`floating point number`] : Radial Limit. Minimum: 0.000000 Default: 10000.000000
    - METHOD [`choice`] : Method. Available Choices: [0] multi scale [1] line tracing Default: 1
    - DLEVEL [`floating point number`] : Multi Scale Factor. Minimum: 1.250000 Default: 3.000000

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_lighting', '8', 'Geomorphons')
    if Tool.is_Okay():
        Tool.Set_Input ('DEM', DEM)
        Tool.Set_Output('GEOMORPHONS', GEOMORPHONS)
        Tool.Set_Option('THRESHOLD', THRESHOLD)
        Tool.Set_Option('RADIUS', RADIUS)
        Tool.Set_Option('METHOD', METHOD)
        Tool.Set_Option('DLEVEL', DLEVEL)
        return Tool.Execute(Verbose)
    return False

