Skip to content

Commit

Permalink
Merge branch '240-ajout-get_sis2-comme-sortie-potentielle' into 'master'
Browse files Browse the repository at this point in the history
Resolve "Ajout los ending point comme sortie potentielle"

Closes #240

See merge request 3d/shareloc!132
  • Loading branch information
duboise-cnes committed Nov 20, 2023
2 parents 2ca741d + cb46600 commit 4572f4d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 30 deletions.
10 changes: 5 additions & 5 deletions shareloc/geofunctions/triangulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def sensor_triangulation(
def distance_point_los(los, points):
"""
distance between points and LOS
norm of cross prodcut between vector defined by LOS sis and point and LOS vis
norm of cross product between vector defined by LOS sis and point and LOS vis
:param los: line of sight
:type los: shareloc.los
Expand All @@ -103,8 +103,8 @@ def distance_point_los(los, points):
"""
# norm(BA vect u)/norm(u)

vis = los.vis
vect_sis_p = points - los.sis
vis = los.viewing_vectors
vect_sis_p = points - los.starting_points
dist = np.linalg.norm(np.cross(vect_sis_p, vis), axis=1)
return dist

Expand All @@ -120,10 +120,10 @@ def los_triangulation(left_los, right_los):
:return: intersections in cartesian crs
:rtype: numpy.array
"""
vis = np.dstack((left_los.vis, right_los.vis))
vis = np.dstack((left_los.viewing_vectors, right_los.viewing_vectors))
vis = np.swapaxes(vis, 1, 2)

sis = np.dstack((left_los.sis, right_los.sis))
sis = np.dstack((left_los.starting_points, right_los.starting_points))
sis = np.swapaxes(sis, 1, 2)

vivi = vis[..., :, np.newaxis] * vis[..., np.newaxis, :]
Expand Down
53 changes: 38 additions & 15 deletions shareloc/geomodels/los.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def __init__(self, sensor_positions, geometrical_model, alt_min_max=None, fill_n
:type fill_nan : boolean
"""

self._number = None
self._starting_points = None # los starting point
self._viewing_vectors = None # los viewing direction
self._ending_points = None # los ending point
self.geometrical_model = geometrical_model
self.sensors_positions = sensor_positions
self.los_creation(alt_min_max, fill_nan)
Expand All @@ -62,49 +66,68 @@ def los_creation(self, alt_min_max, fill_nan=False):
:type fill_nan: boolean
"""

self.los_nb = self.sensors_positions.shape[0]
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.los_nb, 3])
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.los_nb, 2), :] = self.geometrical_model.direct_loc_h(
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.los_nb, 2), :] = self.geometrical_model.direct_loc_h(
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.sis = ecef_coord[0::2, :]
vis = self.sis - ecef_coord[1::2, :]
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)
rep_vis_norm = np.tile(vis_norm, (3, 1)).transpose()
self.vis = vis / rep_vis_norm
self._viewing_vectors = vis / rep_vis_norm

def get_sis(self):
@property
def starting_points(self) -> np.ndarray:
"""
returns los hat
TODO: not used. Use python property instead
:return: sis
"""
return self._starting_points

@property
def ending_points(self) -> np.ndarray:
"""
returns los bottom
:return: eis
:rtype: numpy array
"""
return self.sis
return self._ending_points

def get_vis(self):
@property
def viewing_vectors(self):
"""
returns los viewing vector
TODO: not used. Use python property instead
returns los viewing vectors
:return: vis
:rtype: numpy array
"""
return self._viewing_vectors

@property
def number(self) -> int:
"""
returns los number
:return: number
"""
return self.vis
return self._number
10 changes: 5 additions & 5 deletions tests/geofunctions/test_triangulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,25 @@ class SimulatedLOS:
"""line of sight class"""

def __init__(self):
self.sis = np.array([[100.0, 10.0, 200.0], [100.0, 10.0, 200.0]])
self.vis = np.array([[0.0, 1.0, 0.0], [0.0, 1.0, 0.0]])
self.starting_points = np.array([[100.0, 10.0, 200.0], [100.0, 10.0, 200.0]])
self.viewing_vectors = np.array([[0.0, 1.0, 0.0], [0.0, 1.0, 0.0]])

def print_sis(self):
"""
print los hat
"""
print(self.sis)
print(self.starting_points)

def print_vis(self):
"""
print los viewing vector
"""
print(self.vis)
print(self.viewing_vectors)

los = SimulatedLOS()

distance = 10.0
point = los.sis + 100.0 * los.vis + distance * np.array([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]])
point = los.starting_points + 100.0 * los.viewing_vectors + distance * np.array([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]])
residue = distance_point_los(los, point)
assert distance == pytest.approx(residue, abs=1e-9)

Expand Down
38 changes: 33 additions & 5 deletions tests/geomodels/test_los.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ def test_los_creation_with_different_alt(alt):
rep_vis_norm = np.tile(vis_norm, (3, 1)).transpose()
vis_gt = vis_gt / rep_vis_norm

assert left_los.los_nb == los_nb_gt
assert (left_los.sis == sis_gt).all
assert (left_los.vis == vis_gt).all
assert left_los.number == los_nb_gt
assert (left_los.starting_points == sis_gt).all
assert (left_los.viewing_vectors == vis_gt).all


def test_compare_two_altitude():
Expand All @@ -109,5 +109,33 @@ def test_compare_two_altitude():
model_los = LOS(matches_left, geometrical_model, [310, 850])
wrong_los = LOS(matches_left, geometrical_model, [0, 210])

assert (model_los.sis != wrong_los.sis).all
assert (model_los.vis != wrong_los.vis).all
assert (model_los.starting_points != wrong_los.starting_points).all
assert (model_los.viewing_vectors != wrong_los.viewing_vectors).all


def test_los_parameters():
"""
test los parameters
"""

data_folder = data_path()

# Load matches
matches = np.load(os.path.join(data_folder, "triangulation/matches-crop.npy"))
matches_left = matches[:, 0:2]

# Load geometrical model
id_scene = "P1BP--2017092838284574CP"
file_dimap = os.path.join(data_folder, f"rpc/RPC_{id_scene}.XML")
geometrical_model = RPC.from_any(file_dimap)

# Create los
model_los = LOS(matches_left, geometrical_model, [310, 850])
assert np.allclose(
model_los.starting_points[0], np.array([4581872.88696028, 566896.05875082, 4387122.99450132]), rtol=0, atol=1e-8
)
assert np.allclose(model_los.viewing_vectors[0], np.array([0.61688621, 0.00180051, 0.78705029]), rtol=0, atol=1e-8)
assert np.allclose(
model_los.ending_points[0], np.array([4581535.24740943, 566895.07328168, 4386692.2192622]), rtol=0, atol=1e-8
)
assert model_los.number == 121

0 comments on commit 4572f4d

Please sign in to comment.