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

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. using System;
  17. using System.Collections.Generic;
  18. using System.Collections.ObjectModel;
  19. using System.Text;
  20. namespace SharpMap
  21. {
  22. /// <summary>
  23. /// Map class
  24. /// </summary>
  25. /// <example>
  26. /// Creating a new map instance, adding layers and rendering the map:
  27. /// <code lang="C#">
  28. /// SharpMap.Map myMap = new SharpMap.Map(picMap.Size);
  29. /// myMap.MinimumZoom = 100;
  30. /// myMap.BackgroundColor = Color.White;
  31. /// 
  32. /// SharpMap.Layers.VectorLayer myLayer = new SharpMap.Layers.VectorLayer("My layer");
  33. /// string ConnStr = "Server=127.0.0.1;Port=5432;User Id=postgres;Password=password;Database=myGisDb;";
  34. /// myLayer.DataSource = new SharpMap.Data.Providers.PostGIS(ConnStr, "myTable", "the_geom", 32632);
  35. /// myLayer.FillStyle = new SolidBrush(Color.FromArgb(240,240,240)); //Applies to polygon types only
  36. /// myLayer.OutlineStyle = new Pen(Color.Blue, 1); //Applies to polygon and linetypes only
  37. /// //Setup linestyle (applies to line types only)
  38. /// myLayer.Style.Line.Width = 2;
  39. /// myLayer.Style.Line.Color = Color.Black;
  40. /// myLayer.Style.Line.EndCap = System.Drawing.Drawing2D.LineCap.Round; //Round end
  41. /// myLayer.Style.Line.StartCap = layRailroad.LineStyle.EndCap; //Round start
  42. /// myLayer.Style.Line.DashPattern = new float[] { 4.0f, 2.0f }; //Dashed linestyle
  43. /// myLayer.Style.EnableOutline = true;
  44. /// myLayer.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; //Render smooth lines
  45. /// myLayer.MaxVisible = 40000;
  46. /// 
  47. /// myMap.Layers.Add(myLayer);
  48. /// // [add more layers...]
  49. /// 
  50. /// myMap.Center = new SharpMap.Geometries.Point(725000, 6180000); //Set center of map
  51. /// myMap.Zoom = 1200; //Set zoom level
  52. /// myMap.Size = new System.Drawing.Size(300,200); //Set output size
  53. /// 
  54. /// System.Drawing.Image imgMap = myMap.GetMap(); //Renders the map
  55. /// </code>
  56. /// </example>
  57. public class Map : IDisposable
  58. {
  59. /// <summary>
  60. /// Used for converting numbers to/from strings
  61. /// </summary>
  62. public static System.Globalization.NumberFormatInfo numberFormat_EnUS = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
  63. /// <summary>
  64. /// Initializes a new map
  65. /// </summary>
  66. public Map() : this(new System.Drawing.Size(300,150))
  67. {
  68. }
  69. /// <summary>
  70. /// Initializes a new map
  71. /// </summary>
  72. /// <param name="size">Size of map in pixels</param>
  73. public Map(System.Drawing.Size size)
  74. {
  75. this.Size = size;
  76. this.Layers = new Collection<SharpMap.Layers.ILayer>();
  77. this.BackColor = System.Drawing.Color.Transparent;
  78. this._MaximumZoom = double.MaxValue;
  79. this._MinimumZoom = 0;
  80. _MapTransform = new System.Drawing.Drawing2D.Matrix();
  81. MapTransformInverted = new System.Drawing.Drawing2D.Matrix();
  82. _Center = new SharpMap.Geometries.Point(0, 0);
  83. _Zoom = 1;
  84. _PixelAspectRatio = 1.0;
  85. }
  86. /// <summary>
  87. /// Disposes the map object
  88. /// </summary>
  89. public void Dispose()
  90. {
  91. foreach (SharpMap.Layers.Layer layer in this.Layers)
  92. if (layer is IDisposable)
  93. ((IDisposable)layer).Dispose();
  94. this.Layers.Clear();
  95. }
  96. #region Events
  97. /// <summary>
  98. /// EventHandler for event fired when the maps layer list has been changed
  99. /// </summary>
  100. public delegate void LayersChangedEventHandler();
  101. /// <summary>
  102. /// Event fired when the maps layer list have been changed
  103. /// </summary>
  104. public event LayersChangedEventHandler LayersChanged;
  105. /// <summary>
  106. /// EventHandler for event fired when the zoomlevel or the center point has been changed
  107. /// </summary>
  108. public delegate void MapViewChangedHandler();
  109. /// <summary>
  110. /// Event fired when the zoomlevel or the center point has been changed
  111. /// </summary>
  112. public event MapViewChangedHandler MapViewOnChange;
  113. /// <summary>
  114. /// EventHandler for event fired when all layers have been rendered
  115. /// </summary>
  116. public delegate void MapRenderedEventHandler(System.Drawing.Graphics g);
  117. /// <summary>
  118. /// Event fired when all layers have been rendered
  119. /// </summary>
  120. public event MapRenderedEventHandler MapRendered;
  121. #endregion
  122. #region Methods
  123. /// <summary>
  124. /// Renders the map to an image
  125. /// </summary>
  126. /// <returns></returns>
  127. public System.Drawing.Image GetMap()
  128. {
  129. if (Layers == null || Layers.Count == 0)
  130. throw new InvalidOperationException("No layers to render");
  131. System.Drawing.Image img = new System.Drawing.Bitmap(this.Size.Width, this.Size.Height);
  132. System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img);
  133. g.Transform = this.MapTransform;
  134. g.Clear(this.BackColor);
  135. g.PageUnit = System.Drawing.GraphicsUnit.Pixel;
  136. int SRID = (Layers.Count > 0 ? Layers[0].SRID : -1); //Get the SRID of the first layer
  137. for (int i = 0; i < _Layers.Count; i++)
  138. {
  139. if (_Layers[i].Enabled && _Layers[i].MaxVisible >= this.Zoom && _Layers[i].MinVisible < this.Zoom)
  140. _Layers[i].Render(g, this);
  141. }
  142. if (MapRendered != null) MapRendered(g); //Fire render event
  143. g.Dispose();
  144. return img;
  145. }
  146. /// <summary>
  147. /// Returns an enumerable for all layers containing the search parameter in the LayerName property
  148. /// </summary>
  149. /// <param name="layername">Search parameter</param>
  150. /// <returns>IEnumerable</returns>
  151. public IEnumerable<SharpMap.Layers.ILayer> FindLayer(string layername)
  152. {
  153. foreach (SharpMap.Layers.ILayer l in this.Layers)
  154. if (l.LayerName.Contains(layername))
  155. yield return l;
  156. }
  157. /// <summary>
  158. /// Returns a layer by its name
  159. /// </summary>
  160. /// <param name="name">Name of layer</param>
  161. /// <returns>Layer</returns>
  162. public SharpMap.Layers.ILayer GetLayerByName(string name)
  163. {
  164. //return _Layers.Find(delegate(SharpMap.Layers.ILayer layer) { return layer.LayerName.Equals(name); });
  165.             for (int i = 0; i < _Layers.Count; i++)
  166.                 if (String.Equals(_Layers[i].LayerName, name, StringComparison.InvariantCultureIgnoreCase))
  167.                     return _Layers[i];
  168.             return null;
  169. }
  170. /// <summary>
  171. /// Zooms to the extents of all layers
  172. /// </summary>
  173. public void ZoomToExtents()
  174. {
  175. this.ZoomToBox(this.GetExtents());
  176. }
  177. /// <summary>
  178. /// Zooms the map to fit a bounding box
  179. /// </summary>
  180. /// <remarks>
  181. /// NOTE: If the aspect ratio of the box and the aspect ratio of the mapsize
  182. /// isn't the same, the resulting map-envelope will be adjusted so that it contains
  183. /// the bounding box, thus making the resulting envelope larger!
  184. /// </remarks>
  185. /// <param name="bbox"></param>
  186. public void ZoomToBox(SharpMap.Geometries.BoundingBox bbox)
  187. {
  188. this._Zoom = bbox.Width; //Set the private center value so we only fire one MapOnViewChange event
  189. if (this.Envelope.Height < bbox.Height)
  190. this._Zoom *= bbox.Height / this.Envelope.Height;
  191. this.Center = bbox.GetCentroid();
  192. }
  193. /// <summary>
  194. /// Converts a point from world coordinates to image coordinates based on the current
  195. /// zoom, center and mapsize.
  196. /// </summary>
  197. /// <param name="p">Point in world coordinates</param>
  198. /// <returns>Point in image coordinates</returns>
  199. public System.Drawing.PointF WorldToImage(SharpMap.Geometries.Point p)
  200. {
  201. return Utilities.Transform.WorldtoMap(p, this);
  202. }
  203. /// <summary>
  204. /// Converts a point from image coordinates to world coordinates based on the current
  205. /// zoom, center and mapsize.
  206. /// </summary>
  207. /// <param name="p">Point in image coordinates</param>
  208. /// <returns>Point in world coordinates</returns>
  209. public SharpMap.Geometries.Point ImageToWorld(System.Drawing.PointF p)
  210. {
  211. return Utilities.Transform.MapToWorld(p, this);
  212. }
  213. #endregion
  214. #region Properties
  215. /// <summary>
  216. /// Gets the extents of the current map based on the current zoom, center and mapsize
  217. /// </summary>
  218. public SharpMap.Geometries.BoundingBox Envelope
  219. {
  220. get {
  221. return new SharpMap.Geometries.BoundingBox(
  222. new SharpMap.Geometries.Point(this.Center.X - this.Zoom * .5, this.Center.Y - this.MapHeight * .5),
  223. new SharpMap.Geometries.Point(this.Center.X + this.Zoom * .5, this.Center.Y + this.MapHeight * .5));
  224. }
  225. }
  226. private System.Drawing.Drawing2D.Matrix _MapTransform;
  227. internal System.Drawing.Drawing2D.Matrix MapTransformInverted;
  228. /// <summary>
  229. /// Using the <see cref="MapTransform"/> you can alter the coordinate system of the map rendering.
  230. /// This makes it possible to rotate or rescale the image, for instance to have another direction than north upwards.
  231. /// </summary>
  232. /// <example>
  233. /// Rotate the map output 45 degrees around its center:
  234. /// <code lang="C#">
  235. /// System.Drawing.Drawing2D.Matrix maptransform = new System.Drawing.Drawing2D.Matrix(); //Create transformation matrix
  236. /// maptransform.RotateAt(45,new PointF(myMap.Size.Width/2,myMap.Size.Height/2)); //Apply 45 degrees rotation around the center of the map
  237. /// myMap.MapTransform = maptransform; //Apply transformation to map
  238. /// </code>
  239. /// </example>
  240. public System.Drawing.Drawing2D.Matrix MapTransform
  241. {
  242. get { return _MapTransform; }
  243. set
  244. {
  245. _MapTransform = value;
  246. if (_MapTransform.IsInvertible)
  247. {
  248. MapTransformInverted = _MapTransform.Clone();
  249. MapTransformInverted.Invert();
  250. }
  251. else
  252. MapTransformInverted.Reset();
  253. }
  254. }
  255. private Collection<SharpMap.Layers.ILayer> _Layers;
  256. /// <summary>
  257. /// A collection of layers. The first layer in the list is drawn first, the last one on top.
  258. /// </summary>
  259. public Collection<SharpMap.Layers.ILayer> Layers
  260. {
  261. get { return _Layers; }
  262. set {
  263. int iBefore = 0;
  264. if (_Layers != null)
  265. iBefore = _Layers.Count;
  266. _Layers = value;
  267. if (value != null)
  268. {
  269. if (LayersChanged != null) //Layers changed. Fire event
  270. LayersChanged();
  271. if (MapViewOnChange != null)
  272. MapViewOnChange();
  273. }
  274. }
  275. }
  276. private System.Drawing.Color _BackgroundColor;
  277. /// <summary>
  278. /// Map background color (defaults to transparent)
  279. /// </summary>
  280. public System.Drawing.Color BackColor
  281. {
  282. get { return _BackgroundColor; }
  283. set
  284. {
  285. _BackgroundColor = value;
  286. if (MapViewOnChange != null)
  287. MapViewOnChange();
  288. }
  289. }
  290. private SharpMap.Geometries.Point _Center;
  291. /// <summary>
  292. /// Center of map in WCS
  293. /// </summary>
  294. public SharpMap.Geometries.Point Center
  295. {
  296. get { return _Center; }
  297. set {
  298. _Center = value;
  299. if (MapViewOnChange != null)
  300. MapViewOnChange();
  301. }
  302. }
  303. private double _Zoom;
  304. /// <summary>
  305. /// Gets or sets the zoom level of map.
  306. /// </summary>
  307. /// <remarks>
  308. /// <para>The zoom level corresponds to the width of the map in WCS units.</para>
  309. /// <para>A zoomlevel of 0 will result in an empty map being rendered, but will not throw an exception</para>
  310. /// </remarks>
  311. public double Zoom
  312. {
  313. get { return _Zoom; }
  314. set {
  315. if (value < _MinimumZoom)
  316. _Zoom = _MinimumZoom;
  317. else if (value > _MaximumZoom)
  318. _Zoom = _MaximumZoom;
  319. else
  320. _Zoom = value;
  321. if (MapViewOnChange != null)
  322. MapViewOnChange();
  323. }
  324. }
  325. /// <summary>
  326. /// Gets the extents of the map based on the extents of all the layers in the layers collection
  327. /// </summary>
  328. /// <returns>Full map extents</returns>
  329. public SharpMap.Geometries.BoundingBox GetExtents()
  330. {
  331. if (this.Layers == null || this.Layers.Count == 0)
  332. throw (new InvalidOperationException("No layers to zoom to"));
  333. SharpMap.Geometries.BoundingBox bbox = null;
  334. for (int i = 0; i < this.Layers.Count; i++)
  335. {
  336. if (bbox == null)
  337. bbox = this.Layers[i].Envelope;
  338. else
  339. bbox = bbox.Join(this.Layers[i].Envelope);
  340. }
  341. return bbox;
  342. }
  343. /// <summary>
  344. /// Returns the size of a pixel in world coordinate units
  345. /// </summary>
  346. public double PixelSize
  347. {
  348. get { return this.Zoom / this.Size.Width; }
  349. }
  350. /// <summary>
  351. /// Returns the width of a pixel in world coordinate units.
  352. /// </summary>
  353. /// <remarks>The value returned is the same as <see cref="PixelSize"/>.</remarks>
  354. public double PixelWidth
  355. {
  356. get { return PixelSize; }
  357. }
  358. /// <summary>
  359. /// Returns the height of a pixel in world coordinate units.
  360. /// </summary>
  361. /// <remarks>The value returned is the same as <see cref="PixelSize"/> unless <see cref="PixelAspectRatio"/> is different from 1.</remarks>
  362. public double PixelHeight
  363. {
  364. get { return PixelSize * _PixelAspectRatio; }
  365. }
  366. private double _PixelAspectRatio = 1.0;
  367. /// <summary>
  368. /// Gets or sets the aspect-ratio of the pixel scales. A value less than 
  369. /// 1 will make the map streach upwards, and larger than 1 will make it smaller.
  370. /// </summary>
  371. /// <exception cref="ArgumentException">Throws an argument exception when value is 0 or less.</exception>
  372. public double PixelAspectRatio
  373. {
  374. get { return _PixelAspectRatio; }
  375. set {
  376. if (_PixelAspectRatio <= 0)
  377. throw new ArgumentException("Invalid Pixel Aspect Ratio");
  378. _PixelAspectRatio = value; }
  379. }
  380. /// <summary>
  381. /// Height of map in world units
  382. /// </summary>
  383. /// <returns></returns>
  384. public double MapHeight
  385. {
  386. get { return (this.Zoom * this.Size.Height) / this.Size.Width * this.PixelAspectRatio; }
  387. }
  388. private System.Drawing.Size _Size;
  389. /// <summary>
  390. /// Size of output map
  391. /// </summary>
  392. public System.Drawing.Size Size
  393. {
  394. get { return _Size; }
  395. set { _Size = value; }
  396. }
  397. private double _MinimumZoom;
  398. /// <summary>
  399. /// Minimum zoom amount allowed
  400. /// </summary>
  401. public double MinimumZoom
  402. {
  403. get { return _MinimumZoom; }
  404. set {
  405. if (value < 0)
  406. throw (new ArgumentException("Minimum zoom must be 0 or more"));
  407. _MinimumZoom = value; 
  408. }
  409. }
  410. private double _MaximumZoom;
  411. /// <summary>
  412. /// Maximum zoom amount allowed
  413. /// </summary>
  414. public double MaximumZoom
  415. {
  416. get { return _MaximumZoom; }
  417. set {
  418. if (value <= 0)
  419. throw (new ArgumentException("Maximum zoom must larger than 0"));
  420. _MaximumZoom = value; 
  421. }
  422. }
  423. #endregion
  424. //#region ISerializable Members
  425. ///// <summary>
  426. ///// Populates a SerializationInfo with the data needed to serialize the target object.
  427. ///// </summary>
  428. ///// <param name="info"></param>
  429. ///// <param name="context"></param>
  430. //public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
  431. //{
  432. //    System.Runtime.Serialization.SurrogateSelector ss = SharpMap.Utilities.Surrogates.GetSurrogateSelectors();
  433. //    info.AddValue("BackgroundColor", this._BackgroundColor);
  434. //    info.AddValue("Center", this._Center);
  435. //    info.AddValue("Layers", this._Layers);
  436. //    info.AddValue("MapTransform", this._MapTransform);
  437. //    info.AddValue("MaximumZoom", this._MaximumZoom);
  438. //    info.AddValue("MinimumZoom", this._MinimumZoom);
  439. //    info.AddValue("Size", this._Size);
  440. //    info.AddValue("Zoom", this._Zoom);
  441. //}
  442. ///// <summary>
  443. ///// Deserialization constructor.
  444. ///// </summary>
  445. ///// <param name="info"></param>
  446. ///// <param name="ctxt"></param>
  447. //internal Map(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext ctxt)
  448. //{
  449. //    this._BackgroundColor = (System.Drawing.Color)info.GetValue("BackgroundColor", typeof(System.Drawing.Color));
  450. //    this._Center = (SharpMap.Geometries.Point)info.GetValue("Center", typeof(SharpMap.Geometries.Point));
  451. //    this._Layers = (List<SharpMap.Layers.ILayer>)info.GetValue("Layers", typeof(List<SharpMap.Layers.ILayer>));
  452. //    this._MapTransform = (System.Drawing.Drawing2D.Matrix)info.GetValue("MapTransform", typeof(System.Drawing.Drawing2D.Matrix));
  453. //    this._MaximumZoom = info.GetDouble("MaximumZoom");
  454. //    this._MinimumZoom = info.GetDouble("MinimumZoom");
  455. //    this._Size = (System.Drawing.Size)info.GetValue("Size", typeof(System.Drawing.Size));
  456. //    this._Zoom = info.GetDouble("Zoom");
  457. //}
  458. //#endregion
  459. }
  460. }