#! /usr/bin/env python

'''
Python Interface to SAGA Tools Library
----------
- Category : Imagery
- Name     : Photogrammetry
- ID       : imagery_photogrammetry

Description
----------
Photogrammetry tools.
'''

from PySAGA.helper import Tool_Wrapper

def Resection_Terrestrial(POINTS=None, F=None, W=None, EST_OFFSETS=None, PPX=None, PPY=None, GIVE_DISTORTIONS=None, K1=None, K2=None, K3=None, Xc=None, Yc=None, Zc=None, Xt=None, Yt=None, Zt=None, OUTPUT_FILE=None, Verbose=2):
    '''
    Resection (Terrestrial)
    ----------
    [imagery_photogrammetry.0]\n
    Single Image Spatial Resection (Terrestrial): from at least 3 image points with known coordinates, the Cardan angles of the image orientation and the coordinates of the perspective center are calculated by a least-squares adjustment. The Cardan angles refer to the following transformation between image coordinates (x_image) and global coordinates (X_Global):\n
    x_image = R_1(omega) * R_2(kappa) * R_3(alpha) * X_Global\n
    Here R_1, R_2, R_3 denote rotation matrices of a right-handed (passive) coordinate transformation.\n
    The inputs consist of a point cloud containing the identical points with their pixel indices as additional attributes. The origin of pixels is in the lower left corner of the image. The interior orientation parameters of the camera is to be provided. These include Focal Length (mm), Pixel Size (um), Principal Point Offsets (pixels) and optionally the Radial Distortion Parameters. The distortion model being used is as follows:\n
    x_d = x_u (1 - dR)\n
    y_d = y_u (1 - dR)\n
    where, dR = K1 * r_u ^ 2 + K2 * r_u ^ 4 + K3 * r_u ^ 6,\n
    r_u ^ 2  = x_u ^ 2 + y_u ^ 2,\n
    x_u, y_u are the undistorted (corrected) image coordinates in mm,\n
    x_d, y_d are the distorted (observed) image coordinates in mm,\n
    K1 is in [mm ^ -2], K2 is in [mm ^ -4],  K3 is in [mm ^ -6].\n
    Approximate coordinates in [m] for the Projection Center and the center of image are also to be provided.\n
    Following the adjustment the results are written to a text file. The main contents of the text file are: for each iteration the Sum of Squared Residuals, the A-Posteriori Standard Deviation (Sigma Naught) and the Condition of Normal Matrix, and the final estimated exterior orientation parameters (Xc, Yc, Zc, Omega, Kappa, Alpha).\n
    Optionally the Principal Point Offsets can be estimated. This requires at least 4 image points as input.\n
    [Warning] The tool is dedicated to the terrestrial case which means the viewing direction must be sufficiently different from the vertical direction.\n
    The estimation of Principal Point Offsets is not recommended if the condition of the Normal Matrix is less than 10 ^ -7.\n
    Arguments
    ----------
    - POINTS [`input point cloud`] : Measured Points (PC). List of Measured Points as PC
    - F [`floating point number`] : Focal Length (mm). Default: 0.000000 Focal Length in mm
    - W [`floating point number`] : Pixel Width (um). Default: 0.000000 Pixel Width in micro meters
    - EST_OFFSETS [`boolean`] : Estimate Principal Point Offsets?. Default: 0 Do you wish to estimate Principal Point Offsets?
    - PPX [`floating point number`] : Principal Point Offset in X (pixels). Default: 0.000000 Principal Point Offset in X
    - PPY [`floating point number`] : Principal Point Offset in Y (pixels). Default: 0.000000 Principal Point Offset in Y
    - GIVE_DISTORTIONS [`boolean`] : Provide Radial Distortion Parameters?. Default: 0 Do you wish to provide the Radial Distortion Parameters?
    - K1 [`floating point number`] : K1. Default: 0.000000 K1
    - K2 [`floating point number`] : K2. Default: 0.000000 K2
    - K3 [`floating point number`] : K3. Default: 0.000000 K3
    - Xc [`floating point number`] : X. Default: 0.000000 Approximate Coordinate
    - Yc [`floating point number`] : Y. Default: 0.000000 Approximate Coordinate
    - Zc [`floating point number`] : Z. Default: 0.000000 Approximate Coordinate
    - Xt [`floating point number`] : X. Default: 0.000000 Approximate Coordinate
    - Yt [`floating point number`] : Y. Default: 0.000000 Approximate Coordinate
    - Zt [`floating point number`] : Z. Default: 0.000000 Approximate Coordinate
    - OUTPUT_FILE [`file path`] : Output Text File. The file to write the Calculation Results to.

    - 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('imagery_photogrammetry', '0', 'Resection (Terrestrial)')
    if Tool.is_Okay():
        Tool.Set_Input ('POINTS', POINTS)
        Tool.Set_Option('F', F)
        Tool.Set_Option('W', W)
        Tool.Set_Option('EST_OFFSETS', EST_OFFSETS)
        Tool.Set_Option('ppX', PPX)
        Tool.Set_Option('ppY', PPY)
        Tool.Set_Option('GIVE_DISTORTIONS', GIVE_DISTORTIONS)
        Tool.Set_Option('K1', K1)
        Tool.Set_Option('K2', K2)
        Tool.Set_Option('K3', K3)
        Tool.Set_Option('Xc', Xc)
        Tool.Set_Option('Yc', Yc)
        Tool.Set_Option('Zc', Zc)
        Tool.Set_Option('Xt', Xt)
        Tool.Set_Option('Yt', Yt)
        Tool.Set_Option('Zt', Zt)
        Tool.Set_Option('OUTPUT FILE', OUTPUT_FILE)
        return Tool.Execute(Verbose)
    return False

def run_tool_imagery_photogrammetry_0(POINTS=None, F=None, W=None, EST_OFFSETS=None, PPX=None, PPY=None, GIVE_DISTORTIONS=None, K1=None, K2=None, K3=None, Xc=None, Yc=None, Zc=None, Xt=None, Yt=None, Zt=None, OUTPUT_FILE=None, Verbose=2):
    '''
    Resection (Terrestrial)
    ----------
    [imagery_photogrammetry.0]\n
    Single Image Spatial Resection (Terrestrial): from at least 3 image points with known coordinates, the Cardan angles of the image orientation and the coordinates of the perspective center are calculated by a least-squares adjustment. The Cardan angles refer to the following transformation between image coordinates (x_image) and global coordinates (X_Global):\n
    x_image = R_1(omega) * R_2(kappa) * R_3(alpha) * X_Global\n
    Here R_1, R_2, R_3 denote rotation matrices of a right-handed (passive) coordinate transformation.\n
    The inputs consist of a point cloud containing the identical points with their pixel indices as additional attributes. The origin of pixels is in the lower left corner of the image. The interior orientation parameters of the camera is to be provided. These include Focal Length (mm), Pixel Size (um), Principal Point Offsets (pixels) and optionally the Radial Distortion Parameters. The distortion model being used is as follows:\n
    x_d = x_u (1 - dR)\n
    y_d = y_u (1 - dR)\n
    where, dR = K1 * r_u ^ 2 + K2 * r_u ^ 4 + K3 * r_u ^ 6,\n
    r_u ^ 2  = x_u ^ 2 + y_u ^ 2,\n
    x_u, y_u are the undistorted (corrected) image coordinates in mm,\n
    x_d, y_d are the distorted (observed) image coordinates in mm,\n
    K1 is in [mm ^ -2], K2 is in [mm ^ -4],  K3 is in [mm ^ -6].\n
    Approximate coordinates in [m] for the Projection Center and the center of image are also to be provided.\n
    Following the adjustment the results are written to a text file. The main contents of the text file are: for each iteration the Sum of Squared Residuals, the A-Posteriori Standard Deviation (Sigma Naught) and the Condition of Normal Matrix, and the final estimated exterior orientation parameters (Xc, Yc, Zc, Omega, Kappa, Alpha).\n
    Optionally the Principal Point Offsets can be estimated. This requires at least 4 image points as input.\n
    [Warning] The tool is dedicated to the terrestrial case which means the viewing direction must be sufficiently different from the vertical direction.\n
    The estimation of Principal Point Offsets is not recommended if the condition of the Normal Matrix is less than 10 ^ -7.\n
    Arguments
    ----------
    - POINTS [`input point cloud`] : Measured Points (PC). List of Measured Points as PC
    - F [`floating point number`] : Focal Length (mm). Default: 0.000000 Focal Length in mm
    - W [`floating point number`] : Pixel Width (um). Default: 0.000000 Pixel Width in micro meters
    - EST_OFFSETS [`boolean`] : Estimate Principal Point Offsets?. Default: 0 Do you wish to estimate Principal Point Offsets?
    - PPX [`floating point number`] : Principal Point Offset in X (pixels). Default: 0.000000 Principal Point Offset in X
    - PPY [`floating point number`] : Principal Point Offset in Y (pixels). Default: 0.000000 Principal Point Offset in Y
    - GIVE_DISTORTIONS [`boolean`] : Provide Radial Distortion Parameters?. Default: 0 Do you wish to provide the Radial Distortion Parameters?
    - K1 [`floating point number`] : K1. Default: 0.000000 K1
    - K2 [`floating point number`] : K2. Default: 0.000000 K2
    - K3 [`floating point number`] : K3. Default: 0.000000 K3
    - Xc [`floating point number`] : X. Default: 0.000000 Approximate Coordinate
    - Yc [`floating point number`] : Y. Default: 0.000000 Approximate Coordinate
    - Zc [`floating point number`] : Z. Default: 0.000000 Approximate Coordinate
    - Xt [`floating point number`] : X. Default: 0.000000 Approximate Coordinate
    - Yt [`floating point number`] : Y. Default: 0.000000 Approximate Coordinate
    - Zt [`floating point number`] : Z. Default: 0.000000 Approximate Coordinate
    - OUTPUT_FILE [`file path`] : Output Text File. The file to write the Calculation Results to.

    - 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('imagery_photogrammetry', '0', 'Resection (Terrestrial)')
    if Tool.is_Okay():
        Tool.Set_Input ('POINTS', POINTS)
        Tool.Set_Option('F', F)
        Tool.Set_Option('W', W)
        Tool.Set_Option('EST_OFFSETS', EST_OFFSETS)
        Tool.Set_Option('ppX', PPX)
        Tool.Set_Option('ppY', PPY)
        Tool.Set_Option('GIVE_DISTORTIONS', GIVE_DISTORTIONS)
        Tool.Set_Option('K1', K1)
        Tool.Set_Option('K2', K2)
        Tool.Set_Option('K3', K3)
        Tool.Set_Option('Xc', Xc)
        Tool.Set_Option('Yc', Yc)
        Tool.Set_Option('Zc', Zc)
        Tool.Set_Option('Xt', Xt)
        Tool.Set_Option('Yt', Yt)
        Tool.Set_Option('Zt', Zt)
        Tool.Set_Option('OUTPUT FILE', OUTPUT_FILE)
        return Tool.Execute(Verbose)
    return False

