Skip to content

Commit 565dc09

Browse files
committed
RPCoptim: direct_loc_dtm with ESPG!=4326
refactor: WIP use direct_loc_dtm with dtm espg!=4326. RAF RPCoptim, if dtm epsg!=4326 use python los_extrema not the c++ one refactor: RPCoptim: direct_loc_dtm with ESPG!=4326 CI:desactivate duplicated code on RPCoptim refactor: few correction refactor: rm useless attribut in DTMintersection class CI
1 parent abd6f73 commit 565dc09

11 files changed

Lines changed: 234 additions & 62 deletions

File tree

shareloc/bindings/bind.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ PYBIND11_MODULE(bindings_cpp, m) {
4242
.def("eq_plan", &DTMIntersection::eq_plan)
4343
.def("ter_to_index", &DTMIntersection::ter_to_index)
4444
.def("index_to_ter", &DTMIntersection::index_to_ter)
45-
.def("get_alt_offset", &DTMIntersection::get_alt_offset)
45+
.def("get_footprint_corners", &DTMIntersection::get_footprint_corners)
4646
.def("interpolate", &DTMIntersection::interpolate)
4747
.def("intersect_dtm_cube", &DTMIntersection::intersect_dtm_cube)
4848
.def("intersection", &DTMIntersection::intersection)
@@ -124,7 +124,6 @@ PYBIND11_MODULE(bindings_cpp, m) {
124124
p.set_transform(t[13].cast<std::array<double,6>>());
125125
p.set_nb_rows(t[14].cast<int>());
126126
p.set_nb_columns(t[15].cast<int>());
127-
128127
return p;
129128
}
130129
));
@@ -234,6 +233,7 @@ PYBIND11_MODULE(bindings_cpp, m) {
234233
.def("get_den_lon", &RPC::get_den_lon)
235234
.def("get_num_lat", &RPC::get_num_lat)
236235
.def("get_den_lat", &RPC::get_den_lat)
236+
.def("get_alt_minmax", &RPC::get_alt_minmax)
237237
.def("get_offset_row", &RPC::get_offset_row)
238238
.def("get_scale_row", &RPC::get_scale_row)
239239
.def("get_offset_col", &RPC::get_offset_col)

shareloc/bindings/dtm_intersection.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,14 @@ array<double, 3> DTMIntersection::index_to_ter(array<double, 3> const& vect_ter)
131131
return ter;
132132
}
133133

