index.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import { coordEach } from "@turf/meta";
  2. import { isNumber } from "@turf/helpers";
  3. import clone from "@turf/clone";
  4. /**
  5. * Converts a WGS84 GeoJSON object into Mercator (EPSG:900913) projection
  6. *
  7. * @name toMercator
  8. * @param {GeoJSON|Position} geojson WGS84 GeoJSON object
  9. * @param {Object} [options] Optional parameters
  10. * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)
  11. * @returns {GeoJSON} Projected GeoJSON
  12. * @example
  13. * var pt = turf.point([-71,41]);
  14. * var converted = turf.toMercator(pt);
  15. *
  16. * //addToMap
  17. * var addToMap = [pt, converted];
  18. */
  19. export function toMercator(geojson, options) {
  20. if (options === void 0) { options = {}; }
  21. return convert(geojson, "mercator", options);
  22. }
  23. /**
  24. * Converts a Mercator (EPSG:900913) GeoJSON object into WGS84 projection
  25. *
  26. * @name toWgs84
  27. * @param {GeoJSON|Position} geojson Mercator GeoJSON object
  28. * @param {Object} [options] Optional parameters
  29. * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)
  30. * @returns {GeoJSON} Projected GeoJSON
  31. * @example
  32. * var pt = turf.point([-7903683.846322424, 5012341.663847514]);
  33. * var converted = turf.toWgs84(pt);
  34. *
  35. * //addToMap
  36. * var addToMap = [pt, converted];
  37. */
  38. export function toWgs84(geojson, options) {
  39. if (options === void 0) { options = {}; }
  40. return convert(geojson, "wgs84", options);
  41. }
  42. /**
  43. * Converts a GeoJSON coordinates to the defined `projection`
  44. *
  45. * @private
  46. * @param {GeoJSON} geojson GeoJSON Feature or Geometry
  47. * @param {string} projection defines the projection system to convert the coordinates to
  48. * @param {Object} [options] Optional parameters
  49. * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)
  50. * @returns {GeoJSON} Converted GeoJSON
  51. */
  52. function convert(geojson, projection, options) {
  53. if (options === void 0) { options = {}; }
  54. // Optional parameters
  55. options = options || {};
  56. var mutate = options.mutate;
  57. // Validation
  58. if (!geojson)
  59. throw new Error("geojson is required");
  60. // Handle Position
  61. if (Array.isArray(geojson) && isNumber(geojson[0]))
  62. geojson =
  63. projection === "mercator"
  64. ? convertToMercator(geojson)
  65. : convertToWgs84(geojson);
  66. // Handle GeoJSON
  67. else {
  68. // Handle possible data mutation
  69. if (mutate !== true)
  70. geojson = clone(geojson);
  71. coordEach(geojson, function (coord) {
  72. var newCoord = projection === "mercator"
  73. ? convertToMercator(coord)
  74. : convertToWgs84(coord);
  75. coord[0] = newCoord[0];
  76. coord[1] = newCoord[1];
  77. });
  78. }
  79. return geojson;
  80. }
  81. /**
  82. * Convert lon/lat values to 900913 x/y.
  83. * (from https://github.com/mapbox/sphericalmercator)
  84. *
  85. * @private
  86. * @param {Array<number>} lonLat WGS84 point
  87. * @returns {Array<number>} Mercator [x, y] point
  88. */
  89. function convertToMercator(lonLat) {
  90. var D2R = Math.PI / 180,
  91. // 900913 properties
  92. A = 6378137.0, MAXEXTENT = 20037508.342789244;
  93. // compensate longitudes passing the 180th meridian
  94. // from https://github.com/proj4js/proj4js/blob/master/lib/common/adjust_lon.js
  95. var adjusted = Math.abs(lonLat[0]) <= 180 ? lonLat[0] : lonLat[0] - sign(lonLat[0]) * 360;
  96. var xy = [
  97. A * adjusted * D2R,
  98. A * Math.log(Math.tan(Math.PI * 0.25 + 0.5 * lonLat[1] * D2R)),
  99. ];
  100. // if xy value is beyond maxextent (e.g. poles), return maxextent
  101. if (xy[0] > MAXEXTENT)
  102. xy[0] = MAXEXTENT;
  103. if (xy[0] < -MAXEXTENT)
  104. xy[0] = -MAXEXTENT;
  105. if (xy[1] > MAXEXTENT)
  106. xy[1] = MAXEXTENT;
  107. if (xy[1] < -MAXEXTENT)
  108. xy[1] = -MAXEXTENT;
  109. return xy;
  110. }
  111. /**
  112. * Convert 900913 x/y values to lon/lat.
  113. * (from https://github.com/mapbox/sphericalmercator)
  114. *
  115. * @private
  116. * @param {Array<number>} xy Mercator [x, y] point
  117. * @returns {Array<number>} WGS84 [lon, lat] point
  118. */
  119. function convertToWgs84(xy) {
  120. // 900913 properties.
  121. var R2D = 180 / Math.PI;
  122. var A = 6378137.0;
  123. return [
  124. (xy[0] * R2D) / A,
  125. (Math.PI * 0.5 - 2.0 * Math.atan(Math.exp(-xy[1] / A))) * R2D,
  126. ];
  127. }
  128. /**
  129. * Returns the sign of the input, or zero
  130. *
  131. * @private
  132. * @param {number} x input
  133. * @returns {number} -1|0|1 output
  134. */
  135. function sign(x) {
  136. return x < 0 ? -1 : x > 0 ? 1 : 0;
  137. }