def Colorisation_PC(RGBIMAGE=None, PC_IN=None, PC_OUT=None, RGBIMAGE_GRIDSYSTEM=None, GIVE_TIME=None, IMG_TIME=None, TIME_DIFF=None, F=None, W=None, PPX=None, PPY=None, GIVE_DISTORTIONS=None, K1=None, K2=None, K3=None, Xc=None, Yc=None, Zc=None, OMEGA=None, KAPPA=None, ALPHA=None, Verbose=2):
    '''
    Colorisation (PC)
    ----------
    [imagery_photogrammetry.1]\n
    This tool attaches the color information from a RGB image to Laser Points.\n
    The RGB Image and the Point Cloud to be colorised are the inputs along with the interior and exterior orientation parameters of the camera. The necessary interior orientation parameters are Focal Length (mm), Pixel Size (um), Principal Point Offsets (pixels) and optionally the Radial Distortion Parameters. The distortion model being used is as follows:\n
    x_d = x_u (1 - dR)\n
    y_d = y_u (1 - dR)\n
    where, dR = K1 * r_u ^ 2 + K2 * r_u ^ 4 + K3 * r_u ^ 6,\n
    r_u ^ 2  = x_u ^ 2 + y_u ^ 2,\n
    x_u, y_u are the undistorted (corrected) image coordinates in mm,\n
    x_d, y_d are the distorted (observed) image coordinates in mm,\n
    K1 is in [mm ^ -2], K2 is in [mm ^ -4],  K3 is in [mm ^ -6].\n
    The necessary exterior orientation parameters are the coordinates of the Projection Center and the Cardan angles Omega, Kappa and Alpha. The Cardan angles refer to the following transformation between image coordinates (x_image) and global coordinates (X_Global):\n
    x_image = R_1(omega) * R_2(kappa) * R_3(alpha) * X_Global\n
    [Optional] If the Time Stamp of the RGB Image is given, an acceptable time difference between the points and the image must provided in order to colorise only those points falling that range. If no time is given all points are colorised.\n
    The result is a colorised point cloud.\n
    Arguments
    ----------
    - RGBIMAGE [`input grid`] : RGB Image. RGB Image
    - PC_IN [`input point cloud`] : Points to be Colorised. Points to be Colorised
    - PC_OUT [`output point cloud`] : Colorised Point Cloud. Colorised Point Cloud
    - RGBIMAGE_GRIDSYSTEM [`grid system`] : Grid system
    - GIVE_TIME [`boolean`] : Provide Time stamp of Image?. Default: 0 Do you wish to provide the time stamp of Image?
    - IMG_TIME [`floating point number`] : Time stamp of Image. Default: 0.000000 Time stamp of Image
    - TIME_DIFF [`floating point number`] : Time Difference between Image & Points. Default: 0.000000 Acceptable Time Difference between Image and Laser Points
    - F [`floating point number`] : Focal Length (mm). Default: 0.000000 Focal Length in mm
    - W [`floating point number`] : Pixel Width (um). Default: 0.000000 Pixel Width in micro meters
    - PPX [`floating point number`] : Principal Point Offset in X (pixles). Default: 0.000000 Principal Point Offset in X
    - PPY [`floating point number`] : Principal Point Offset in Y (pixels). Default: 0.000000 Principal Point Offset in Y
    - GIVE_DISTORTIONS [`boolean`] : Provide Radial Distortion Parameters?. Default: 0 Do you wish to provide the Radial Distortion Parameters?
    - K1 [`floating point number`] : K1. Default: 0.000000 K1
    - K2 [`floating point number`] : K2. Default: 0.000000 K2
    - K3 [`floating point number`] : K3. Default: 0.000000 K3
    - Xc [`floating point number`] : Projection Centre - X. Default: 0.000000 Projection Centre
    - Yc [`floating point number`] : Projection Centre - Y. Default: 0.000000 Projection Centre
    - Zc [`floating point number`] : Projection Centre - Z. Default: 0.000000 Projection Centre
    - OMEGA [`floating point number`] : Omega. Default: 0.000000 Rotation Angle
    - KAPPA [`floating point number`] : Kappa. Default: 0.000000 Rotation Angle
    - ALPHA [`floating point number`] : Alpha. Default: 0.000000 Rotation Angle

    - 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('imagery_photogrammetry', '1', 'Colorisation (PC)')
    if Tool.is_Okay():
        Tool.Set_Input ('rgbImage', RGBIMAGE)
        Tool.Set_Input ('PC_IN', PC_IN)
        Tool.Set_Output('PC_OUT', PC_OUT)
        Tool.Set_Option('rgbImage_GRIDSYSTEM', RGBIMAGE_GRIDSYSTEM)
        Tool.Set_Option('GIVE_TIME', GIVE_TIME)
        Tool.Set_Option('IMG_TIME', IMG_TIME)
        Tool.Set_Option('TIME_DIFF', TIME_DIFF)
        Tool.Set_Option('F', F)
        Tool.Set_Option('W', W)
        Tool.Set_Option('ppX', PPX)
        Tool.Set_Option('ppY', PPY)
        Tool.Set_Option('GIVE_DISTORTIONS', GIVE_DISTORTIONS)
        Tool.Set_Option('K1', K1)
        Tool.Set_Option('K2', K2)
        Tool.Set_Option('K3', K3)
        Tool.Set_Option('Xc', Xc)
        Tool.Set_Option('Yc', Yc)
        Tool.Set_Option('Zc', Zc)
        Tool.Set_Option('omega', OMEGA)
        Tool.Set_Option('kappa', KAPPA)
        Tool.Set_Option('alpha', ALPHA)
        return Tool.Execute(Verbose)
    return False

def run_tool_imagery_photogrammetry_1(RGBIMAGE=None, PC_IN=None, PC_OUT=None, RGBIMAGE_GRIDSYSTEM=None, GIVE_TIME=None, IMG_TIME=None, TIME_DIFF=None, F=None, W=None, PPX=None, PPY=None, GIVE_DISTORTIONS=None, K1=None, K2=None, K3=None, Xc=None, Yc=None, Zc=None, OMEGA=None, KAPPA=None, ALPHA=None, Verbose=2):
    '''
    Colorisation (PC)
    ----------
    [imagery_photogrammetry.1]\n
    This tool attaches the color information from a RGB image to Laser Points.\n
    The RGB Image and the Point Cloud to be colorised are the inputs along with the interior and exterior orientation parameters of the camera. The necessary interior orientation parameters are Focal Length (mm), Pixel Size (um), Principal Point Offsets (pixels) and optionally the Radial Distortion Parameters. The distortion model being used is as follows:\n
    x_d = x_u (1 - dR)\n
    y_d = y_u (1 - dR)\n
    where, dR = K1 * r_u ^ 2 + K2 * r_u ^ 4 + K3 * r_u ^ 6,\n
    r_u ^ 2  = x_u ^ 2 + y_u ^ 2,\n
    x_u, y_u are the undistorted (corrected) image coordinates in mm,\n
    x_d, y_d are the distorted (observed) image coordinates in mm,\n
    K1 is in [mm ^ -2], K2 is in [mm ^ -4],  K3 is in [mm ^ -6].\n
    The necessary exterior orientation parameters are the coordinates of the Projection Center and the Cardan angles Omega, Kappa and Alpha. The Cardan angles refer to the following transformation between image coordinates (x_image) and global coordinates (X_Global):\n
    x_image = R_1(omega) * R_2(kappa) * R_3(alpha) * X_Global\n
    [Optional] If the Time Stamp of the RGB Image is given, an acceptable time difference between the points and the image must provided in order to colorise only those points falling that range. If no time is given all points are colorised.\n
    The result is a colorised point cloud.\n
    Arguments
    ----------
    - RGBIMAGE [`input grid`] : RGB Image. RGB Image
    - PC_IN [`input point cloud`] : Points to be Colorised. Points to be Colorised
    - PC_OUT [`output point cloud`] : Colorised Point Cloud. Colorised Point Cloud
    - RGBIMAGE_GRIDSYSTEM [`grid system`] : Grid system
    - GIVE_TIME [`boolean`] : Provide Time stamp of Image?. Default: 0 Do you wish to provide the time stamp of Image?
    - IMG_TIME [`floating point number`] : Time stamp of Image. Default: 0.000000 Time stamp of Image
    - TIME_DIFF [`floating point number`] : Time Difference between Image & Points. Default: 0.000000 Acceptable Time Difference between Image and Laser Points
    - F [`floating point number`] : Focal Length (mm). Default: 0.000000 Focal Length in mm
    - W [`floating point number`] : Pixel Width (um). Default: 0.000000 Pixel Width in micro meters
    - PPX [`floating point number`] : Principal Point Offset in X (pixles). Default: 0.000000 Principal Point Offset in X
    - PPY [`floating point number`] : Principal Point Offset in Y (pixels). Default: 0.000000 Principal Point Offset in Y
    - GIVE_DISTORTIONS [`boolean`] : Provide Radial Distortion Parameters?. Default: 0 Do you wish to provide the Radial Distortion Parameters?
    - K1 [`floating point number`] : K1. Default: 0.000000 K1
    - K2 [`floating point number`] : K2. Default: 0.000000 K2
    - K3 [`floating point number`] : K3. Default: 0.000000 K3
    - Xc [`floating point number`] : Projection Centre - X. Default: 0.000000 Projection Centre
    - Yc [`floating point number`] : Projection Centre - Y. Default: 0.000000 Projection Centre
    - Zc [`floating point number`] : Projection Centre - Z. Default: 0.000000 Projection Centre
    - OMEGA [`floating point number`] : Omega. Default: 0.000000 Rotation Angle
    - KAPPA [`floating point number`] : Kappa. Default: 0.000000 Rotation Angle
    - ALPHA [`floating point number`] : Alpha. Default: 0.000000 Rotation Angle

    - 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('imagery_photogrammetry', '1', 'Colorisation (PC)')
    if Tool.is_Okay():
        Tool.Set_Input ('rgbImage', RGBIMAGE)
        Tool.Set_Input ('PC_IN', PC_IN)
        Tool.Set_Output('PC_OUT', PC_OUT)
        Tool.Set_Option('rgbImage_GRIDSYSTEM', RGBIMAGE_GRIDSYSTEM)
        Tool.Set_Option('GIVE_TIME', GIVE_TIME)
        Tool.Set_Option('IMG_TIME', IMG_TIME)
        Tool.Set_Option('TIME_DIFF', TIME_DIFF)
        Tool.Set_Option('F', F)
        Tool.Set_Option('W', W)
        Tool.Set_Option('ppX', PPX)
        Tool.Set_Option('ppY', PPY)
        Tool.Set_Option('GIVE_DISTORTIONS', GIVE_DISTORTIONS)
        Tool.Set_Option('K1', K1)
        Tool.Set_Option('K2', K2)
        Tool.Set_Option('K3', K3)
        Tool.Set_Option('Xc', Xc)
        Tool.Set_Option('Yc', Yc)
        Tool.Set_Option('Zc', Zc)
        Tool.Set_Option('omega', OMEGA)
        Tool.Set_Option('kappa', KAPPA)
        Tool.Set_Option('alpha', ALPHA)
        return Tool.Execute(Verbose)
    return False

