# %% x, sqnorm, rank, s = numpy.linalg.lstsq(A, b) # solution a, b, x_0, y_0 = x # %% ratio = a / b print(f"ratio of scales {ratio}" ) # the original plot has vertical exagerration of 6x # %% # we use homogeneus coordinats and set up the transform, scale and translation are considered # we assembly the matrix T = np.array([[a, 0, x_0], [0, b, y_0], [0, 0, 1]]) np.savetxt(of("radargram_transform.txt"), T) # and save for future uses # %% # extract and prepare the points to be transformed pt_px = np.array([np.array(p.coords)[0] for p in depths.geometry]) pt_px = np.column_stack([pt_px, np.ones(len(pt_px))]) # %% # apply the transform on te input points just to check how far we are pt_mt_est = np.array([T @ pt for pt in pt_px])[:, :2] pt_mt_obs = np.column_stack([depths.x, depths.y]) pt_mt_obs - pt_mt_est # %% [markdown] # just to see if we are near enough, around 0.1 meters is the error in progressive positioning due to digitalization #
figure(figsize=(10, 10)) # fast inspection imshow(im) # %% [markdown] # Now we want to save the raster as a geotiff file using rasterio # # We define the absolute position of the landing site in an absolute reference frame. These values are obtanied from QGIS and picking the landing site onto the orthoimage (see companion dataset) # # Note that we do not actually know the crs of the map we imported, but we know is a metric framework. We will try to use the same crs with eqc projection as the orthoimages and the DEM from LROC NAC. For such small distances using the wrong projection will not be noticeable # %% coords_start = np.array([3500707.20, 1337897.55 ]) # landing site coords in the ref frame below crs = "+proj=eqc +lat_ts=44 +lat_0=0 +lon_0=180 +x_0=0 +y_0=0 +R=1737400 +units=m +no_defs +type=crs" # the crs of the coords above np.savetxt(of("landing_coordinates.txt"), coords_start) # we also save them for future use # T provide the transform from pixel to meter coordinates in a reference frame with the origin in the top left corner with y-axis upward # we need to alter the transform to a different reference with y downward: for this reason we chenge the sign of mt[1,1] mt = np.array(T.get_matrix())[:2, :] mt[1, 1] = -mt[1, 1] mt[:, 2] += coords_start # add the global shift import rasterio at = rasterio.transform.Affine( *mt.ravel()) # fnally recreate a rasterio-compatible affine transform # %% im_asarr = np.array(im) # to a numpy array
# %% import attr @attr.attrs class ArchivableFile: filename = attr.ib() extend_to_aux = attr.ib(default=False) group = attr.ib(default=None) rename_to = attr.ib(default=None) is_aux = attr.ib(default=False) # %% files = [ ArchivableFile(of("crater_cropped_dem_textured.obj"), True, "model/meshes"), ArchivableFile(of("radargram.obj"), True, "model/meshes"), ArchivableFile(of("yutu_path.obj"), False, "model/meshes") ] # %% for i in [0, 1, 2]: files.append( ArchivableFile(of(f"tube_{i}.obj"), False, "model/meshes", f"plane_topography_intersection_horizon_{i}.obj")) for i in [0, 1, 2]: files.append( ArchivableFile(of(f"large_plane_{i}.obj"), False, "model/meshes", f"modelled_horizon_{i}.obj"))
# jupytext_version: 1.5.2 # kernelspec: # display_name: Python 3 # language: python # name: python3 # --- # %% # %pylab inline import geopandas as gpd import rasterio from smalllib import crop_raster_rectangle, raster_to_pyvista_mesh, of, ff, save_mesh_and_texture_as_obj import vtk, pyvista # %% center_coords = np.loadtxt(of("center_coords.txt")) # %% # crop_raster_rectangle? # %% newbounds = gpd.read_file("../images/crater_bounds.gpkg") newbounds = newbounds.geometry[0] base = "../rasters/NAC_DTM_CHANGE3_M1144922100_160CM.TIF" basemap = rasterio.open(base) cropped2, bmeta = crop_raster_rectangle(basemap, newbounds.bounds[:2], newbounds.bounds[2:], outfile=of("crater_cropped_dem.tif"))
# --- # %% # %pylab inline import geopandas as gpd import attr # using attr here to create a commodity class for horizon-related data storage from smalllib import of, ff # %% [markdown] # we will explore several methods to obtain 3D models representing the subsurface starting from the simpler techniques. # The problem is pretty simple in this case and can be tackled completely without commercial software. # We will perform an "analytical" modeling of the surfaces, in this case as flat planes, we do not have many constrints so flat planes might be a good first order approximation # %% # we load the horizons hfile = of("horizons.gpkg") horizons = [] for i in np.arange(3): h = gpd.read_file(hfile, layer=f"{str(i)}") horizons.append(h) # %% import rasterio rdem = rasterio.open(of("cropped_dem_up.tif")) # %% p_0 = np.loadtxt(of("center_coords.txt")) # local center region = np.loadtxt(of("region.txt")) #the region we are going to be inerested in
import pyvista # going to use pyvista as 3d visualization backend from smalllib import sampleRasterAtPoints, of, ff # we will reuse this method import rasterio # %% bp = pyvista.BackgroundPlotter( ) # start the pyvista plotter we will populate with 3d data # %% [markdown] # # Topography # we want to transform to a mesh, there are several ways of doing that we show here one that does not need external tools. # The topography is turned into a 3d triangulated mesh, one mesh vertice for each pixel. # %% # reload landing coordinates, we are going to use those as local reference frame for the 3d model. lcoord_file = of("landing_coordinates.txt") pt = np.loadtxt(lcoord_file) # the dtm, using the upsampled version computed in previous notebook dtm_f = of("cropped_dem_up.tif") dset = rasterio.open(dtm_f) # %% # %% zero_el = sampleRasterAtPoints(dset, np.array( [pt]))[0] # estimate elevation at landing site center_coords = np.array( [*pt, zero_el] ) # define a point that we will use as center for a local ref frame, we do not really need to propagate big coordinates. It might also confuse 3D vis packages
# --- # %% # %pylab inline import geopandas as gpd import attr # using attr here to create a commodity class for horizon-related data storage from smalllib import of, ff # %% [markdown] # we will explore several methods to obtain 3D models representing the subsurface starting from the simpler techniques. # The problem is pretty simple in this case and can be tackled completely without commercial software. # We will perform an "analytical" modeling of the surfaces, in this case as flat planes, we do not have many constrints so flat planes might be a good first order approximation # %% # we load the horizons hfile = of("horizons.gpkg") horizons = [] for i in np.arange(3): h = gpd.read_file(hfile, layer=f"{str(i)}") horizons.append(h) # %% import rasterio rdem = rasterio.open(of("cropped_dem_up.tif")) # %% p_0 = np.loadtxt(of("center_coords.txt")) # local center region = np.loadtxt( of("region.txt")) #the region we are going to be inerested in
import pyvista # going to use pyvista as 3d visualization backend from smalllib import sampleRasterAtPoints, of, ff, save_as_obj # we will reuse this method import rasterio # %% bp = pyvista.BackgroundPlotter( ) # start the pyvista plotter we will populate with 3d data # %% [markdown] # # Topography # we want to transform to a mesh, there are several ways of doing that we show here one that does not need external tools. # The topography is turned into a 3d triangulated mesh, one mesh vertice for each pixel. # %% # reload landing coordinates, we are going to use those as local reference frame for the 3d model. lcoord_file = of("landing_coordinates.txt") pt = np.loadtxt(lcoord_file) # the dtm, using the upsampled version computed in previous notebook dtm_f = of("cropped_dem_up.tif") dset = rasterio.open(dtm_f) # %% # %% zero_el = sampleRasterAtPoints(dset, np.array( [pt]))[0] # estimate elevation at landing site center_coords = np.array( [*pt, zero_el] ) # define a point that we will use as center for a local ref frame, we do not really need to propagate big coordinates. It might also confuse 3D vis packages