PageRenderTime 36ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/google/maps/extras/arcgislink/LambertConformalConic.as

http://gmaps-utility-library-flash.googlecode.com/
ActionScript | 128 lines | 87 code | 3 blank | 38 comment | 3 complexity | 37cd3273f0e36bda54853c737c72ce59 MD5 | raw file
  1. /*
  2. * ArcGIS for Google Maps Flash API
  3. *
  4. * License http://www.apache.org/licenses/LICENSE-2.0
  5. */
  6. /**
  7. * @author nianwei at gmail dot com
  8. */
  9. package com.google.maps.extras.arcgislink
  10. {
  11. /**
  12. * This class represents a Spatial Reference System based on <a target = wiki href = 'http://en.wikipedia.org/wiki/Lambert_conformal_conic_projection'>Lambert Conformal Conic Projection</a>. */
  13. public class LambertConformalConic extends SpatialReference
  14. {
  15. private var a_:Number;
  16. private var e_:Number;
  17. private var F_:Number;
  18. private var FE_:Number;
  19. private var lamdaF_:Number;
  20. private var n_:Number;
  21. private var rF_:Number;
  22. private var FN_:Number;
  23. /**
  24. * Create a Lambert Conformal Conic Projection based Spatial Reference. The <code>params</code> passed in construction should
  25. * include the following properties:<code>
  26. * <br/>-wkid: well-known id
  27. * <br/>-semi_major: ellipsoidal semi-major axis in meter
  28. * <br/>-unit: meters per unit
  29. * <br/>-inverse_flattening: inverse of flattening of the ellipsoid where 1/f = a/(a - b)
  30. * <br/>-standard_parallel_1: phi1, latitude of the first standard parallel
  31. * <br/>-standard_parallel_2: phi2, latitude of the second standard parallel
  32. * <br/>-latitude_of_origin: phiF, latitude of the false origin
  33. * <br/>-central_meridian: lamdaF, longitude of the false origin (with respect to the prime meridian)
  34. * <br/>-false_easting: FE, false easting, the Eastings value assigned to the natural origin
  35. * <br/>-false_northing: FN, false northing, the Northings value assigned to the natural origin
  36. * </code>
  37. * <br/> e.g. North Carolina State Plane NAD83 Feet: <br/>
  38. * <code> var ncsp82 = new ArcGISLambertConformalConic({wkid:2264, semi_major: 6378137.0,inverse_flattening: 298.257222101,
  39. * standard_parallel_1: 34.33333333333334, standard_parallel_2: 36.16666666666666,
  40. * central_meridian: -79.0, latitude_of_origin: 33.75,'false_easting': 2000000.002616666,
  41. * 'false_northing': 0, unit: 0.3048006096012192 }); </code>
  42. * @name ArcGISLambertConformalConic
  43. * @extends ArcGISSpatialReference
  44. * @constructor
  45. * @param {Object} params
  46. */
  47. public function LambertConformalConic(params:Object)
  48. {
  49. //http://pubs.er.usgs.gov/djvu/PP/PP_1395.pdf
  50. // http://www.posc.org/Epicentre.2_2/DataModel/ExamplesofUsage/eu_cs34.html
  51. //for NCSP83: GLatLng(35.102363,-80.5666)< === > GPoint(1531463.95, 495879.744);
  52. params = params || {};
  53. super(params);
  54. var f_i:Number = params.inverse_flattening;
  55. var phi1:Number = params.standard_parallel_1 * RAD_DEG;
  56. var phi2:Number = params.standard_parallel_2 * RAD_DEG;
  57. var phiF:Number = params.latitude_of_origin * RAD_DEG;
  58. this.a_ = params.semi_major / params.unit;
  59. this.lamdaF_ = params.central_meridian * RAD_DEG;
  60. this.FE_ = params.false_easting;
  61. this.FN_ = params.false_northing;
  62. var f:Number = 1.0 / f_i; //e: eccentricity of the ellipsoid where e^2 = 2f - f^2
  63. var es:Number = 2 * f - f * f;
  64. this.e_ = Math.sqrt(es);
  65. var m1:Number = this.calc_m_(phi1, es);
  66. var m2:Number = this.calc_m_(phi2, es);
  67. var tF:Number = this.calc_t_(phiF, this.e_);
  68. var t1:Number = this.calc_t_(phi1, this.e_);
  69. var t2:Number = this.calc_t_(phi2, this.e_);
  70. this.n_ = Math.log(m1 / m2) / Math.log(t1 / t2);
  71. this.F_ = m1 / (this.n_ * Math.pow(t1, this.n_));
  72. this.rF_ = this.calc_r_(this.a_, this.F_, tF, this.n_);
  73. }
  74. private function calc_m_(phi:Number, es:Number):Number{
  75. var sinphi:Number = Math.sin(phi);
  76. return Math.cos(phi) / Math.sqrt(1 - es * sinphi * sinphi);
  77. }
  78. private function calc_t_(phi:Number, e:Number):Number{
  79. var esinphi:Number = e * Math.sin(phi);
  80. return Math.tan(Math.PI / 4 - phi / 2) / Math.pow((1 - esinphi) / (1 + esinphi), e / 2);
  81. }
  82. private function calc_r_ (a:Number, F:Number, t:Number, n:Number):Number {
  83. return a * F * Math.pow(t, n);
  84. };
  85. private function calc_phi_(t_i:Number, e:Number, phi:Number):Number{
  86. var esinphi:Number = e * Math.sin(phi);
  87. return Math.PI / 2 - 2 * Math.atan(t_i * Math.pow((1 - esinphi) / (1 + esinphi), e / 2));
  88. }
  89. private function solve_phi_(t_i:Number, e:Number, init:Number):Number{
  90. // iteration
  91. var i:int = 0;
  92. var phi:Number = init;
  93. var newphi:Number = this.calc_phi_(t_i, e, phi);//this.
  94. while (Math.abs(newphi - phi) > 0.000000001 && i < 10) {
  95. i++;
  96. phi = newphi;
  97. newphi = this.calc_phi_(t_i, e, phi);//this.
  98. }
  99. return newphi;
  100. }
  101. override public function forward(lnglat:Array):Array{
  102. var phi:Number = lnglat[1] * RAD_DEG;// (Math.PI / 180);
  103. var lamda:Number = lnglat[0] * RAD_DEG;
  104. var t:Number = this.calc_t_(phi, this.e_);
  105. var r:Number = this.calc_r_(this.a_, this.F_, t, this.n_);
  106. var theta:Number = this.n_ * (lamda - this.lamdaF_);
  107. var E:Number = this.FE_ + r * Math.sin(theta);
  108. var N:Number = this.FN_ + this.rF_ - r * Math.cos(theta);
  109. return [E, N];
  110. }
  111. override public function reverse(coords:Array):Array{
  112. var E:Number = coords[0];
  113. var N:Number = coords[1];
  114. var theta_i:Number = Math.atan((E - this.FE_) / (this.rF_ - (N - this.FN_)));
  115. var r_i:Number = (this.n_ > 0 ? 1 : -1) * Math.sqrt((E - this.FE_) * (E - this.FE_) + (this.rF_ - (N - this.FN_)) * (this.rF_ - (N - this.FN_)));
  116. var t_i:Number = Math.pow((r_i / (this.a_ * this.F_)), 1 / this.n_);
  117. var phi:Number = this.solve_phi_(t_i, this.e_, 0);
  118. var lamda:Number = theta_i / this.n_ + this.lamdaF_;
  119. return [lamda / RAD_DEG, phi / RAD_DEG];
  120. }
  121. override public function getCircumference():Number{
  122. return Math.PI * 2 * this.a_;
  123. }
  124. }
  125. }