def get_bounding_box_area(bounding_box): crs_4326 = CRS('epsg:4326') geod_wgs84 = crs_4326.get_geod() polygon_area_m2, _ = geod_wgs84.geometry_area_perimeter(bounding_box) polygon_area_km2 = polygon_area_m2 / 1000000.0 return polygon_area_km2
def georef_by_worker(sv_corr: list, alt: xr.DataArray, lon: xr.DataArray, lat: xr.DataArray, hdng: xr.DataArray, heave: xr.DataArray, wline: float, vert_ref: str, input_crs: CRS, horizontal_crs: CRS, z_offset: float, vdatum_directory: str = None): """ Use the raw attitude/navigation to transform the vessel relative along/across/down offsets to georeferenced soundings. Will support transformation to geographic and projected coordinate systems and with a vertical reference that you select. Parameters ---------- sv_corr [x, y, z] offsets generated with sv_correct alt 1d (time) altitude in meters lon 1d (time) longitude in degrees lat 1d (time) latitude in degrees hdng 1d (time) heading in degrees heave 1d (time) heave in degrees wline waterline offset from reference point vert_ref vertical reference point, one of ['ellipse', 'vessel', 'waterline'] input_crs pyproj CRS object, input coordinate reference system information for this run horizontal_crs pyproj CRS object, destination coordinate reference system information for this run z_offset lever arm from reference point to transmitter vdatum_directory if 'NOAA MLLW' 'NOAA MHW' is the vertical reference, a path to the vdatum directory is required here Returns ------- list [xr.DataArray alongtrack offset (time, beam), xr.DataArray acrosstrack offset (time, beam), xr.DataArray down offset (time, beam), xr.DataArray corrected heave for TX - RP lever arm, all zeros if in 'ellipse' mode (time), xr.DataArray corrected altitude for TX - RP lever arm, all zeros if in 'vessel' or 'waterline' mode (time)] """ g = horizontal_crs.get_geod() # unpack the sv corrected data output alongtrack = sv_corr[0] acrosstrack = sv_corr[1] depthoffset = sv_corr[2] + z_offset # generate the corrected depth offset depending on the desired vertical reference corr_dpth = None corr_heave = None corr_altitude = None if vert_ref in kluster_variables.ellipse_based_vertical_references: corr_altitude = alt corr_heave = xr.zeros_like(corr_altitude) corr_dpth = (depthoffset - corr_altitude.values[:, None]).astype( np.float32) elif vert_ref == 'vessel': corr_heave = heave corr_altitude = xr.zeros_like(corr_heave) corr_dpth = (depthoffset + corr_heave.values[:, None]).astype( np.float32) elif vert_ref == 'waterline': corr_heave = heave corr_altitude = xr.zeros_like(corr_heave) corr_dpth = (depthoffset + corr_heave.values[:, None] - wline).astype( np.float32) # get the sv corrected alongtrack/acrosstrack offsets stacked without the NaNs (arrays have NaNs for beams that do not exist in that sector) at_idx, alongtrack_stck = stack_nan_array(alongtrack, stack_dims=('time', 'beam')) ac_idx, acrosstrack_stck = stack_nan_array(acrosstrack, stack_dims=('time', 'beam')) # determine the beam wise offsets bm_azimuth = np.rad2deg(np.arctan2(acrosstrack_stck, alongtrack_stck)) + np.float32( hdng[at_idx[0]].values) bm_radius = np.sqrt(acrosstrack_stck**2 + alongtrack_stck**2) pos = g.fwd(lon[at_idx[0]].values, lat[at_idx[0]].values, bm_azimuth.values, bm_radius.values) z = np.around(corr_dpth, 3) if vert_ref == 'NOAA MLLW': sep, vdatum_unc = transform_vyperdatum( pos[0], pos[1], xr.zeros_like(z), input_crs.to_epsg(), 'mllw', vdatum_directory=vdatum_directory) elif vert_ref == 'NOAA MHW': sep, vdatum_unc = transform_vyperdatum( pos[0], pos[1], xr.zeros_like(z), input_crs.to_epsg(), 'mhw', vdatum_directory=vdatum_directory) else: sep = 0 vdatum_unc = xr.zeros_like(z) z = z - sep if horizontal_crs.is_projected: # Transformer.transform input order is based on the CRS, see CRS.geodetic_crs.axis_info # - lon, lat - this appears to be valid when using CRS from proj4 string # - lat, lon - this appears to be valid when using CRS from epsg # use the always_xy option to force the transform to expect lon/lat order georef_transformer = Transformer.from_crs(input_crs, horizontal_crs, always_xy=True) newpos = georef_transformer.transform( pos[0], pos[1], errcheck=True) # longitude / latitude order (x/y) else: newpos = pos x = reform_nan_array(np.around(newpos[0], 3), at_idx, alongtrack.shape, alongtrack.coords, alongtrack.dims) y = reform_nan_array(np.around(newpos[1], 3), ac_idx, acrosstrack.shape, acrosstrack.coords, acrosstrack.dims) return [x, y, z, corr_heave, corr_altitude, vdatum_unc]