def clip_glacier_with_terminus(line): """ Clip glacier extent with a terminus. """ gpoly = shapely.geometry.Polygon(shell=Glacier()) # Extend western edge past polygon boundary wpoint = shapely.geometry.Point(line[0]) west_snaps = shapely.ops.nearest_points(wpoint, gpoly.exterior) if west_snaps[0] != west_snaps[1]: new_west = west_snaps[1].coords d = new_west - line[0] d /= np.linalg.norm(d) line = np.row_stack((new_west + d, line)) # Extend eastern edge past polygon boundary epoint = shapely.geometry.Point(line[-1]) east_snaps = shapely.ops.nearest_points(epoint, gpoly.exterior) if east_snaps[0] != east_snaps[1]: new_east = east_snaps[1].coords d = new_east - line[-1] d /= np.linalg.norm(d) line = np.row_stack((line, new_east + d)) tline = shapely.geometry.LineString(line) # Split glacier at terminus splits = shapely.ops.split(gpoly, tline) if len(splits) < 2: raise ValueError('Glacier polygon not split by terminus') else: areas = [split.area for split in splits] return np.asarray(splits[np.argmax(areas)].exterior.coords)
def select_repeat_tracks(runs): """ Return Tracks composed of the best track for each initial point. Selects the track for each point that minimizes the temporal mean standard deviation for vx + vy, i.e. mean(sqrt(vx_sigma**2 + vy_sigma**2)). Arguments: runs (iterable): Tracks objects with identical point and time dimensions """ # Compute metric for each track metric = np.row_stack([ np.nanmean(np.sqrt(np.nansum(run.sigmas[..., 3:5]**2, axis=2)), axis=1) for run in runs ]) # Choose run with the smallest metric selected = np.argmin(metric, axis=0) # Merge runs means = runs[0].means.copy() sigmas = runs[0].sigmas.copy() for i, run in enumerate(runs[1:], start=1): mask = selected == i means[mask, ...] = run.means[mask, ...] sigmas[mask, ...] = run.sigmas[mask, ...] return glimpse.Tracks(datetimes=runs[0].datetimes, means=means, sigmas=sigmas)
cam_args = cg.load_calibrations(image, station_estimate=True, station=True, merge=True, file_errors=False) img = glimpse.Image(img_path, cam=cam_args) img.cam.resize(img_size) # Select nearest dem and ortho img_date = datetime.datetime.strptime(cg.parse_image_path(image)['date_str'], '%Y%m%d') i_dem = np.argmin(np.abs(np.asarray(dem_dates) - img_date)) i_ortho = np.argmin(np.abs(np.asarray(ortho_dates) - img_date)) dem_path = dem_paths[i_dem] ortho_path = ortho_paths[i_ortho] # Load raster metadata dem_grid = glimpse.Grid.read(dem_path, d=grid_size) ortho_grid = glimpse.Grid.read(ortho_path, d=grid_size) # Intersect bounding boxes cam_box = img.cam.viewbox(50e3)[[0, 1, 3, 4]] box = glimpse.helpers.intersect_boxes(np.row_stack(( cam_box, dem_grid.box2d, ortho_grid.box2d))) # Read dem and ortho dem = glimpse.Raster.read(dem_path, xlim=box[0::2], ylim=box[1::2], d=grid_size) dem.crop(zlim=(0.1, np.inf)) radius = circle_radius.get(image, circle_radius_default) dem.fill_circle(center=img.cam.xyz, radius=radius) nbands = gdal.Open(ortho_path).RasterCount bands = [] for i in range(nbands): bands.append(glimpse.Raster.read(ortho_path, band=i + 1, d=grid_size, xlim=box[0::2], ylim=box[1::2]).Z) orthoZ = np.dstack(bands).astype(float) if not color: orthoZ = np.atleast_3d(glimpse.helpers.rgb_to_gray(orthoZ)) orthoZ[orthoZ == 0] = np.nan # HACK: Clip dem and ortho to same size relative to x, y min
services=services, snap=SNAP, use_exif=False, service_exif=True, anchors=True, viewdir=True, viewdir_as_anchor=True) # Keep only oriented images images = np.array([img for img in images if img.anchor]) # Write animation(s) # HACK: Split at camera changes to use observer.animate() # HACK: Use k1 to quickly differentiate between cameras ks = np.array([img.cam.k[0] for img in images]) for k in np.unique(ks): idx = np.where(ks == k)[0] sizes = np.row_stack([img.cam.imgsz for img in images[idx]]) unique_sizes = np.unique(sizes, axis=0) if len(unique_sizes) > 1: # Standardize image sizes size = unique_sizes.min(axis=0) not_size = np.any(sizes != size, axis=1) f = images[~not_size][0].cam.f for img in images[not_size]: img.cam.resize(size, force=True) # HACK: Fix focal length rounding errors if any(img.cam.f - f > 0.1): raise ValueError('Focal lengths cannot be reconciled') img.cam.f = f observer = glimpse.Observer(images[idx], cache=False).subset(snap=snap) path = os.path.join( 'viewdirs-animations',
bw = glimpse.helpers.rgb_to_gray(img.read()).astype(np.uint8) img.write(path=path, I=clahe.apply(bw)) # Select nearest dem and ortho img_date = datetime.datetime.strptime( cg.parse_image_path(image)['date_str'], '%Y%m%d') i_dem = np.argmin(np.abs(np.asarray(dem_dates) - img_date)) i_ortho = np.argmin(np.abs(np.asarray(ortho_dates) - img_date)) dem_path = dem_paths[i_dem] ortho_path = ortho_paths[i_ortho] # Load raster metadata dem_grid = glimpse.Grid.read(dem_path, d=grid_size) ortho_grid = glimpse.Grid.read(ortho_path, d=grid_size) # Intersect bounding boxes cam_box = img.cam.viewbox(50e3)[[0, 1, 3, 4]] box = glimpse.helpers.intersect_boxes( np.row_stack((cam_box, dem_grid.box2d, ortho_grid.box2d))) # Read dem and ortho dem = glimpse.Raster.read(dem_path, xlim=box[0::2], ylim=box[1::2], d=grid_size) dem.crop(zlim=(0.1, np.inf)) radius = circle_radius.get(image, circle_radius_default) dem.fill_circle(center=img.cam.xyz, radius=radius) nbands = gdal.Open(ortho_path).RasterCount bands = [] for i in range(nbands): bands.append( glimpse.Raster.read(ortho_path, band=i + 1, d=grid_size,