在MapXtreme2004中创建自定义工具
此文档描述如何在MapInfo MapXtreme 2004中创建Web应用中的自定义工具,使用起来如同内置的工具。当前的程序以C#编写,可以将源代码拷贝粘贴到类文件中。
许多的开发者询问,如何编写自定义工具获取用户点击处X,Y坐标点。 他们常常参考创建拉框放大的自定义工具(开发手册中提供)。
这个例子中有若干事项需要注意:
1. 用户需要在地图上点击鼠标两次,服务器端会相应事件。
2. 例子中使用默认的html button 选择自定义工具,而不是是用java script 和内置的工具和工具控件。
3. 工具的逻辑处理过程包含在工具对象中。如果开发者需要相同的工具在其他的页面上执行稍微不同的行为,必须要创建一个新的工具。
经过多次测试,我采用下面的方法创建自定义工具:
1. 直接获取用户在地图上点击处的X,Y 坐标点.
2. 触发事件,开发人员可以在事件中编写处理程序。
3. 拥有自己的控件,这样我们可以象使用内置的工具一样使用它。
首先,我们要创建一个新的工具。我们的工具会继承自MapInfo.Web.UI.WebControls.MapTool, 就像其他内置的控件。这是一个抽象类,我们必须实现5个抽象属性(字符串类型)和一个抽象(void)。
Property ClientCodeSource: 获取/设置放置客户端绘制代码的Javascript的路径或者URL。
Property ClientStartMethod: 获取/设置客户端建立用于绘画的鼠标事件处理程序的方法名。
Property ClientStopMethod: 获取/设置客户端停止鼠标操作事件处理程序的方法名。
Property CursorUrl: 获取/设置放置光标图像放置的路径和URL。
Property Name: 获取/设置工具的名字。
Method Execute: 包含完成操作的代码。
我们必须实现这些属性,这样这些值保存在私有的变量中。我们必须自己设置的属性有 ClientStartMethod, ClientStopMethod ,Name。
我们要象其他工具实现Name属性一样实现Name property。 我们使用静态变量'Toolname', 设置它的值为 'GetPointTool' (工具名), 然后赋给工具构造函数的私有变量 _name。
按照MapXtreme 2004 开发手册, 我们要使用 MapInfoWebPointStart 和 MapInfoWebPointStop javascript 方法去处理地图点击事件,所以我们将它赋值给私有的 clientStartMethod 和 clientStopMethod 变量。
归根结底,代码如下:
public class GetPointTool : MapInfo.Web.UI.WebControls.MapTool
{
private string _clientStartMethod;
private string _clientStopMethod;
private string _clientSourceCode;
private string _cursorUrl;
private string _name;
public static readonly string Toolname = "GetPointTool";
public override string Name
{
get { return _name;
}
set { _name = value; }
}
public override string ClientCodeSource
{
get { return _clientSourceCode; }
set { _clientStartMethod = value; }
}
public override string ClientStartMethod
{
get { return _clientStartMethod; }
set { _clientStartMethod = value; }
}
public override string ClientStopMethod
{
get { return _clientStopMethod; }
set { _clientStopMethod = value; }
}
public override string CursorUrl
{
get { return _cursorUrl; }
set { _cursorUrl = value; }
}
public GetPointTool()
{
Name = Toolname;
ClientStartMethod = "MapInfoWebPointStart";
ClientStopMethod = "MapInfoWebPointStop";
}
public override void Execute(string dataString, System.Collections.ArrayList arrayList, MapInfo.Mapping.Map map)
{
}
}
这里,我们可以把工具实现逻辑写在Execute方法中, 但是这就意味着我们的工具永远实现相同的操作。可以替代的方法是,我们在Execute方法中触发一个事件。为了保持一致性,我们创建一个事件变量类称为PointFoundEventArgs,在这个类中我们可以加入自己需要的点数据。这个类继承自System.EventArgs ,如下所示:
public class PointFoundEventArgs: EventArgs
{
private MapInfo.Mapping.Map _map;
private MapInfo.Geometry.DPoint _point;
public PointFoundEventArgs(MapInfo.Mapping.Map map, MapInfo.Geometry.DPoint point)
{
this ._map = map;
this._point = point;
}
public MapInfo.Mapping.Map Map
{
get { return _map; }
set { _map = value; }
}
public MapInfo.Geometry.DPoint Point
{
get { return _point; }
set { _point = value; }
}
}
现在我们可以在工具中加入代理(PointFoundEventHandler) 和事件 (PointFound),然后从 Execute 方法中激活事件。 为了创建事件,我们在类中加入下面的 2 行:
public delegate void PointFoundEventHandler(object sender, PointFoundEventArgs e);
public event PointFoundEventHandler PointFound;
现在我们要做的就是获取用户点击处的点和在Execute 方法中激活事件。 为此,在Execute 方法中加入如下代码:
public override void Execute(string dataString, System.Collections.ArrayList arrayList, MapInfo.Mapping.Map map)
{
MapInfo.Geometry.DPoint Point;
//从datastring 抽取点
System.Drawing.Point [] points = base.ExtractPoints(dataString);
//转换为可用的投影坐标
map.DisplayTransform.FromDisplay(points[0], out Point);
//创建一个新的PointsFoundEventArgs,设置Point 属性 (通过构造函数)
PointFoundEventArgs e = new PointFoundEventArgs(map, Point);
//激活事件
PointFound(this, e);
}
这里,我们可以测试新建的工具:
创建一个webapplication,增加一个地图控件 (MapControl1) 到 .aspx 页,并使用设计时图层控制控件加入一些图层到地图。同时在页中加入2个label控件 (Label1 and Label2)。我们在触发PointFound事件时设置label控件的Text属性为X和Y坐标。
将下面代码加入Page_Load()事件:
public void Page_Load(object sender, System.EventArgs e)
{
//创建一个工具实例
GetPointTool tool = new GetPointTool();
//将工具加入到地图控件MapControl 的MapTools中
MapControl1.MapTools.Add(tool);
//设置地图控件的当前工具为我们创建的工具
MapControl1.MapTools.CurrentTool = GetPointTool.Toolname;
//加入PointFound 事件处理
tool.PointFound+=new GetPointTool.PointFoundEventHandler(tool_PointFound);
}
别忘了我们的事件处理程序...
private void tool_PointFound(object sender, PointFoundEventArgs e)
{
Label1.Text = e.Point.x.ToString();
Label2.Text = e.Point.x.ToString();
}
当页面加载时,创建自定义工具的实例并加载到地图控件,且当前的工具设置为我们自己创建的自定义工具. 同时我们为PointFound 事件加入处理程序。启动应用并点击地图。请求被提交并且激活PointFound 事件。 方法 tool_PointFound 中将 X 和 Y 坐标值写入Label控件.
创建的工具控件继承MapInfo.Web.UI.WebControls.ToolControl 类. 我们要创建一个事件指向自定义工具的PointFound事件.在类的构造函数中,我们要为属性'ActiveImageUrl' 和 'crsorImageUrl' 设置值。
我们要覆盖OnLoad 事件并创建工具的实例,设置工具控件的MapTool属性,并将工具加入到地图控件MapControl的工具集MapTools中,同时设置自定义工具控件的事件PointFound。
using System;
using MapInfo.Web.UI.WebControls;
public class GetPointToolControl : MapInfo.Web.UI.WebControls.ToolControl
{
public event GetPointTool.PointFoundEventHandler PointFound;
public GetPointToolControl()
{
//工具提示.
this.TooltipText = "Click on the Map to add a DriveTime or Distance Buffer";
//设置光标文件
this .crsorImageUrl = MapInfoMapTool.GetResourcePath() + "/MapInfoWebPointSelection.cur";
//设置工具按钮的图像
this.ActiveImageUrl = MapInfoMapTool.GetResourcePath() + "/PointSelectionToolControlActive.gif";
this.InactiveImageUrl = MapInfoMapTool.GetResourcePath() + "/PointSelectionToolControlInActive.gif";
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (this.mapControl != null)
{
GetPointTool tool = new GetPointTool();
this.MapTool = tool;
this.mapControl.MapTools.Add(tool);
tool.PointFound+=PointFound;
}
}
}
为了使用我们定义的控件,我们需要在页面上注册tagprefix,如下所示:(注:Namespace要设置为你自己的应用的命名空间)
<%@ Register TagPrefix="cc1" Namespace="YourNameSpace" Assembly="YourAssembly"%>
现在,将工具控件加入到页面的工具条控件中
<cc1:getpointtoolcontrol id="Getpointtoolcontrol1" runat="server" MapID="MapControl1"></cc1:getpointtoolcontrol>
加入事件:
private void Getpointtoolcontrol1_PointFound(object sender, MapXtremeWebApplication6.PointFoundEventArgs e)
{
Console.WriteLine ("坐标点:{0},{1}",e.Point.x,e.Point.y);
}
我们不需要在Page_Load事件中加入任何初始化控件的代码,所有工作在后台进行。