MapXtreme2004

 今天想实现往一个图层加入一个文字,如下:

             // 加入一个文字对象作为其描述
            MapInfo.Styles.TextStyle sty2 = new  TextStyle();
            sty2.Font.ForeColor
= System.Drawing.Color.Red;
            sty2.Font.TextEffect
= TextEffect.Halo;
            DRect drect
= new  DRect(ftr.Geometry.Centroid.x + 2 ,ftr.Geometry.Centroid.y,ftr.Geometry.Centroid.x + 30 ,ftr.Geometry.Centroid.y + 12 );
            LegacyText lt
= new  LegacyText(ftr.Geometry.CoordSys,drect,ftr[ " f_name " ].ToString());
            Feature f2
= new  Feature(lt,sty2);
            _tempTable.InsertFeature(f2);

        ftr是传入的一个图元。 Halo我很喜欢,可以在纷乱的背景下依然清楚的显示文字。

        其实,我最希望实现的是,能够把一个图元复制到新图层,然后,修改它的autolabel属性,使文字颜色变红最好。可惜,我现在只能做到在gst中设置好,打开时能够显示(原来我以为不行,这次却莫名其妙的好了)

 

一、Table
        2004中,Table还是表,可以来自原始的mapinfo表,也可以来自数据库的二维表、文本等。Table的等价概念是feature集合,如下代码:
        (_tempTable as IFeatureCollection).Clear();
        当然,可以通过枚举器,来逐个访问table的行,如下:
         Selection sl =MapInfo.Engine.Session.Current.Selections.DefaultSelection;
         IResultSetFeatureCollection fc=sl[0];        
         IFeatureEnumerator fn=fc.GetFeatureEnumerator();        //IFeatureCollection也有GetFeatureEnumerator
         ListBox1.Items.Clear();
         while(fn.MoveNext())
            if(fn.Current.Geometry.GetType().ToString()=="MapInfo.Geometry.LegacyText")
                 ListBox1.Items.Add(((MapInfo.Geometry.LegacyText)fn.Current.Geometry).Caption);
        当然,用
                foreach(Feature feature in tb)
        也是毫无问题的,因而,table和结果集是等价的。   
二、Feature
        Feature等价于表中的行。只与行有关,而与具体的图元的类型无关。换言之,Feature只是指图元对应的表行,而与图元的属性无关。
        用Feature.Table可以引用到所属的表。
        用Table.TableInfo可以引用到表的结构信息。
        Feature具有的默认列,一般都包括obj,Mi_key,Mi_Style。obj我个人认为就是Feature对应的几何对象。用Feature.Geometry属性可以引用。
        Feature.Geometry的类型是FeatureGeometry,它是各种具体图元(点线面文字...)的父类,Feature.Geometry属性所对应的,其实是具体的类。(我向这个属性赋点对象,发现没错)。
        对Feature的使用,可以通过CataLog的SearchForFeature来查找,如下
            MapInfo.Engine.Session.Current.Catalog.SearchForFeature("Layer1",MapInfo.Data.SearchInfoFactory.SearchWhere("MI_Key='"+strKey+"'") ) 
        由于ID其实并不唯一,所以,较好的查找对象是MI_Key。同时,Catalog还有其他的查找函数,如SearchNearest等。
        加入Feature时,往往需要指定这些基本的信息,有多种加入方法,参见本系列的[5]。

 

 

 

 

在Web上标点,首先要将图层所在文件夹的写权限放开。如果是普通的标点,可以这样:
   MapInfo.Data.Table tb=MapInfo.Engine.Session.Current.Catalog.GetTable("lyr");

   MapInfo.Geometry.Point pt = new MapInfo.Geometry.Point(MapControl1.Map.GetDisplayCoordSys(),e.point);
   MapInfo.Styles.SimpleVectorPointStyle vs = new MapInfo.Styles.SimpleVectorPointStyle();
   vs.PointSize = 25;
   vs.Color = Color.DarkMagenta;
   MapInfo.Data.Feature ft = new MapInfo.Data.Feature(pt,vs);
   tb.InsertFeature(ft2);