134-
tuple<double,double> DTMIntersection::get_alt_offset(int epsg)const{
134+
py::array_t<double> DTMIntersection::get_footprint_corners()const{
135135

136-
if(epsg!=m_epsg){
137-
cout<<"C++ : DTMintersection get_alt_offset not valid epsg"<<endl;
138-
}
139-
return{0.,0.};
136+
vector<double> res = {-0.5,-0.5,\
137+
-0.5,this->get_nb_columns()-0.5,\
138+
this->get_nb_rows()-0.5,this->get_nb_columns()-0.5,\
139+
this->get_nb_rows()-0.5,-0.5};
140+
141+
return py::array_t<double>({4, 2}, res.data());
140142
}
141143

142144
double DTMIntersection::interpolate(double delta_shift_row, double delta_shift_col)const{

shareloc/bindings/dtm_intersection.hpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ class DTMIntersection
6161
/**index_to_ter*/
6262
std::array<double, 3> index_to_ter(std::array<double, 3> const& vect_ter)const;
6363

64-
/**get_alt_offset*/
65-
std::tuple<double,double> get_alt_offset(int epsg)const;
64+
/**get_footprint_corners*/
65+
pybind11::array_t<double> get_footprint_corners()const;
6666

6767
/**interpolate*/
6868
double interpolate(double delta_shift_row, double delta_shift_col) const;
@@ -164,10 +164,6 @@ class DTMIntersection
164164
/**set_nb_columns*/
165165
void set_nb_columns(int a) noexcept {m_nb_columns = a;};
166166

167-
168-
169-
170-
171167
private:
172168

173169
/**alt_data attribut*/

shareloc/bindings/rpc.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ tuple<double,double,double> RPC::direct_loc_dtm(
161161
{
162162
if(dtm.get_epsg() != 4326){
163163
throw runtime_error("C++ : direct_loc_dtm : epsg!=4326 -> Exiting");
164+
//cout<<"C++ : direct_loc_dtm : epsg!=4326 -> get_diff_alti_min/max initialized ?"<<endl;
164165
}
165166

166167
double min_dtm = dtm.get_alt_min() - 1.0;
@@ -204,11 +205,12 @@ tuple<vector<double>,vector<double>,vector<double>> RPC::direct_loc_dtm(
204205
{
205206
if(dtm.get_epsg() != 4326){
206207
throw runtime_error("C++ : direct_loc_dtm : epsg!=4326 -> Exiting");
208+
//cout<<"C++ : direct_loc_dtm : epsg!=4326 -> get_diff_alti_min/max initialized ?"<<endl;
207209
}
208210

209211
double min_dtm = dtm.get_alt_min() - 1.0;
210212
double max_dtm = dtm.get_alt_max() + 1.0;
211-
213+
212214
size_t nb_points = row.size();
213215

214216
vector<double> lon (2);

shareloc/bindings/rpc.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ class RPC : public GeoModelTemplate
207207
/**get_den_lat*/
208208
std::array<double, 20> const& get_den_lat() const noexcept {return m_den_lat;};
209209

210+
/**get_m_alt_minmax*/
211+
std::array<double, 2> const& get_alt_minmax() const noexcept {return m_alt_minmax;};
212+
210213
/**get_offset_row*/
211214
double get_offset_row() const noexcept {return m_offset_row;};
212215
/**get_scale_row*/

shareloc/geofunctions/dtm_intersection.py

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@
3131

3232
# Shareloc imports
3333
from shareloc.math_utils import interpol_bilin
34-
from shareloc.proj_utils import (
35-
coordinates_conversion,
36-
transform_index_to_physical_point,
37-
transform_physical_point_to_index,
38-
)
34+
from shareloc.proj_utils import transform_index_to_physical_point, transform_physical_point_to_index
3935

4036

4137
class DTMIntersection:
@@ -179,27 +175,19 @@ def index_to_ter(self, vect_dtm):
179175
(vect_ter[1], vect_ter[0]) = transform_index_to_physical_point(self.transform, vect_dtm[0], vect_dtm[1])
180176
return vect_ter
181177

182-
def get_alt_offset(self, epsg):
178+
def get_footprint_corners(self):
183179
"""
184-
returns min/amx altitude offset between dtm coordinates system and another one
180+
get_footprint_corners method
185181
186-
:param epsg: epsg code to compare with
187-
:type epsg: int
188-
:return: min/max altimetric difference between epsg in parameter minus dtm alti expressed in dtm epsg
189-
:rtype: list of float (1x2)
182+
:return: footrpint corners of dtm
183+
:rtype: np.ndarray(4x2) top_left, top_right, bottom_right, bottom_left
190184
"""
191-
if epsg != self.epsg:
192-
alti_moy = (self.alt_min + self.alt_max) / 2.0
193-
corners = np.zeros([4, 2])
194-
corners[:, 0] = [0.0, 0.0, self.nb_rows, self.nb_rows]
195-
corners[:, 1] = [0.0, self.nb_columns, self.nb_columns, 0.0]
196-
corners -= 0.5 # index to corner
197-
ground_corners = np.zeros([3, 4])
198-
ground_corners[2, :] = alti_moy
199-
ground_corners[1::-1, :] = transform_index_to_physical_point(self.transform, corners[:, 0], corners[:, 1])
200-
converted_corners = coordinates_conversion(ground_corners.transpose(), self.epsg, epsg)
201-
return [np.min(converted_corners[:, 2]) - alti_moy, np.max(converted_corners[:, 2]) - alti_moy]
202-
return [0.0, 0.0]
185+
186+
corners = np.zeros([4, 2])
187+
corners[:, 0] = [0.0, 0.0, self.nb_rows, self.nb_rows]
188+
corners[:, 1] = [0.0, self.nb_columns, self.nb_columns, 0.0]
189+
corners -= 0.5 # index to corner
190+
return corners
203191

204192
def interpolate(self, pos_row, pos_col):
205193
"""
@@ -892,3 +880,6 @@ def get_alt_max(self): # same api as cpp for direct_loc_dtm
892880

893881
def get_epsg(self): # same api as cpp for direct_loc_dtm
894882
return self.epsg
883+
884+
def get_transform(self): # same api as cpp for direct_loc_dtm
885+
return self.transform

shareloc/geomodels/rpc.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,21 @@
2727
import logging
2828
import os
2929
from ast import literal_eval
30+
from typing import Union
3031

3132
# Third party imports
3233
import numpy as np
34+
from affine import Affine
3335
from numba import config, njit, prange
3436

37+
import bindings_cpp
38+
from shareloc.geofunctions.dtm_intersection import DTMIntersection
39+
3540
# Shareloc imports
3641
from shareloc.geomodels.geomodel import GeoModel
3742
from shareloc.geomodels.geomodel_template import GeoModelTemplate
3843
from shareloc.geomodels.rpc_readers import rpc_reader
39-
from shareloc.proj_utils import coordinates_conversion
44+
from shareloc.proj_utils import coordinates_conversion, transform_index_to_physical_point
4045

4146
# Set numba type of threading layer before parallel target compilation
4247
config.THREADING_LAYER = "omp"
@@ -315,21 +320,22 @@ def direct_loc_dtm(self, row, col, dtm):
315320
row = np.array([row])
316321
col = np.array([col])
317322

318-
diff_alti_min, diff_alti_max = dtm.get_alt_offset(self.epsg)
323+
diff_alti_min, diff_alti_max = self.get_dtm_alt_offset(dtm.get_footprint_corners(), dtm)
324+
319325
# print("min {} max {}".format(dtm.Zmin,dtm.Zmax))
320326
(min_dtm, max_dtm) = (dtm.get_alt_min() - 1.0 + diff_alti_min, dtm.get_alt_max() + 1.0 + diff_alti_max)
321327
if min_dtm < self.offset_alt - self.scale_alt:
322328
logging.debug("minimum dtm value is outside RPC validity domain, extrapolation will be done")
323329
if max_dtm > self.offset_alt + self.scale_alt:
324330
logging.debug("maximum dtm value is outside RPC validity domain, extrapolation will be done")
331+
325332
los = self.los_extrema(row, col, min_dtm, max_dtm, epsg=dtm.get_epsg())
326333

327334
# los -> (nb_point,nb_alt,3)
328335
los = los.T
329336
los = np.expand_dims(los, axis=0)
330337
los = np.moveaxis(los, 1, -1)
331338
los = los.reshape((len(col), 2, 3))
332-
333339
direct_dtm = dtm.intersection_n_los_dtm(los)
334340

335341
return direct_dtm
@@ -559,6 +565,29 @@ def get_alt_min_max(self):
559565
"""
560566
return [self.offset_alt - self.scale_alt / 2.0, self.offset_alt + self.scale_alt / 2.0]
561567

568+
def get_dtm_alt_offset(self, corners: np.ndarray, dtm: Union[DTMIntersection, bindings_cpp.DTMIntersection]):
569+
"""
570+
returns min/max altitude offset between dtm coordinates system and RPC one
571+
572+
:param corners: corners of the DTM's footprint
573+
:type corners: np.ndarray (4x2)
574+
:param dtm: DTM to get alt offset from
575+
:type dtm: DTMIntersection or bindings_cpp.DTMIntersection
576+
:return: min/max altimetric difference between RPC's epsg minus dtm alti expressed in dtm epsg
577+
:rtype: list of float (1x2)
578+
"""
579+
580+
alti_moy = (dtm.get_alt_min() + dtm.get_alt_max()) / 2.0
581+
582+
ground_corners = np.zeros([3, 4])
583+
ground_corners[2, :] = alti_moy
584+
transform = dtm.get_transform()
585+
if not isinstance(transform, Affine):
586+
transform = Affine.from_gdal(*transform)
587+
ground_corners[1::-1, :] = transform_index_to_physical_point(transform, corners[:, 0], corners[:, 1])
588+
converted_corners = coordinates_conversion(ground_corners.transpose(), dtm.get_epsg(), self.epsg)
589+
return [np.min(converted_corners[:, 2]) - alti_moy, np.max(converted_corners[:, 2]) - alti_moy]
590+
562591
def los_extrema(self, row, col, alt_min=None, alt_max=None, fill_nan=False, epsg=None):
563592
"""
564593
compute los extrema
@@ -603,6 +632,7 @@ def los_extrema(self, row, col, alt_min=None, alt_max=None, fill_nan=False, epsg
603632
col_array = np.array([col, col])
604633
alt_array = np.array([los_alt_max, los_alt_min])
605634
los_edges = self.direct_loc_h(row_array, col_array, alt_array, fill_nan)
635+
606636
if extrapolate:
607637
diff = los_edges[0::2, :] - los_edges[1::2, :]
608638
delta_alt = diff[:, 2]
@@ -612,8 +642,10 @@ def los_extrema(self, row, col, alt_min=None, alt_max=None, fill_nan=False, epsg
612642
coeff_alt_min = np.tile(coeff_alt_min[:, np.newaxis], (1, 3))
613643
los_edges[0::2, :] = los_edges[1::2, :] + diff * coeff_alt_max
614644
los_edges[1::2, :] = los_edges[1::2, :] + diff * coeff_alt_min
645+
615646
if epsg is not None and epsg != self.epsg:
616647
los_edges = coordinates_conversion(los_edges, self.epsg, epsg)
648+
617649
return los_edges
618650

619651

0 commit comments

Comments
 (0)