MapObject.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. using System;
  2. using System.ComponentModel;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.IO;
  6. using FastReport.Utils;
  7. using FastReport.Map.Import.Shp;
  8. using FastReport.Map.Import.Osm;
  9. using System.Windows.Forms;
  10. namespace FastReport.Map
  11. {
  12. /// <summary>
  13. /// Represents a map object.
  14. /// </summary>
  15. public partial class MapObject : ReportComponentBase, IParent
  16. {
  17. #region Fields
  18. private float scale;
  19. private float zoom;
  20. private float minZoom;
  21. private float maxZoom;
  22. private float offsetX;
  23. private float offsetY;
  24. private LayerCollection layers;
  25. private ColorScale colorScale;
  26. private Padding padding;
  27. private bool mercatorProjection;
  28. #endregion // Fields
  29. #region Properties
  30. /// <summary>
  31. /// Gets or sets the path to folder containing shapefiles.
  32. /// </summary>
  33. /// <remarks>
  34. /// This property is used by the map editor when selecting a shapefile.
  35. /// </remarks>
  36. public static string ShapefileFolder;
  37. /// <summary>
  38. /// Gets or sets the map zoom.
  39. /// </summary>
  40. [DefaultValue(1.0f)]
  41. [Category("Appearance")]
  42. public float Zoom
  43. {
  44. get { return zoom; }
  45. set
  46. {
  47. if (value < MinZoom)
  48. value = MinZoom;
  49. if (value > MaxZoom)
  50. value = MaxZoom;
  51. zoom = value;
  52. }
  53. }
  54. /// <summary>
  55. /// Gets or sets minimum zoom value.
  56. /// </summary>
  57. [DefaultValue(1.0f)]
  58. [Category("Appearance")]
  59. public float MinZoom
  60. {
  61. get { return minZoom; }
  62. set { minZoom = value; }
  63. }
  64. /// <summary>
  65. /// Gets or sets maximum zoom value.
  66. /// </summary>
  67. [DefaultValue(50f)]
  68. [Category("Appearance")]
  69. public float MaxZoom
  70. {
  71. get { return maxZoom; }
  72. set { maxZoom = value; }
  73. }
  74. /// <summary>
  75. /// Gets or sets the X offset of the map.
  76. /// </summary>
  77. [DefaultValue(0f)]
  78. [Category("Layout")]
  79. public float OffsetX
  80. {
  81. get { return offsetX; }
  82. set { offsetX = value; }
  83. }
  84. /// <summary>
  85. /// Gets or sets the Y offset of the map.
  86. /// </summary>
  87. [DefaultValue(0f)]
  88. [Category("Layout")]
  89. public float OffsetY
  90. {
  91. get { return offsetY; }
  92. set { offsetY = value; }
  93. }
  94. /// <summary>
  95. /// Gets or sets the value indicating that mercator projection must be used to view the map.
  96. /// </summary>
  97. [DefaultValue(true)]
  98. [Category("Appearance")]
  99. public bool MercatorProjection
  100. {
  101. get { return mercatorProjection; }
  102. set { mercatorProjection = value; }
  103. }
  104. /// <summary>
  105. /// Gets the color scale settings.
  106. /// </summary>
  107. [Category("Appearance")]
  108. public ColorScale ColorScale
  109. {
  110. get { return colorScale; }
  111. }
  112. /// <summary>
  113. /// Gets or sets a collection of map layers.
  114. /// </summary>
  115. [Browsable(false)]
  116. public LayerCollection Layers
  117. {
  118. get { return layers; }
  119. set { layers = value; }
  120. }
  121. /// <summary>
  122. /// Gets or sets padding within the map.
  123. /// </summary>
  124. [Category("Layout")]
  125. public Padding Padding
  126. {
  127. get { return padding; }
  128. set { padding = value; }
  129. }
  130. internal float ScaleG
  131. {
  132. get { return scale * Zoom; }
  133. }
  134. internal float OffsetXG
  135. {
  136. get { return -((Width * Zoom - Width) / 2) + offsetX * Zoom; }
  137. }
  138. internal float OffsetYG
  139. {
  140. get { return -((Height * Zoom - Height) / 2) + offsetY * Zoom; }
  141. }
  142. internal bool IsEmpty
  143. {
  144. get { return Layers.Count == 0; }
  145. }
  146. #endregion // Properties
  147. #region Private Methods
  148. private void DrawLayers(FRPaintEventArgs e)
  149. {
  150. IGraphics g = e.Graphics;
  151. RectangleF drawRect = new RectangleF(
  152. (AbsLeft + Padding.Left) * e.ScaleX,
  153. (AbsTop + Padding.Top) * e.ScaleY,
  154. (Width - Padding.Horizontal) * e.ScaleX,
  155. (Height - Padding.Vertical) * e.ScaleY);
  156. IGraphicsState state = g.Save();
  157. try
  158. {
  159. g.SetClip(drawRect);
  160. foreach (MapLayer layer in layers)
  161. {
  162. layer.SetPrinting(IsPrinting);
  163. layer.Draw(e);
  164. }
  165. }
  166. finally
  167. {
  168. g.Restore(state);
  169. }
  170. }
  171. private void DrawScales(FRPaintEventArgs e)
  172. {
  173. ColorScale.Data = null;
  174. // find the layer which ColorRanges is set to show in the color scale
  175. foreach (MapLayer layer in Layers)
  176. {
  177. if (layer.ColorRanges.ShowInColorScale)
  178. {
  179. ColorScale.Data = layer.ColorRanges;
  180. break;
  181. }
  182. }
  183. if (ColorScale.Visible)
  184. ColorScale.Draw(e, this);
  185. }
  186. internal void DrawMap(FRPaintEventArgs e)
  187. {
  188. if (IsEmpty)
  189. return;
  190. SmoothingMode saveMode = e.Graphics.SmoothingMode;
  191. e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
  192. MapLayer layer = Layers[0];
  193. double layerWidth = layer.Box.MaxX - layer.Box.MinX;
  194. double layerHeight = MercatorProjection ?
  195. CoordinateConverter.ConvertMercator(layer.Box.MaxY) - CoordinateConverter.ConvertMercator(layer.Box.MinY) :
  196. layer.Box.MaxY - layer.Box.MinY;
  197. float scaleX = (Width - Padding.Horizontal) / (float)layerWidth;
  198. float scaleY = (Height - Padding.Vertical) / (float)layerHeight;
  199. scale = scaleX < scaleY ? scaleX : scaleY;
  200. DrawLayers(e);
  201. e.Graphics.SmoothingMode = saveMode;
  202. DrawScales(e);
  203. }
  204. private void ZoomIn()
  205. {
  206. Zoom *= 1.2f;
  207. }
  208. private void ZoomOut()
  209. {
  210. Zoom /= 1.2f;
  211. }
  212. #endregion // Private Methods
  213. #region IParent Members
  214. /// <inheritdoc/>
  215. public bool CanContain(Base child)
  216. {
  217. return child is MapLayer;
  218. }
  219. /// <inheritdoc/>
  220. public void GetChildObjects(ObjectCollection list)
  221. {
  222. foreach (MapLayer layer in layers)
  223. {
  224. list.Add(layer);
  225. }
  226. }
  227. /// <inheritdoc/>
  228. public void AddChild(Base child)
  229. {
  230. if (child is MapLayer)
  231. layers.Add(child as MapLayer);
  232. }
  233. /// <inheritdoc/>
  234. public void RemoveChild(Base child)
  235. {
  236. if (child is MapLayer)
  237. layers.Remove(child as MapLayer);
  238. }
  239. /// <inheritdoc/>
  240. public int GetChildOrder(Base child)
  241. {
  242. if (child is MapLayer)
  243. return layers.IndexOf(child as MapLayer);
  244. return 0;
  245. }
  246. /// <inheritdoc/>
  247. public void SetChildOrder(Base child, int order)
  248. {
  249. int oldOrder = child.ZOrder;
  250. if (oldOrder != -1 && order != -1 && order != oldOrder)
  251. {
  252. if (child is MapLayer)
  253. {
  254. if (order > layers.Count)
  255. {
  256. order = layers.Count;
  257. }
  258. if (order >= oldOrder)
  259. {
  260. order--;
  261. }
  262. layers.Remove(child as MapLayer);
  263. layers.Insert(order, child as MapLayer);
  264. }
  265. }
  266. }
  267. /// <inheritdoc/>
  268. public void UpdateLayout(float dx, float dy)
  269. {
  270. // do nothing
  271. }
  272. #endregion // IParent Members
  273. #region Report Engine
  274. /// <inheritdoc/>
  275. public override void SaveState()
  276. {
  277. base.SaveState();
  278. foreach (MapLayer layer in Layers)
  279. {
  280. layer.SaveState();
  281. }
  282. }
  283. /// <inheritdoc/>
  284. public override void RestoreState()
  285. {
  286. base.RestoreState();
  287. foreach (MapLayer layer in Layers)
  288. {
  289. layer.RestoreState();
  290. }
  291. }
  292. /// <inheritdoc/>
  293. public override void GetData()
  294. {
  295. base.GetData();
  296. foreach (MapLayer layer in Layers)
  297. {
  298. layer.GetData();
  299. }
  300. }
  301. /// <inheritdoc/>
  302. public override void InitializeComponent()
  303. {
  304. base.InitializeComponent();
  305. foreach (MapLayer layer in Layers)
  306. {
  307. layer.InitializeComponent();
  308. }
  309. }
  310. /// <inheritdoc/>
  311. public override void FinalizeComponent()
  312. {
  313. base.FinalizeComponent();
  314. foreach (MapLayer layer in Layers)
  315. {
  316. layer.FinalizeComponent();
  317. }
  318. }
  319. #endregion // Report Engine
  320. #region Public Methods
  321. /// <inheritdoc/>
  322. public override void Assign(Base source)
  323. {
  324. base.Assign(source);
  325. MapObject src = source as MapObject;
  326. MinZoom = src.MinZoom;
  327. MaxZoom = src.MaxZoom;
  328. Zoom = src.Zoom;
  329. OffsetX = src.OffsetX;
  330. OffsetY = src.OffsetY;
  331. Padding = src.Padding;
  332. MercatorProjection = src.MercatorProjection;
  333. ColorScale.Assign(src.ColorScale);
  334. }
  335. /// <inheritdoc/>
  336. public override void Serialize(FRWriter writer)
  337. {
  338. MapObject c = writer.DiffObject as MapObject;
  339. base.Serialize(writer);
  340. if (MinZoom != c.MinZoom)
  341. writer.WriteFloat("MinZoom", MinZoom);
  342. if (MaxZoom != c.MaxZoom)
  343. writer.WriteFloat("MaxZoom", MaxZoom);
  344. if (Zoom != c.Zoom)
  345. writer.WriteFloat("Zoom", Zoom);
  346. if (OffsetX != c.OffsetX)
  347. writer.WriteFloat("OffsetX", OffsetX);
  348. if (OffsetY != c.OffsetY)
  349. writer.WriteFloat("OffsetY", OffsetY);
  350. if (Padding != c.Padding)
  351. writer.WriteValue("Padding", Padding);
  352. if (MercatorProjection != c.MercatorProjection)
  353. writer.WriteBool("MercatorProjection", MercatorProjection);
  354. ColorScale.Serialize(writer, "ColorScale", c.ColorScale);
  355. }
  356. /// <summary>
  357. /// Loads a map from file.
  358. /// </summary>
  359. /// <param name="filename">Name of file that contains a map.</param>
  360. public void Load(string filename)
  361. {
  362. string extension = Path.GetExtension(filename).ToLower();
  363. if (extension == ".shp")
  364. {
  365. using (ShpMapImport import = new ShpMapImport())
  366. {
  367. import.ImportMap(this, null, filename);
  368. if (Layers.Count > 0)
  369. Layers[Layers.Count - 1].Simplify(0.03);
  370. CreateUniqueNames();
  371. }
  372. }
  373. else if (extension == ".osm")
  374. {
  375. mercatorProjection = false;
  376. using (OsmMapImport import = new OsmMapImport())
  377. {
  378. import.ImportMap(this, null, filename);
  379. if (Layers.Count > 0)
  380. Layers[Layers.Count - 1].Simplify(0.03);
  381. CreateUniqueNames();
  382. }
  383. }
  384. }
  385. /// <summary>
  386. /// Creates unique names for all contained objects such as layers, shapes, etc.
  387. /// </summary>
  388. public void CreateUniqueNames()
  389. {
  390. if (Report != null)
  391. {
  392. FastNameCreator nameCreator = new FastNameCreator(Report.AllNamedObjects);
  393. foreach (MapLayer layer in layers)
  394. {
  395. if (String.IsNullOrEmpty(layer.Name))
  396. nameCreator.CreateUniqueName(layer);
  397. layer.CreateUniqueNames();
  398. }
  399. }
  400. }
  401. #endregion // Public Methods
  402. /// <summary>
  403. /// Initializes a new instance of the <see cref="MapObject"/> class.
  404. /// </summary>
  405. public MapObject()
  406. {
  407. layers = new LayerCollection(this);
  408. zoom = 1;
  409. minZoom = 1;
  410. maxZoom = 50;
  411. padding = new Padding();
  412. colorScale = new ColorScale();
  413. colorScale.Dock = ScaleDock.BottomLeft;
  414. mercatorProjection = true;
  415. Fill = new SolidFill(Color.Gainsboro);
  416. SetFlags(Flags.InterceptsPreviewMouseEvents, true);
  417. FlagProvidesHyperlinkValue = true;
  418. }
  419. }
  420. }