14
14
# If not, see <https://www.gnu.org/licenses/>.
15
15
16
16
"""Orthorectification using DEM and camera model input."""
17
+
17
18
from __future__ import annotations
18
19
19
20
import logging
38
39
39
40
from orthority import common
40
41
from orthority .camera import Camera , FrameCamera
41
- from orthority .enums import Compress , Interp , Driver
42
- from orthority .errors import CrsMissingError , OrthorityWarning , OrthorityError
42
+ from orthority .enums import Compress , Driver , Interp
43
+ from orthority .errors import CrsMissingError , OrthorityError , OrthorityWarning
43
44
44
45
logger = logging .getLogger (__name__ )
45
46
@@ -138,13 +139,16 @@ def _get_init_dem(
138
139
# crs comparison is time-consuming - perform it once here
139
140
crs_equal = self ._crs == dem_im .crs
140
141
141
- # find the scale from meters to ortho crs z units
142
+ # find the scale from meters to ortho crs z units (projects from a valid (x,y) in ortho
143
+ # crs so that we stay inside projection domains (#18))
142
144
zs = []
143
145
ref_crs = rio .CRS .from_epsg (4979 )
146
+ ji = np .array (self .camera .im_size ).reshape (- 1 , 1 ) / 2
147
+ world_xyz = self .camera .pixel_to_world_z (ji , 0 )
144
148
for z in [0 , 1 ]:
145
- world_xyz = transform (ref_crs , self ._crs , [0 ], [ 0 ], [z ])
146
- zs .append (world_xyz [2 ][0 ])
147
- z_scale = zs [1 ] - zs [0 ]
149
+ ref_xyz = transform (self ._crs , ref_crs , world_xyz [0 ], world_xyz [ 1 ], [z ])
150
+ zs .append (ref_xyz [2 ][0 ])
151
+ z_scale = 1 / ( zs [1 ] - zs [0 ])
148
152
dem_full_win = Window (0 , 0 , dem_im .width , dem_im .height )
149
153
150
154
def get_win_at_zs (zs : Sequence [float ]) -> Window :
@@ -166,10 +170,10 @@ def get_win_at_zs(zs: Sequence[float]) -> Window:
166
170
raise OrthorityError (f"Ortho for '{ self ._src_name } ' lies outside the DEM." )
167
171
return common .expand_window_to_grid (dem_win )
168
172
169
- # get a dem window containing the ortho bounds at min & max possible altitude, read the
170
- # window from the dem
173
+ # get a dem window containing the ortho bounds at min & max possible altitude
171
174
zs = np .array ([self ._egm_minmax [0 ], self ._z_max + self ._egm_minmax [1 ]]) * z_scale
172
175
dem_win = get_win_at_zs (zs )
176
+ # read the window from the dem
173
177
dem_array = dem_im .read (dem_band , window = dem_win , masked = True )
174
178
dem_array_win = dem_win
175
179
0 commit comments