LambertConformalConic.cs
上传用户:sex100000
上传日期:2013-11-09
资源大小:1377k
文件大小:13k
源码类别:

GIS编程

开发平台:

C#

  1. // Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
  2. //
  3. // This file is part of SharpMap.
  4. // SharpMap is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. // 
  9. // SharpMap is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU Lesser General Public License for more details.
  13. // You should have received a copy of the GNU Lesser General Public License
  14. // along with SharpMap; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  16. // SOURCECODE IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
  17. /*
  18.  *  Copyright (C) 2002 Urban Science Applications, Inc. 
  19.  *
  20.  *  This library is free software; you can redistribute it and/or
  21.  *  modify it under the terms of the GNU Lesser General Public
  22.  *  License as published by the Free Software Foundation; either
  23.  *  version 2.1 of the License, or (at your option) any later version.
  24.  *
  25.  *  This library is distributed in the hope that it will be useful,
  26.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  27.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  28.  *  Lesser General Public License for more details.
  29.  *
  30.  *  You should have received a copy of the GNU Lesser General Public
  31.  *  License along with this library; if not, write to the Free Software
  32.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  33.  *
  34.  */
  35. using System;
  36. using System.Collections.Generic;
  37. using System.Collections.ObjectModel;
  38. using SharpMap.CoordinateSystems;
  39. using SharpMap.CoordinateSystems.Transformations;
  40. namespace SharpMap.CoordinateSystems.Projections
  41. {
  42. /// <summary>
  43. /// Implemetns the Lambert Conformal Conic 2SP Projection.
  44. /// </summary>
  45. /// <remarks>
  46. /// <para>The Lambert Conformal Conic projection is a standard projection for presenting maps
  47. /// of land areas whose East-West extent is large compared with their North-South extent.
  48. /// This projection is "conformal" in the sense that lines of latitude and longitude, 
  49. /// which are perpendicular to one another on the earth's surface, are also perpendicular
  50. /// to one another in the projected domain.</para>
  51. /// </remarks>
  52. internal class LambertConformalConic2SP : MapProjection
  53. {
  54. double _falseEasting;
  55. double _falseNorthing;
  56. private double es=0;              /* eccentricity squared         */
  57. private double e=0;               /* eccentricity                 */
  58. private double center_lon=0;      /* center longituted            */
  59. private double center_lat=0;      /* cetner latitude              */
  60. private double ns=0;              /* ratio of angle between meridian*/
  61. private double f0=0;              /* flattening of ellipsoid      */
  62. private double rh=0;              /* height above ellipsoid       */
  63. #region Constructors
  64. /// <summary>
  65. /// Creates an instance of an LambertConformalConic2SPProjection projection object.
  66. /// </summary>
  67. /// <remarks>
  68. /// <para>The parameters this projection expects are listed below.</para>
  69. /// <list type="table">
  70. /// <listheader><term>Items</term><description>Descriptions</description></listheader>
  71. /// <item><term>latitude_of_false_origin</term><description>The latitude of the point which is not the natural origin and at which grid coordinate values false easting and false northing are defined.</description></item>
  72. /// <item><term>longitude_of_false_origin</term><description>The longitude of the point which is not the natural origin and at which grid coordinate values false easting and false northing are defined.</description></item>
  73. /// <item><term>latitude_of_1st_standard_parallel</term><description>For a conic projection with two standard parallels, this is the latitude of intersection of the cone with the ellipsoid that is nearest the pole.  Scale is true along this parallel.</description></item>
  74. /// <item><term>latitude_of_2nd_standard_parallel</term><description>For a conic projection with two standard parallels, this is the latitude of intersection of the cone with the ellipsoid that is furthest from the pole.  Scale is true along this parallel.</description></item>
  75. /// <item><term>easting_at_false_origin</term><description>The easting value assigned to the false origin.</description></item>
  76. /// <item><term>northing_at_false_origin</term><description>The northing value assigned to the false origin.</description></item>
  77. /// </list>
  78. /// </remarks>
  79. /// <param name="parameters">List of parameters to initialize the projection.</param>
  80. public LambertConformalConic2SP(Collection<ProjectionParameter> parameters) : this(parameters,false)
  81. {
  82. }
  83. /// <summary>
  84. /// Creates an instance of an Albers projection object.
  85. /// </summary>
  86. /// <remarks>
  87. /// <para>The parameters this projection expects are listed below.</para>
  88. /// <list type="table">
  89. /// <listheader><term>Parameter</term><description>Description</description></listheader>
  90. /// <item><term>latitude_of_origin</term><description>The latitude of the point which is not the natural origin and at which grid coordinate values false easting and false northing are defined.</description></item>
  91. /// <item><term>central_meridian</term><description>The longitude of the point which is not the natural origin and at which grid coordinate values false easting and false northing are defined.</description></item>
  92. /// <item><term>standard_parallel_1</term><description>For a conic projection with two standard parallels, this is the latitude of intersection of the cone with the ellipsoid that is nearest the pole.  Scale is true along this parallel.</description></item>
  93. /// <item><term>standard_parallel_2</term><description>For a conic projection with two standard parallels, this is the latitude of intersection of the cone with the ellipsoid that is furthest from the pole.  Scale is true along this parallel.</description></item>
  94. /// <item><term>false_easting</term><description>The easting value assigned to the false origin.</description></item>
  95. /// <item><term>false_northing</term><description>The northing value assigned to the false origin.</description></item>
  96. /// </list>
  97. /// </remarks>
  98. /// <param name="parameters">List of parameters to initialize the projection.</param>
  99. /// <param name="isInverse">Indicates whether the projection forward (meters to degrees or degrees to meters).</param>
  100. public LambertConformalConic2SP(Collection<ProjectionParameter> parameters, bool isInverse)
  101. : base(parameters, isInverse)
  102. {
  103. this.Name = "Lambert_Conformal_Conic_2SP";
  104. this.Authority = "EPSG";
  105. this.AuthorityCode = 9802;
  106. ProjectionParameter latitude_of_origin = GetParameter("latitude_of_origin");
  107. ProjectionParameter central_meridian = GetParameter("central_meridian");
  108. ProjectionParameter standard_parallel_1 = GetParameter("standard_parallel_1");
  109. ProjectionParameter standard_parallel_2 = GetParameter("standard_parallel_2");
  110. ProjectionParameter false_easting = GetParameter("false_easting");
  111. ProjectionParameter false_northing = GetParameter("false_northing");
  112. //Check for missing parameters
  113. if (latitude_of_origin == null)
  114. throw new ArgumentException("Missing projection parameter 'latitude_of_origin'");
  115. if (central_meridian == null)
  116. throw new ArgumentException("Missing projection parameter 'central_meridian'");
  117. if (standard_parallel_1 == null)
  118. throw new ArgumentException("Missing projection parameter 'standard_parallel_1'");
  119. if (standard_parallel_2 == null)
  120. throw new ArgumentException("Missing projection parameter 'standard_parallel_2'");
  121. if (false_easting == null)
  122. throw new ArgumentException("Missing projection parameter 'false_easting'");
  123. if (false_northing == null)
  124. throw new ArgumentException("Missing projection parameter 'false_northing'");
  125. double c_lat = Degrees2Radians(latitude_of_origin.Value);
  126. double c_lon = Degrees2Radians(central_meridian.Value);
  127. double lat1 = Degrees2Radians(standard_parallel_1.Value);
  128. double lat2 = Degrees2Radians(standard_parallel_2.Value);
  129. this._falseEasting = false_easting.Value;
  130. this._falseNorthing = false_northing.Value;
  131. double sin_po;                  /* sin value                            */
  132. double cos_po;                  /* cos value                            */
  133. double con;                     /* temporary variable                   */
  134. double ms1;                     /* small m 1                            */
  135. double ms2;                     /* small m 2                            */
  136. double ts0;                     /* small t 0                            */
  137. double ts1;                     /* small t 1                            */
  138. double ts2;                     /* small t 2                            */
  139. /* Standard Parallels cannot be equal and on opposite sides of the equator
  140. ------------------------------------------------------------------------*/
  141. if (Math.Abs(lat1+lat2) < EPSLN)
  142. {
  143. //Debug.Assert(true,"LambertConformalConic:LambertConformalConic() - Equal Latitiudes for St. Parallels on opposite sides of equator");
  144. throw new ArgumentException("Equal latitudes for St. Parallels on opposite sides of equator.");
  145. }
  146. es = 1.0 - Math.Pow(this._semiMinor / this._semiMajor,2);
  147. e = Math.Sqrt(es);
  148. center_lon = c_lon;
  149. center_lat = c_lat;
  150. sincos(lat1,out sin_po,out cos_po);
  151. con = sin_po;
  152. ms1 = msfnz(e,sin_po,cos_po);
  153. ts1 = tsfnz(e,lat1,sin_po);
  154. sincos(lat2,out sin_po,out cos_po);
  155. ms2 = msfnz(e,sin_po,cos_po);
  156. ts2 = tsfnz(e,lat2,sin_po);
  157. sin_po = Math.Sin(center_lat);
  158. ts0 = tsfnz(e,center_lat,sin_po);
  159. if (Math.Abs(lat1 - lat2) > EPSLN)
  160. ns = Math.Log(ms1/ms2)/ Math.Log (ts1/ts2);
  161. else
  162. ns = con;
  163. f0 = ms1 / (ns * Math.Pow(ts1,ns));
  164. rh = this._semiMajor * f0 * Math.Pow(ts0,ns);
  165. }
  166. #endregion
  167. /// <summary>
  168. /// Converts coordinates in decimal degrees to projected meters.
  169. /// </summary>
  170. /// <param name="lonlat">The point in decimal degrees.</param>
  171. /// <returns>Point in projected meters</returns>
  172. public override SharpMap.Geometries.Point DegreesToMeters(SharpMap.Geometries.Point lonlat)
  173. {
  174. double dLongitude = Degrees2Radians(lonlat.X);
  175. double dLatitude = Degrees2Radians(lonlat.Y);
  176. double con;                     /* temporary angle variable             */
  177. double rh1;                     /* height above ellipsoid               */
  178. double sinphi;                  /* sin value                            */
  179. double theta;                   /* angle                                */
  180. double ts;                      /* small value t                        */
  181. con  = Math.Abs( Math.Abs(dLatitude) - HALF_PI);
  182. if (con > EPSLN)
  183. {
  184. sinphi = Math.Sin(dLatitude);
  185. ts = tsfnz(e,dLatitude,sinphi);
  186. rh1 = this._semiMajor * f0 * Math.Pow(ts,ns);
  187. }
  188. else
  189. {
  190. con = dLatitude * ns;
  191. if (con <= 0)
  192. {
  193. throw new ApplicationException();
  194. }
  195. rh1 = 0;
  196. }
  197. theta = ns * adjust_lon(dLongitude - center_lon);
  198. return new SharpMap.Geometries.Point(
  199. rh1 * Math.Sin(theta) + this._falseEasting,
  200. rh - rh1 * Math.Cos(theta) + this._falseNorthing);
  201. }
  202. /// <summary>
  203. /// Converts coordinates in projected meters to decimal degrees.
  204. /// </summary>
  205. /// <param name="p">Point in meters</param>
  206. /// <returns>Transformed point in decimal degrees</returns>
  207. public override SharpMap.Geometries.Point MetersToDegrees(SharpMap.Geometries.Point p)
  208. {
  209. double dLongitude =Double.NaN;
  210. double dLatitude =Double.NaN;
  211. double rh1; /* height above ellipsoid */
  212. double con; /* sign variable */
  213. double ts; /* small t */
  214. double theta; /* angle */
  215. long   flag; /* error flag */
  216. flag = 0;
  217. double dX = p.X - this._falseEasting;
  218. double dY = rh - p.Y + this._falseNorthing;
  219. if (ns > 0)
  220. {
  221. rh1 = Math.Sqrt(dX * dX + dY * dY);
  222. con = 1.0;
  223. }
  224. else
  225. {
  226. rh1 = -Math.Sqrt(dX * dX + dY * dY);
  227. con = -1.0;
  228. }
  229. theta = 0.0;
  230. if (rh1 != 0)
  231. theta = Math.Atan2((con * dX),(con * dY));
  232. if ((rh1 != 0) || (ns > 0.0))
  233. {
  234. con = 1.0/ns;
  235. ts = Math.Pow((rh1/(this._semiMajor * f0)),con);
  236. dLatitude = phi2z(e,ts,out flag);
  237. if (flag != 0)
  238. {
  239. throw new ApplicationException();
  240. }
  241. }
  242. else
  243. {
  244. dLatitude = -HALF_PI;
  245. }
  246. dLongitude = adjust_lon(theta/ns + center_lon);
  247. return new SharpMap.Geometries.Point(Radians2Degrees(dLongitude), Radians2Degrees(dLatitude));
  248. }
  249. /// <summary>
  250. /// Returns the inverse of this projection.
  251. /// </summary>
  252. /// <returns>IMathTransform that is the reverse of the current projection.</returns>
  253. public override IMathTransform Inverse()
  254. {
  255. if (_inverse==null)
  256. {
  257. _inverse = new LambertConformalConic2SP(this._Parameters, ! _isInverse);
  258. }
  259. return _inverse;
  260. }
  261. }
  262. }