geoutils.operators.Interpolator#
- class geoutils.operators.Interpolator(neighborhood=None)[source]#
Interpolator to continuously predict values at new coordinates from nearby observations.
An Interpolator assumes a spatial field that can be predicted continuously at a point. It is tied to a neighborhood, a nodata propagation scheme, and has optional support for sample weights, when the method accepts them. Use a Reducer when the prediction should reduce observations across a neighborhood instead (e.g., average over an area). Fractional area support exists only for Reducers, not Interpolators.
To define your own interpolator, implement predict(). It will receive a LocalData object with nearby values, their X/Y coordinates and the target X/Y coordinate. Implement coefficients() instead when the prediction is a weighted sum that can also be used for uncertainty propagation.
For example, the custom interpolator below fits a plane to nearby raster cell values:
import numpy as np import geoutils as gu class LocalPlane(gu.operators.Interpolator): minimum_inputs = 3 def predict(self, data): # Calculate the X and Y differences between each source cell and the requested point x_from_target = data.coordinates[:, 0] - data.target[0] y_from_target = data.coordinates[:, 1] - data.target[1] # Fit value = value_at_target + x_slope * x_from_target + y_slope * y_from_target plane_terms = np.column_stack((np.ones(len(data.values)), x_from_target, y_from_target)) value_at_target, x_slope, y_slope = np.linalg.lstsq(plane_terms, data.values, rcond=None)[0] return float(value_at_target) predicted = raster.interp_at_points((x, y), method=LocalPlane(), as_array=True)
A linear interpolator should implement coefficients() to support weights and uncertainty propagation. As an example below, a simple inverse-distance interpolation can be naturally written as a weighted sum:
class SimpleInverseDistance(gu.operators.Interpolator): '''Predict from nearby cells, giving closer cells more weight.''' def coefficients(self, data): '''Return normalized inverse-distance weights for each cell.''' # A cell at the target takes precedence and avoids division by zero exact = data.distances == 0 if np.any(exact): weights = exact.astype(float) else: weights = 1 / data.distances return gu.operators.LinearCoefficients(weights / weights.sum()) errors = gu.ErrorStructure([gu.ErrorComponent("measurement", 2.0)]) summary = gu.uncertainty.propagate( raster.interp_at_points, error_structure=errors, operation_kwargs=dict(points=(x, y), method=SimpleInverseDistance(), as_array=True), ) predicted = summary.estimate
An Interpolator can also limit which nearby observations it uses. The following example uses at most eight points within 50 coordinate units of each output cell:
nearby = gu.operators.PointNeighbours(max_points=8, radius=50) gridded = point_cloud.grid( ref=reference_raster, resampling=SimpleInverseDistance(neighborhood=nearby) )
- __init__(neighborhood=None)[source]#
Choose how nearby points or raster cells are selected.
- Parameters:
neighborhood (
PointNeighbours|GridNeighbours|None) – PointNeighbours for a point cloud or GridNeighbours for a raster. By default, the input type determines which to use (eight nearest points or a 3 x 3 window for a custom interpolator).
Methods
__init__([neighborhood])Choose how nearby points or raster cells are selected.
coefficients(data)Return the weights and optional constant offset for a prediction.
evaluate(data, *[, nodata_propagation])Check nodata and weights before predicting a value.
predict(data)Predict a value from the nearby source observations.
predict_batch(data, *[, nodata_propagation])Predict several values by calling evaluate() for each group of source observations.
Attributes
accepts_sample_weightsdefault_neighborhooddefault_nodata_propagationerror_structureinterpolation_orderminimum_inputs