def test_centerline_mesh(test_river): """Test centerline_mesh().""" avg_chan_width = np.sum(test_river.Imask) * test_river.pixarea / np.sum( test_river.links['len_adj']) mvw = ru.max_valley_width(test_river.Imask) perps_out, polys, cl_resampled, s_out = ru.centerline_mesh( test_river.centerline, avg_chan_width, mvw * test_river.pixlen * 1.1, mvw * test_river.pixlen * 1.1 / 10, 1) # make assertions assert np.shape(perps_out) == (86, 2, 2) assert np.shape(polys) == (86, 5, 2) assert np.shape(cl_resampled) == (95, 2) assert np.shape(s_out) == (86, ) assert s_out[-1] == pytest.approx(134836.27933429673)
def test_max_valley_width(test_river): """Test max_valley_width function.""" mvw = ru.max_valley_width(test_river.Imask) # make assertions assert mvw == pytest.approx(479.8541445064323)
def compute_mesh(self, grid_spacing=None, smoothing=0.1, buf_halfwidth=None): """ Generates an along-centerline mesh that indicates a valley-direction of sorts. The mesh is useful for computing spatial statistics as a function of downstream distance. The resulting mesh captures the low-frequency characteristic of the river corridor. This tool is tricky to fully automate, and the user may need to play with the smoothing and bufferdist parameters if errors are thrown or the result is not satisfying. Parameters ---------- grid_spacing : float Defines the distance between perpendicular-to-centerline transects. Units are defined by input mask CRS. smoothing : float Defines the smoothing window of the left- and right-valleylines as a fraction of the total centerline length. Range is [0, 1]. buf_halfwidth : float Defines the offset distance of the left- and right-valleylines from from the centerline. Units correspond to those of the CRS of the input mask. """ # Need a centerline if hasattr(self, 'centerline') is False: self.compute_centerline() # Need average channel width for parameterizing mesh generation if hasattr(self, 'avg_chan_width') is False: if hasattr(self, 'links') is False: self.compute_network() if hasattr(self.links, 'wid_adj') is False: self.compute_link_width_and_length() # self.avg_chan_width = np.mean(self.links['wid_a1dj']) self.avg_chan_width = np.sum(self.Imask) * self.pixarea / np.sum(self.links['len_adj']) # If not specified, grid spacing is set to one channel width if grid_spacing is None: grid_spacing = self.avg_chan_width # If buffer halfwidth is not specified, it is set to 10% larger than the maximum valley width if buf_halfwidth is None: # Compute the maximum valley width in pixels if hasattr(self, 'max_valley_width_pixels') is False: logger.info('Computing maximum valley width...') self.max_valley_width_pixels = ru.max_valley_width(self.Imask) logger.info('valley width computation is done.') # Multiply by pixlen to keep units consistent buf_halfwidth = self.max_valley_width_pixels * self.pixlen * 1.1 logger.info('Generating mesh...') self.meshlines, self.meshpolys, self.centerline_smooth = ru.valleyline_mesh(self.centerline, self.avg_chan_width, buf_halfwidth, grid_spacing, smoothing=smoothing) logger.info('mesh generation is done.')