ArcEngine C# GIS開發入門作業 (二)Ex03——基本應用程序生成,右擊菜單實現:顯示、移除和打開屬性表功能
這篇文章轉自我舍友的文章,沒有他的幫忙以我的基礎和水平這個學期肯定學不懂AE開發,他的文章鏈接在這裏 https://blog.csdn.net/m0_37768631/article/details/84196202
大家可以看看他的其他文章對我們這些入門水平的同學是很幫助的
目錄:
- 準備工作 - 工具方法等
- 代碼
首先說明一下第一個作業,這是第二個的鏈接:https://pan.baidu.com/s/1NziPHoMEJx0vc8DCNrX-dA提取碼:qpee看的時候希望能夠靜下心來看,不要着急,不然略過了信息可能後面代碼看不懂,我的初衷是希望能夠通過以下準備工作和理論講解加深對我窗體工作的理解,急不得,有問題可留言啊,我儘量回覆,畢竟代碼內容有很多問題,還有錯別字啥的HH,別介意。
- 代碼爲同學我的所有代碼,但是完成度並非100%,一些小的改動和功能添加可以自行增補,而且帶有個人習慣,所以重在屬性功能;另外,同學我用的是10.2 + VS2012的環境,不同的版本應該有差異,雖然我這裏測試無誤,但是我不能保證其他人賦值粘貼過去後也能正常運行;
- 還有一點想強調一下,在開始寫代碼之前,準備工作不能落下,包括使用,嵌入操作,控件的命名,屬性的設置,添加mapcontrol,lincensecontrol等等,可以省去一些不必要的麻煩。
第一個文章寫的很爛,對於沒有C#和窗體基礎的同學可能較爲吃力,但這個沒辦法啦,這畢竟是我的個人總結。大早爬起來終於把第二個寫好了,現在寫點總結。第一個作業的基礎之後大致熟悉了窗體的基本操作,基本空間的使用,基本設置等等,如果沒有,可以找一些視頻或者自己看看書熟悉一下。
第二個作業實現的功能:
EX03 * :關係關係編寫程序,地圖顯示座標,工具條命令提示信息,並移除圖層。
- 在狀態欄顯示地圖中鼠標當前位置的座標信息(地圖控件的的的的的OnMouseMove)。
- 在狀態欄顯示工具條命令的提示信息(ToolbarControl的的的的的OnMouseMove,的的的的HitTest)。
在TOCControl的圖層上按鼠標右鍵,移除該圖層(TOCControl的onmousedown事件事件事件,的的的HitTest)
生成初始界面(帶工具條);
- 鼠標移動顯示座標和工具狀態信息;
- 右擊菜單實現;
- 右擊菜單中刪除圖層功能和AttributeTable打開功能。
<p> </p> </li>
本次作業使用到的工具和方法,需瞭解,不若不易理解後續代碼:
- ArcEngine的控件:地圖控件,ToolbarControl,TOCControl(目錄樹),LicenseControl,中間兩個不能夠單獨使用,必須與夥伴控件一起使用,所以在使用時我們需要將它們綁定到地圖控件或頁面...... .ToolbarControl綁定之後,我們就可以通過工具條對“夥伴控件”進行訪問操作;同理,TOCControl可以用來顯示“夥伴”的地圖,圖層,符號系統等內容的交互式視圖→當在TOC中刪除,隱藏圖層時,地圖控件中也會相應移除,不可見。
- 基本控件的常用屬性,由於初始不熟悉,這裏補充一下很多都是可以望文生義的屬性,同時點擊之後會有相應的功能描述,如下圖所示:常用的碼頭,設置控件在窗體中的位置,文字文本顯示等。
- 本次我用了stateStrip控件和的的ContextMenuStrip,toolStripContainer,的textBox中(可以直接在左側工具欄搜索),也可以使用其他控件實現相同的功能,看個人習慣。至於這些功能基本的使用,可自行百度。這幾個控件都比較搞,顯示爲了好還需要這幾個設置位於頂層或者底層才行,忘記了,總之不要把地圖控件下部分蓋住。
- 引用的類庫:
使用ESRI.ArcGIS.esriSystem;必須
使用ESRI.ArcGIS.Carto;必須
使用ESRI.ArcGIS.Controls;
使用ESRI.ArcGIS.SystemUI;
使用ESRI.ArcGIS.Geodatabase; //必須
非全部必須,具體使用可隨時添加,這裏地理數據庫初始可能找不到,按下圖所示方法查找即可:
- 函數說明https://blog.csdn.net/haizhongliangji/article/details/43955627
- public void HitTest(int X,int Y,ref esriTOCControlItem ItemType,ref IBasicMap BasicMap,ref ILayer
Layer,ref object unk,ref object Data);
各參數的含義如下:
X,Y:鼠標點擊的座標;
項目類型:esriTOCControlItem枚舉常量
BasicMap:綁定地圖控件的IBasicMap接口
層:被點擊的圖層
UNK:TOCControl的LegendGroup對象
數據:LegendClass在LegendGroup中的索引
.esriTOCControlItem枚舉常量用於描述TocControl上的項目的類型,其定義如下:
esriTOCControlItemNone 0沒有對象
esriTOCControlItemMap 1地圖對象
esriTOCControlItemLayer 2圖層對象
esriTOCControlItemHeading 3對象的標題
esriTOCControlItemLegendClass 4 LegendClass對象
這裏我個人理解的爲綁定TOC和地圖控件後通過該函數來判斷鼠標所處的位置,還有其他的功能但本次未用到。
C#幾個經常用到的字符串截取,因爲顯示的字段類型還有一些單位,比如Meters會是esriMeters,Polyline則爲esriGeometryPolyline,所以我用到了字符創截取功能:https://www.cnblogs。 com /lykbk/archive/2012/06/28/lyk1232132.html
如圖1所示,取字符串的前我個字符
(1)string str1 = str.Substring(0,i);
(2)string str1 = str.Remove(i,str.Length -i);
2,去掉字符串的前我個字符
string str1 = str.Remove(0,i);
string str1 = str.SubString(i);
3,從右邊開始取我個字符:
string str1 = str.SubString(str.Length -i);
string str1 = str.Remove(0,str.Length -i);
如圖4所示,從右邊開始去掉我個字符:
string str1 = str.Substring(0,str.Length -i);
string str1 = str.Remove(str.Length-i,i);
5,如果字符串中有“abc”則替換成“ABC”
str = str.Replace(“abc”,“ABC”);
6,C#截取字符串最後一個字符的問題!!!!!!!!!!!!!!!!!!!!
str1.Substring(str1.LastIndexOf(“”)+ 1);
7,C#截取字符串最後一個字符
k = k.Substring(k.Length-1,1);
就是還有基本窗體怎麼生成的問題,就是自帶工具條的那個,這裏就不多此一舉了,看這裏http://zhihu.esrichina.com.cn/?/article/535與兩種方法,我參考的的是它的第二種方式;這位前輩知乎上的教程不錯,有6章,都可以看看但是有些代碼拿過來還是有錯HH,需要自己調試
生成之後添加工具如果不能使用(灰色的)需要注意,TolllBarControl綁定地圖控件添加工具應該選擇mapnevigation裏的工具纔會生效,有的是針對layerout ......這個同學我也還沒去了解
http://zhihu.esrichina.com.cn/article/537這的英文右擊菜單生成的方法,也是上面前輩的
還有選擇控件時如果覆蓋點不到,可以右擊選擇,就像圖層一樣也可以直接點下方的控件名稱。
準備工作時很重要的,下面基本開始羅列代碼了,再次聲明,僅供參考!!!代碼是使用CSDN編輯器C#選項,應該可複製。
代碼
這是筆者的界面,下面是各個部分的代碼,因爲部分改了控件的名稱屬性,可能不一致,比如MapX的是lablestrip改名的,所以你在寫代碼的時候要改我的代碼來適應你的窗體而不是通過我的代碼來改動你的窗體和控件。
1,鼠標移動在地圖上時,顯示相關信息
private void axMapControl1_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e)
{
string path = axMapControl1.DocumentFilename;
mapx.Text = "X:" + e.mapX.ToString("0.00");
mapy.Text = "Y:" + e.mapY.ToString("0.00");
//或者toolStripStatusLabel1.Text = Math.Round(e.mapX, 2).ToString();
mapunits.Text = this.axMapControl1.MapUnits.ToString().Remove(0,4);
//string str1 = str.Remove(0, i);
//string str1 = str.SubString(i);
textBox1.Text = "比例尺 1:" + ((long)this.axMapControl1.MapScale).ToString();
}
2,鼠標移動至工具條工具時,顯示工具信息(索引初始索引爲-1)
private void axToolbarControl1_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IToolbarControlEvents_OnMouseMoveEvent e)
{
//取得鼠標所在工具的索引號
int index = axToolbarControl1.HitTest(e.x, e.y, false);
if (index != -1)
{
toolinfo.Text = axToolbarControl1.GetItem(index).Command.Message;
}
//toolinfo爲我自己改的控件名,原來是statelable1,就是那個statestrip的子菜單
else
{
toolinfo.Text = "就緒";
}
}
3,右擊菜單的實現,全局變量的設置就是因爲前面講到的幾控件之間的關聯關係
//右擊菜單的實現
public ILayer pLayer;
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
esriTOCControlItem pItem = new esriTOCControlItem();
pLayer = new FeatureLayerClass();
IBasicMap pBasicMap = new MapClass();
object pUnk = new object();
object pData = new object();
//實例化HITtest中的後五個參數
axTOCControl1.HitTest(e.x, e.y, ref pItem, ref pBasicMap, ref pLayer, ref pUnk, ref pData); //調用函數
if (e.button == 2 && pItem == esriTOCControlItem.esriTOCControlItemLayer)
//e.button=2代表鼠標右擊,=1則是單擊左鍵,pItem=...表示圖層
{
contextMenuStrip1.Show(axTOCControl1, new Point(e.x, e.y));
}//如果點擊的是圖層,則彈出右擊菜單
}
4,圖層移除功能實現
private void removeLayerToolStripMenuItem_Click(object sender, EventArgs e)
{
if (axMapControl1.LayerCount > 0)
{
if (pLayer != null)
{
axMapControl1.Map.DeleteLayer(pLayer);
}
}
}
5,屬性表功能實現,需要在這個項目裏新建一個窗體,感覺比較複雜,直接擺出供參考
//屬性表窗體連接並顯示
private void openAtriiToolStripMenuItem_Click(object sender, EventArgs e)
{
AttributeTable pAttributeTable = new AttributeTable(pLayer as IFeatureLayer);
pAttributeTable.Show();
}
5.1,的的的dataGridView控件需要用於顯示屬性表,同時還需要設置屬性時全局顯示,沒記錯應該是AutoSizeColumnsMode,行兩個,下面是代碼,詳情略
public partial class AttributeTable : Form
{
private IFeatureLayer pFeatureLayer = null;
public AttributeTable(IFeatureLayer _FeatureLayer)
{
InitializeComponent();
pFeatureLayer = _FeatureLayer;
}
private void AttributeTable_Load(object sender, EventArgs e)
{
IFields pFields;
pFields = pFeatureLayer.FeatureClass.Fields;//連接屬性表的列
dataGridView1.ColumnCount = pFields.FieldCount;
for (int i = 0; i < pFields.FieldCount; i++)
{
string fldName = pFields.get_Field(i).Name;//字段名
dataGridView1.Columns[i].Name = fldName;
dataGridView1.Columns[i].ValueType = Type.GetType(ParseFieldType(pFields.get_Field(i).Type));
//列名和值類型
}
IFeatureCursor pFeatureCursor;//定義遊標/指針
pFeatureCursor = pFeatureLayer.FeatureClass.Search(null, false);
IFeature pFeature;
pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
string[] fldValue = new string[pFields.FieldCount];
for (int i = 0; i < pFields.FieldCount; i++)
{
string fldName;
fldName = pFields.get_Field(i).Name;
//下代碼判斷是數值類型還是幾何類型字段
if (fldName == pFeatureLayer.FeatureClass.ShapeFieldName)
{
fldValue[i] = pFeature.Shape.GeometryType.ToString().Remove(0,12);
}
else
fldValue[i] = pFeature.get_Value(i).ToString();
}
dataGridView1.Rows.Add(fldValue);//寫入行值
pFeature = pFeatureCursor.NextFeature();
}
}
private string ParseFieldType(esriFieldType TableFieldType)
{
switch (TableFieldType)
{
case esriFieldType.esriFieldTypeBlob:
return "System.String";
case esriFieldType.esriFieldTypeDate:
return "System.DateTime";
case esriFieldType.esriFieldTypeDouble:
return "System.Double";
case esriFieldType.esriFieldTypeGeometry:
return "System.String";
case esriFieldType.esriFieldTypeGlobalID:
return "System.String";
case esriFieldType.esriFieldTypeGUID:
return "System.String";
case esriFieldType.esriFieldTypeInteger:
return "System.Int32";
case esriFieldType.esriFieldTypeOID:
return "System.String";
case esriFieldType.esriFieldTypeRaster:
return "System.String";
case esriFieldType.esriFieldTypeSingle:
return "System.Single";
case esriFieldType.esriFieldTypeSmallInteger:
return "System.Int32";
case esriFieldType.esriFieldTypeString:
return "System.String";
default:
return "System.String";
}
}
}
代碼就到這裏結束了,但是可能還是會遇到很多問題,我也深有體會HH感謝你看完了,有需要的留言,博客可以修改這點是真的好用,當筆記本不錯,下面是我的效果圖(這個比例尺是可以直接添加的工具,我一開始沒找到,就懶得改了,添加了比例尺工具就可以把我這裏的關代碼去除了):