index.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. 'use strict';
  2. var clone = require('@turf/clone');
  3. var center = require('@turf/center');
  4. var centroid = require('@turf/centroid');
  5. var turfBBox = require('@turf/bbox');
  6. var rhumbBearing = require('@turf/rhumb-bearing');
  7. var rhumbDistance = require('@turf/rhumb-distance');
  8. var rhumbDestination = require('@turf/rhumb-destination');
  9. var meta = require('@turf/meta');
  10. var helpers = require('@turf/helpers');
  11. var invariant = require('@turf/invariant');
  12. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  13. var clone__default = /*#__PURE__*/_interopDefaultLegacy(clone);
  14. var center__default = /*#__PURE__*/_interopDefaultLegacy(center);
  15. var centroid__default = /*#__PURE__*/_interopDefaultLegacy(centroid);
  16. var turfBBox__default = /*#__PURE__*/_interopDefaultLegacy(turfBBox);
  17. var rhumbBearing__default = /*#__PURE__*/_interopDefaultLegacy(rhumbBearing);
  18. var rhumbDistance__default = /*#__PURE__*/_interopDefaultLegacy(rhumbDistance);
  19. var rhumbDestination__default = /*#__PURE__*/_interopDefaultLegacy(rhumbDestination);
  20. /**
  21. * Scale a GeoJSON from a given point by a factor of scaling (ex: factor=2 would make the GeoJSON 200% larger).
  22. * If a FeatureCollection is provided, the origin point will be calculated based on each individual Feature.
  23. *
  24. * @name transformScale
  25. * @param {GeoJSON} geojson GeoJSON to be scaled
  26. * @param {number} factor of scaling, positive or negative values greater than 0
  27. * @param {Object} [options={}] Optional parameters
  28. * @param {string|Coord} [options.origin='centroid'] Point from which the scaling will occur (string options: sw/se/nw/ne/center/centroid)
  29. * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)
  30. * @returns {GeoJSON} scaled GeoJSON
  31. * @example
  32. * var poly = turf.polygon([[[0,29],[3.5,29],[2.5,32],[0,29]]]);
  33. * var scaledPoly = turf.transformScale(poly, 3);
  34. *
  35. * //addToMap
  36. * var addToMap = [poly, scaledPoly];
  37. * scaledPoly.properties = {stroke: '#F00', 'stroke-width': 4};
  38. */
  39. function transformScale(geojson, factor, options) {
  40. // Optional parameters
  41. options = options || {};
  42. if (!helpers.isObject(options)) throw new Error("options is invalid");
  43. var origin = options.origin;
  44. var mutate = options.mutate;
  45. // Input validation
  46. if (!geojson) throw new Error("geojson required");
  47. if (typeof factor !== "number" || factor === 0)
  48. throw new Error("invalid factor");
  49. var originIsPoint = Array.isArray(origin) || typeof origin === "object";
  50. // Clone geojson to avoid side effects
  51. if (mutate !== true) geojson = clone__default['default'](geojson);
  52. // Scale each Feature separately
  53. if (geojson.type === "FeatureCollection" && !originIsPoint) {
  54. meta.featureEach(geojson, function (feature, index) {
  55. geojson.features[index] = scale(feature, factor, origin);
  56. });
  57. return geojson;
  58. }
  59. // Scale Feature/Geometry
  60. return scale(geojson, factor, origin);
  61. }
  62. /**
  63. * Scale Feature/Geometry
  64. *
  65. * @private
  66. * @param {Feature|Geometry} feature GeoJSON Feature/Geometry
  67. * @param {number} factor of scaling, positive or negative values greater than 0
  68. * @param {string|Coord} [origin="centroid"] Point from which the scaling will occur (string options: sw/se/nw/ne/center/centroid)
  69. * @returns {Feature|Geometry} scaled GeoJSON Feature/Geometry
  70. */
  71. function scale(feature, factor, origin) {
  72. // Default params
  73. var isPoint = invariant.getType(feature) === "Point";
  74. origin = defineOrigin(feature, origin);
  75. // Shortcut no-scaling
  76. if (factor === 1 || isPoint) return feature;
  77. // Scale each coordinate
  78. meta.coordEach(feature, function (coord) {
  79. var originalDistance = rhumbDistance__default['default'](origin, coord);
  80. var bearing = rhumbBearing__default['default'](origin, coord);
  81. var newDistance = originalDistance * factor;
  82. var newCoord = invariant.getCoords(rhumbDestination__default['default'](origin, newDistance, bearing));
  83. coord[0] = newCoord[0];
  84. coord[1] = newCoord[1];
  85. if (coord.length === 3) coord[2] *= factor;
  86. });
  87. return feature;
  88. }
  89. /**
  90. * Define Origin
  91. *
  92. * @private
  93. * @param {GeoJSON} geojson GeoJSON
  94. * @param {string|Coord} origin sw/se/nw/ne/center/centroid
  95. * @returns {Feature<Point>} Point origin
  96. */
  97. function defineOrigin(geojson, origin) {
  98. // Default params
  99. if (origin === undefined || origin === null) origin = "centroid";
  100. // Input Coord
  101. if (Array.isArray(origin) || typeof origin === "object")
  102. return invariant.getCoord(origin);
  103. // Define BBox
  104. var bbox = geojson.bbox ? geojson.bbox : turfBBox__default['default'](geojson);
  105. var west = bbox[0];
  106. var south = bbox[1];
  107. var east = bbox[2];
  108. var north = bbox[3];
  109. switch (origin) {
  110. case "sw":
  111. case "southwest":
  112. case "westsouth":
  113. case "bottomleft":
  114. return helpers.point([west, south]);
  115. case "se":
  116. case "southeast":
  117. case "eastsouth":
  118. case "bottomright":
  119. return helpers.point([east, south]);
  120. case "nw":
  121. case "northwest":
  122. case "westnorth":
  123. case "topleft":
  124. return helpers.point([west, north]);
  125. case "ne":
  126. case "northeast":
  127. case "eastnorth":
  128. case "topright":
  129. return helpers.point([east, north]);
  130. case "center":
  131. return center__default['default'](geojson);
  132. case undefined:
  133. case null:
  134. case "centroid":
  135. return centroid__default['default'](geojson);
  136. default:
  137. throw new Error("invalid origin");
  138. }
  139. }
  140. module.exports = transformScale;
  141. module.exports.default = transformScale;