MapXtreme開發(一)

1、簡單專題圖的顯示 MapControl1.Map.Clear(); MapGeosetLoader gl=new MapGeosetLoader(@"F:/test.gst"); MapControl1.Map.Load(gl);//打開地圖 MapControl1.Map.Load(new MapTableLoader(@"F:/test.tab"));//打開test.tab地圖文件 FeatureLayer lyrPnt=MapControl1.Map.Layers["test"] as FeatureLayer; RangedTheme thm = new RangedTheme(lyrPnt,"PH__1999","ph",3,DistributionMethod.EqualCountPerRange); lyrPnt.Modifiers.Insert(0,thm);//定義一個RangedTheme ThemeLegendFrame frame = LegendFrameFactory.CreateThemeLegendFrame("PH__1999","pp",thm); Legend legend = MapControl1.Map.Legends.CreateLegend(new Size(5,5)); legend.Frames.Append(frame);//定義一個Legend //MapControl1.Map.Adornments.Append(legend);//如果保留此句,MapControl1中將顯示Legend LegendControl1.Map = MapControl1.Map; if (MapControl1.Map.Legends.Count > 0) { LegendControl1.Legend = MapControl1.Map.Legends[0]; }//在LegendControl1控件中顯示Legend 
2、從MapX到MapXtreme2004[1]-工具選擇在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、從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); 
4、從MapX到MapXtreme2004[3]-搜索圖元一、根據名稱搜索圖元
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); 
5、從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,試試,的確可以 
6、從MapX到MapXtreme2004[5]-自定義工具從MapX到MapXtreme2004[5]-自定義工具 參見月光寶盒的文章http://jerry429.blogchina.com/2149736.html 參見 《MapXtreme2004_DevGuide_A4.pdf》 p155 Example 
1: Writing a Server SIde Custom Tool 自己的體會: 1、要寫一個自定義的事件參數,傳遞需要的信息 
2、最好從一個MapTool派生新的工具類,而不要從現成的工具如點選工具派生,否則會帶來很多問題。 感謝James.Liu給出的提示 http://www.mygis.com.cn/forum/dispbbs.asp?boardID=23&replyID=38340&ID=8090&skin=1 
3、創建好的自定義工具,必須先建立實例,加到MapControl的Maptools中,才能被設置爲當前工具。還有一點也很重要,Maptools似乎沒有Viewstate,每次postback都會還原,所有在pageload中必須每次都加入新工具。 
4、自定義工具的類型可以是多種多樣,如下: To draw a rectangle: MapInfoWebRectangleStart MapInfoWebRectangleStop To process a click: MapInfoWebPointStart MapInfoWebPointStop To process panning of a map: MapInfoWebPanStart MapInfoWebPanStop To draw a circle: MapInfoWebCircleStart MapInfoWebCircleStop To draw a polyline: MapInfoWebDistanceStart MapInfoWebDistanceStop To draw a polygon: MapInfoWebPolygonStart MapInfoWebPolygonStop 
7、從MapX到MapXtreme2004[6]-對Table、Feature等的理解一、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時,往往需要指定這些基本的信息,有多種加入方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章