index.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import bbox from '@turf/bbox';
  2. import hexGrid from '@turf/hex-grid';
  3. import pointGrid from '@turf/point-grid';
  4. import distance from '@turf/distance';
  5. import centroid from '@turf/centroid';
  6. import squareGrid from '@turf/square-grid';
  7. import triangleGrid from '@turf/triangle-grid';
  8. import clone from '@turf/clone';
  9. import { featureCollection } from '@turf/helpers';
  10. import { featureEach } from '@turf/meta';
  11. import { collectionOf } from '@turf/invariant';
  12. /**
  13. * Takes a set of points and estimates their 'property' values on a grid using the [Inverse Distance Weighting (IDW) method](https://en.wikipedia.org/wiki/Inverse_distance_weighting).
  14. *
  15. * @name interpolate
  16. * @param {FeatureCollection<Point>} points with known value
  17. * @param {number} cellSize the distance across each grid point
  18. * @param {Object} [options={}] Optional parameters
  19. * @param {string} [options.gridType='square'] defines the output format based on a Grid Type (options: 'square' | 'point' | 'hex' | 'triangle')
  20. * @param {string} [options.property='elevation'] the property name in `points` from which z-values will be pulled, zValue fallbacks to 3rd coordinate if no property exists.
  21. * @param {string} [options.units='kilometers'] used in calculating cellSize, can be degrees, radians, miles, or kilometers
  22. * @param {number} [options.weight=1] exponent regulating the distance-decay weighting
  23. * @returns {FeatureCollection<Point|Polygon>} grid of points or polygons with interpolated 'property'
  24. * @example
  25. * var points = turf.randomPoint(30, {bbox: [50, 30, 70, 50]});
  26. *
  27. * // add a random property to each point
  28. * turf.featureEach(points, function(point) {
  29. * point.properties.solRad = Math.random() * 50;
  30. * });
  31. * var options = {gridType: 'points', property: 'solRad', units: 'miles'};
  32. * var grid = turf.interpolate(points, 100, options);
  33. *
  34. * //addToMap
  35. * var addToMap = [grid];
  36. */
  37. function interpolate(points, cellSize, options) {
  38. // Optional parameters
  39. options = options || {};
  40. if (typeof options !== "object") throw new Error("options is invalid");
  41. var gridType = options.gridType;
  42. var property = options.property;
  43. var weight = options.weight;
  44. // validation
  45. if (!points) throw new Error("points is required");
  46. collectionOf(points, "Point", "input must contain Points");
  47. if (!cellSize) throw new Error("cellSize is required");
  48. if (weight !== undefined && typeof weight !== "number")
  49. throw new Error("weight must be a number");
  50. // default values
  51. property = property || "elevation";
  52. gridType = gridType || "square";
  53. weight = weight || 1;
  54. var box = bbox(points);
  55. var grid;
  56. switch (gridType) {
  57. case "point":
  58. case "points":
  59. grid = pointGrid(box, cellSize, options);
  60. break;
  61. case "square":
  62. case "squares":
  63. grid = squareGrid(box, cellSize, options);
  64. break;
  65. case "hex":
  66. case "hexes":
  67. grid = hexGrid(box, cellSize, options);
  68. break;
  69. case "triangle":
  70. case "triangles":
  71. grid = triangleGrid(box, cellSize, options);
  72. break;
  73. default:
  74. throw new Error("invalid gridType");
  75. }
  76. var results = [];
  77. featureEach(grid, function (gridFeature) {
  78. var zw = 0;
  79. var sw = 0;
  80. // calculate the distance from each input point to the grid points
  81. featureEach(points, function (point) {
  82. var gridPoint =
  83. gridType === "point" ? gridFeature : centroid(gridFeature);
  84. var d = distance(gridPoint, point, options);
  85. var zValue;
  86. // property has priority for zValue, fallbacks to 3rd coordinate from geometry
  87. if (property !== undefined) zValue = point.properties[property];
  88. if (zValue === undefined) zValue = point.geometry.coordinates[2];
  89. if (zValue === undefined) throw new Error("zValue is missing");
  90. if (d === 0) zw = zValue;
  91. var w = 1.0 / Math.pow(d, weight);
  92. sw += w;
  93. zw += w * zValue;
  94. });
  95. // write interpolated value for each grid point
  96. var newFeature = clone(gridFeature);
  97. newFeature.properties[property] = zw / sw;
  98. results.push(newFeature);
  99. });
  100. return featureCollection(results);
  101. }
  102. export default interpolate;