posts - 77, comments - 54, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

为自定义工具创建控件(MapXtreme 2004)

Posted on 2006-06-14 08:38 东人EP 阅读(1334) 评论(2)  编辑 收藏 引用 所属分类: MapInfo
在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事件中加入任何初始化控件的代码,所有工作在后台进行。

Feedback

# re: 为自定义工具创建控件(MapXtreme 2004)  回复  更多评论   

2006-12-18 17:42 by xuexi
楼主能不能发个完整代码给我
我是处学者 上网也没找到什么资料 谢谢了
kingyzb@yahoo.com.cn

# re: 为自定义工具创建控件(MapXtreme 2004)  回复  更多评论   

2008-05-01 18:03 by 如冰
楼主,这些代码可不可以用VB.net的语言实现呢,怎么实现,能给我写一下吗?我看不懂C#的,我现在是用的VB.net和ASP.net,就想实现这个功能,可一直都实现不了,不知道该怎么办 pingzi2001@126.com
只有注册用户登录后才能发表评论。