但是,如果有扩展的列,想要在标点时同时写上数据,将非常痛苦。查帮助,很自然得会用这个
   MapInfo.Data.Key ftrkey=tb.InsertFeature(ft);
   ...  //然后根据Key去进行操作
   实际发现,那是不可能的事。虽然帮助中写得明明白白,可以返回一个Key,但无论如何,实际都不行。包括用它自己的Assign,Clone。

最后摸索出来的方法是:
   Feature ft2=new Feature(tb.TableInfo.Columns);
   ft2.Geometry=pt;
   ft2["f_name"]="aaa";
   ft2["ID"]="123";
   ft2["MI_Style"]=vs;
   tb.InsertFeature(ft2);
   每个列都要赋值,缺一不可。

错误的方法:
  试图修改Geometry.centerid

 

 

 

MapControl控件放大或移动错位的问题

原因:表格结构过于复杂
解决:简化表格结构

 

从MapX到MapXtreme2004[4]-标注AutoLabel

 

  好日子一去不复返了,原来总觉得Mapx很多地方设计得不是很自然,比如,feature和具体的feature之间的某些属性的关系,有时令人迷惑。但是,用了Mapxtreme,才感觉到Mapx的方便。真不知MapInfo怎么想的!原来的标注非常简单,layer有个autolabel属性,一设就可以了。现在呢:

            //James.Liu的代码 
           Table table = Session.Current.Catalog.OpenTable("usa.tab");
            Map map = Session.Current.MapFactory.CreateEmptyMap(new Size(300, 300));
            LabelLayer layer = new LabelLayer();
            map.Layers.Add(layer);
            LabelSource source = new LabelSource(table);
            source.DefaultLabelProperties.Caption = "State_Name";
            layer.Sources.Append(source);

            //我的
            LabelLayer layer = new LabelLayer();
            MapControl1.Map.Layers.Add(layer);
            LabelSource source = new LabelSource(MapInfo.Engine.Session.Current.Catalog.GetTable("地名"));
            source.DefaultLabelProperties.Caption = "f_name";        //标注用到的那个字段名称
            layer.Sources.Append(source);

            看Layer.Sources的架势,好像可以共用一个LabelLayer,试试,的确可以

 

 

Mapxtreme之活活气死

