gis-tools-ts
Version:
A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.
77 lines • 2.96 kB
JavaScript
import { defaultGetInterpolateCurrentValue } from './index.js';
import { pointDistance as distance } from '../../geometry/s2/point.js';
import { lRGBToGamma, sRGBToLinear } from '../../index.js';
/**
* # Nearest Neighbor Interpolation
*
* ## Description
* Finds the nearest point in the reference data to the given point and returns its value.
*
* ## Usage
* ```ts
* import { nearestInterpolation, PointIndexFast } from 'gis-tools-ts';
* import type { VectorPoint } from 'gis-tools-ts';
*
* // We have m-value data that we want to interpolate
* interface TempData { temp: number; }
*
* const pointIndex = new PointIndexFast<TempData>();
* // add lots of points
* pointIndex.insertLonLat(lon, lat, data);
* // ....
*
* // given a point we are interested in
* const point: VectorPoint = { x: 20, y: -40 };
* // get a collection of points relative to the point
* const data = await pointIndex.searchRadius(point.x, point.y, radius);
*
* // interpolate
* const interpolatedValue = nearestInterpolation<TempData>(point, data, (p) => p.m.temp);
* ```
* @param point - Point to interpolate
* @param refData - Reference data to search from
* @param getValue - Function to get value from reference data
* defaults to function that returns the z value or 0 if the z value is undefined
* @returns - The value of the nearest point
*/
export function nearestInterpolation(point, refData, getValue = defaultGetInterpolateCurrentValue) {
if (refData.length === 0)
return 0;
// Find the nearest point
let nearestPoint;
let minDistance = Infinity;
for (const refPoint of refData) {
const dist = distance(point, refPoint);
if (dist < minDistance || nearestPoint === undefined) {
minDistance = dist;
nearestPoint = refPoint;
}
}
// Return the value of the nearest point
if (nearestPoint !== undefined)
return getValue(nearestPoint);
return getValue(refData[0]);
}
/**
* Helper function for {@link nearestInterpolation} on RGB(A) data.
* Light in RGB data is logarithmically weighted, so we need to expand each component by n^2 to
* get the correct weight for each component.
* @param point - Point to interpolate
* @param refData - Reference data points
* @returns - The interpolated RGBA data.
*/
export function rgbaNearestInterpolation(point, refData) {
if (refData.length === 0)
return { r: 0, g: 0, b: 0, a: 255 };
const rData = nearestInterpolation(point, refData, (p) => sRGBToLinear(p.m?.r ?? 0));
const gData = nearestInterpolation(point, refData, (p) => sRGBToLinear(p.m?.g ?? 0));
const bData = nearestInterpolation(point, refData, (p) => sRGBToLinear(p.m?.b ?? 0));
const a = nearestInterpolation(point, refData, (p) => p.m?.a ?? 255);
return {
r: lRGBToGamma(rData),
g: lRGBToGamma(gData),
b: lRGBToGamma(bData),
a,
};
}
//# sourceMappingURL=nearest.js.map