def interpolate_raster_vector_points(source, target, layer_name=None, attribute_name=None, mode='linear'): """Interpolate from raster layer to point data Args: * source: Raster data set (grid) * target: Vector data set (points) * layer_name: Optional name of returned interpolated layer. If None the name of target is used for the returned layer. * attribute_name: Name for new attribute. If None (default) the name of layer source is used * mode: 'linear' or 'constant' - determines whether interpolation from grid to points should be bilinear or piecewise constant Output I: Vector data set; points located as target with values interpolated from source """ msg = ('There are no data points to interpolate to. Perhaps zoom out ' 'and try again') verify(len(target) > 0, msg) # Input checks verify(source.is_raster) verify(target.is_vector) verify(target.is_point_data) # Get raster data and corresponding x and y axes A = source.get_data(nan=True) longitudes, latitudes = source.get_geometry() verify(len(longitudes) == A.shape[1]) verify(len(latitudes) == A.shape[0]) # Get vector point geometry as Nx2 array coordinates = numpy.array(target.get_geometry(), dtype='d', copy=False) # Get original attributes attributes = target.get_data() # Create new attribute and interpolate try: values = interpolate_raster(longitudes, latitudes, A, coordinates, mode=mode) except (BoundsError, InaSAFEError), e: msg = (tr('Could not interpolate from raster layer %(raster)s to ' 'vector layer %(vector)s. Error message: %(error)s') % { 'raster': source.get_name(), 'vector': target.get_name(), 'error': str(e) }) raise InaSAFEError(msg)
def interpolate_raster_vector_points(source, target, layer_name=None, attribute_name=None, mode='linear'): """Interpolate from raster layer to point data Args: * source: Raster data set (grid) * target: Vector data set (points) * layer_name: Optional name of returned interpolated layer. If None the name of target is used for the returned layer. * attribute_name: Name for new attribute. If None (default) the name of layer source is used * mode: 'linear' or 'constant' - determines whether interpolation from grid to points should be bilinear or piecewise constant Output I: Vector data set; points located as target with values interpolated from source """ msg = ('There are no data points to interpolate to. Perhaps zoom out ' 'and try again') verify(len(target) > 0, msg) # Input checks verify(source.is_raster) verify(target.is_vector) verify(target.is_point_data) # Get raster data and corresponding x and y axes A = source.get_data(nan=True) longitudes, latitudes = source.get_geometry() verify(len(longitudes) == A.shape[1]) verify(len(latitudes) == A.shape[0]) # Get vector point geometry as Nx2 array coordinates = numpy.array(target.get_geometry(), dtype='d', copy=False) # Get original attributes attributes = target.get_data() # Create new attribute and interpolate try: values = interpolate_raster(longitudes, latitudes, A, coordinates, mode=mode) except (BoundsError, InaSAFEError), e: msg = ( tr( 'Could not interpolate from raster layer %(raster)s to ' 'vector layer %(vector)s. Error message: %(error)s' ) % { 'raster': source.get_name(), 'vector': target.get_name(), 'error': str(e)}) raise InaSAFEError(msg)
def test_interpolation_raster_data(self): """Interpolation library works for raster data This shows interpolation of data arranged with latitudes bottom - up and longitudes left - right """ # Create test data lon_ul = 100 # Longitude of upper left corner lat_ul = 10 # Latitude of upper left corner numlon = 8 # Number of longitudes numlat = 5 # Number of latitudes # Define array where latitudes are rows and longitude columns A = numpy.zeros((numlat, numlon)) # Establish coordinates for lower left corner lat_ll = lat_ul - numlat lon_ll = lon_ul # Define pixel centers along each direction longitudes = numpy.linspace(lon_ll + 0.5, lon_ll + numlon - 0.5, numlon) latitudes = numpy.linspace(lat_ll + 0.5, lat_ll + numlat - 0.5, numlat) # Define raster with latitudes going bottom-up (south to north). # Longitudes go left-right (west to east) for i in range(numlat): for j in range(numlon): A[numlat - 1 - i, j] = linear_function(longitudes[j], latitudes[i]) # Then test that interpolated points are correct xis = numpy.linspace(lon_ll + 1, lon_ll + numlon - 1, 100) etas = numpy.linspace(lat_ll + 1, lat_ll + numlat - 1, 100) points = combine_coordinates(xis, etas) vals = interpolate_raster(longitudes, latitudes, A, points, mode='linear') refs = linear_function(points[:, 0], points[:, 1]) assert numpy.allclose(vals, refs, rtol=1e-12, atol=1e-12)