Source code for shareloc.geomodels.los

#!/usr/bin/env python
# coding: utf8
#
# Copyright (c) 2022 Centre National d'Etudes Spatiales (CNES).
#
# This file is part of Shareloc
# (see https://github.com/CNES/shareloc).
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
This module contains the LOS class to handle line of sights
for geometric models.
"""

# Third party imports
import numpy as np

# Shareloc imports
from shareloc.proj_utils import coordinates_conversion


[docs] class LOS: """line of sight class""" def __init__(self, sensor_positions, geometrical_model, alt_min_max=None, fill_nan=False): """ LOS Constructor :param sensor_positions: sensor_positions :type sensor_positions: numpy array (Nx2) :param geometrical_model: geometrical model :type geometrical_model: shareloc.grid or shareloc.rpc.rpc :param alt_min_max: min/max altitude to compute los, if None model min/max will be used :type alt_min_max : list :param fill_nan : fill numpy.nan values with lon and lat offset if true (same as OTB/OSSIM), nan is returned otherwise :type fill_nan : boolean """
[docs] self._number = None
[docs] self._starting_points = None # los starting point
[docs] self._viewing_vectors = None # los viewing direction
[docs] self._ending_points = None # los ending point
[docs] self.geometrical_model = geometrical_model
[docs] self.sensors_positions = sensor_positions
self.los_creation(alt_min_max, fill_nan)
[docs] def los_creation(self, alt_min_max, fill_nan=False): """ create los from extrema: los starting point, and normalized viewing vector :param alt_min_max: min/max altitude to compute los, if None model min/max will be used :type alt_min_max: list :param fill_nan: option to fill with nan ot not. :type fill_nan: boolean """ self._number = self.sensors_positions.shape[0] if alt_min_max is None: alt_min, alt_max = self.geometrical_model.get_alt_min_max() else: alt_min, alt_max = alt_min_max # LOS construction right los_extrema = np.zeros([2 * self._number, 3]) list_col, list_row = (self.sensors_positions[:, 0], self.sensors_positions[:, 1]) los_extrema[np.arange(0, 2 * self._number, 2), :] = self.geometrical_model.direct_loc_h( list_row, list_col, alt_max, fill_nan ) los_extrema[np.arange(1, 2 * self._number, 2), :] = self.geometrical_model.direct_loc_h( list_row, list_col, alt_min, fill_nan ) in_crs = 4326 out_crs = 4978 ecef_coord = coordinates_conversion(los_extrema, in_crs, out_crs) self._starting_points = ecef_coord[0::2, :] self._ending_points = ecef_coord[1::2, :] vis = self._starting_points - ecef_coord[1::2, :] # /!\ normalized # # direction vector creation vis_norm = np.linalg.norm(vis, axis=1) # discard null norm vis = sis vis_norm[vis_norm == 0] = np.nan rep_vis_norm = np.tile(vis_norm, (3, 1)).transpose() self._viewing_vectors = vis / rep_vis_norm
@property
[docs] def starting_points(self) -> np.ndarray: """ returns los hat :return: sis """ return self._starting_points
@property
[docs] def ending_points(self) -> np.ndarray: """ returns los bottom :return: eis :rtype: numpy array """ return self._ending_points
@property
[docs] def viewing_vectors(self): """ returns los viewing vectors :return: vis """ return self._viewing_vectors
@property
[docs] def number(self) -> int: """ returns los number :return: number """ return self._number