都是小问题,但是都耗费了我巨大的精力和时间。在缺乏资料的情况下,一点点小问题都会非常麻烦,有时真是气死人不偿命:(
1、加载地图(gst文件),设定的selectable属性不管用
2、手工添加MapControl.SelectableLayers,发现添加Layer对象完全可以,但是完全无效,上下求索之后,发现只能添加图层字符串才有效!!!
 3、发现无论是修改feature还是加入feature,都报告不能执行,化了几乎一天的时间,将几乎各种可能性都试验过了,包括帮助和mapinfo的官方文档,都不行。最终发现:只是因为没有开发写权限(跟上传文件夹一样)
4、自定义工具,无论用网上的还是官方的代码,都报错,说没有对象,最后怀疑是没有保持住状态,检查发现,虽然把新工具加入到maptools中,但每次postback都会消失,所有在load中每次都需加载一次。
5、创建一个鹰眼功能类,能够响应Map控件的修改事件。但是,在原来页面下代码正常,但在类中却不正常,在重新修改表后不能绘制。反复检查:session,postback,事件传递......都不是,真正的原因是,在类中如果修改后需要Invalidate();
6、7-25:在用Map.SetView Method (DPoint, CoordSys, Distance)设置范围时,想着前面取Coordsys都用这个,
MapControl1.Map.SetView(ftr.Geometry.Centroid,MapControl1.Map.GetDisplayCoordSys(),new Distance(0.3,DistanceUnit.Kilometer));
但是出错,找帮助,发现改用这个
MapControl1.Map.SetView(ftr.Geometry.Centroid,ftr.Geometry.CoordSys ,new Distance(0.3,DistanceUnit.Kilometer));

 

 

从MapX到MapXtreme2004[3]-搜索图元Feature

一、根据名称搜索图元

  1、Mapxtreme的架构和Mapx有所变化,Mapx中,Layer包含Features,而Mapxtreme中则不是

  2、Mapxtreme的例子中的查找,是通过Find对象来实现的,而Find对象的构造,需要指定Table和Colume,Table好办,FeatureLayer.table即可,而Colume通过FeatureLayer.table.tableinfo.colums["列名"]来指定。但是,关键问题,大多数的地图,并未设计过多的字段来供查询,查的其实就是个标题和label而已。

  3、要用笨办法,遍历图层的features,通过这个方法
           foreach(Feature feature in lyr.table)
           {
           }

  4、Feature派生自Object,包含一个Geometry属性,这个属性是各种几何图形对象的基类

      Geometry classes that derive from FeatureGeometry include: Point, MultiPoint, MultiCurve, MultiPolygon, FeatureGeometryCollection, Rectangle, RoundedRectangle, Ellipse, LegacyArc, and LegacyText.

  5、通过如下方式引用feature对象
            ((MapInfo.Geometry.LegacyText)feature.Geometry).Caption

二、通过search方法搜索

  1、catalog的search方法可以按条件搜索图元(第一个图元)
        // also uses search for feature
        Feature fDEU = _catalog.SearchForFeature("europe", MapInfo.Data.SearchInfoFactory.SearchWhere
("Country='DEU'"));

  2、先利用SearchInfoFactory构造一个SearchInfo对象,指定其搜索属性: 

            SearchAll: Returns all the rows.
            SearchNearest: Returns the rows with table geometries that are closest to the given search point.
            SearchWhere: Returns the rows specified by the given where Clause.
            SearchWithinDistance: Returns the rows where the table geometry is contained within a buffer of the search point, rectangle or geometry.
            SearchWithinFeature: Returns the rows where the table geometry is contained within the search features's geometry.
            SearchWithinGeometry: Returns the rows where the table geometry is contained within the search geometry.
            SearchWithinRect: Returns the rows where the table geometry intersects the given rectangle.
            SearchIntersectsFeature: Returns the rows where the table geometry intersects with the search features's geometry.
            SearchIntersectsGeometry: Returns the rows where the table geometry intersects with the search geometry.
            SearchWithinScreenRadius: Creates a SearchInfo that returns the rows where the table geometry intersects a screen circle.
            SearchWithinScreenRect:Returns the rows where the table geometry intersects the given screen rectangle  
  3、再调用search方法,将结果放到
            MultiResultSetFeatureCollection
            IResultSetFeatureCollection
  4、或许还要设置视图
            MapInfo.Engine.Session.Current.MapFactory[0].SetView(fc.Envelope);
三、通过选择工具来选择一个范围
        1、需要控制选择的图层
        2、选择的结果,通过MapInfo.Engine.Session.Current.Selections.DefaultSelection得到一个Selection对象
        3、Selection对象,是一个IResultSetFeatureCollection的集合,每个对应一个表
        4、对每一个IResultSetFeatureCollection,可以通过枚举器来遍历访问
   Selection sl =MapInfo.Engine.Session.Current.Selections.DefaultSelection;
   IResultSetFeatureCollection fc=sl[0];
   IFeatureEnumerator fn=fc.GetFeatureEnumerator();
   ListBox1.Items.Clear();
   while(fn.MoveNext())
    if(fn.Current.Geometry.GetType().ToString()=="MapInfo.Geometry.LegacyText")
     ListBox1.Items.Add(((MapInfo.Geometry.LegacyText)fn.Current.Geometry).Caption);

 

 

从MapX到MapXtreme2004[2]-图层操作

Mapx中基本的图层操作还是比较简单的,集中在对Layers和Layer的处理上,对别的没有太多要求。

  在MapXtreme中,要完成类似功能,发生了一点变化,如下:
  1、图层的显示
  在MapXtreme中,图层的显示控制发生了奇怪的变化,有一个IsVisible属性,但它是只读的,不能通过它来改变图层的显示。要控制图层的显示与隐藏,可以通过设置Layer.Enable来控制。
  2、图层的动态添加
  代码如下:
        Catalog _catalog=MapInfo.Engine.Session.Current.Catalog;
        MapInfo.Data.Table _tempTable=null;
        Map _map=MapControl1.Map ;   

        TableInfo ti = TableInfoFactory.CreateTemp("临时"); 
        _tempTable = _catalog.CreateTable(ti);
        _map.Layers.Insert(0, new FeatureLayer(_tempTable));

  可以看出:加图层实际就是加表;Catalog对象统管表的加载以及列举;
  查帮助还可以了解:表信息其实还可以包括表的类型和坐标系。类型是指原生表,文本,access ...
  上面的ti也可以这样取得,但是,上面的表默认是MeMTab,应该是内存中的吧。

        CoordSys cs=_map.GetDisplayCoordSys();
        TableInfo ti = TableInfoFactory.CreateTemp("临时",MapInfo.Data.TableType.Native,cs);

  以上只能算是学习心得,肯定错误百出,但总比什么都没有强,至少能够提供一个思路。至于表如何保存,Mapx中的动画层和标签层在MapxTreme中如何对应,因为暂时不急用,先放着。

        4、根据名称打开图层
            MapInfo.Engine.Session.Current.Catalog.GetTable(TableName)

从MapX到MapXtreme2004[1]-工具选择

 

网上的MapXtreme的资料实在太少了,MapXtreme编程基本上只能靠英文帮助和以前的Mapx的一些底子。我想写一个系列,把Mapx到Mapxtreme的学习历程记录下来。

  在Mapx中为控件选择工具比较迅速,也很直观,如下:
             Map1.CurrentTool = miZoomInTool
  miZoomInTool是个枚举量,指定给CurrentTool属性即可,而且象在VB中,直接在等号之后就把备选项就列出来了,非常容易。
  在MapXtreme中,这个不起眼的问题却搞得有点麻烦,主要是架构有点变化,设置位置很容易找
              MapControl1.MapTools.CurrentTool=
  可是,要赋的值却比较麻烦,因为C#中并没有给出智能提示,而且在帮助和对象浏览器中也没有找到什么枚举值。帮助中说要赋String类型,试着
              MapControl1.MapTools.CurrentTool="ZoomInMapTool";
  但是出错。于是查找帮助,了解MapXtreme中的架构,大致如此:MapTools属于MapControl控件的工具集合,其中已经包含了10个工具,debug中挨个求出如下:
                    0:ZoomInMapTool
                    1:ZoomOutMapTool
                    2:PanMapTool
                    3:CenterMapTool
                    4:PointSelectionMapTool
                    5:RadiusSelectionMapTool
                    6:RectangleSelectionMapTool
                    7:PolygonSelectionMapTool
                    8:DistanceMapTool
                    9:InfoMapTool
  但是要选择工具,却不能用Index,也不能用某项的名字字符串,必须用toolname属性,而且必须这样
                    MapControl1.MapTools.CurrentTool =ZoomInMapTool.Toolname;
  因为Toolname是一个静态属性,所以必须用类名来引用,其他别的方式都不行。
  看来,以后要用哪个工具,得先查到工具名称,然后才能指定了。

其他相关:
  1、Toolname是这几个类的特定属性,在其他的工具类中没有。
  2、如果界面中已经放置了同功能的操作控件并关联到MapControl控件,那么将会干扰到程序选择的工具。比如,既放了自带的移动控件,又有一个按钮可以设置移动工具,在点击自定义的按钮,选择移动工具时,那么,界面中的移动控件就会自动处于被按下的状态。这时,再用自定义的选择工具去设置别的功能就不管用了,怎么都是移动功能。所以,最好只要一个就行了。

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值