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

GIS编程

开发平台:

C#

  1. // Copyright 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.ComponentModel;
  19. using System.Text;
  20. using System.Web;
  21. using System.Web.UI;
  22. using System.Web.UI.WebControls;
  23. using System.Web.UI.HtmlControls;
  24. using System.ComponentModel.Design;
  25. namespace SharpMap.Web.UI.Ajax
  26. {
  27. /// <summary>
  28. /// The Ajax Map Control is a javascript controlled map that is able to refresh
  29. /// the map without the whole webpage has to do a roundtrip to the server.
  30. /// </summary>
  31. /// <remarks>
  32. /// <para>This webcontrol is tested with both IE and FireFox.</para>
  33. /// <para>The webcontrol creates a client-side javascript object named after
  34. /// the ClientID of this control
  35. /// and appends "Obj" to it. Below are a list of some of the properties
  36. /// and methods of the client-side object. The <see cref="OnViewChanging"/> 
  37. /// and <see cref="OnViewChange"/> client-side events
  38. /// are also is parsing a reference to this object.</para>
  39. /// <list type="table">
  40. /// <listheader><term>Method/Property</term><description>Description</description></listheader>
  41. /// <item><term>.minX</term><description>World coordinate of the left side of the current view</description></item>
  42. /// <item><term>.maxY</term><description>World coordinate of the top of the current view</description></item>
  43. /// <item><term>.GetCenter()</term><description>Gets a center point object with the current view (use the .x and .y properties of the returned object for the coordinates)</description></item>
  44. /// <item><term>.zoom</term><description>The current zoom level of the map (map width)</description></item>
  45. /// <item><term>.zoomAmount</term><description>The amount to zoom on a zoom-in event (negative values equals zoom out)</description></item>
  46. /// <item><term>.container</term><description>Reference to the map box element</description></item>
  47. /// <item><term>.statusbar</term><description>Reference to the statusbar element</description></item>
  48. /// </list>
  49. /// </remarks>
  50. [DefaultProperty("Map")]
  51. [ToolboxData("<{0}:AjaxMapControl runat="server"></{0}:AjaxMapControl>")]
  52. [Designer(typeof(AjaxMapControlDesigner))]
  53. public class AjaxMapControl : System.Web.UI.WebControls.WebControl, INamingContainer, ICallbackEventHandler
  54. {
  55. internal static System.Globalization.NumberFormatInfo numberFormat_EnUS = new System.Globalization.CultureInfo("en-US", false).NumberFormat;
  56. SharpMap.Map map;
  57. private System.Web.UI.WebControls.Image imgMap1;
  58. private System.Web.UI.WebControls.Image imgMap2;
  59. private HtmlGenericControl spanCursorLocation;
  60. private HtmlGenericControl divTopBar;
  61. private int _ZoomSpeed;
  62. /// <summary>
  63. /// Sets the speed which the zoom is (lower = faster).
  64. /// The default value is 15
  65. /// </summary>
  66. [Category("Behavior")]
  67. [DefaultValue(15)]
  68. [Description("Sets the speed which the zoom is (lower = faster).")]
  69. public int ZoomSpeed
  70. {
  71. get { return _ZoomSpeed; }
  72. set { _ZoomSpeed = value; }
  73. }
  74. private int _FadeSpeed;
  75. /// <summary>
  76. /// Sets the speed of the fade (lower = faster).
  77. /// The default value is 10
  78. /// </summary>
  79. [Category("Behavior")]
  80. [DefaultValue(10)]
  81. [Description("Sets the speed of the fade (lower = faster).")]
  82. public int FadeSpeed
  83. {
  84. get { return _FadeSpeed; }
  85. set { _FadeSpeed = value; }
  86. }
  87. private string _OnViewChange;
  88. /// <summary>
  89. /// Client-side method to call when map view have changed
  90. /// </summary>
  91. [Bindable(false)]
  92. [Category("Behavior")]
  93. [DefaultValue("")]
  94. [Description("Client-side method to call when map view have changed")]
  95. public string OnViewChange
  96. {
  97. get { return _OnViewChange; }
  98. set { _OnViewChange = value; }
  99. }
  100. private string _OnViewChanging;
  101. /// <summary>
  102. /// Client-side method to call when map are starting to update
  103. /// </summary>
  104. [Bindable(false)]
  105. [Category("Behavior")]
  106. [DefaultValue("")]
  107. [Description("Client-side method to call when map are starting to update")]
  108. public string OnViewChanging
  109. {
  110. get { return _OnViewChanging; }
  111. set { _OnViewChanging = value; }
  112. }
  113. private string _OnClickEvent;
  114. /// <summary>
  115. /// Gets or sets the clientside method to call when custom click-event is active.
  116. /// </summary>
  117. [Bindable(false)]
  118. [Category("Behavior")]
  119. [DefaultValue("")]
  120. [Description("Clientside method to call when custom click-event is active")]
  121. public string OnClickEvent
  122. {
  123. get { return _OnClickEvent; }
  124. set { _OnClickEvent = value; }
  125. }
  126. /// <summary>
  127. /// Gets the name of the clientside ClickEvent property on the map object.
  128. /// </summary>
  129. public string ClickEventPropertyName
  130. {
  131. get { return this.ClientID + "Obj.clickEvent"; }
  132. }
  133. /// <summary>
  134. /// Gets the name of the clientside ToogleClickEvent method to enable or disable 
  135. /// the custom click-event on the map object.
  136. /// </summary>
  137. public string ToogleClickEventMethodName
  138. {
  139. get { return this.ClientID + "Obj.toogleClickEvent"; }
  140. }
  141. /// <summary>
  142. /// Gets the name of the clientside DisableClickEvent method to disable 
  143. /// the custom click-event on the map object.
  144. /// </summary>
  145. public string DisableClickEventMethodName
  146. {
  147. get { return this.ClientID + "Obj.disableClickEvent"; }
  148. }
  149. /// <summary>
  150. /// Gets the name of the clientside EnableClickEvent method to enable
  151. /// the custom click-event on the map object.
  152. /// </summary>
  153. public string EnableClickEventMethodName
  154. {
  155. get { return this.ClientID + "Obj.enableClickEvent"; }
  156. }
  157. private bool _UseCache;
  158. /// <summary>
  159. /// Sets whether the control should use the http cache or call a specific maphandler
  160. /// </summary>
  161. [Bindable(false)]
  162. [Category("Behavior")]
  163. [DefaultValue(true)]
  164. [Description("Sets whether the control should use the http cache or call a specific maphandler")]
  165. public bool UseCache
  166. {
  167. get { return _UseCache; }
  168. set { _UseCache = value; }
  169. }
  170. private string _StatusBarText = "[X], [Y] - Map width=[ZOOM]";
  171. /// <summary>
  172. /// Text shown on the map status bar.
  173. /// </summary>
  174. /// <remarks>
  175. /// <para>Use [X] and [Y] to display cursor position in world coordinates and [ZOOM] for displaying the zoom value.</para>
  176. /// <para>The default value is "[X], [Y] - Map width=[ZOOM]"</para>
  177. /// </remarks>
  178. [Bindable(false)]
  179. [Category("Appearance")]
  180. [DefaultValue("[X], [Y] - Map width=[ZOOM]")]
  181. [Description("Text shown on the map status bar.")]
  182. public string StatusBarText
  183. {
  184. get { return _StatusBarText; }
  185. set { _StatusBarText = value; }
  186. }
  187. private string _ResponseFormat = "myMapHandler.aspx?Width=[WIDTH]&Height=[HEIGHT]&Zoom=[ZOOM]&X=[X]&Y=[Y]";
  188. /// <summary>
  189. /// Formatting of the callback response used when <see cref="UseCache"/> is false.
  190. /// </summary>
  191. /// <remarks>
  192. /// <para>
  193. /// Use [X] and [Y] for center position, [ZOOM] for zoom value,
  194. /// [WIDTH] for image width and [WIDTH] for image height. These values will automatically
  195. /// be replaced by the current values. The return-result should correspond to the url of
  196. /// a maphandler that renders the map from these values
  197. /// </para>
  198. /// <para>myMapHandler.aspx?Width=[WIDTH]&amp;Height=[HEIGHT]&amp;Zoom=[ZOOM]&amp;X=[X]&amp;Y=[Y]</para>
  199. /// </remarks>
  200. [Bindable(false)]
  201. [Category("Data")]
  202. [DefaultValue("myMapHandler.aspx?Width=[WIDTH]&Height=[HEIGHT]&Zoom=[ZOOM]&X=[X]&Y=[Y]")]
  203. [Description("Formatting of the callback response used when UseCache property is false.")]
  204. public string ResponseFormat
  205. {
  206. get { return _ResponseFormat; }
  207. set { _ResponseFormat = value; }
  208. }
  209. private bool _DisplayStatusBar;
  210. /// <summary>
  211. /// Specifies whether the statusbar is visible or not.
  212. /// </summary>
  213. [Bindable(false)]
  214. [Category("Appearance")]
  215. [DefaultValue(true)]
  216. [Description("Specifies whether the statusbar is visible or not.")]
  217. public bool DisplayStatusBar
  218. {
  219. get { return _DisplayStatusBar; }
  220. set { _DisplayStatusBar = value; }
  221. }
  222. /// <summary>
  223. /// Initializes a new instance of the <see cref="AjaxMapControl"/>
  224. /// </summary>
  225. public AjaxMapControl()
  226. {
  227. ZoomSpeed = 15;
  228. FadeSpeed = 10;
  229. _DisplayStatusBar = true;
  230. }
  231. /// <summary>
  232. /// The <see cref="SharpMap.Map"/> that is to be rendered in the control
  233. /// </summary>
  234. [Bindable(false)]
  235. [Category("Data")]
  236. [DefaultValue("")]
  237. [Localizable(true)]
  238. [Description("The map instance that is to be rendered in the control")]
  239. public SharpMap.Map Map
  240. {
  241. get { return map; }
  242. set { map = value; }
  243. }
  244. #region ICallbackEventHandler Members
  245. private string callbackArg = "";
  246. /// <summary>
  247. /// Returns the result of the callback event that targets <see cref="SharpMap.Web.UI.Ajax.AjaxMapControl"/>
  248. /// </summary>
  249. /// <returns></returns>
  250. public string GetCallbackResult()
  251. {
  252. EnsureChildControls();
  253. if (callbackArg.Trim() == "") return String.Empty;
  254. string[] vals = callbackArg.Split(new char[] { ';' });
  255. try
  256. {
  257. map.Zoom = double.Parse(vals[2], numberFormat_EnUS);
  258. map.Center = new SharpMap.Geometries.Point(double.Parse(vals[0], numberFormat_EnUS), double.Parse(vals[1], numberFormat_EnUS));
  259. map.Size= new System.Drawing.Size(int.Parse(vals[3]), int.Parse(vals[4]));
  260. return GenerateMap();
  261. //If you want to use the Cache for storing the map, instead of a maphandler,
  262. //uncomment the following lines, and comment the above return statement
  263. /*System.Drawing.Image img = map.GetMap();
  264. string imgID = SharpMap.Web.Caching.InsertIntoCache(1, img);
  265. return "getmap.aspx?ID=" + HttpUtility.UrlEncode(imgID);*/
  266. }
  267. catch { return String.Empty; }
  268. }
  269. /// <summary>
  270. /// Creates the arguments for the callback handler in the
  271. /// <see cref="System.Web.UI.ClientScriptManager.GetCallbackEventReference(System.Web.UI.Control,string,string,string)"/> method. 
  272. /// </summary>
  273. /// <param name="eventArgument"></param>
  274. public void RaiseCallbackEvent(string eventArgument)
  275. {
  276. callbackArg = eventArgument;
  277. }
  278. /// <summary>
  279. /// Sends server control content to a provided HtmlTextWriter object, which writes the content to be rendered on the client.
  280. /// </summary>
  281. /// <param name="writer">The HtmlTextWriter object that receives the server control content.</param>
  282. protected override void Render(HtmlTextWriter writer)
  283. {
  284. base.Render(writer);
  285. }
  286. /// <summary>
  287. /// Called by the ASP.NET page framework to notify server controls that use
  288. /// composition-based implementation to create any child controls they
  289. /// contain in preparation for posting back or rendering
  290. /// </summary>
  291. protected override void CreateChildControls()
  292. {
  293. if (!Page.IsCallback)
  294. {
  295. GenerateMapBox();
  296. GenerateClientScripts();
  297. }
  298. //base.CreateChildControls();
  299. }
  300. /// <summary>
  301. /// Returns a Url to the map
  302. /// </summary>
  303. private string GenerateMap()
  304. {
  305. if (_UseCache)
  306. {
  307. System.Drawing.Image img = Map.GetMap();
  308. string imgID = SharpMap.Web.Caching.InsertIntoCache(1, img);
  309. return "getmap.aspx?ID=" + HttpUtility.UrlEncode(imgID);
  310. }
  311. else
  312. return _ResponseFormat.Replace("[WIDTH]", map.Size.Width.ToString()).
  313.   Replace("[HEIGHT]", map.Size.Height.ToString()).
  314.   Replace("[ZOOM]", map.Zoom.ToString(numberFormat_EnUS)).
  315.   Replace("[X]", map.Center.X.ToString(numberFormat_EnUS)).
  316.   Replace("[Y]", map.Center.Y.ToString(numberFormat_EnUS));
  317. }
  318. /// <summary>
  319. /// Registers the client-side scripts and creates an initialize script for the current map
  320. /// </summary>
  321. private void GenerateClientScripts()
  322. {
  323. string newline = Environment.NewLine;
  324. //Include scriptresource
  325. string scriptLocation = Page.ClientScript.GetWebResourceUrl(this.GetType(), "SharpMap.UI.Web.UI.Ajax.AjaxMap.js");
  326. Page.ClientScript.RegisterClientScriptInclude("SharpMap.UI.AjaxMap.js", scriptLocation);
  327. string obj = this.ClientID + "Obj";
  328. string setvarsScript = "SetVars_" + this.ClientID + "();" + newline + 
  329. "function SetVars_" + this.ClientID + "() {" + newline +
  330. obj + " = SharpMap_Init('" + this.ClientID + "','"
  331. + imgMap1.ClientID + "','" + imgMap2.ClientID + "','" + (_DisplayStatusBar ? spanCursorLocation.ClientID : "") + "','"+
  332. (_DisplayStatusBar ? _StatusBarText : "") + "','"+this.UniqueID+"');" + newline;
  333. setvarsScript +=
  334. obj + ".zoom = " + map.Zoom.ToString(numberFormat_EnUS) + ";" + newline +
  335. obj + ".minX = " + map.Envelope.Left.ToString(numberFormat_EnUS) + ";" + newline +
  336. obj + ".maxY = " + map.Center.Y.ToString(numberFormat_EnUS) + "+" + obj + ".zoom/" + obj + ".container.offsetWidth*" + obj + ".container.offsetHeight*0.5;" + newline +
  337. obj + ".minZoom = " + map.MinimumZoom.ToString(numberFormat_EnUS) + ";" + newline +
  338. obj + ".maxZoom = " + map.MaximumZoom.ToString(numberFormat_EnUS) + ";" + newline +
  339. obj + ".zoomAmount = 3.0;" + newline +
  340. obj + ".zoomSpeed = " + this._ZoomSpeed.ToString() +";" + newline +
  341. obj + ".fadeSpeed = " + this._FadeSpeed.ToString() + ";" + newline;
  342. if (_UseCache)
  343. setvarsScript += obj + ".map1.src = '" + this.GenerateMap() +"';rn";
  344. else
  345. setvarsScript += obj + ".map1.src = '" + _ResponseFormat.Replace("[WIDTH]", "'+" + obj + ".container.offsetWidth+'").
  346.   Replace("[HEIGHT]", "'+" + obj + ".container.offsetHeight+'").
  347.   Replace("[ZOOM]", "'+" + obj + ".zoom+'").
  348.   Replace("[X]", map.Center.X.ToString(numberFormat_EnUS)).
  349.   Replace("[Y]", map.Center.Y.ToString(numberFormat_EnUS)) + "';rn";
  350. if (!String.IsNullOrEmpty(_OnViewChange))
  351. setvarsScript += obj + ".onViewChange = function() { " + _OnViewChange + "(" + obj + "); }" + newline;
  352. if (!String.IsNullOrEmpty(_OnViewChanging))
  353. setvarsScript += obj + ".onViewChanging = function() { " + _OnViewChanging + "(" + obj + "); }" + newline;
  354. if (!String.IsNullOrEmpty(this._OnClickEvent))
  355. setvarsScript += this.ClickEventPropertyName + " = function(event) { " + this.OnClickEvent + "(event," + obj + ");};";
  356. //setvarsScript += "SharpMap_BeginRefreshMap(" + obj + ",1);" + newline;
  357. setvarsScript += "}";
  358. //Register scripts in page
  359. ClientScriptManager cm = Page.ClientScript;
  360. //cm.RegisterClientScriptBlock(this.GetType(), "SetVars_" + this.ClientID, setvarsScript, true);
  361. cm.RegisterStartupScript(this.GetType(), "SetVars_" + this.ClientID, setvarsScript, true);
  362. //The following doesn't really do anything, but it cheats ASP.NET to include its callback scripts
  363. cm.GetCallbackEventReference(this, "SharpMap_MapOnClick(event,this)", "SharpMap_RefreshMap", "null", "SharpMap_AjaxOnError", true);
  364. //this.Controls.Add(new LiteralControl("<script type="text/javascript">SetVars_" + this.ClientID + "();</script>rn"));
  365. }
  366. private void GenerateMapBox()
  367. {
  368. this.Style.Add("overflow", "hidden");
  369. this.Style.Add("z-index", "101");
  370. this.Style.Add("cursor", "pointer");
  371. this.Style.Add("position", "relative");
  372. this.Style.Add("display", "block");
  373. if(this.Style["BackColor"]!=null)
  374. this.Style.Add("background", System.Drawing.ColorTranslator.ToHtml(map.BackColor));
  375. imgMap1 = new System.Web.UI.WebControls.Image();
  376. imgMap2 = new System.Web.UI.WebControls.Image();
  377. imgMap1.Attributes["galleryimg"] = "false"; //Disable Internet Explorer image toolbar
  378. imgMap2.Attributes["galleryimg"] = "false"; //Disable Internet Explorer image toolbar
  379. imgMap1.Style.Add("position", "absolute");
  380. imgMap1.Style.Add("Z-index", "10");
  381. imgMap2.Style.Add("position", "absolute");
  382. imgMap2.Style.Add("visibility", "hidden");
  383. imgMap2.Style.Add("opacity","0");
  384. imgMap2.Style.Add("filter","'ALPHA(opacity=0)'");
  385. imgMap2.Style.Add("Z-index","9");
  386. this.Controls.Add(imgMap1);
  387. this.Controls.Add(imgMap2);
  388. if (_DisplayStatusBar)
  389. {
  390. spanCursorLocation = new HtmlGenericControl("span");
  391. spanCursorLocation.InnerText = "";
  392. spanCursorLocation.Style.Add("filter", "ALPHA(opacity=100)");
  393. divTopBar = new HtmlGenericControl("div");
  394. divTopBar.Style.Clear();
  395. divTopBar.Style.Add("Z-index", "20");
  396. divTopBar.Style.Add("border-bottom", "1px solid #000");
  397. divTopBar.Style.Add("position", "absolute");
  398. divTopBar.Style.Add("filter", "ALPHA(opacity=50)");
  399. divTopBar.Style.Add("opacity ", "0.5");
  400. divTopBar.Style.Add("background", "#fff");
  401. divTopBar.Style.Add("width", "100%");
  402. divTopBar.Controls.Add(spanCursorLocation);
  403. this.Controls.Add(divTopBar);
  404. }
  405. }
  406. #endregion
  407. }
  408. }