transform.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import {D2R, R2D, PJD_3PARAM, PJD_7PARAM, PJD_GRIDSHIFT} from './constants/values';
  2. import datum_transform from './datum_transform';
  3. import adjust_axis from './adjust_axis';
  4. import proj from './Proj';
  5. import toPoint from './common/toPoint';
  6. import checkSanity from './checkSanity';
  7. function checkNotWGS(source, dest) {
  8. return (
  9. (source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM || source.datum.datum_type === PJD_GRIDSHIFT) && dest.datumCode !== 'WGS84') ||
  10. ((dest.datum.datum_type === PJD_3PARAM || dest.datum.datum_type === PJD_7PARAM || dest.datum.datum_type === PJD_GRIDSHIFT) && source.datumCode !== 'WGS84');
  11. }
  12. export default function transform(source, dest, point, enforceAxis) {
  13. var wgs84;
  14. if (Array.isArray(point)) {
  15. point = toPoint(point);
  16. } else {
  17. // Clone the point object so inputs don't get modified
  18. point = {
  19. x: point.x,
  20. y: point.y,
  21. z: point.z,
  22. m: point.m
  23. };
  24. }
  25. var hasZ = point.z !== undefined;
  26. checkSanity(point);
  27. // Workaround for datum shifts towgs84, if either source or destination projection is not wgs84
  28. if (source.datum && dest.datum && checkNotWGS(source, dest)) {
  29. wgs84 = new proj('WGS84');
  30. point = transform(source, wgs84, point, enforceAxis);
  31. source = wgs84;
  32. }
  33. // DGR, 2010/11/12
  34. if (enforceAxis && source.axis !== 'enu') {
  35. point = adjust_axis(source, false, point);
  36. }
  37. // Transform source points to long/lat, if they aren't already.
  38. if (source.projName === 'longlat') {
  39. point = {
  40. x: point.x * D2R,
  41. y: point.y * D2R,
  42. z: point.z || 0
  43. };
  44. } else {
  45. if (source.to_meter) {
  46. point = {
  47. x: point.x * source.to_meter,
  48. y: point.y * source.to_meter,
  49. z: point.z || 0
  50. };
  51. }
  52. point = source.inverse(point); // Convert Cartesian to longlat
  53. if (!point) {
  54. return;
  55. }
  56. }
  57. // Adjust for the prime meridian if necessary
  58. if (source.from_greenwich) {
  59. point.x += source.from_greenwich;
  60. }
  61. // Convert datums if needed, and if possible.
  62. point = datum_transform(source.datum, dest.datum, point);
  63. if (!point) {
  64. return;
  65. }
  66. // Adjust for the prime meridian if necessary
  67. if (dest.from_greenwich) {
  68. point = {
  69. x: point.x - dest.from_greenwich,
  70. y: point.y,
  71. z: point.z || 0
  72. };
  73. }
  74. if (dest.projName === 'longlat') {
  75. // convert radians to decimal degrees
  76. point = {
  77. x: point.x * R2D,
  78. y: point.y * R2D,
  79. z: point.z || 0
  80. };
  81. } else { // else project
  82. point = dest.forward(point);
  83. if (dest.to_meter) {
  84. point = {
  85. x: point.x / dest.to_meter,
  86. y: point.y / dest.to_meter,
  87. z: point.z || 0
  88. };
  89. }
  90. }
  91. // DGR, 2010/11/12
  92. if (enforceAxis && dest.axis !== 'enu') {
  93. return adjust_axis(dest, true, point);
  94. }
  95. if (!hasZ) {
  96. delete point.z;
  97. }
  98. return point;
  99. }