lcc.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import msfnz from '../common/msfnz';
  2. import tsfnz from '../common/tsfnz';
  3. import sign from '../common/sign';
  4. import adjust_lon from '../common/adjust_lon';
  5. import phi2z from '../common/phi2z';
  6. import {HALF_PI, EPSLN} from '../constants/values';
  7. export function init() {
  8. //double lat0; /* the reference latitude */
  9. //double long0; /* the reference longitude */
  10. //double lat1; /* first standard parallel */
  11. //double lat2; /* second standard parallel */
  12. //double r_maj; /* major axis */
  13. //double r_min; /* minor axis */
  14. //double false_east; /* x offset in meters */
  15. //double false_north; /* y offset in meters */
  16. //the above value can be set with proj4.defs
  17. //example: proj4.defs("EPSG:2154","+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
  18. if (!this.lat2) {
  19. this.lat2 = this.lat1;
  20. } //if lat2 is not defined
  21. if (!this.k0) {
  22. this.k0 = 1;
  23. }
  24. this.x0 = this.x0 || 0;
  25. this.y0 = this.y0 || 0;
  26. // Standard Parallels cannot be equal and on opposite sides of the equator
  27. if (Math.abs(this.lat1 + this.lat2) < EPSLN) {
  28. return;
  29. }
  30. var temp = this.b / this.a;
  31. this.e = Math.sqrt(1 - temp * temp);
  32. var sin1 = Math.sin(this.lat1);
  33. var cos1 = Math.cos(this.lat1);
  34. var ms1 = msfnz(this.e, sin1, cos1);
  35. var ts1 = tsfnz(this.e, this.lat1, sin1);
  36. var sin2 = Math.sin(this.lat2);
  37. var cos2 = Math.cos(this.lat2);
  38. var ms2 = msfnz(this.e, sin2, cos2);
  39. var ts2 = tsfnz(this.e, this.lat2, sin2);
  40. var ts0 = tsfnz(this.e, this.lat0, Math.sin(this.lat0));
  41. if (Math.abs(this.lat1 - this.lat2) > EPSLN) {
  42. this.ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2);
  43. }
  44. else {
  45. this.ns = sin1;
  46. }
  47. if (isNaN(this.ns)) {
  48. this.ns = sin1;
  49. }
  50. this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns));
  51. this.rh = this.a * this.f0 * Math.pow(ts0, this.ns);
  52. if (!this.title) {
  53. this.title = "Lambert Conformal Conic";
  54. }
  55. }
  56. // Lambert Conformal conic forward equations--mapping lat,long to x,y
  57. // -----------------------------------------------------------------
  58. export function forward(p) {
  59. var lon = p.x;
  60. var lat = p.y;
  61. // singular cases :
  62. if (Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) {
  63. lat = sign(lat) * (HALF_PI - 2 * EPSLN);
  64. }
  65. var con = Math.abs(Math.abs(lat) - HALF_PI);
  66. var ts, rh1;
  67. if (con > EPSLN) {
  68. ts = tsfnz(this.e, lat, Math.sin(lat));
  69. rh1 = this.a * this.f0 * Math.pow(ts, this.ns);
  70. }
  71. else {
  72. con = lat * this.ns;
  73. if (con <= 0) {
  74. return null;
  75. }
  76. rh1 = 0;
  77. }
  78. var theta = this.ns * adjust_lon(lon - this.long0);
  79. p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0;
  80. p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0;
  81. return p;
  82. }
  83. // Lambert Conformal Conic inverse equations--mapping x,y to lat/long
  84. // -----------------------------------------------------------------
  85. export function inverse(p) {
  86. var rh1, con, ts;
  87. var lat, lon;
  88. var x = (p.x - this.x0) / this.k0;
  89. var y = (this.rh - (p.y - this.y0) / this.k0);
  90. if (this.ns > 0) {
  91. rh1 = Math.sqrt(x * x + y * y);
  92. con = 1;
  93. }
  94. else {
  95. rh1 = -Math.sqrt(x * x + y * y);
  96. con = -1;
  97. }
  98. var theta = 0;
  99. if (rh1 !== 0) {
  100. theta = Math.atan2((con * x), (con * y));
  101. }
  102. if ((rh1 !== 0) || (this.ns > 0)) {
  103. con = 1 / this.ns;
  104. ts = Math.pow((rh1 / (this.a * this.f0)), con);
  105. lat = phi2z(this.e, ts);
  106. if (lat === -9999) {
  107. return null;
  108. }
  109. }
  110. else {
  111. lat = -HALF_PI;
  112. }
  113. lon = adjust_lon(theta / this.ns + this.long0);
  114. p.x = lon;
  115. p.y = lat;
  116. return p;
  117. }
  118. export var names = [
  119. "Lambert Tangential Conformal Conic Projection",
  120. "Lambert_Conformal_Conic",
  121. "Lambert_Conformal_Conic_1SP",
  122. "Lambert_Conformal_Conic_2SP",
  123. "lcc",
  124. "Lambert Conic Conformal (1SP)",
  125. "Lambert Conic Conformal (2SP)"
  126. ];
  127. export default {
  128. init: init,
  129. forward: forward,
  130. inverse: inverse,
  131. names: names
  132. };