index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { coordEach } from '@turf/meta';
  2. import { isObject } from '@turf/helpers';
  3. import { getCoords } from '@turf/invariant';
  4. import clone from '@turf/clone';
  5. import rhumbDestination from '@turf/rhumb-destination';
  6. /**
  7. * Moves any geojson Feature or Geometry of a specified distance along a Rhumb Line
  8. * on the provided direction angle.
  9. *
  10. * @name transformTranslate
  11. * @param {GeoJSON} geojson object to be translated
  12. * @param {number} distance length of the motion; negative values determine motion in opposite direction
  13. * @param {number} direction of the motion; angle from North in decimal degrees, positive clockwise
  14. * @param {Object} [options={}] Optional parameters
  15. * @param {string} [options.units='kilometers'] in which `distance` will be express; miles, kilometers, degrees, or radians
  16. * @param {number} [options.zTranslation=0] length of the vertical motion, same unit of distance
  17. * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)
  18. * @returns {GeoJSON} the translated GeoJSON object
  19. * @example
  20. * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]);
  21. * var translatedPoly = turf.transformTranslate(poly, 100, 35);
  22. *
  23. * //addToMap
  24. * var addToMap = [poly, translatedPoly];
  25. * translatedPoly.properties = {stroke: '#F00', 'stroke-width': 4};
  26. */
  27. function transformTranslate(geojson, distance, direction, options) {
  28. // Optional parameters
  29. options = options || {};
  30. if (!isObject(options)) throw new Error("options is invalid");
  31. var units = options.units;
  32. var zTranslation = options.zTranslation;
  33. var mutate = options.mutate;
  34. // Input validation
  35. if (!geojson) throw new Error("geojson is required");
  36. if (distance === undefined || distance === null || isNaN(distance))
  37. throw new Error("distance is required");
  38. if (zTranslation && typeof zTranslation !== "number" && isNaN(zTranslation))
  39. throw new Error("zTranslation is not a number");
  40. // Shortcut no-motion
  41. zTranslation = zTranslation !== undefined ? zTranslation : 0;
  42. if (distance === 0 && zTranslation === 0) return geojson;
  43. if (direction === undefined || direction === null || isNaN(direction))
  44. throw new Error("direction is required");
  45. // Invert with negative distances
  46. if (distance < 0) {
  47. distance = -distance;
  48. direction = direction + 180;
  49. }
  50. // Clone geojson to avoid side effects
  51. if (mutate === false || mutate === undefined) geojson = clone(geojson);
  52. // Translate each coordinate
  53. coordEach(geojson, function (pointCoords) {
  54. var newCoords = getCoords(
  55. rhumbDestination(pointCoords, distance, direction, { units: units })
  56. );
  57. pointCoords[0] = newCoords[0];
  58. pointCoords[1] = newCoords[1];
  59. if (zTranslation && pointCoords.length === 3)
  60. pointCoords[2] += zTranslation;
  61. });
  62. return geojson;
  63. }
  64. export default transformTranslate;