arcgis开发常用源码
arcgis開(kāi)發(fā)常用源碼
1.點(diǎn)上生成面的代碼
if (m_pFeatureLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon) { IPointCollection m_pPointCollection = new PolygonClass(); object missing = Type.Missing; int icount = newFeature.XLIST.Count; if (icount < 3) return; for (int i = 0; i < icount; i++) { IPoint point = new PointClass(); point.PutCoords(newFeature.XLIST, newFeature.YLIST); m_pPointCollection.AddPoint(point, ref missing, ref missing); } IPolygon m_pPolygon = m_pPointCollection as IPolygon; if (m_pPolygon == null) { System.Windows.Forms.MessageBox.Show("null"); return; } else { ITopologicalOperator pTopo = m_pPolygon as ITopologicalOperator; if (pTopo != null) { pTopo.Simplify(); } } IWorkspaceEdit m_pWorkspaceEdit = m_EngineEditor.EditWorkspace as IWorkspaceEdit; m_pWorkspaceEdit.StartEditOperation(); IFeature m_pFeature = m_pFeatureLayer.FeatureClass.CreateFeature(); m_pFeature.Shape = m_pPolygon as IGeometry; m_pFeature.Store(); m_pWorkspaceEdit.StopEditOperation(); }
2.文件的打開(kāi) 保存 另存的代碼
using System;
using System.Windows.Forms;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Carto;
namespace SaveMapDocument
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class SaveMapDocument : System.Windows.Forms.Form
{
public System.Windows.Forms.TextBox txtMapDocument;
public System.Windows.Forms.Button cmdOpen;
public System.Windows.Forms.Button cmdSave;
public System.Windows.Forms.Button cmdSaveAs;
private System.Windows.Forms.OpenFileDialog openFileDialog1;
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
private IMapDocument m_MapDocument;
private ESRI.ArcGIS.Controls.AxToolbarControl axToolbarControl1;
private ESRI.ArcGIS.Controls.AxPageLayoutControl axPageLayoutControl1;
private ESRI.ArcGIS.Controls.AxLicenseControl axLicenseControl1;
private ESRI.ArcGIS.Controls.AxTOCControl axTOCControl1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public SaveMapDocument()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
//Release COM objects
ESRI.ArcGIS.ADF.COMSupport.AOUninitialize.Shutdown();
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new SaveMapDocument());
}
private void Form1_Load(object sender, System.EventArgs e)
{
//Add toolbar definitions to the ToolbarControl
axToolbarControl1.AddToolbarDef("esriControls.ControlsPageLayoutToolbar", -1, false, 0, esriCommandStyles.esriCommandStyleIconOnly);
axToolbarControl1.AddToolbarDef("esriControls.ControlsGraphicElementToolbar", -1, true, 0, esriCommandStyles.esriCommandStyleIconOnly);
//Set buddy control
axToolbarControl1.SetBuddyControl(axPageLayoutControl1);
axTOCControl1.SetBuddyControl(axPageLayoutControl1);
cmdSave.Enabled = false;
cmdSaveAs.Enabled = false;
}
private void cmdOpen_Click(object sender, System.EventArgs e)
{
//Open a file dialog for opening map documents
openFileDialog1.Title = "Open Map Document";
openFileDialog1.Filter = "Map Documents (*.mxd)|*.mxd";
openFileDialog1.ShowDialog();
// Exit if no map document is selected
string sFilePath = openFileDialog1.FileName;
if (sFilePath == "")
{
return;
}
//Open document
OpenDocument((sFilePath));
if (cmdSave.Enabled == false)
{
cmdSave.Enabled = true;
}
if (cmdSaveAs.Enabled == false)
{
cmdSaveAs.Enabled = true;
}
}
private void cmdSave_Click(object sender, System.EventArgs e)
{
//Save changes to the current document
SaveDocument();
}
private void cmdSaveAs_Click(object sender, System.EventArgs e) 另存為
{
//Open a file dialog for saving map documents
saveFileDialog1.Title = "Save Map Document As";
saveFileDialog1.Filter = "Map Documents (*.mxd)|*.mxd";
saveFileDialog1.ShowDialog();
//Exit if no map document is selected
string sFilePath = saveFileDialog1.FileName;
if (sFilePath == "")
{
return;
}
if (sFilePath == m_MapDocument.DocumentFilename)
{
//Save changes to the current document
SaveDocument();
}
else
{
//SaveAs a new document with relative paths
m_MapDocument.SaveAs(sFilePath, true, true);
//Open document
OpenDocument((sFilePath));
MessageBox.Show("Document saved successfully!");
}
}
private void OpenDocument(string sFilePath)
{
if (m_MapDocument != null) m_MapDocument.Close();
//Create a new map document
m_MapDocument = new MapDocumentClass();
//Open the map document selected
m_MapDocument.Open(sFilePath,"");
//Set the PageLayoutControl page layout to the map document page layout
axPageLayoutControl1.PageLayout = m_MapDocument.PageLayout;
txtMapDocument.Text = m_MapDocument.DocumentFilename;
}
private void SaveDocument()
{
//Check that the document is not read only
if (m_MapDocument.get_IsReadOnly(m_MapDocument.DocumentFilename) == true)
{
MessageBox.Show("This map document is read only!");
return;
}
//Save with the current relative path setting
m_MapDocument.Save(m_MapDocument.UsesRelativePaths,true);
MessageBox.Show("Changes saved successfully!");
}
}
}
3.訪問(wèn)一個(gè)地圖
static void OpenMXDViaMapDocument(string path)
{
IMapDocument pMapDocument = new MapDocumentClass();
if (pMapDocument.get_IsMapDocument(path))
{
pMapDocument.Open(path,null);
IMap pMap;
for (int i = 0; i <= pMapDocument.MapCount - 1; i++)
{
pMap = pMapDocument.get_Map(i);
Console.WriteLine(pMap.Name);
IEnumLayer pEnumLayer = pMap.get_Layers(null,true);
pEnumLayer.Reset();
ILayer pLayer = pEnumLayer.Next();
while (pLayer != null)
{
Console.WriteLine(pLayer.Name);
pLayer = pEnumLayer.Next();
}
}
}
}
4、地圖坐標(biāo)
private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
string outx = null;
string outy = null;
IActiveView pActiveView = axMapControl1.ActiveView;
BJAEINFunction.bj54tojingweiduAo(pActiveView, e.mapX, e.mapY, ref outx, ref outy);
labelItem1.Text = "地理坐標(biāo): 經(jīng)度:" + outx + " 緯度:" + outy;
//IFeatureLayer pFeatLyr;
//pFeatLyr = axMapControl1.Map.get_Layer(2) as IFeatureLayer;
//pFeatLyr.DisplayField = "面積";
//pFeatLyr.ShowTips = true;
//string pTips;
//pTips = pFeatLyr.get_TipText(e.mapX, e.mapY, pActiveView.FullExtent.Width / 100);
//toolTip1.SetToolTip(axMapControl1, pTips);
}
5、大地轉(zhuǎn)北京54
public static void bj54tojingweiduAo(IActiveView pActiveView, double inx, double iny, ref string outx, ref string outy)
{
try
{
IMap pMap = pActiveView.FocusMap;
SpatialReferenceEnvironment pSpRE = new SpatialReferenceEnvironment();
IGeographicCoordinateSystem pGeoCS = pSpRE.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_Beijing1954);
ISpatialReference pSpr = pGeoCS;
IPoint pPoint = new ESRI.ArcGIS.Geometry.Point();
pPoint.X = inx;
pPoint.Y = iny;
IGeometry pGeo = pPoint;
pGeo.SpatialReference = pMap.SpatialReference;
pGeo.Project(pSpr);//坐標(biāo)轉(zhuǎn)換,由當(dāng)前地圖坐標(biāo)轉(zhuǎn)為北京54經(jīng)緯度坐標(biāo)
double jwd_jd = pPoint.X;
double jwd_wd = pPoint.Y;
//轉(zhuǎn)化成度、分、秒
//經(jīng)度
int Jd, Wd, Jf, Wf;
double temp;
Single Jm, Wm;
Jd = (int)jwd_jd; //度
temp = (jwd_jd - Jd) * 60;
Jf = (int)temp; //分
temp = (temp - Jf) * 60;
Jm = Convert.ToInt32(temp); //秒
//緯度
Wd = (int)jwd_wd; //度
temp = (jwd_wd - Wd) * 60;
Wf = (int)temp; //分
temp = (temp - Wf) * 60;
Wm = Convert.ToInt32(temp); //秒
outx = Jd + "度" + Jf + "分" + Jm + "秒";
outy = Wd + "度" + Wf + "分" + Wm + "秒";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
6.拖動(dòng)代碼
private void btnClearSelction_Click(object sender, EventArgs e)
{
ICommand pCommand = new ControlsMapIdentifyToolClass();
ITool pTool = pCommand as ITool;
switch (this.tabControl.SelectedTabIndex)
{
case 0:
pCommand.OnCreate(this.mainMapControl.Object);
this.mainMapControl.CurrentTool = pTool;
break;
case 1:
pCommand.OnCreate(this.axPageLayoutControl.Object);
this.axPageLayoutControl.CurrentTool = pTool;
break;
}
}
7.axMapControl和axPagelayoutControl數(shù)據(jù)同步顯示的程序 private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e) { axMapControl1.MousePointer = esriControlsMousePointer.esriPointerCrosshair; IGeometry pGeom = axMapControl1.TrackRectangle(); DrawMapShape(pGeom); axMapControl1.CtlRefresh(esriViewDrawPhase.esriViewGeography, null, null); } private void DrawMapShape(IGeometry pGeom) { IRgbColor pColor; pColor = new RgbColorClass(); pColor.Red =100; pColor.Green =100; pColor.Blue =100; ISimpleFillSymbol pFillsyl; pFillsyl = new SimpleFillSymbolClass();
pFillsyl.Color = pColor; object oFillsyl = pFillsyl; axMapControl1.DrawShape(pGeom, ref oFillsyl); } private void CopyAndOverwriteMap() { IObjectCopy objectCopy = new ObjectCopyClass(); object toCopyMap = axMapControl1.Map; object copiedMap = objectCopy.Copy(toCopyMap); object toOverwriteMap = axPageLayoutControl1.ActiveView.FocusMap; objectCopy.Overwrite(copiedMap, ref toOverwriteMap); } private void axMapControl1_OnAfterScreenDraw(object sender, IMapControlEvents2_OnAfterScreenDrawEvent e) { IActiveView activeView = (IActiveView)axPageLayoutControl1.ActiveView.FocusMap; IDisplayTransformation displayTransformation = activeView.ScreenDisplay.DisplayTransformation; displayTransformation.VisibleBounds = axMapControl1.Extent;
axPageLayoutControl1.ActiveView.Refresh(); CopyAndOverwriteMap(); } private void axPageLayoutControl1_OnViewRefreshed(object sender, IPageLayoutControlEvents_OnViewRefreshedEvent e) { axTOCControl1.CtlUpdate(); CopyAndOverwriteMap(); }
8.放大 縮小
放大
ICommand pCommand = new ControlsMapZoomInToolClass(); ITool pTool = pCommand as ITool; pCommand.OnCreate(this.axMapControl1.Object); this.axMapControl1.CurrentTool = pTool;
縮小
ICommand pCommand = new ControlsMapZoomOutToolClass(); ITool pTool = pCommand as ITool; pCommand.OnCreate(this.axMapControl1.Object); this.axMapControl1.CurrentTool = pTool;
9. 在arcsence中的各個(gè)控件的應(yīng)用 類似的arcmap也一樣。
case "ZoomIn":
{
ICommand command = new ControlsSceneZoomInTool();//ControlsSceneZoomInToolClass();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
}
break;
case "toolFly":
{
ICommand command = new ControlsSceneFlyToolClass();//ControlsSceneZoomInToolClass();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
}
break;
case "toolSelectFeatures":
{
ICommand command = new ControlsSceneSelectFeaturesToolClass();//ControlsSceneZoomInToolClass();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
}
break;
case "toolTargetZoom":
{
ICommand command = new ControlsSceneTargetZoomToolClass();//ControlsSceneZoomInToolClass();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
}
break;
case "toolFullExtent":
{
ICommand command = new ControlsSceneFullExtentCommandClass();//ControlsSceneZoomInToolClass();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
}
break;
case "ZoomOut":
{
ICommand command = new ControlsSceneZoomOutTool();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
}
break;
case "Pan":
{
ICommand command = new ControlsScenePanTool();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
}
break;
case "Navigate":
{
ICommand command = new ControlsSceneNavigateTool();
command.OnCreate(this.axSceneControl1.Object);
this.axSceneControl1.CurrentTool = command as ESRI.ArcGIS.SystemUI.ITool;
10.在C#中如何連接ACCESS數(shù)據(jù)庫(kù)
using System.Data.OleDb
public string myConnstring="Provider=Microsoft.Jet.OLEDB.4.0;
Data Source="+HttpContext.Current.Server.MapPath("data.mdb"); //data.mdb是你的數(shù)據(jù)庫(kù)名稱
OleDbConnection MyConnection;
MyConnection = new OleDbConnection(myConnstring);
strInsert=""; //strinsert是你的sql語(yǔ)句
OleDbCommand MyCommand = new OleDbCommand(strInsert,MyConnection);
MyConnection.Open();
MyCommand.ExecuteNonQuery();
MyConnection.Close();
11.創(chuàng)建文件(word) //創(chuàng)建文件夾 System.Object Nothing = System.Reflection.Missing.Value; Directory.CreateDirectory("c:/CNSI"); //創(chuàng)建文件所在目錄 string name = "CNSI_" + DateTime.Now.ToLongDateString() + ".doc"; object filename = "c://CNSI//" + name; //文件保存路徑
//創(chuàng)建Word文檔 Microsoft.Office.Interop.Word.Application WordApp = new Microsoft.Office.Interop.Word.ApplicationClass(); Microsoft.Office.Interop.Word.Document WordDoc = WordApp.Documents.Add(ref Nothing, ref Nothing, ref Nothing, ref Nothing); IQueryFilter pQueryFilter; pQueryFilter = pFeatureWorkspace;
保存文檔: string name = "y00"; object filename = "c://CNSI//" + name;//保存文件路徑。 object Nothing = System.Reflection.Missing.Value; //Microsoft.Office.Interop.Word.Application WordApp = new Microsoft.Office.Interop.Word.ApplicationClass(); Microsoft.Office.Interop.Word.Document WordDocs = WordApp.Documents.Add(ref Nothing, ref Nothing, ref Nothing, ref Nothing); WordDocs.Close(ref Nothing, ref Nothing, ref Nothing); WordApp.Quit(ref Nothing, ref Nothing, ref Nothing); WordDocs.SaveAs(ref filename, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing);
//WordApp.Quit(ref Nothing, ref Nothing, ref Nothing); message = name + "文檔生成成功,以保存到C:CNSI下"; hy catch { message = "文件導(dǎo)出異常!"; } string path = "E:\\yxl\\tianjia\\database2.mdb"; IWorkspace iW = AccessWorkspaceFromPropertySet(path); IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)iW; ITable pTable = pFeatureWorkspace.OpenTable("database2");
12. C#操作Access數(shù)據(jù)庫(kù)的方法
//取得連接 public OleDbConnection getConn() { ConnectDatabase connstr=new ConnectDatabase(); string connStr=connstr.GetConnectionString(); OleDbConnection oledb=new OleDbConnection(connStr); return oledb; }
(1)采用OleDbCommand,OleDbDataReader訪問(wèn)數(shù)據(jù)庫(kù)
1.查詢
public User getUserFromName(string Searchname) { User tempUser=new User(); try { OleDbConnection oleconn=getConn();//數(shù)據(jù)庫(kù)連接 string strSel="select * from MyUser where UserName='"+Searchname+"'";//查詢語(yǔ)句 OleDbCommand myCommand=new OleDbCommand(strSel,oleconn);//查詢命令 oleconn.Open();//打開(kāi)數(shù)據(jù)庫(kù)連接 OleDbDataReader reader; reader=myCommand.ExecuteReader();//執(zhí)行查詢命令,返回記錄集 if(reader.Read()) { tempUser.ID=(int)reader["UserID"]; tempUser.Name=reader["UserName"].ToString(); tempUser.Salary=(float)reader["UserSalary"]; tempUser.Password=reader["UserPassword"].ToString(); tempUser.Memo=reader["UserMemo"].ToString(); tempUser.Birthday=(DateTime)reader["UserBirthday"]; tempUser.Address=reader["UserAddress"].ToString(); } else
{ throw new Exception("沒(méi)有記錄"); } reader.Close();//關(guān)閉記錄集 oleconn.Close();//關(guān)閉連接
} catch(Exception e) { throw new Exception("打開(kāi)數(shù)據(jù)庫(kù)出錯(cuò)"+e.Message); } return tempUser; }
2.插入記錄
public void InsertUser(User insertuser) { try { OleDbConnection oleconn=getConn();//數(shù)據(jù)庫(kù)連接 oleconn.Open();//打開(kāi)數(shù)據(jù)庫(kù)連接 string strSel="insert into [MyUser]([UserName],[UserPassword],
[UserSalary],[UserAddress],[UserBirthday],[UserMemo])"; //插入語(yǔ)句 strSel+=" values
('"+insertuser.Name+"','"+insertuser.Password+"',"+insertuser.Salary.ToSt
ring(); strSel+=",'"+insertuser.Address+"',#"+insertuser.Birthday.ToString()
+"#,'"+insertuser.Memo+"')"; OleDbCommand myCommand=new OleDbCommand(strSel,oleconn);//查詢命令 myCommand.ExecuteNonQuery(); oleconn.Close();//關(guān)閉連接
} catch(Exception e) { throw new Exception("打開(kāi)數(shù)據(jù)庫(kù)出錯(cuò)"+e.Message); } }
3.刪除記錄
public void DeleteUser(int m_id) { try { OleDbConnection oleconn=getConn(); oleconn.Open(); string strSel="Delete From [Myuser] where UserID="+m_id.ToString(); OleDbCommand myCommand=new OleDbCommand(strSel,oleconn); myCommand.ExecuteNonQuery(); oleconn.Close(); } catch(Exception e) { throw new Exception("刪除記錄出錯(cuò)"+e.Message); } }
(2)采用OleDbDataAdapter,OleDbCommandBuilder,DataSet,DataTable,DataRow訪
問(wèn)數(shù)據(jù)庫(kù)
添加記錄如下
public void InsertUserA(User insertUser) { using(OleDbConnection conn=getConn()) { OleDbDataAdapter adapter = new OleDbDataAdapter(); string queryString="Select * from MyUser order by UserID"; adapter.SelectCommand = new OleDbCommand(queryString, conn);
OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter); // builder.QuotePrefix="["; // builder.QuoteSuffix="]"; conn.Open();
DataSet users = new DataSet(); adapter.Fill(users,"MyUser"); DataTable dt=new DataTable(); dt=users.Tables["MyUser"]; DataRow r=dt.NewRow(); r["UserName"]=insertUser.Name; r["UserPassword"]=insertUser.Password; r["UserAddress"]=insertUser.Address; r["UserSalary"]=insertUser.Salary; r["UserBirthday"]=insertUser.Birthday; r["UserMemo"]=insertUser.Memo; dt.Rows.Add(r); adapter.Update(users, "MyUser");
} }
需要注意字段不能和關(guān)鍵字相同,否則會(huì)出現(xiàn)Insert into出錯(cuò)的提示。解決辦法在
前一篇
(3)采用參數(shù)化查詢的方式
public class AccessUtil { public AccessUtil() { } private string connString;
public string ConnString {
get { return connString; } set { connString = value; } } public AccessUtil(string connstr) { this.connString = connstr; } //帶參數(shù)的插入語(yǔ)句,返回值為id關(guān)鍵字的值,單條插入語(yǔ)句 public int ExecuteInsert(string SQL, OleDbParameter[]
parameters) { using(OleDbConnection conn=new OleDbConnection(connString)) { OleDbCommand cmd = new OleDbCommand(SQL, conn); try { conn.Open(); if (parameters!=null) { cmd.Parameters.AddRange(parameters); } cmd.ExecuteNonQuery(); cmd.CommandText = @"Select @@identity"; int value = Int32.Parse(cmd.ExecuteScalar().ToString
()); return value;
} catch (System.Exception e) { throw e; } } } //不帶參數(shù)的插入語(yǔ)句,返回值為關(guān)鍵字的值 public int ExecuteInsert(string SQL)
{ return ExecuteInsert(SQL, null); } //帶參數(shù)的插入、刪除、更新語(yǔ)句,返回受影響的記錄的個(gè)數(shù) public int ExecuteNoQuery(string SQL, OleDbParameter[]
parameters) { using(OleDbConnection conn=new OleDbConnection(connString)) { conn.Open(); OleDbCommand cmd = new OleDbCommand(SQL, conn); try { if (parameters!=null) { cmd.Parameters.AddRange(parameters); } int rows=cmd.ExecuteNonQuery(); return rows; } catch (System.Exception e) { throw e; } } } //不帶參數(shù)的插入、刪除、更新語(yǔ)句,返回受影響的記錄的個(gè)數(shù) public int ExecuteNoQuery(string SQL) { return ExecuteNoQuery(SQL, null); } //帶參數(shù)的查詢語(yǔ)句,返回所查詢到的記錄集 public DataSet ExecuteQuery(string SQL, OleDbParameter[]
parameters) { using(OleDbConnection conn=new OleDbConnection(connString)) {
DataSet ds = new DataSet(); try { conn.Open(); OleDbDataAdapter da = new OleDbDataAdapter(SQL,
conn); if (parameters != null) { da.SelectCommand.Parameters.AddRange(parameters); } da.Fill(ds, "ds"); } catch(System.Exception e) { throw e; } return ds; } } //不帶參數(shù)的查詢,返回所查詢到的記錄集 public DataSet ExecuteQuery(string SQL) { return ExecuteQuery(SQL, null); }
}
class ManageUser { //Access數(shù)據(jù)庫(kù)工具對(duì)象 AccessUtil accessutil = new AccessUtil
(ConnectDatabase.GetConnectionString()); public ArrayList GetAllUserArr()//獲得User表中的所有記錄,存儲(chǔ)進(jìn)
ArrayList。 {
string SQL = "select * from MyUser order by ID"; DataSet ds=accessutil.ExecuteQuery(SQL);//返回的臨時(shí)表的名稱
為“ds” /* ArrayList arr = new ArrayList(); for (int i = 0; i < ds.Tables
["ds"].Rows.Count;i++ ) { arr.Add(DataRow2User(ds.Tables["ds"].Rows
)); }*/ ArrayList arr = DataTable2ArrayList(ds.Tables["ds"]); return arr; } public DataSet GetAllUserDataSet()//存儲(chǔ)成DataSet { string SQL = "select * from MyUser order by ID"; DataSet ds = accessutil.ExecuteQuery(SQL); return ds; } private User DataRow2User(DataRow dr)//將數(shù)據(jù)表中的一條記錄轉(zhuǎn)換為
一個(gè)User類的實(shí)例 { User user = new User(); user.ID = Int32.Parse(dr["ID"].ToString()); user.Name = dr["Name"].ToString(); user.Address = dr["Address"].ToString(); user.Birthday = Convert.ToDateTime(dr
["Birthday"].ToString()); user.Memo = dr["Memo"].ToString(); user.Salary =(float) Convert.ToDouble(dr
["Salary"].ToString()); user.Password = dr["Password"].ToString(); return user; } private ArrayList DataTable2ArrayList(DataTable dt)//將一個(gè)表中的
記錄轉(zhuǎn)化為ArrayList對(duì)象 { ArrayList tempArr = new ArrayList(); DataTableReader dr = new DataTableReader(dt); while(dr.Read()) { User user = new User(); user.ID = Int32.Parse(dr["ID"].ToString()); user.Name = dr["Name"].ToString(); user.Address = dr["Address"].ToString(); user.Birthday = Convert.ToDateTime(dr["Birthday"].ToString()); user.Memo = dr["Memo"].ToString(); user.Salary = (float)Convert.ToDouble(dr["Salary"].ToString
()); user.Password = dr["Password"].ToString(); tempArr.Add(user); } return tempArr; } public DataSet GetUserByName(string name) { String SQL = "Select * from MyUser where Name=?"; OleDbParameter[] parameter = new OleDbParameter[1]; parameter[0] = new OleDbParameter("@Name",
OleDbType.VarChar); parameter[0].Value = name; DataSet dt= accessutil.ExecuteQuery(SQL, parameter); return dt; }
public int InsertUser(User inUser) { String SQL = "insert into [MyUser]([Name],[Password],
[Salary],[Address],[Birthday],[Memo]) values(?,?,?,?,?,?)"; OleDbParameter[] parameters = new OleDbParameter[6]; parameters[0] = new OleDbParameter("@Name",
OleDbType.VarChar); parameters[0].Value = inUser.Name; parameters[1] = new OleDbParameter("@Password",
OleDbType.VarChar); parameters[1].Value = inUser.Password; parameters[2] = new OleDbParameter("@Salary",
OleDbType.Single); parameters[2].Value = inUser.Salary; parameters[3] = new OleDbParameter("@Address",
OleDbType.VarChar); parameters[3].Value = inUser.Address; parameters[4] = new OleDbParameter("@Birthday",
OleDbType.Date); parameters[4].Value = inUser.Birthday; parameters[5] = new OleDbParameter("@Memo",
OleDbType.VarChar); parameters[5].Value = inUser.Memo; return accessutil.ExecuteInsert(SQL, parameters); } public void DelUserById(int id) {
String SQL = "DELETE FROM [MyUser] where ID=?"; OleDbParameter[] parameters = new OleDbParameter[1]; parameters[0] = new OleDbParameter("@ID", OleDbType.Integer); parameters[0].Value = id;
accessutil.ExecuteNoQuery(SQL, parameters); } public void UpdateUser(User userupdate) { String SQL = "update [MyUser] Set [Name]=?,[Password]=?,
[Salary]=?,[Address]=?,[Birthday]=?,[Memo]=? where [ID]=?"; OleDbParameter[] parameters = new OleDbParameter[7]; parameters[0] = new OleDbParameter("@Name",
OleDbType.VarChar); parameters[0].Value = userupdate.Name; parameters[1] = new OleDbParameter("@Password",
OleDbType.VarChar); parameters[1].Value = userupdate.Password; parameters[2] = new OleDbParameter("@Salary",
OleDbType.Single); parameters[2].Value = userupdate.Salary; parameters[3] = new OleDbParameter("@Address",
OleDbType.VarChar); parameters[3].Value = userupdate.Address; parameters[4] = new OleDbParameter("@Birthday",
OleDbType.Date); parameters[4].Value = userupdate.Birthday; parameters[5] = new OleDbParameter("@Memo",
OleDbType.VarChar); parameters[5].Value = userupdate.Memo; parameters[6] = new OleDbParameter("@ID", OleDbType.Integer); parameters[6].Value = userupdate.ID; accessutil.ExecuteNoQuery(SQL, parameters); } }
13.加載cad代碼
private void AddCADRasterLayer(string sPath, string sName)
{
IWorkspaceFactory pCadWorkspaceFactory= new CadWorkspaceFactoryClass();
IWorkspace pWorkspace = pCadWorkspaceFactory.OpenFromFile(sPath,0);
ICadDrawingWorkspace pCadDrawingWorkspace = pWorkspace as ICadDrawingWorkspace;
ICadDrawingDataset pCadDataset; //'定義并獲得CAD文件的數(shù)據(jù)集
pCadDataset = pCadDrawingWorkspace.OpenCadDrawingDataset(sName);
ICadLayer pCadLayer; //'加入圖層到Map對(duì)象中去
pCadLayer = new CadLayerClass();
pCadLayer.CadDrawingDataset = pCadDataset;
axMapControl1.AddLayer(pCadLayer, 0);
axMapControl1.Refresh();
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "所有文件|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
AddCADRasterLayer(openFileDialog1.FileName,"11.dwg");//
}
}
您正在看的文章來(lái)自地信網(wǎng)論壇 http://bbs.3s001.com,原文地址:http://bbs.3s001.com/read.php?tid=8114.html
(七) 給PageLayoutControl添加彈出式菜單?
與給跟綁定控件協(xié)作的ToolbarControl增加ArcGIS Engine命令一樣,按照前面的步驟,你也可以從ArcGIS Engine命令創(chuàng)建彈出式菜單。下面將向你的應(yīng)用程序中增加與PageLayoutControl協(xié)作的彈出式菜單。當(dāng)在PageLayoutControl可視區(qū)域點(diǎn)擊鼠標(biāo)右鍵的時(shí)候,彈出式菜單將顯示。
1.?????? 向類中添加如下的成員變量(紅色部分):
? public class Form1 : System.Windows.Forms.Form
? {
????? private ESRI.ArcGIS.MapControl.AxMapControl axMapControl1;
????? private ESRI.ArcGIS.PageLayoutControl.AxPageLayoutControl axPageLayoutControl1;
????? private ESRI.ArcGIS.TOCControl.AxTOCControl axTOCControl1;
????? private ESRI.ArcGIS.ToolbarControl.AxToolbarControl axToolbarControl1;
?
?? private IToolbarMenu m_ToolbarMenu = new ToolbarMenuClass(); // 彈出式菜單
// ……
2.?????? 在Form_Load事件中向ToolbarControl增加命令代碼的后面加載文檔代碼的前面增加如下代碼。
???? private void Form1_Load(object sender, System.EventArgs e)
???? {
???????? // 前面是增加地圖導(dǎo)航的代碼……
????????
// 共享ToolbarControl的命令池
???????? m_ToolbarMenu.CommandPool = axToolbarControl1.CommandPool;
?
???????? // 向ToolbarMenu增加命令
???????? progID = "esriControlToolsPageLayout.ControlsPageZoomInFixedCommand";
???????? m_ToolbarMenu.AddItem(progID, -1, -1, false,
???????????? esriCommandStyles.esriCommandStyleIconAndText);
?
???????? progID = "esriControlToolsPageLayout.ControlsPageZoomOutFixedCommand";
???????? m_ToolbarMenu.AddItem(progID, -1, -1, false,
???????????? esriCommandStyles.esriCommandStyleIconAndText);
?
???????? progID = "esriControlToolsPageLayout.ControlsPageZoomWholePageCommand";
???????? m_ToolbarMenu.AddItem(progID, -1, -1, false,
???????????? esriCommandStyles.esriCommandStyleIconAndText);
?
???????? progID = "esriControlToolsPageLayout.ControlsPageZoomPageToLastExtentBackCommand";
???????? m_ToolbarMenu.AddItem(progID, -1, -1, true,
???????????? esriCommandStyles.esriCommandStyleIconAndText);
?
???????? progID = "esriControlToolsPageLayout.ControlsPageZoomPageToLastExtentForwardCommand";
???????? m_ToolbarMenu.AddItem(progID, -1, -1, false,
???????????? esriCommandStyles.esriCommandStyleIconAndText);
?
???????? // 設(shè)置與PageLayoutControl掛接
?????? m_ToolbarMenu.SetHook(axPageLayoutControl1);
??????
??????????? // 后面是加載圖形文檔的代碼……
??????????? // ……
3.?????? 在設(shè)計(jì)模式顯示窗體并從屬性窗口中選擇axPageLayoutControl1,顯示axPageLayoutControl事件。雙擊OnMouseDown事件,向代碼窗口中增加事件處理代碼。
4.?????? 在axPageLayoutControl1_OnMouseDown事件中增加如下代碼:
???? private void axPageLayoutControl1_OnMouseDown(object sender, ESRI.ArcGIS.PageLayoutControl.IPageLayoutControlEvents_OnMouseDownEvent e)
???? {
???????? // 彈出ToolbarMenu
???????? if ( e.button == 2)
???????? {
???????????? m_ToolbarMenu.PopupMenu(e.x, e.y, axPageLayoutControl1.hWnd);
???????? }
}
5.???? 生成并運(yùn)行應(yīng)用程序。在PageLayoutControl的顯示區(qū)域單擊右鍵以顯示彈出菜單,并為頁(yè)面布局導(dǎo)航。
?
(八) 在TOCControl中控制標(biāo)簽編輯?
TOCControl默認(rèn)允許用戶自動(dòng)地切換圖層的可見(jiàn)性并改變顯示在目錄表中的名稱。你可以增加代碼防止用戶在編輯名稱時(shí)輸入空的字符串。
1.?????? 在Form_Load事件的開(kāi)始增加下列代碼。
???? private void Form1_Load(object sender, System.EventArgs e)
???? {
???????? // 當(dāng)縮放時(shí)禁止重繪
???????? this.SetStyle(ControlStyles.EnableNotifyMessage, true);
?
???????? // 設(shè)置標(biāo)簽編輯為手動(dòng)方式
???????? axTOCControl1.LabelEdit = esriTOCControlEdit.esriTOCControlManual;
?
??????????? // 后面是加載文檔代碼
??????????? // ……
2.?????? 在設(shè)計(jì)模式顯示窗體并從屬性窗口選擇AxTOCControl1控件,顯示AxTOCControl事件。雙擊OnEndLabelEdit向代碼窗口添加事件處理函數(shù)。
3.???? 在axTOCControl1_OnEndLabelEdit事件中添加以下代碼:
???? private void axTOCControl1_OnEndLabelEdit(object sender, ESRI.ArcGIS.TOCControl.ITOCControlEvents_OnEndLabelEditEvent e)
???? {
???????? // 禁止在編輯標(biāo)簽時(shí)鍵入空字串
???????? string newLabel = e.newLabel;
???????? if ( newLabel.Trim() == "" )
???????? {
???????????? e.canEdit = false;
???????? }
???? }
4.?????? 生成并生成應(yīng)用程序。編輯TOCControl控件的地圖、圖層、標(biāo)題或圖例類的標(biāo)簽,在其上點(diǎn)擊一次,然后再點(diǎn)一次調(diào)用標(biāo)簽編輯。試著用空字串替代標(biāo)簽。在編輯期間,你可以隨時(shí)使用鍵盤(pán)上的ESC鍵取消編輯。
(九) 在MapControl上繪制圖形?
你可以將MapControl作為縮略圖窗體使用,并在其上繪制顯示PageLayoutControl內(nèi)的焦點(diǎn)地圖的當(dāng)前范圍。當(dāng)你瀏覽PageLayoutControl數(shù)據(jù)框架內(nèi)的數(shù)據(jù)時(shí),你將看到縮略圖窗口也進(jìn)行了更新。
注:使用地圖導(dǎo)航工具導(dǎo)航焦點(diǎn)圖(活動(dòng)圖)將改變PageLayoutControl中焦點(diǎn)地圖的范圍并引起MapControl更新。使用頁(yè)面布局工具導(dǎo)航頁(yè)面布局將改變頁(yè)面布局的范圍(不是PageLayoutControl中的焦點(diǎn)圖的范圍),而MapControl將不更新。
1.?????? 向類中增加下列成員變量:
public class Form1 : System.Windows.Forms.Form
{
???? private ESRI.ArcGIS.MapControl.AxMapControl axMapControl1;
???? private ESRI.ArcGIS.PageLayoutControl.AxPageLayoutControl axPageLayoutControl1;
???? private ESRI.ArcGIS.TOCControl.AxTOCControl axTOCControl1;
???? private ESRI.ArcGIS.ToolbarControl.AxToolbarControl axToolbarControl1;
?
???? private IToolbarMenu m_ToolbarMenu = new ToolbarMenuClass(); // 彈出式菜單
?
???? private IEnvelope m_Envelope;?? // MapControl繪制的范圍
???? private Object m_FillSymbol;??? // 在MapControl上繪制范圍使用的符號(hào)
???? private ITransformEvents_VisibleBoundsUpdatedEventHandler
????????? visBoundsUpdatedE;????????? // PageLayoutControl的焦點(diǎn)圖事件
注:聲明的變量visBoundsUpdatedE是一個(gè)托管。托管是一個(gè)類,它能夠擁有對(duì)指定方法的引用,并使它鏈接到一個(gè)特定的事件。在事件和方法之間的鏈接過(guò)程有時(shí)在.NET中被稱作wiring。
2.?????? 創(chuàng)建一個(gè)叫CreateOverviewSymbol的新函數(shù)。這個(gè)函數(shù)是創(chuàng)建你將在MapControl中使用的符號(hào)的地方,此符號(hào)是用來(lái)描述PageLayoutControl焦點(diǎn)地圖數(shù)據(jù)范圍的。函數(shù)中增加的代碼如下:
private void CreateOverviewSymbol()
???? {
???????? // 獲取IRGBColor接口
???????? IRgbColor color = new RgbColor();
???????? // 設(shè)置顏色屬性
???????? color.RGB = 255;
?
???????? // 獲取ILine符號(hào)接口
???????? ILineSymbol outline = new SimpleLineSymbol();
???????? // 設(shè)置線符號(hào)屬性
???????? outline.Width = 1.5;
???????? outline.Color = color;
?
???????? // 獲取IFillSymbol接口
???????? ISimpleFillSymbol simpleFillSymbol = new SimpleFillSymbolClass();
???????? // 設(shè)置填充符號(hào)屬性
???????? simpleFillSymbol.Outline = outline;
???????? simpleFillSymbol.Style = esriSimpleFillStyle.esriSFSHollow;
???????? m_FillSymbol = simpleFillSymbol;???????????
}
3.?????? 從Form_Load事件在TOCControl標(biāo)簽編輯代碼之前調(diào)用CreateOverviewSymbol函數(shù)。
???? private void Form1_Load(object sender, System.EventArgs e)
???? {
???????? // 當(dāng)縮放時(shí)禁止重繪
???????? this.SetStyle(ControlStyles.EnableNotifyMessage, true);
?
???????? // 創(chuàng)建MapControl使用的符號(hào)
CreateOverviewSymbol();
?
// 下面是標(biāo)簽編輯處理代碼
// ……
}
4.?????? 增加下列OnVisibleBoundsUpdated函數(shù)。此函數(shù)將與地圖范圍改變時(shí)觸發(fā)的事件相連接,并用來(lái)設(shè)置新的地圖可見(jiàn)邊界范圍框。通過(guò)刷新MapControl,你強(qiáng)制它重繪其上顯示的圖形。
???? private void OnVisibleBoundsUpdated(IDisplayTransformation sender, bool sizeChanged)
???? {
???????? // 設(shè)置新的可見(jiàn)范圍
???????? m_Envelope = sender.VisibleBounds;
?
???????? // 改變MapControl的前景狀態(tài)
axMapControl1.ActiveView.PartialRefresh(
esriViewDrawPhase,esriViewForeground, null, null);??????
}
5.?????? PageLayoutControl默認(rèn)的事件接口是IPageLayoutControlEvents。這些事件不告訴我們數(shù)據(jù)邊框內(nèi)的地圖范圍。為此你需要使用PageLayoutControl的焦點(diǎn)地圖的ItransformEvents接口。在PageLayoutControl_OnPageLayoutReplaced事件處理中的加載文檔代碼前面增加以下代碼。
private void axPageLayoutControl1_OnPageLayoutReplaced(object sender, ESRI.ArcGIS.PageLayoutControl.IPageLayoutControlEvents_OnPageLayoutReplacedEvent e)
???? {
???????? // 獲取PageLayoutControl中焦點(diǎn)地圖的IActiveView對(duì)象
???????? IActiveView activeView = (IActiveView)
???????????? axPageLayoutControl1.ActiveView.FocusMap;
?
???????? // 捕捉PageLayoutControl的焦點(diǎn)圖的ITransformEvents事件
???????? visBoundsUpdatedE = new ??????? ITransformEvents_VisibleBoundsUpdatedEventHandler(OnVisibleBoundsUpdated);
???????? ((ITransformEvents_Event)activeView.ScreenDisplay
???????????? .DisplayTransformation).VisibleBoundsUpdated += visBoundsUpdatedE;
????????
???????? // 獲取焦點(diǎn)圖的范圍
m_Envelope = activeView.Extent;
?
// 后面是加載地圖文檔的代碼
// ……
6.?????? 在設(shè)計(jì)模式下顯示窗體并從屬性窗中選擇axMapControl1,顯示axMapControl事件。雙擊OnAfterDraw向代碼窗口中增加事件處理。
7.?????? 向axMapControl1_OnAfterDraw事件處理中增加以下代碼,使用前面創(chuàng)建的符號(hào)繪制MapControl顯示邊框。
private void axMapControl1_OnAfterDraw(object sender, ESRI.ArcGIS.MapControl.IMapControlEvents2_OnAfterDrawEvent e)
???? {
???????? if ( m_Envelope == null)
???????? {
???????????? return;
???????? }
?
???????? // 如果前景狀態(tài)被重繪
???????? esriViewDrawPhase viewDrawPhase = (esriViewDrawPhase)e.viewDrawPhase;
???????? if ( viewDrawPhase == esriViewDrawPhase.esriViewForeground )
???????? {
???????????? IGeometry geometry = m_Envelope;
???????????? axMapControl1.DrawShape(geometry, ref m_FillSymbol);
???????? }
}
生成并運(yùn)行應(yīng)用程序。使用你先前已經(jīng)加好的地圖導(dǎo)航工具改變PageLayoutControl中焦點(diǎn)地圖的范圍。新的范圍被繪制在MapControl上。
本講主要是使用MapControl、PageLayoutControl、ToolbarControl、TOCControl四個(gè)控件建立起基本的桌面GIS應(yīng)用程序框架。最終成果預(yù)覽如下:
?
1、新建項(xiàng)目
啟動(dòng)VS2005,選擇“文件|新建|項(xiàng)目”,在項(xiàng)目類型中選擇Visual C#,再選擇Windows應(yīng)用程序模板,輸入名稱“3sdnMap”,點(diǎn)擊確定。
?
在解決方案管理器中將“Form1.cs”重命名為“3sdnMap.cs”,在設(shè)計(jì)視圖中,選中窗體,將其屬性中的“Text”改為“3sdnMap”。
2、添加控件
選擇工具箱中的“菜單和工具欄|MenuStrip”,將其拖入窗體。
選擇工具箱中的“ArcGIS Windows Forms”節(jié),將“ToolbarControl”控件拖入窗體,并將其屬性中的Dock設(shè)置為T(mén)op。
選擇工具箱中的“菜單和工具欄|StatusStrip”,將其拖入到窗體。
選擇工具箱中的“容器|SplitContainer”容器拖入窗體,并將其屬性中的Dock設(shè)置為Fill。
將TabControl控件拖入Panel1,將Alignment屬性設(shè)置為Bottom,Dock屬性設(shè)置為Fill。點(diǎn)擊TabPages屬性右邊的按鈕,彈出TabPage集合編輯器,將tabPage1的Name設(shè)置為tabPageLayer,Text設(shè)置為圖層,將tabPage2的Name設(shè)置為tabPageProperty,Text設(shè)置為屬性。如下所示。
?
選擇“圖層”選項(xiàng)卡,拖入TOCControl控件,設(shè)置Dock屬性為Fill。
選擇“屬性”選項(xiàng)卡,拖入DataGridView控件,設(shè)置Dock屬性為Fill。
拖入TabControl控件到Panel2,設(shè)置Dock屬性為Fill。并上述類似的方法,將兩個(gè)選項(xiàng)卡的Name和Text分別設(shè)置為:(tabPageMap、地圖),(tabPageLayout,制版)。
選擇“地圖”選項(xiàng)卡,拖入MapControl控件,設(shè)置Dock屬性為Fill。
選擇“制版”選項(xiàng)卡,拖入PageLayoutControl控件,設(shè)置Dock屬性為Fill。
最后將LicenseControl控件拖入到窗體的任意地方。
按F5編譯運(yùn)行,可以看到剛才布局好的程序界面了。
3、控件綁定
通過(guò)以上步驟添加的控件還只是單獨(dú)存在,而我們的程序需要各控件間協(xié)同工作,因此要進(jìn)行控件綁定。
分別右擊ToolbarControl、TOCControl控件,將Buddy設(shè)置為axMapControl1,如下圖所示。
?
這樣,工具條和圖層控件就與地圖控件關(guān)聯(lián)了。
4、添加工具
此時(shí),工具條中還沒(méi)有任何工具,添加的方法也很簡(jiǎn)單。右擊ToolbarControl,選擇“屬性|Items”,點(diǎn)擊Add,選擇Commands選項(xiàng)卡中的Generic,雙擊Open、SaveAs、Redo、Undo即可將相應(yīng)工具添加到工具條。
?
常見(jiàn)的工具有:
Map Navigation中的導(dǎo)航工具,Map Inquiry中的查詢工具,Feature Selection中的選擇工具,你可以根據(jù)需要酌情添加工具。
5、編譯運(yùn)行
按F5即可編譯運(yùn)行程序,至此桌面GIS應(yīng)用程序框架基本框架已經(jīng)搭建好了,你可以通過(guò)工具條的工具打開(kāi)地圖文檔,瀏覽地圖了,效果如開(kāi)篇所示.
在這一講中,主要講解菜單的添加和實(shí)現(xiàn)。
1、 添加菜單
在設(shè)計(jì)視圖中,單擊菜單欄,會(huì)出現(xiàn)“請(qǐng)?jiān)诖颂庢I入”的提示,單擊提示就可以鍵入菜單名稱,如“文件”,再單擊“文件”,即可輸入其下拉子菜單,如下所示:
Tips :
每創(chuàng)建一個(gè)菜單,請(qǐng)?jiān)谄鋵傩悦姘逯性O(shè)置 Name 屬性,而且不要為中文,因此 Name 值將是此菜單響應(yīng)函數(shù)的函數(shù)名的一部分,帶中文的函數(shù)名,總是不好吧。
本講中,我們將添加新建( New )、打開(kāi)( Open )、添加數(shù)據(jù)( AddData )、保存( Save )、另存為( SaveAs )、退出( Exit )這些菜單,()內(nèi)為相應(yīng)的 Name 屬性值。
Tips:
你可以在屬性面板中的 Text 屬性中,把菜單名設(shè)置為中英文形式,如“打開(kāi) O pen ”,帶下劃線的 O 表示此項(xiàng)菜單的快捷鍵是字母 O ,設(shè)置方法是在相應(yīng)字母前加上“ & ”字符,如“打開(kāi) &Open ”。但這種快捷鍵只在打開(kāi)此下拉菜單時(shí)才有效,即當(dāng)你單擊“文件”菜單彈出下拉菜單時(shí),按下字母 O 就可以定位到“打開(kāi)”菜單。
還有一種在程序運(yùn)行時(shí)都有效的全局快捷鍵,可以在屬性面板中的“ ShortCutKeys ”中設(shè)置。
你還可以在屬性面板中的 Image 屬性中設(shè)置你喜歡的菜單圖標(biāo)。單擊 Image 那一行右邊的按鈕,彈出如下菜單。選擇“項(xiàng)目資源文件”,再單擊導(dǎo)入就可以選擇你的圖標(biāo)了。
最終效果如下所示。
注意,在解決方案面板中,選中剛才添加的所有圖標(biāo),在其屬性面板中將生成操作設(shè)置為“嵌入的資源”,這一點(diǎn)很重要!
2、 實(shí)現(xiàn)相關(guān)菜單
首先定義指針(寫(xiě)在 public partial class Form1 : Form 下面即可):
| ?private ESRI.ArcGIS.Controls.IMapControl3 m_mapControl = null; private ESRI.ArcGIS.Controls.IPageLayoutControl2 m_pageLayoutControl = null; private IMapDocument pMapDocument; |
?若以上指針無(wú)效,請(qǐng)?zhí)砑右韵乱?#xff1a;
| using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.SystemUI; |
在設(shè)計(jì)視圖中的屬性面板中,選擇 Form1 ,即主窗體,單擊事件按鈕(閃電形狀的那個(gè)按鈕),打到“ Load ”事件并雙擊,添加此事件。
在 Form1_Load 函數(shù)中初始化這些指針:
// 取得 MapControl 和 PageLayoutControl 的引用
| m_mapControl = (IMapControl3)this.axMapControl1.Object; m_pageLayoutControl = (IPageLayoutControl2)this.axPageLayoutControl1.Object; |
依次雙擊每個(gè)菜單項(xiàng),添加菜單響應(yīng)函數(shù)。實(shí)現(xiàn)代碼如下:
| /// <summary> /// 新建地圖命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void New_Click(object sender, EventArgs e) { // 本命令涉及到 MapControl 和 PageLayoutControl 同步問(wèn)題,將在下一講中實(shí)現(xiàn) } /// <summary> /// 打開(kāi)地圖文檔 Mxd 命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Open_Click(object sender, EventArgs e) { // 本命令涉及到 MapControl 和 PageLayoutControl 同步問(wèn)題,將在下一講中實(shí)現(xiàn) } /// <summary> /// 添加數(shù)據(jù)命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void AddData_Click(object sender, EventArgs e) { int currentLayerCount = this.axMapControl1.LayerCount; ICommand pCommand = new ControlsAddDataCommandClass(); pCommand.OnCreate(this.axMapControl1.Object); pCommand.OnClick(); } /// <summary> /// 保存地圖文檔命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Save_Click(object sender, EventArgs e) { // 首先確認(rèn)當(dāng)前地圖文檔是否有效 if (null != m_pageLayoutControl.DocumentFilename && m_mapControl.CheckMxFile(m_pageLayoutControl.DocumentFilename)) { // 創(chuàng)建一個(gè)新的地圖文檔實(shí)例 IMapDocument mapDoc = new MapDocumentClass(); // 打開(kāi)當(dāng)前地圖文檔 mapDoc.Open(m_pageLayoutControl.DocumentFilename, string.Empty); // 用 PageLayout 中的文檔替換當(dāng)前文檔中的 PageLayout 部分 mapDoc.ReplaceContents((IMxdContents)m_pageLayoutControl.PageLayout); // 保存地圖文檔 mapDoc.Save(mapDoc.UsesRelativePaths, false); mapDoc.Close(); } } /// <summary> /// 另存為地圖文檔命令 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void SaveAs_Click(object sender, EventArgs e) { // 調(diào)用另存為命令 ICommand command = new ControlsSaveAsDocCommandClass(); command.OnCreate(m_controlsSynchronizer.ActiveControl); command.OnClick(); } /// <summary> /// 退出程序 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Exit_Click(object sender, EventArgs e) { Application.Exit(); } |
3、 編譯運(yùn)行
按 F5 編譯運(yùn)行程序。也許你會(huì)發(fā)現(xiàn),菜單命令的實(shí)現(xiàn)方式都是類型的。沒(méi)錯(cuò),在 AE9.2 中,內(nèi)置了許多常用的 Command 和 Tool ,如 ControlsAddDataCommandClass 、 ControlsMapZoomInToolClass 、 ControlsMapPanToolClass 等等,這些內(nèi)置對(duì)象在 ESRI.ArcGIS.Controls 命名空間中,你可以對(duì)象瀏覽器中查看。而且這些內(nèi)置對(duì)象的調(diào)用方式都類似,如下所示:
| ?// 定義 |
希望你可以舉一反三,去實(shí)現(xiàn)更多的你想要的功能。
在ArcMap中,能夠很方面地進(jìn)行MapView和Layout View兩種視圖的切換,而且二者之間的數(shù)據(jù)是同步顯示的。
關(guān)于兩種視圖同步的實(shí)現(xiàn)方法有多種,可以使用ObjectCopy對(duì)象進(jìn)行數(shù)據(jù)硬拷貝,而比較簡(jiǎn)單的方法莫過(guò)于二者共享一份地圖了,這也是最常用的方法。
1、新建同步類ControlsSynchronizer
在解決方案面板中右擊項(xiàng)目名,選擇“添加|類”,在類別中選擇“Visual C#項(xiàng)目項(xiàng)”,在模板中選擇“類”,輸入類名“ControlsSynchronizer.cs”,將以下代碼覆蓋自動(dòng)生成的代碼:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.SystemUI;
namespace _sdnMap
{
??? /// <summary>
??? /// This class is used to synchronize a gven PageLayoutControl and a MapControl.
??? /// When initialized, the user must pass the reference of these control to the class, bind
??? /// the control together by calling 'BindControls' which in turn sets a joined Map referenced
??? /// by both control; and set all the buddy controls joined between these two controls.
??? /// When alternating between the MapControl and PageLayoutControl, you should activate the visible control
??? /// and deactivate the other by calling ActivateXXX.
??? /// This calss is limited to a situation where the controls are not simultaneously visible.
??? /// </summary>
??? public class ControlsSynchronizer
??? {
??????? #region class members
??????? private IMapControl3 m_mapControl = null;
??????? private IPageLayoutControl2 m_pageLayoutControl = null;
??????? private ITool m_mapActiveTool = null;
??????? private ITool m_pageLayoutActiveTool = null;
??????? private bool m_IsMapCtrlactive = true;
??????? private ArrayList m_frameworkControls = null;
??????? #endregion
??????? #region constructor
??????? /// <summary>
??????? /// 默認(rèn)構(gòu)造函數(shù)
??????? /// </summary>
??????? public ControlsSynchronizer()
??????? {
??????????? //初始化ArrayList
??????????? m_frameworkControls = new ArrayList();
??????? }
??????? /// <summary>
??????? /// 構(gòu)造函數(shù)
??????? /// </summary>
??????? /// <param name="mapControl"></param>
??????? /// <param name="pageLayoutControl"></param>
??????? public ControlsSynchronizer(IMapControl3 mapControl, IPageLayoutControl2 pageLayoutControl)
??????????? : this()
??????? {
??????????? //為類成員賦值
??????????? m_mapControl = mapControl;
??????????? m_pageLayoutControl = pageLayoutControl;
??????? }
??????? #endregion
??????? #region properties
??????? /// <summary>
??????? /// 取得或設(shè)置MapControl
??????? /// </summary>
??????? public IMapControl3 MapControl
??????? {
??????????? get { return m_mapControl; }
??????????? set { m_mapControl = value; }
??????? }
??????? /// <summary>
??????? /// 取得或設(shè)置PageLayoutControl
??????? /// </summary>
??????? public IPageLayoutControl2 PageLayoutControl
??????? {
??????????? get { return m_pageLayoutControl; }
??????????? set { m_pageLayoutControl = value; }
??????? }
??????? /// <summary>
??????? /// 取得當(dāng)前ActiveView的類型
??????? /// </summary>
??????? public string ActiveViewType
??????? {
??????????? get
??????????? {
??????????????? if (m_IsMapCtrlactive)
??????????????????? return "MapControl";
??????????????? else
??????????????????? return "PageLayoutControl";
??????????? }
??????? }
??????? /// <summary>
??????? /// 取得當(dāng)前活動(dòng)的Control
??????? /// </summary>
??????? public object ActiveControl
??????? {
??????????? get
??????????? {
??????????????? if (m_mapControl == null || m_pageLayoutControl == null)
??????????????????? throw new Exception("ControlsSynchronizer::ActiveControl:\r\nEither MapControl?or?PageLayoutControl are not initialized!");
??????????????? if (m_IsMapCtrlactive)
??????????????????? return m_mapControl.Object;
??????????????? else
??????????????????? return m_pageLayoutControl.Object;
??????????? }
??????? }
??????? #endregion
??????? #region Methods
??????? /// <summary>
??????? /// 激活MapControl并解除the PagleLayoutControl
??????? /// </summary>
??????? public void ActivateMap()
??????? {
??????????? try
??????????? {
??????????????? if (m_pageLayoutControl == null || m_mapControl == null)
??????????????????? throw new Exception("ControlsSynchronizer::ActivateMap:\r\nEither MapControl?or?PageLayoutControl are not initialized!");
??????????????? //緩存當(dāng)前PageLayout的CurrentTool
??????????????? if (m_pageLayoutControl.CurrentTool != null) m_pageLayoutActiveTool = m_pageLayoutControl.CurrentTool;
??????????????? //解除PagleLayout
??????????????? m_pageLayoutControl.ActiveView.Deactivate();
?????????????? //激活MapControl
??????????????? m_mapControl.ActiveView.Activate(m_mapControl.hWnd);
??????????????? //將之前MapControl最后使用的tool,作為活動(dòng)的tool,賦給MapControl的CurrentTool
??????????????? if (m_mapActiveTool != null) m_mapControl.CurrentTool = m_mapActiveTool;
??????????????? m_IsMapCtrlactive = true;
??????????????? //為每一個(gè)的framework controls,設(shè)置Buddy control為MapControl
??????????????? this.SetBuddies(m_mapControl.Object);
??????????? }
??????????? catch (Exception ex)
??????????? {
??????????????? throw new Exception(string.Format("ControlsSynchronizer::ActivateMap:\r\n{0}", ex.Message));
??????????? }
??????? }
??????? /// <summary>
??????? /// 激活PagleLayoutControl并減活MapCotrol
??????? /// </summary>
??????? public void ActivatePageLayout()
??????? {
??????????? try
??????????? {
??????????????? if (m_pageLayoutControl == null || m_mapControl == null)
??????????????????? throw new Exception("ControlsSynchronizer::ActivatePageLayout:\r\nEither MapControl?or?PageLayoutControl are not initialized!");
??????????????? //緩存當(dāng)前MapControl的CurrentTool
??????????????? if (m_mapControl.CurrentTool != null) m_mapActiveTool = m_mapControl.CurrentTool;
??????????????? //解除MapControl
??????????????? m_mapControl.ActiveView.Deactivate();
??????????????? //激活PageLayoutControl
??????????????? m_pageLayoutControl.ActiveView.Activate(m_pageLayoutControl.hWnd);
??????????????? //將之前PageLayoutControl最后使用的tool,作為活動(dòng)的tool,賦給PageLayoutControl的CurrentTool
??????????????? if (m_pageLayoutActiveTool != null) m_pageLayoutControl.CurrentTool = m_pageLayoutActiveTool;
??????????????? m_IsMapCtrlactive = false;
??????????????? //為每一個(gè)的framework controls,設(shè)置Buddy control為PageLayoutControl
??????????????? this.SetBuddies(m_pageLayoutControl.Object);
??????????? }
??????????? catch (Exception ex)
??????????? {
??????????????? throw new Exception(string.Format("ControlsSynchronizer::ActivatePageLayout:\r\n{0}", ex.Message));
??????????? }
??????? }
??????? /// <summary>
??????? /// 給予一個(gè)地圖, 置換PageLayoutControl和MapControl的focus map
??????? /// </summary>
??????? /// <param name="newMap"></param>
??????? public void ReplaceMap(IMap newMap)
??????? {
??????????? if (newMap == null)
??????????????? throw new Exception("ControlsSynchronizer::ReplaceMap:\r\nNew map for replacement is not initialized!");
??????????? if (m_pageLayoutControl == null || m_mapControl == null)
??????????????? throw new Exception("ControlsSynchronizer::ReplaceMap:\r\nEither MapControl?or?PageLayoutControl are not initialized!");
??????????? //create a new instance of IMaps collection which is needed by the PageLayout
??????????? //創(chuàng)建一個(gè)PageLayout需要用到的,新的IMaps collection的實(shí)例
??????????? IMaps maps = new Maps();
??????????? //add the new map to the Maps collection
??????????? //把新的地圖加到Maps collection里頭去
??????????? maps.Add(newMap);
??????????? bool bIsMapActive = m_IsMapCtrlactive;
??????????? //call replace map on the PageLayout in order to replace the focus map
??????????? //we must call ActivatePageLayout, since it is the control we call 'ReplaceMaps'
??????????? //調(diào)用PageLayout的replace map來(lái)置換focus map
??????????? //我們必須調(diào)用ActivatePageLayout,因?yàn)樗悄莻€(gè)我們可以調(diào)用"ReplaceMaps"的Control
??????????? this.ActivatePageLayout();
??????????? m_pageLayoutControl.PageLayout.ReplaceMaps(maps);
??????????? //assign the new map to the MapControl
??????????? //把新的地圖賦給MapControl
??????????? m_mapControl.Map = newMap;
??????????? //reset the active tools
??????????? //重設(shè)active tools
??????????? m_pageLayoutActiveTool = null;
??????????? m_mapActiveTool = null;
??????????? //make sure that the last active control is activated
??????????? //確認(rèn)之前活動(dòng)的control被激活
??????????? if (bIsMapActive)
??????????? {
??????????????? this.ActivateMap();
??????????????? m_mapControl.ActiveView.Refresh();
??????????? }
??????????? else
??????????? {
??????????????? this.ActivatePageLayout();
??????????????? m_pageLayoutControl.ActiveView.Refresh();
??????????? }
??????? }
??????? /// <summary>
??????? /// bind the MapControl and PageLayoutControl together by assigning a new joint focus map
??????? /// 指定共同的Map來(lái)把MapControl和PageLayoutControl綁在一起
??????? /// </summary>
??????? /// <param name="mapControl"></param>
??????? /// <param name="pageLayoutControl"></param>
??????? /// <param name="activateMapFirst">true if the MapControl supposed to be activated first,如果MapControl被首先激活,則為true</param>
??????? public void BindControls(IMapControl3 mapControl, IPageLayoutControl2 pageLayoutControl, bool activateMapFirst)
??????? {
??????????? if (mapControl == null || pageLayoutControl == null)
??????????????? throw new Exception("ControlsSynchronizer::BindControls:\r\nEither MapControl?or?PageLayoutControl are not initialized!");
??????????? m_mapControl = MapControl;
??????????? m_pageLayoutControl = pageLayoutControl;
??????????? this.BindControls(activateMapFirst);
??????? }
??????? /// <summary>
??????? /// bind the MapControl and PageLayoutControl together by assigning a new joint focus map
??????? /// 指定共同的Map來(lái)把MapControl和PageLayoutControl綁在一起
??????? /// </summary>
??????? /// <param name="activateMapFirst">true if the MapControl supposed to be activated first,如果MapControl被首先激活,則為true</param>
??????? public void BindControls(bool activateMapFirst)
??????? {
??????????? if (m_pageLayoutControl == null || m_mapControl == null)
??????????????? throw new Exception("ControlsSynchronizer::BindControls:\r\nEither MapControl?or?PageLayoutControl are not initialized!");
??????????? //create a new instance of IMap
??????????? //創(chuàng)造IMap的一個(gè)實(shí)例
??????????? IMap newMap = new MapClass();
??????????? newMap.Name = "Map";
??????????? //create a new instance of IMaps collection which is needed by the PageLayout
??????????? //創(chuàng)造一個(gè)新的IMaps collection的實(shí)例,這是PageLayout所需要的
??????????? IMaps maps = new Maps();
??????????? //add the new Map instance to the Maps collection
??????????? //把新的Map實(shí)例賦給Maps collection
??????????? maps.Add(newMap);
??????????? //call replace map on the PageLayout in order to replace the focus map
??????????? //調(diào)用PageLayout的replace map來(lái)置換focus map
??????????? m_pageLayoutControl.PageLayout.ReplaceMaps(maps);
??????????? //assign the new map to the MapControl
??????????? //把新的map賦給MapControl
??????????? m_mapControl.Map = newMap;
??????????? //reset the active tools
??????????? //重設(shè)active tools
??????????? m_pageLayoutActiveTool = null;
??????????? m_mapActiveTool = null;
??????????? //make sure that the last active control is activated
??????????? //確定最后活動(dòng)的control被激活
??????????? if (activateMapFirst)
??????????????? this.ActivateMap();
??????????? else
??????????????? this.ActivatePageLayout();
??????? }
??????? /// <summary>
??????? ///by passing the application's toolbars and TOC to the synchronization class, it saves you the
??????? ///management of the buddy control each time the active control changes. This method ads the framework
??????? ///control to an array; once the active control changes, the class iterates through the array and
??????? ///calles SetBuddyControl on each of the stored framework control.
??????? /// </summary>
??????? /// <param name="control"></param>
??????? public void AddFrameworkControl(object control)
??????? {
??????????? if (control == null)
??????????????? throw new Exception("ControlsSynchronizer::AddFrameworkControl:\r\nAdded control is not initialized!");
??????????? m_frameworkControls.Add(control);
??????? }
??????? /// <summary>
??????? /// Remove a framework control from the managed list of controls
??????? /// </summary>
??????? /// <param name="control"></param>
??????? public void RemoveFrameworkControl(object control)
??????? {
??????????? if (control == null)
??????????????? throw new Exception("ControlsSynchronizer::RemoveFrameworkControl:\r\nControl to be removed is not initialized!");
??????????? m_frameworkControls.Remove(control);
??????? }
??????? /// <summary>
??????? /// Remove a framework control from the managed list of controls by specifying its index in the list
??????? /// </summary>
??????? /// <param name="index"></param>
??????? public void RemoveFrameworkControlAt(int index)
??????? {
??????????? if (m_frameworkControls.Count < index)
??????????????? throw new Exception("ControlsSynchronizer::RemoveFrameworkControlAt:\r\nIndex is out of range!");
??????????? m_frameworkControls.RemoveAt(index);
??????? }
??????? /// <summary>
??????? /// when the active control changes, the class iterates through the array of the framework controls
??????? ///? and calles SetBuddyControl on each of the controls.
??????? /// </summary>
??????? /// <param name="buddy">the active control</param>
??????? private void SetBuddies(object buddy)
??????? {
??????????? try
??????????? {
??????????????? if (buddy == null)
??????????????????? throw new Exception("ControlsSynchronizer::SetBuddies:\r\nTarget Buddy Control is not initialized!");
??????????????? foreach (object obj in m_frameworkControls)
??????????????? {
??????????????????? if (obj is IToolbarControl)
??????????????????? {
??????????????????????? ((IToolbarControl)obj).SetBuddyControl(buddy);
??????????????????? }
??????????????????? else if (obj is ITOCControl)
??????????????????? {
??????????????????????? ((ITOCControl)obj).SetBuddyControl(buddy);
??????????????????? }
??????????????? }
??????????? }
??????????? catch (Exception ex)
??????????? {
??????????????? throw new Exception(string.Format("ControlsSynchronizer::SetBuddies:\r\n{0}", ex.Message));
??????????? }
??????? }
??????? #endregion
??? }
}
2、新建Maps類
在同步類中,要用到Maps類,用于管理地圖對(duì)象。與新建同步類ControlsSynchronizer類似,我們新建一Maps類,其所有代碼如下所示:
?using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Carto;
namespace _sdnMap
{
??? [Guid("f27d8789-fbbc-4801-be78-0e3cd8fff9d5")]
??? [ClassInterface(ClassInterfaceType.None)]
??? [ProgId("_sdnMap.Maps")]
??? public class Maps : IMaps, IDisposable
??? {
??????? //class member - using internally an ArrayList to manage the Maps collection
??????? private ArrayList m_array = null;
??????? #region class constructor
??????? public Maps()
??????? {
??????????? m_array = new ArrayList();
??????? }
??????? #endregion
??????? #region IDisposable Members
??????? /// <summary>
???? ???/// Dispose the collection
??????? /// </summary>
??????? public void Dispose()
??????? {
??????????? if (m_array != null)
??????????? {
??????????????? m_array.Clear();
??????????????? m_array = null;
??????????? }
??????? }
??????? #endregion
????? ??#region IMaps Members
??????? /// <summary>
??????? /// Remove the Map at the given index
??????? /// </summary>
??????? /// <param name="Index"></param>
??????? public void RemoveAt(int Index)
??????? {
??????????? if (Index > m_array.Count || Index < 0)
??????????????? throw new Exception("Maps::RemoveAt:\r\nIndex is out of range!");
??????????? m_array.RemoveAt(Index);
??????? }
??????? /// <summary>
??????? /// Reset the Maps array
??????? /// </summary>
??????? public void Reset()
??????? {
????? ??????m_array.Clear();
??????? }
??????? /// <summary>
??????? /// Get the number of Maps in the collection
??????? /// </summary>
??????? public int Count
??????? {
??????????? get
??????????? {
??????????????? return m_array.Count;
??????????? }
?????? ?}
??????? /// <summary>
??????? /// Return the Map at the given index
??????? /// </summary>
??????? /// <param name="Index"></param>
??????? /// <returns></returns>
??????? public IMap get_Item(int Index)
??????? {
??????????? if (Index > m_array.Count || Index < 0)
??????????????? throw new Exception("Maps::get_Item:\r\nIndex is out of range!");
??????????? return m_array[Index] as IMap;
??????? }
??????? /// <summary>
??????? /// Remove the instance of the given Map
??????? /// </summary>
??????? /// <param name="Map"></param>
??????? public void Remove(IMap Map)
??????? {
??????????? m_array.Remove(Map);
??????? }
??????? /// <summary>
??????? /// Create a new Map, add it to the collection and return it to the caller
??????? /// </summary>
??????? /// <returns></returns>
??????? public IMap Create()
??????? {
??????????? IMap newMap = new MapClass();
??????????? m_array.Add(newMap);
??????????? return newMap;
??????? }
??????? /// <summary>
??????? /// Add the given Map to the collection
??????? /// </summary>
??????? /// <param name="Map"></param>
??????? public void Add(IMap Map)
??????? {
??????????? if (Map == null)
??????????????? throw new Exception("Maps::Add:\r\nNew Map is mot initialized!");
??????????? m_array.Add(Map);
??????? }
?????? ?#endregion
??? }
}
3、新建打開(kāi)文檔類OpenNewMapDocument
由于從工具欄自帶的打開(kāi)按鈕打開(kāi)地圖文檔的時(shí)候,不會(huì)自動(dòng)進(jìn)行兩種視圖之間的同步,所以我們要自己派生一個(gè)OpenNewMapDocument類,用于打開(kāi)地圖文檔。
?右擊項(xiàng)目名,選擇“添加|類”,再選擇ArcGIS類別中的BaseCommand模板,輸入類名為“OpenNewMapDocument.cs”。
首先添加引用:
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
再添加如下成員變量:
?private ControlsSynchronizer m_controlsSynchronizer = null;
修改默認(rèn)的構(gòu)造函數(shù)如下所示:
?//添加參數(shù)
public OpenNewMapDocument(ControlsSynchronizer controlsSynchronizer)
??????? {
??????????? //
??????????? // TODO: Define values for the public properties
???????? ???//
//設(shè)定相關(guān)屬性值
??????????? base.m_category = "Generic"; //localizable text
??????????? base.m_caption = "Open";? //localizable text
??????????? base.m_message = "This should work in ArcMap/MapControl/PageLayoutControl";? //localizable text
??????????? base.m_toolTip = "Open";? //localizable text
??????????? base.m_name = "Generic_Open";?? //unique id, non-localizable (e.g. "MyCategory_MyCommand")
???????????
?? //初始化m_controlsSynchronizer
??????????? m_controlsSynchronizer = controlsSynchronizer;
????? ??????try
??????????? {
??????????????? //
??????????????? // TODO: change bitmap name if necessary
??????????????? //
??????????????? string bitmapResourceName = GetType().Name + ".bmp";
??????????????? base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
??????????? }
??????????? catch (Exception ex)
??????????? {
??????????????? System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
??????????? }
??????? }
再在OnClick函數(shù)中添加如下代碼:
?public override void OnClick()
??????? {
??????????? // TODO: Add OpenNewMapDocument.OnClick implementation
??????????? OpenFileDialog dlg = new OpenFileDialog();
??????????? dlg.Filter = "Map Documents (*.mxd)|*.mxd";
??????????? dlg.Multiselect = false;
??????????? dlg.Title = "Open Map Document";
??????????? if (dlg.ShowDialog() == DialogResult.OK)
??????????? {
??????????????? string docName = dlg.FileName;
??????????????? IMapDocument mapDoc = new MapDocumentClass();
??????????? ????if (mapDoc.get_IsPresent(docName) && !mapDoc.get_IsPasswordProtected(docName))
??????????????? {
??????????????????? mapDoc.Open(docName, string.Empty);
??????????????????? IMap map = mapDoc.get_Map(0);
??????????????????? m_controlsSynchronizer.ReplaceMap(map);
??????????????????? mapDoc.Close();
??????????????? }
??????????? }
??????? }
在添加類時(shí),模板會(huì)自動(dòng)添加一個(gè)名為“OpenNewMapDocument.bmp”的圖標(biāo),你可以自己修改或者替換為打開(kāi)的文件夾的圖標(biāo)。
4、兩種視圖的同步
在3sdnMap.cs中添加成員變量,即同步類對(duì)象:
?private ControlsSynchronizer m_controlsSynchronizer = null;
在Form1_Load函數(shù)中進(jìn)行初始化工作:
?//初始化controls synchronization calss
m_controlsSynchronizer = new
ControlsSynchronizer(m_mapControl, m_pageLayoutControl);
???? //把MapControl和PageLayoutControl綁定起來(lái)(兩個(gè)都指向同一個(gè)Map),然后設(shè)置MapControl為活動(dòng)的Control
???? m_controlsSynchronizer.BindControls(true);
???? //為了在切換MapControl和PageLayoutControl視圖同步,要添加Framework Control
??? m_controlsSynchronizer.AddFrameworkControl(axToolbarControl1.Object);
??? m_controlsSynchronizer.AddFrameworkControl(this.axTOCControl1.Object);
// 添加打開(kāi)命令按鈕到工具條
OpenNewMapDocument openMapDoc = new OpenNewMapDocument(m_controlsSynchronizer);
axToolbarControl1.AddItem(openMapDoc, -1, 0, false, -1, esriCommandStyles.esriCommandStyleIconOnly);
因?yàn)槲覀冏詣?dòng)派生了打開(kāi)文檔類,并自己將其添加到工具條,所以我們就不需要工具條原來(lái)的“打開(kāi)”按鈕了,可以ToolbarControl的屬性中將其刪除。
下面,我們可完成上一講遺留的功能了。
?/// <summary>
??????? /// 新建地圖命令
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void New_Click(object sender, EventArgs e)
??????? {
??????????? //詢問(wèn)是否保存當(dāng)前地圖
??????????? DialogResult res = MessageBox.Show("是否保存當(dāng)前地圖?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
??????????? if (res == DialogResult.Yes)
??????????? {
??????????????? //如果要保存,調(diào)用另存為對(duì)話框
??????????????? ICommand command = new ControlsSaveAsDocCommandClass();
??????????????? if (m_mapControl != null)
??????????????????? command.OnCreate(m_controlsSynchronizer.MapControl.Object);
??????????????? else
??????????????????? command.OnCreate(m_controlsSynchronizer.PageLayoutControl.Object);
??????????????? command.OnClick();
??????????? }
???? //創(chuàng)建新的地圖實(shí)例
??????????? IMap map = new MapClass();
??????????? map.Name = "Map";
??????????? m_controlsSynchronizer.MapControl.DocumentFilename = string.Empty;
??????????? //更新新建地圖實(shí)例的共享地圖文檔
??????????? m_controlsSynchronizer.ReplaceMap(map);
??????? }
/// <summary>
??????? /// 打開(kāi)地圖文檔Mxd命令
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void Open_Click(object sender, EventArgs e)
??????? {
if (this.axMapControl1.LayerCount > 0)
?? ?????????{
??????????????? DialogResult result = MessageBox.Show("是否保存當(dāng)前地圖?", "警告",
MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
??????????????? if (result == DialogResult.Cancel) return;
??????????????? if (result == DialogResult.Yes) this.Save_Click(null, null);
??????????? }
??????????? OpenNewMapDocument openMapDoc =
new OpenNewMapDocument(m_controlsSynchronizer);
??????????? openMapDoc.OnCreate(m_controlsSynchronizer.MapControl.Object);
??????????? openMapDoc.OnClick();
}
在添加數(shù)據(jù)AddData時(shí),我們也要進(jìn)行地圖共享,故在AddData_Click函數(shù)后面添加如下代碼:
?IMap pMap = this.axMapControl1.Map;
this.m_controlsSynchronizer.ReplaceMap(pMap);
在另存為地圖文檔時(shí),有可能會(huì)丟失數(shù)據(jù),因此我們需要提示用戶以確認(rèn)操作,故需修改SaveAs_Click函數(shù),如下所示:
?/// <summary>
??????? /// 另存為地圖文檔命令
??????? /// </summary>
?????? ?/// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void SaveAs_Click(object sender, EventArgs e)
??????? {
??????????? //如果當(dāng)前視圖為MapControl時(shí),提示用戶另存為操作將丟失PageLayoutControl中的設(shè)置
??????????? if (m_controlsSynchronizer.ActiveControl is IMapControl3)
??????????? {
??????????????? if (MessageBox.Show("另存為地圖文檔將丟失制版視圖的設(shè)置\r\n您要繼續(xù)嗎?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
??????????????????? return;
??????????? }
??????????? //調(diào)用另存為命令
???????? ???ICommand command = new ControlsSaveAsDocCommandClass();
??????????? command.OnCreate(m_controlsSynchronizer.ActiveControl);
??????????? command.OnClick();
??????? }
在切換視圖時(shí),我們要激活相關(guān)的視圖,故在設(shè)計(jì)視圖的屬性面板中選擇tabControl2控件,再選擇事件按鈕,找到“SelectedIndexChanged”事件雙擊添加之。其實(shí)現(xiàn)代碼如下所示:
?/// <summary>
??????? /// 切換地圖和制版視圖
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void tabControl2_SelectedIndexChanged(object sender, EventArgs e)
??????? {
?????????? ?if (this.tabControl2.SelectedIndex == 0)
??????????? {
??????????????? //激活MapControl
??????????????? m_controlsSynchronizer.ActivateMap();
??????????? }
??????????? else
??????????? {
??????????????? //激活PageLayoutControl
??????????????? m_controlsSynchronizer.ActivatePageLayout();
??????????? }
??????? }
5、編譯運(yùn)行
按F5編譯運(yùn)行程序,至此我們完成了MapControl和PageLayoutControl兩種視圖的同步工作。
1、 添加狀態(tài)欄項(xiàng)目
在設(shè)計(jì)視圖中,點(diǎn)擊窗體中的狀態(tài)欄,在其屬性面板中找到“ Items ”項(xiàng),單擊其右邊的按鈕,在下拉框中選擇“ StatusLabel ”,單擊“添加按鈕”,依次添加四個(gè) StatusLabel ,依次修改屬性參數(shù)如下表所示:
序號(hào)
?Name 屬性
?Text 屬性
?Spring 屬性
?說(shuō)明
1
?MessageLabel
?就緒
?False
?當(dāng)前所用工具信息
2
?Blank
? True
?占位
3
?ScaleLabel
?比例尺
?False
?當(dāng)前比例尺
4
?CoordinateLabel
?當(dāng)前坐標(biāo)
?False
?當(dāng)前坐標(biāo)
設(shè)置好之后如下圖所示:
Tips :
我們?cè)O(shè)計(jì)出的狀態(tài)欄最終如下所示:
就緒
?( Blank )
?比例尺
?當(dāng)前坐標(biāo)
Spring 屬性表示可以按狀態(tài)欄剩余空間自動(dòng)伸縮。所以加入 Blank 項(xiàng)目,只是為了占個(gè)位子,以達(dá)到 ScaleLabel 和 CoordinateLabel 項(xiàng)目右對(duì)齊而 MessageLabel 項(xiàng)目左對(duì)齊的目的。
2、 顯示當(dāng)前所用工具信息
首先添加 axToolbarControl1 的 OnMouseMove 事件 ( 相信大家看了以上的教程,已經(jīng)知道怎么添加事件了吧,還不知道的建議再溫習(xí)下前幾講的內(nèi)容 ) 。在其事件響應(yīng)函數(shù)代碼如下:
?private void axToolbarControl1_OnMouseMove(object sender, IToolbarControlEvents_OnMouseMoveEvent e)
{
// 取得鼠標(biāo)所在工具的索引號(hào)
int index = axToolbarControl1.HitTest(e.x, e.y, false);
if (index != -1)
{
// 取得鼠標(biāo)所在工具的 ToolbarItem
IToolbarItem toolbarItem = axToolbarControl1.GetItem(index);
// 設(shè)置狀態(tài)欄信息
MessageLabel.Text = toolbarItem.Command.Message;
}
else
{
MessageLabel.Text = " 就緒 ";
}
}
3、 顯示當(dāng)前比例尺
添加 axMapControl1 的 OnMouseMove 事件,其代碼如下:
?private void axMapControl1_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
// 顯示當(dāng)前比例尺
ScaleLabel.Text = " 比例尺 1:" + ((long)this.axMapControl1.MapScale).ToString();
}
4、 顯示當(dāng)前坐標(biāo)
顯示當(dāng)前坐標(biāo)也是 axMapControl1 的 OnMouseMove 事件中響應(yīng),故只要在 axMapControl1_OnMouseMove 函數(shù)中添加如下代碼即可:
?// 顯示當(dāng)前坐標(biāo)
CoordinateLabel.Text = " 當(dāng)前坐標(biāo) X = " + e.mapX.ToString() + " Y = " + e.mapY.ToString() + " " + this.axMapControl1.MapUnits;
按 F5 編譯運(yùn)行,可以看到,我們的程序已經(jīng)能夠正常工作了。但是細(xì)心的你可能會(huì)發(fā)現(xiàn),當(dāng)前坐標(biāo)的后面的坐標(biāo)單位為“ esriUnknownUnits ”或“ esriMeters ”之類,即系統(tǒng)在正常單位的前面加上了“ esri ”,追求完美的我們自然看得不舒服。那就進(jìn)行簡(jiǎn)單的替換吧。
首先定義個(gè)全局坐標(biāo)單位變量 sMapUnits ,如下所示:
?private string sMapUnits;?
再 Form1_Load 函數(shù)中進(jìn)行初始化:
sMapUnits = "Unknown";??
添加 axMapControl1 控件的 OnMapReplaced 事件,在事件響應(yīng)函數(shù)中進(jìn)行坐標(biāo)單位替換,代碼如下:
?private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
{
esriUnits mapUnits = axMapControl1.MapUnits;
switch (mapUnits)
{
case esriUnits.esriCentimeters:
sMapUnits = "Centimeters";
break;
case esriUnits.esriDecimalDegrees:
sMapUnits = "Decimal Degrees";
break;
case esriUnits.esriDecimeters:
sMapUnits = "Decimeters";
break;
case esriUnits.esriFeet:
sMapUnits = "Feet";
break;
case esriUnits.esriInches:
sMapUnits = "Inches";
break;
case esriUnits.esriKilometers:
sMapUnits = "Kilometers";
break;
case esriUnits.esriMeters:
sMapUnits = "Meters";
break;
case esriUnits.esriMiles:
sMapUnits = "Miles";
break;
case esriUnits.esriMillimeters:
sMapUnits = "Millimeters";
break;
case esriUnits.esriNauticalMiles:
sMapUnits = "NauticalMiles";
break;
case esriUnits.esriPoints:
sMapUnits = "Points";
break;
case esriUnits.esriUnknownUnits:
sMapUnits = "Unknown";
break;
case esriUnits.esriYards:
sMapUnits = "Yards";
break;
}
}
5、 編譯運(yùn)行
按 F5 編譯運(yùn)行程序。如果你足夠細(xì)心的話,相信你已經(jīng)成功了!
在本講中,介紹中 StatusStrip 控件的基本使用方法和 AE 中當(dāng)所用工具信息、當(dāng)前比例尺和當(dāng)前坐標(biāo)的顯示調(diào)用方法。
所謂的鷹眼,就是一個(gè)縮略地圖,上面有一個(gè)矩形框,矩形框區(qū)域就是當(dāng)前顯示的地圖區(qū)域,拖動(dòng)矩形框可以改變當(dāng)前地圖顯示的位置,改變矩形框的大小,可以改變當(dāng)前地圖的顯示區(qū)域大小,從起到導(dǎo)航的作用。鷹眼是地圖瀏覽中常用的功能之一。
關(guān)于鷹眼的實(shí)現(xiàn)方式,最常用的是用一個(gè) MapControl 控件顯示地圖全圖,并在上面畫(huà)一個(gè)紅色矩形框表示當(dāng)前地圖的顯示范圍,并實(shí)現(xiàn)鷹眼 MapControl 與主窗體的 MapControl 互動(dòng)。本講最終效果如下所示:
圖 1 鷹眼效果
1 、添加鷹眼控件
由于本教程在第一講中沒(méi)有預(yù)先考慮到鷹眼所放的位置,故我們要先稍微調(diào)整一下程序框架,并添加一個(gè) MapControl 用于顯示鷹眼。
在本教程中,我們將鷹眼放在圖層控件的下方,調(diào)整方法如下:
( 1 )在設(shè)計(jì)視圖中,選擇 tabControl1 控件,即放圖層和屬性的那個(gè)容器,將其 Dock 屬性設(shè)為 None ,并用鼠標(biāo)拖拽將其縮小。把工具箱中的 SplitContainer 控件拖到窗體的左窗格,即放在 tabControl1 控件的旁邊。并將其 Orientation 屬性設(shè)置為 Horizontal 。
( 2 )選中 tabControl1 控件,按 Ctrl+X 剪切,再選中剛才粘貼到 SplitContainer2 的 Panel1 中,如圖 2 所示。操作完成后效果如圖 3 所示。
圖 2
圖 3
( 3 )再選中 SplitContainer2 控件(如果不好選中,直接以屬性面板中選擇 SplitContainer2 ),將其 Dock 屬性設(shè)置為 Fill 。再選中 tabControl1 ,將其 Dock 屬性也設(shè)置為 Fill 。
( 4 )從工具箱中選擇 MapControl 控件并拖到 SplitContainer2 的 Panel2 ,作為鷹眼控件。最終效果如圖 4 所示。
圖 4
2 、鷹眼的實(shí)現(xiàn)
( 1 )載入地圖到鷹眼控件
當(dāng)?shù)貓D載入到主 Map 控件時(shí),同時(shí)也載入到鷹眼控件,在 axMapControl1_OnMapReplaced 事件響應(yīng)函數(shù)(此函數(shù)上一講中已經(jīng)添加了)中添加如下代碼:
private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
{
// 前面代碼省略
// 當(dāng)主地圖顯示控件的地圖更換時(shí),鷹眼中的地圖也跟隨更換
this.axMapControl2.Map = new MapClass();
// 添加主地圖控件中的所有圖層到鷹眼控件中
for (int i = 1; i <= this.axMapControl1.LayerCount; i++)
{
this.axMapControl2.AddLayer(this.axMapControl1.get_Layer(this.axMapControl1.LayerCount - i));
}
// 設(shè)置 MapControl 顯示范圍至數(shù)據(jù)的全局范圍
this.axMapControl2.Extent = this.axMapControl1.FullExtent;
// 刷新鷹眼控件地圖
this.axMapControl2.Refresh();
}
( 2 )繪制鷹眼矩形框
為鷹眼控件 MapControl1 添加 OnExtentUpdated 事件,此事件是在主 Map 控件的顯示范圍改變時(shí)響應(yīng),從而相應(yīng)更新鷹眼控件中的矩形框。其響應(yīng)函數(shù)代碼如下:
private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e)
{
// 得到新范圍
IEnvelope pEnv = (IEnvelope)e.newEnvelope;
IGraphicsContainer pGra = axMapControl2.Map as IGraphicsContainer;
IActiveView pAv = pGra as IActiveView;
// 在繪制前,清除 axMapControl2 中的任何圖形元素
pGra.DeleteAllElements();
IRectangleElement pRectangleEle = new RectangleElementClass();
IElement pEle = pRectangleEle as IElement;
pEle.Geometry = pEnv;
// 設(shè)置鷹眼圖中的紅線框
IRgbColor pColor = new RgbColorClass();
pColor.Red = 255;
pColor.Green = 0;
pColor.Blue = 0;
pColor.Transparency = 255;
// 產(chǎn)生一個(gè)線符號(hào)對(duì)象
ILineSymbol pOutline = new SimpleLineSymbolClass();
pOutline.Width = 2;
pOutline.Color = pColor;
// 設(shè)置顏色屬性
pColor = new RgbColorClass();
pColor.Red = 255;
pColor.Green = 0;
pColor.Blue = 0;
pColor.Transparency = 0;
// 設(shè)置填充符號(hào)的屬性
IFillSymbol pFillSymbol = new SimpleFillSymbolClass();
pFillSymbol.Color = pColor;
pFillSymbol.Outline = pOutline;
IFillShapeElement pFillShapeEle = pEle as IFillShapeElement;
pFillShapeEle.Symbol = pFillSymbol;
pGra.AddElement((IElement)pFillShapeEle, 0);
// 刷新
pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
( 3 )鷹眼與主 Map 控件互動(dòng)
為鷹眼控件 MapControl2 添加 OnMouseDown 事件,代碼如下:
private void axMapControl2_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
if (this.axMapControl2.Map.LayerCount != 0)
{
// 按下鼠標(biāo)左鍵移動(dòng)矩形框
if (e.button == 1)
{
IPoint pPoint = new PointClass();
pPoint.PutCoords(e.mapX, e.mapY);
IEnvelope pEnvelope = this.axMapControl1.Extent;
pEnvelope.CenterAt(pPoint);
this.axMapControl1.Extent = pEnvelope;
this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
}
// 按下鼠標(biāo)右鍵繪制矩形框
else if (e.button == 2)
{
IEnvelope pEnvelop = this.axMapControl2.TrackRectangle();
this.axMapControl1.Extent = pEnvelop;
this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
}
}
}
為鷹眼控件 MapControl2 添加 OnMouseMove 事件,主要實(shí)現(xiàn)按下鼠標(biāo)左鍵的時(shí)候移動(dòng)矩形框,同時(shí)也改變主的圖控件的顯示范圍。代碼如下:
private void axMapControl2_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
// 如果不是左鍵按下就直接返回
if (e.button != 1) return;
IPoint pPoint = new PointClass();
pPoint.PutCoords(e.mapX, e.mapY);
this.axMapControl1.CenterAt(pPoint);
this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
}
1、 編譯運(yùn)行
按 F5 編譯運(yùn)行程序。
期待的鷹眼功能你已經(jīng)實(shí)現(xiàn)了,按下左鍵在鷹眼窗口中移動(dòng),或者按下右鍵在鷹眼窗口中畫(huà)一個(gè)矩形,主地圖窗口的顯示范圍都會(huì)跟著變化。主地圖窗口中的地圖經(jīng)放大縮小等操作后,鷹眼窗口的矩形框大小也會(huì)隨著改變。
在AE開(kāi)發(fā)中,右鍵菜單有兩種實(shí)現(xiàn)方式,一是使用VS2005自帶的ContextMenuStrip控件,二是用AE封裝的IToolbarMenu接口。相比較而言,后者更為簡(jiǎn)單實(shí)用,本文采用后者的實(shí)現(xiàn)方法。
?????? 1、創(chuàng)建右鍵菜單
?? 在Form1類里面添加如下變量的定義:
??????? //TOCControl控件變量
private ITOCControl2 m_tocControl = null;
//TOCControl中Map菜單
private IToolbarMenu m_menuMap = null;
//TOCControl中圖層菜單
private IToolbarMenu m_menuLayer = null;
????????????? 在Form1_Load函數(shù)進(jìn)行初始化,即菜單的創(chuàng)建:
m_menuMap = new ToolbarMenuClass();
m_menuLayer = new ToolbarMenuClass();
2、添加菜單項(xiàng)
第1步中創(chuàng)建的菜單可認(rèn)為是菜單容器,里面什么都沒(méi)有,具體的命令或工具作為菜單項(xiàng)添加到菜單容器才能工作。一般情況下,啟動(dòng)程序就要完成菜單項(xiàng)的添加,故此工作在Form1_Load函數(shù)完成。
當(dāng)然,添加菜單項(xiàng)之前,必須實(shí)現(xiàn)相應(yīng)命令或工具。這里的命令或工具可以AE內(nèi)置的也可以是自定義的。AE內(nèi)置了許多可以直接調(diào)用的常用命令和工具,如ControlsAddDataCommandClass,在ESRI.ArcGIS.Controls命名空間中,大家可以對(duì)象瀏覽器中查看。當(dāng)然,這里也可以直接調(diào)用AE內(nèi)置的菜單,如ControlsFeatureSelectionMenu。另外,本講也實(shí)現(xiàn)三自定義命令,以做示范。它們分別為圖層可視控制命令(用于控制圖層顯示與否)、移除圖層和放大到整個(gè)圖層命令。實(shí)現(xiàn)方法也很簡(jiǎn)單,就是右擊3sdnMap項(xiàng)目,選擇“添加|類”,選擇C#普通的類模板,用以下代碼覆蓋系統(tǒng)自己生成的所有代碼。
圖層可視控制類LayerVisibility代碼:
?using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.SystemUI;
namespace _sdnMap
{
??? /// <summary>
??? /// 圖層可視控制
??? /// </summary>
?????? public sealed class LayerVisibility : BaseCommand, ICommandSubType
?????? {
????????????? private IHookHelper m_hookHelper = new HookHelperClass();
????????????? private long m_subType;
????????????? public LayerVisibility()
????????????? {
????????????? }
??????
????????????? public override void OnClick()
????????????? {
???????????????????? for (int i=0; i <= m_hookHelper.FocusMap.LayerCount - 1; i++)
???????????????????? {
??????????????????????????? if (m_subType == 1) m_hookHelper.FocusMap.get_Layer(i).Visible = true;
??????????????????????????? if (m_subType == 2) m_hookHelper.FocusMap.get_Layer(i).Visible = false;
???????????????????? }
???????????????????? m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography,null,null);
????????????? }
??????
????????????? public override void OnCreate(object hook)
????????????? {
???????????????????? m_hookHelper.Hook = hook;
????????????? }
??????
????????????? public int GetCount()
? ????????????{
???????????????????? return 2;
????????????? }
??????
????????????? public void SetSubType(int SubType)
????????????? {
???????????????????? m_subType = SubType;
????????????? }
??????
????????????? public override string Caption
????????????? {
???????????????????? get
???????????????????? {
??????????????????????????? if (m_subType == 1) return "Turn All Layers On";
??????????????????????????? else? return "Turn All Layers Off";
???????????????????? }
????????????? }
???? ??
????????????? public override bool Enabled
????????????? {
???????????????????? get
???????????????????? {
??????????????????????????? bool enabled = false; int i;
??????????????????????????? if (m_subType == 1)
??????????????????????????? {
? ?????????????????????????????????for (i=0;i<=m_hookHelper.FocusMap.LayerCount - 1;i++)
?????????????????????????????????? {
????????????????????????????????????????? if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == false)
?????????????????? ???????????????????????{
???????????????????????????????????????????????? enabled = true;
???????????????????????????????????????????????? break;
????????????????????????????????????????? }
?????????????????????????????????? }
??????????????????????? ????}
??????????????????????????? else
??????????????????????????? {
?????????????????????????????????? for (i=0;i<=m_hookHelper.FocusMap.LayerCount - 1;i++)
?????????????????????????????????? {
????????????????????????????????????????? if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == true)
????????????????????????????????????????? {
???????????????????????????????????????????????? enabled = true;
???????????????????????????????????????????????? break;
???????????????????????????????? ?????????}
?????????????????????????????????? }
??????????????????????????? }
??????????????????????????? return enabled;
???????????????????? }
????????????? }
?????? }
}
移除圖層類RemoveLayer代碼:
?????? using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
namespace _sdnMap
{
??? /// <summary>
??? /// 刪除圖層
??? /// </summary>
??? public sealed class RemoveLayer : BaseCommand
??? {
? ??????private IMapControl3 m_mapControl;
??????? public RemoveLayer()
??????? {
??????????? base.m_caption = "Remove Layer";
??????? }
??????? public override void OnClick()
??????? {
??????????? ILayer layer = (ILayer)m_mapControl.CustomProperty;
??????????? m_mapControl.Map.DeleteLayer(layer);
??????? }
??????? public override void OnCreate(object hook)
??????? {
??????????? m_mapControl = (IMapControl3)hook;
??????? }
??? }
}
放大至整個(gè)圖層類ZoomToLayer:
?????? using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
namespace _sdnMap
{
??? /// <summary>
??? /// 放大至整個(gè)圖層
??? /// </summary>
??? public sealed class ZoomToLayer : BaseCommand
??? {
??????? private IMapControl3 m_mapControl;
???? ???public ZoomToLayer()
??????? {
??????????? base.m_caption = "Zoom To Layer";
??????? }
??????? public override void OnClick()
??????? {
??????????? ILayer layer = (ILayer)m_mapControl.CustomProperty;
??????????? m_mapControl.Extent = layer.AreaOfInterest;
??????? }
??????? public override void OnCreate(object hook)
??????? {
??????????? m_mapControl = (IMapControl3)hook;
??????? }
??? }
}
以上三個(gè)工具或命令的實(shí)現(xiàn)代碼比較簡(jiǎn)單,在此不過(guò)多的分析,請(qǐng)讀者自行理解。
下面在Form1_Load函數(shù)中進(jìn)行菜單項(xiàng)的添加,代碼如下:
?????? //添加自定義菜單項(xiàng)到TOCCOntrol的Map菜單中
//打開(kāi)文檔菜單
?m_menuMap.AddItem(new OpenNewMapDocument(m_controlsSynchronizer), -1, 0, false, esriCommandStyles.esriCommandStyleIconAndText);
//添加數(shù)據(jù)菜單
?m_menuMap.AddItem(new ControlsAddDataCommandClass(), -1, 1, false, esriCommandStyles.esriCommandStyleIconAndText);
?//打開(kāi)全部圖層菜單
?m_menuMap.AddItem(new LayerVisibility(), 1, 2, false, esriCommandStyles.esriCommandStyleTextOnly);
//關(guān)閉全部圖層菜單
?m_menuMap.AddItem(new LayerVisibility(), 2, 3, false, esriCommandStyles.esriCommandStyleTextOnly);
?//以二級(jí)菜單的形式添加內(nèi)置的“選擇”菜單
?m_menuMap.AddSubMenu("esriControls.ControlsFeatureSelectionMenu", 4, true);
//以二級(jí)菜單的形式添加內(nèi)置的“地圖瀏覽”菜單
?m_menuMap.AddSubMenu("esriControls.ControlsMapViewMenu",5, true);
//添加自定義菜單項(xiàng)到TOCCOntrol的圖層菜單中
?m_menuLayer = new ToolbarMenuClass();
//添加“移除圖層”菜單項(xiàng)
?m_menuLayer.AddItem(new RemoveLayer(), -1, 0, false, esriCommandStyles.esriCommandStyleTextOnly);
//添加“放大到整個(gè)圖層”菜單項(xiàng)
?m_menuLayer.AddItem(new ZoomToLayer(), -1, 1, true, esriCommandStyles.esriCommandStyleTextOnly);
?//設(shè)置菜單的Hook
?m_menuLayer.SetHook(m_mapControl);
?m_menuMap.SetHook(m_mapControl);
3、
彈出右鍵菜單
顧名思義,右鍵菜單是在鼠標(biāo)右鍵按下的時(shí)候彈出,所以我們要添加TOCControl1控件的OnMouseDown事件,實(shí)現(xiàn)代碼如下:
?????? private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
? ?????//如果不是右鍵按下直接返回
?????? if (e.button != 2) return;
?????? esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
?????? IBasicMap map = null;
?????? ILayer layer = null;
?????? object other = null;
?????? object index = null;
?????? //判斷所選菜單的類型
?????? m_tocControl.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index);
?????? //確定選定的菜單類型,Map或是圖層菜單
?????? if (item == esriTOCControlItem.esriTOCControlItemMap)
????????????? m_tocControl.SelectItem(map, null);
?????? else
????????????? m_tocControl.SelectItem(layer, null);
?????? //設(shè)置CustomProperty為layer (用于自定義的Layer命令)??????????????????
?????? m_mapControl.CustomProperty = layer;
?????? //彈出右鍵菜單
?????? if (item == esriTOCControlItem.esriTOCControlItemMap)
????????????? m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd);
?????? if (item == esriTOCControlItem.esriTOCControlItemLayer)
????????????? m_menuLayer.PopupMenu(e.x, e.y, m_tocControl.hWnd);
}
同樣的方法,我們也可以實(shí)現(xiàn)主地圖控件的右鍵菜單,以方便地圖瀏覽。添加MapControl1控件的OnMouseDown事件,實(shí)現(xiàn)代碼如下:
?????? /// <summary>
/// 主地圖控件的右鍵響應(yīng)函數(shù)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
??? if (e.button == 2)
??? {
??????? //彈出右鍵菜單
??????? m_menuMap.PopupMenu(e.x,e.y,m_mapControl.hWnd);
??? }
}
4、編譯運(yùn)行
按F5編譯運(yùn)行程序,你會(huì)發(fā)現(xiàn),原來(lái)右鍵菜單實(shí)現(xiàn)起來(lái)是這么的簡(jiǎn)單啊!
到第六講為止已經(jīng)發(fā)現(xiàn)的教程Bug及解決方法如下:
1、在第二講可能會(huì)出現(xiàn)變量未定義。
原因:第二講與第三講聯(lián)系緊密,我為控制篇幅才將其分為兩講,某些變量是在第三講才進(jìn)行定義,請(qǐng)大家注意。
2、第六講彈不出TOCControl的右鍵菜單
原因:沒(méi)有取得m_tocControl的指針,即沒(méi)有把m_tocControl指針與axTOCControl1控件綁定,導(dǎo)致調(diào)用m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd);時(shí)m_tocControl.hWnd為NULL,故無(wú)法彈出菜單。
解決方法:在Form1_Load()函數(shù)中,添加如下代碼:
m_tocControl = (ITOCControl2)this.axTOCControl1.Object;
目前已經(jīng)發(fā)現(xiàn)的優(yōu)化方案如下:
1、教程第四講,坐標(biāo)單位前面的esri,原用switch語(yǔ)句逐一替換,其實(shí)直接用取子串(Substring)的方法截去更方便。
修改代碼如下:
?CoordinateLabel.Text = " 當(dāng)前坐標(biāo) X = " + e.mapX.ToString() + " Y = " + e.mapY.ToString() + " " + this.axMapControl1.MapUnits.ToString().Substring(4);
2、教程第四講,固定狀態(tài)欄中的比例尺和當(dāng)前坐標(biāo)項(xiàng)目的寬度以防止閃爍。
方法如下:
選中狀態(tài)欄中的比例尺或當(dāng)前坐標(biāo)項(xiàng)目,把其autoSize屬性設(shè)為False,再在Size屬性里設(shè)置寬度。經(jīng)測(cè)試,比例尺寬度為150,當(dāng)前坐標(biāo)寬度為400比較合適。
這一講,我們要實(shí)現(xiàn)的是圖層符號(hào)選擇器,與ArcMap中的Symbol Selector的類似。本講較前幾講而言,些許有些復(fù)雜,不過(guò)只要仔細(xì)琢磨,認(rèn)真操作,你就很容易實(shí)現(xiàn)如下所示的符號(hào)選擇器。因?yàn)楸局v篇幅較長(zhǎng),故我將其分成兩個(gè)階段,本文是第一階段。
圖1
在AE開(kāi)發(fā)中,符號(hào)選擇器有兩種實(shí)現(xiàn)方式。
一是在程序中直接調(diào)用ArcMap中的符號(hào)選擇器,如下所示:
圖2
二是自定義符號(hào)選擇器,如圖1所示。
由于第一種方式前提是必須安裝ArcGIS Desktop,其界面還是英文的,而對(duì)二次開(kāi)發(fā)來(lái)說(shuō),大部分用戶希望應(yīng)該是中文界面。因此開(kāi)發(fā)人員通常選擇第二種方式,本講也著重講解第二種方式。
通過(guò)對(duì)《ArcGIS Engine+C#實(shí)例開(kāi)發(fā)教程》前六講的學(xué)習(xí),我已經(jīng)假定你已經(jīng)基本熟悉C#語(yǔ)言和VS2005的操作,故在下面的教程中,我不準(zhǔn)備說(shuō)明每一步驟的具體操作方法,而只是說(shuō)明操作步驟,以節(jié)省時(shí)間和篇幅。
1.??????? 直接調(diào)用ArcMap中的符號(hào)選擇器
(1)添加ESRI.ArcGIS.DisplayUI的引用。
分別在解決方案管理器和代碼中添加引用。
(2)添加TOCControl的Double_Click事件。
(3)實(shí)現(xiàn)TOCControl的Double_Click事件。
因?yàn)榉N方法不是本講的重點(diǎn),故不對(duì)代碼進(jìn)行分析,有興趣的讀者請(qǐng)自行理解或結(jié)合后面的內(nèi)容理解。代碼如下:
?private void axTOCControl1_OnDoubleClick(object sender, ITOCControlEvents_OnDoubleClickEvent e)
{
??? esriTOCControlItem toccItem = esriTOCControlItem.esriTOCControlItemNone;
??? ILayer iLayer = null;
??? IBasicMap iBasicMap = null;
??? object unk = null;
??? object data = null;
??? if (e.button == 1)
??? {
??????? axTOCControl1.HitTest(e.x, e.y, ref toccItem, ref iBasicMap, ref iLayer, ref unk,
??????????? ref data);
??????? System.Drawing.Point pos = new System.Drawing.Point(e.x, e.y);
??????? if (toccItem == esriTOCControlItem.esriTOCControlItemLegendClass)
??????? {
??????????? ESRI.ArcGIS.Carto.ILegendClass pLC = new LegendClassClass();
??????????? ESRI.ArcGIS.Carto.ILegendGroup pLG = new LegendGroupClass();
??????????? if (unk is ILegendGroup)
??????????? {
??????????????? pLG = (ILegendGroup)unk;
??????????? }
??????????? pLC = pLG.get_Class((int)data);
??????????? ISymbol pSym;
??????????? pSym = pLC.Symbol;
??????????? ESRI.ArcGIS.DisplayUI.ISymbolSelector pSS = new
??????????????? ESRI.ArcGIS.DisplayUI.SymbolSelectorClass();
? ??????????bool bOK = false;
??????????? pSS.AddSymbol(pSym);
??????????? bOK = pSS.SelectSymbol(0);
??????????? if (bOK)
??????????? {
??????????????? pLC.Symbol = pSS.GetSymbolAt(0);
??????????? }
??????????? this.axMapControl1.ActiveView.Refresh();
??????????? this.axTOCControl1.Refresh();
??????? }
??? }
}
(4)編譯運(yùn)行即可。
?2.??????? 自定義符號(hào)選擇器
AE9.2提供了SymbologyControl控件,極大的方便了圖層符號(hào)選擇器的制作。本講實(shí)現(xiàn)的符號(hào)選擇器有如下功能。
用戶雙擊TOCControl控件中圖層的符號(hào)時(shí),彈出選擇符號(hào)對(duì)話框,對(duì)話框能夠根據(jù)圖層類型自動(dòng)加載相應(yīng)的符號(hào),如點(diǎn)、線、面。用戶可以調(diào)整符號(hào)的顏色、線寬、角度等參數(shù)。還可以打開(kāi)自定義的符號(hào)文件(*.ServerStyle),加載更多的符號(hào)。
2.1???? 新建符號(hào)選擇器窗體
新建Winodws窗體,命名為SymbolSelectorFrm,修改窗體的Text屬性為“選擇符號(hào)”。并添加SymboloryControl、PictureBox、Button、Label、NumericUpDown、GroupBox、ColorDialog、OpenFileDialog、ContextMenuStrip控件。控件布局如下所示:
圖3
2.2???? 設(shè)置控件屬性
設(shè)置相應(yīng)控件的相關(guān)屬性,如下表所示(空則不用修改):
控件
?Name屬性
?Text屬性
?其它
SymbologyControl
?axSymbologyControl
PictureBox
?ptbPreview
Label
?lblColor
?顏色
Label
?lblSize
?大小
Label
?lblWidth
?線寬
Label
?lblAngle
?角度
Label
?lblOutlineColor
?外框顏色
NumericUpDown
?nudSize
NumericUpDown
?nudWidth
NumericUpDown
?nudAngle
Button
?btnColor
?(設(shè)置為空)
Button
?btnOutlineColor
?(設(shè)置為空)
Button
?btnMoreSymbols
?更多符號(hào)
Button
?btnOK
?確定
?DialogResult屬性設(shè)為OK
Button
?btnCancel
?取消
GroupBox
?groupBox1
?預(yù)覽
GroupBox
?groupBox2
?設(shè)置
ColorDialog
?colorDialog
OpenFileDialog
?openFileDialog
?Filter屬性設(shè)置為:
Styles 文件|*.ServerStyle
ContextMenuStrip
?contextMenuStripMoreSymbol
2.3???? 添加引用
在解決方案資源管理器中添加ArcGIS Engine的ESRI.ArcGIS.Geodatabase引用,在SymbolSelectorFrm.cs文件中添加如下引用代碼:
?? using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geodatabase;
2.4?? 初始化
(1)?????? 添加SymbolSelectorFrm的全局變量,代碼如下:
private IStyleGalleryItem pStyleGalleryItem;
private ILegendClass pLegendClass;
private ILayer pLayer;
public ISymbol pSymbol;
public Image pSymbolImage;
(2)?????? 修改SymbolSelectorFrm的構(gòu)造函數(shù),傳入圖層和圖例接口。代碼如下:
?? /// <summary>
/// 構(gòu)造函數(shù),初始化全局變量
/// </summary>
/// <param name="tempLegendClass">TOC圖例</param>
/// <param name="tempLayer">圖層</param>
public SymbolSelectorFrm(ILegendClass tempLegendClass, ILayer tempLayer)
{
??? InitializeComponent();
??? this.pLegendClass = tempLegendClass;
??? this.pLayer = tempLayer;
}
(3)?????? 添加SymbolControl的SymbologyStyleClass設(shè)置函數(shù)SetFeatureClassStyle(),代碼如下:
/// <summary>
/// 初始化SymbologyControl的StyleClass,圖層如果已有符號(hào),則把符號(hào)添加到SymbologyControl中的第一個(gè)符號(hào),并選中
/// </summary>
/// <param name="symbologyStyleClass"></param>
private void SetFeatureClassStyle(esriSymbologyStyleClass symbologyStyleClass)
{
??? this.axSymbologyControl.StyleClass = symbologyStyleClass;
??? ISymbologyStyleClass pSymbologyStyleClass = this.axSymbologyControl.GetStyleClass(symbologyStyleClass);
??? if (this.pLegendClass != null)
??? {
??????? IStyleGalleryItem currentStyleGalleryItem = new ServerStyleGalleryItem();
??????? currentStyleGalleryItem.Name = "當(dāng)前符號(hào)";
??????? currentStyleGalleryItem.Item = pLegendClass.Symbol;
??????? pSymbologyStyleClass.AddItem(currentStyleGalleryItem,0);
??????? this.pStyleGalleryItem = currentStyleGalleryItem;
??? }
??? pSymbologyStyleClass.SelectItem(0);
}
(4)?????? 添加注冊(cè)表讀取函數(shù)ReadRegistry(),此函數(shù)從注冊(cè)表中讀取ArcGIS的安裝路徑,代碼如下:
??? /// <summary>
/// 從注冊(cè)表中取得指定軟件的路徑
/// </summary>
/// <param name="sKey"></param>
/// <returns></returns>
private string ReadRegistry(string sKey)
{
??? //Open the subkey for reading
??? Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey, true);
??? if (rk == null) return "";
??? // Get the data from a specified item in the key.
??? return (string)rk.GetValue("InstallDir");
}
(5)? ?????添加SymbolSelectorFrm的Load事件。根據(jù)圖層類型為SymbologyControl導(dǎo)入相應(yīng)的符號(hào)樣式文件,如點(diǎn)、線、面,并設(shè)置控件的可視性。代碼如下:
private void SymbolSelectorFrm_Load(object sender, EventArgs e)
{
//取得ArcGIS安裝路徑
string sInstall = ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
//載入ESRI.ServerStyle文件到SymbologyControl
this.axSymbologyControl.LoadStyleFile(sInstall + "\\Styles\\ESRI.ServerStyle");
//確定圖層的類型(點(diǎn)線面),設(shè)置好SymbologyControl的StyleClass,設(shè)置好各控件的可見(jiàn)性(visible)
IGeoFeatureLayer pGeoFeatureLayer = (IGeoFeatureLayer)pLayer;
switch (((IFeatureLayer)pLayer).FeatureClass.ShapeType)
{
??? case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassMarkerSymbols);
??????? this.lblAngle.Visible = true;
??????? this.nudAngle.Visible = true;
??????? this.lblSize.Visible = true;
??????? this.nudSize.Visible = true;
??????? this.lblWidth.Visible = false;
??????? this.nudWidth.Visible = false;
??????? this.lblOutlineColor.Visible = false;
??????? this.btnOutlineColor.Visible = false;
??????? break;
??? case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
??????? this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassLineSymbols);
??????? this.lblAngle.Visible = false;
??????? this.nudAngle.Visible = false;
??????? this.lblSize.Visible = false;
??????? this.nudSize.Visible = false;
??????? this.lblWidth.Visible = true;
??????? this.nudWidth.Visible = true;
??????? this.lblOutlineColor.Visible = false;
??????? this.btnOutlineColor.Visible = false;
? ??????break;
??? case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
??????? this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);
??????? this.lblAngle.Visible = false;
??????? this.nudAngle.Visible = false;
????? ??this.lblSize.Visible = false;
??????? this.nudSize.Visible = false;
??????? this.lblWidth.Visible = true;
??????? this.nudWidth.Visible = true;
??????? this.lblOutlineColor.Visible = true;
??????? this.btnOutlineColor.Visible = true;
??????? break;
??? case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultiPatch:
??????? this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);
??????? this.lblAngle.Visible = false;
??????? this.nudAngle.Visible = false;
??????? this.lblSize.Visible = false;
??????? this.nudSize.Visible = false;
??????? this.lblWidth.Visible = true;
??????? this.nudWidth.Visible = true;
??????? this.lblOutlineColor.Visible = true;
??????? this.btnOutlineColor.Visible = true;
??????? break;
??? default:
??????? this.Close();
???? break;
}
}
(6)?????? 雙擊確定按鈕和取消按鈕,分別添加如下代碼:
??? /// <summary>
/// 確定按鈕
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOK_Click(object sender, EventArgs e)
{
??? //取得選定的符號(hào)
??? this.pSymbol = (ISymbol)pStyleGalleryItem.Item;
??? //更新預(yù)覽圖像
??? this.pSymbolImage = this.ptbPreview.Image;
??? //關(guān)閉窗體
??? this.Close();
}
/// <summary>
/// 取消按鈕
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCancel_Click(object sender, EventArgs e)
{
??? this.Close();
}
(7)?????? 為了操作上的方便,我們添加SymbologyControl的DoubleClick事件,當(dāng)雙擊符號(hào)時(shí)同按下確定按鈕一樣,選定符號(hào)并關(guān)閉符號(hào)選擇器窗體。代碼如下:
??? /// <summary>
/// 雙擊符號(hào)同單擊確定按鈕,關(guān)閉符號(hào)選擇器。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axSymbologyControl_OnDoubleClick(object sender, ESRI.ArcGIS.Controls.ISymbologyControlEvents_OnDoubleClickEvent e)
{
??? this.btnOK.PerformClick();
}
(8)?????? 再添加符號(hào)預(yù)覽函數(shù),當(dāng)用戶選定某一符號(hào)時(shí),符號(hào)可以顯示在PictureBox控件中,方便預(yù)覽,函數(shù)代碼如下:
/// <summary>
/// 把選中并設(shè)置好的符號(hào)在picturebox控件中預(yù)覽
/// </summary>
private void PreviewImage()
{
??? stdole.IPictureDisp picture = this.axSymbologyControl.GetStyleClass(this.axSymbologyControl.StyleClass).PreviewItem(pStyleGalleryItem, this.ptbPreview.Width, this.ptbPreview.Height);
??? System.Drawing.Image image = System.Drawing.Image.FromHbitmap(new System.IntPtr(picture.Handle));
??? this.ptbPreview.Image = image;
}
(9)?????? 當(dāng)SymbologyControl的樣式改變時(shí),需要重新設(shè)置符號(hào)參數(shù)調(diào)整控件的可視性,故要添加SymbologyControl的OnStyleClassChanged事件,事件代碼與Load事件類似,如下:
??? /// <summary>
/// 當(dāng)樣式(Style)改變時(shí),重新設(shè)置符號(hào)類型和控件的可視性
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axSymbologyControl_OnStyleClassChanged(object sender, ESRI.ArcGIS.Controls.ISymbologyControlEvents_OnStyleClassChangedEvent e)
{
??? switch ((esriSymbologyStyleClass)(e.symbologyStyleClass))
??? {
??????? case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
??????????? this.lblAngle.Visible = true;
??????????? this.nudAngle.Visible = true;
??????????? this.lblSize.Visible = true;
??????????? this.nudSize.Visible = true;
??????????? this.lblWidth.Visible = false;
??????????? this.nudWidth.Visible = false;
??????????? this.lblOutlineColor.Visible = false;
??????????? this.btnOutlineColor.Visible = false;
??????????? break;
??????? case esriSymbologyStyleClass.esriStyleClassLineSymbols:
??????????? this.lblAngle.Visible = false;
??????????? this.nudAngle.Visible = false;
??????????? this.lblSize.Visible = false;
??????????? this.nudSize.Visible = false;
??????????? this.lblWidth.Visible = true;
??????????? this.nudWidth.Visible = true;
??????????? this.lblOutlineColor.Visible = false;
??????????? this.btnOutlineColor.Visible = false;
??????????? break;
??????? case esriSymbologyStyleClass.esriStyleClassFillSymbols:
??????????? this.lblAngle.Visible = false;
??????????? this.nudAngle.Visible = false;
??????????? this.lblSize.Visible = false;
??????????? this.nudSize.Visible = false;
??????????? this.lblWidth.Visible = true;
??????????? this.nudWidth.Visible = true;
??????????? this.lblOutlineColor.Visible = true;
??????????? this.btnOutlineColor.Visible = true;
??????????? break;
??? }
}
2.5???? 調(diào)用自定義符號(hào)選擇器
通過(guò)以上操作,本符號(hào)選擇器雛形已經(jīng)完成,我們可以3sdnMap主窗體中調(diào)用并進(jìn)行測(cè)試。如果您已經(jīng)完成“直接調(diào)用ArcMap中的符號(hào)選擇器”這一節(jié),請(qǐng)注釋axTOCControl1_OnDoubleClick事件響應(yīng)函數(shù)里的代碼,并添加如下代碼。如果您是直接學(xué)習(xí)自定義符號(hào)選擇器這一節(jié)的,請(qǐng)先添加axTOCControl1控件的OnDoubleClick事件,再添加如下事件響應(yīng)函數(shù)代碼:
?? /// <summary>
/// 雙擊TOCControl控件時(shí)觸發(fā)的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axTOCControl1_OnDoubleClick(object sender, ITOCControlEvents_OnDoubleClickEvent e)
{
??? esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone;
??? IBasicMap basicMap = null;
??? ILayer layer = null;
??? object unk = null;
??? object data = null;
??? axTOCControl1.HitTest(e.x, e.y, ref itemType, ref basicMap, ref layer, ref unk, ref data);
??? if (e.button == 1)
??? {
??????? if(itemType==esriTOCControlItem.esriTOCControlItemLegendClass)
??????? {????????????
??????????????? //取得圖例
??????????????? ILegendClass pLegendClass = ((ILegendGroup)unk).get_Class((int)data);
??????????????? //創(chuàng)建符號(hào)選擇器SymbolSelector實(shí)例
??????????????? SymbolSelectorFrm SymbolSelectorFrm = new SymbolSelectorFrm(pLegendClass, layer);
??????????????? if (SymbolSelectorFrm.ShowDialog() == DialogResult.OK)
??????????????? {
??????????????????? //局部更新主Map控件
??????????????????? m_mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
??????????????????? //設(shè)置新的符號(hào)
??????????????????? pLegendClass.Symbol = SymbolSelectorFrm.pSymbol;
??????????????????? //更新主Map控件和圖層控件
??????????????????? this.axMapControl1.ActiveView.Refresh();
?????????? ?????????this.axTOCControl1.Refresh();
??????????????? }
??????? }
}
?????? 按F5編譯運(yùn)行,相信你已經(jīng)看到自己新手打造的符號(hào)選擇器已經(jīng)出現(xiàn)在眼前了。當(dāng)然,它還比較簡(jiǎn)陋,下面我們將一起把它做得更完美些。
2.6???? 符號(hào)參數(shù)調(diào)整
在地圖整飾中,符號(hào)參數(shù)的調(diào)整是必須的功能。下面我們將實(shí)現(xiàn)符號(hào)顏色、外框顏色、線寬、角度等參數(shù)的調(diào)整。
(1)?????? 添加SymbologyControl的OnItemSelected事件,此事件在鼠標(biāo)選中符號(hào)時(shí)觸發(fā),此時(shí)顯示出選定符號(hào)的初始參數(shù),事件響應(yīng)函數(shù)代碼如下:
/// <summary>
/// 選中符號(hào)時(shí)觸發(fā)的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axSymbologyControl_OnItemSelected(object sender, ESRI.ArcGIS.Controls.ISymbologyControlEvents_OnItemSelectedEvent e)
{
??? pStyleGalleryItem = (IStyleGalleryItem)e.styleGalleryItem;
??? Color color;
??? switch (this.axSymbologyControl.StyleClass)
??? {
??????????? //點(diǎn)符號(hào)
??????? case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
??????????? color = this.ConvertIRgbColorToColor(((IMarkerSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
??????????? //設(shè)置點(diǎn)符號(hào)角度和大小初始值
??????????? this.nudAngle.Value = (decimal)((IMarkerSymbol)this.pStyleGalleryItem.Item).Angle;
???????? ???this.nudSize.Value = (decimal)((IMarkerSymbol)this.pStyleGalleryItem.Item).Size;
??????????? break;
??????????? //線符號(hào)
??????? case esriSymbologyStyleClass.esriStyleClassLineSymbols:
??????????? color = this.ConvertIRgbColorToColor(((ILineSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
??????????? //設(shè)置線寬初始值
??????????? this.nudWidth.Value = (decimal)((ILineSymbol)this.pStyleGalleryItem.Item).Width;
??????????? break;
??????????? //面符號(hào)
??????? case esriSymbologyStyleClass.esriStyleClassFillSymbols:
??????????? color = this.ConvertIRgbColorToColor(((IFillSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
??????????? this.btnOutlineColor.BackColor = this.ConvertIRgbColorToColor(((IFillSymbol)pStyleGalleryItem.Item).Outline.Color as IRgbColor);
??????????? //設(shè)置外框線寬度初始值
??????????? this.nudWidth.Value = (decimal)((IFillSymbol)this.pStyleGalleryItem.Item).Outline.Width;
??????????? break;
??????? default:
??????????? color = Color.Black;
??????????? break;
??? }
??? //設(shè)置按鈕背景色
??? this.btnColor.BackColor = color;
??? //預(yù)覽符號(hào)
??? this.PreviewImage();
}
?
(2)?????? 調(diào)整點(diǎn)符號(hào)的大小
添加nudSize控件的ValueChanged事件,即在控件的值改變時(shí)響應(yīng)此事件,然后重新設(shè)置點(diǎn)符號(hào)的大小。代碼如下:
??? /// <summary>
/// 調(diào)整符號(hào)大小-點(diǎn)符號(hào)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void nudSize_ValueChanged(object sender, EventArgs e)
{
??? ((IMarkerSymbol)this.pStyleGalleryItem.Item).Size = (double)this.nudSize.Value;
??? this.PreviewImage();
}
(3)?????? 調(diào)整點(diǎn)符號(hào)的角度
添加nudAngle控件的ValueChanged事件,以重新設(shè)置點(diǎn)符號(hào)的角度。代碼如下:
??? /// <summary>
/// 調(diào)整符號(hào)角度-點(diǎn)符號(hào)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void nudAngle_ValueChanged(object sender, EventArgs e)
{
??? ((IMarkerSymbol)this.pStyleGalleryItem.Item).Angle = (double)this.nudAngle.Value;
??? this.PreviewImage();
}
(4)?????? 調(diào)整線符號(hào)和面符號(hào)的線寬
添加nudWidth控件的ValueChanged事件,以重新設(shè)置線符號(hào)的線寬和面符號(hào)的外框線的線寬。代碼如下:
?
/// <summary>
/// 調(diào)整符號(hào)寬度-限于線符號(hào)和面符號(hào)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void nudWidth_ValueChanged(object sender, EventArgs e)
{
??? switch (this.axSymbologyControl.StyleClass)
??? {
??????? case esriSymbologyStyleClass.esriStyleClassLineSymbols:
??????????? ((ILineSymbol)this.pStyleGalleryItem.Item).Width = Convert.ToDouble(this.nudWidth.Value);
??????????? break;
??????? case esriSymbologyStyleClass.esriStyleClassFillSymbols:
??????????? //取得面符號(hào)的輪廓線符號(hào)
??????????? ILineSymbol pLineSymbol = ((IFillSymbol)this.pStyleGalleryItem.Item).Outline;
??????????? pLineSymbol.Width = Convert.ToDouble(this.nudWidth.Value);
??????????? ((IFillSymbol)this.pStyleGalleryItem.Item).Outline = pLineSymbol;
??????????? break;
??? }
??? this.PreviewImage();
}
(5)?????? 顏色轉(zhuǎn)換
在ArcGIS Engine中,顏色由IRgbColor接口實(shí)現(xiàn),而在.NET框架中,顏色則由Color結(jié)構(gòu)表示。故在調(diào)整顏色參數(shù)之前,我們必須完成以上兩種不同顏色表示方式的轉(zhuǎn)換。關(guān)于這兩種顏色結(jié)構(gòu)的具體信息,請(qǐng)大家自行查閱相關(guān)資料。下面添加兩個(gè)顏色轉(zhuǎn)換函數(shù)。
ArcGIS Engine中的IRgbColor接口轉(zhuǎn)換至.NET中的Color結(jié)構(gòu)的函數(shù):
??? /// <summary>
/// 將ArcGIS Engine中的IRgbColor接口轉(zhuǎn)換至.NET中的Color結(jié)構(gòu)
/// </summary>
/// <param name="pRgbColor">IRgbColor</param>
/// <returns>.NET中的System.Drawing.Color結(jié)構(gòu)表示ARGB顏色</returns>
public Color ConvertIRgbColorToColor(IRgbColor pRgbColor)
{
??? return ColorTranslator.FromOle(pRgbColor.RGB);
}
.NET中的Color結(jié)構(gòu)轉(zhuǎn)換至于ArcGIS Engine中的IColor接口的函數(shù):
??? /// <summary>
/// 將.NET中的Color結(jié)構(gòu)轉(zhuǎn)換至于ArcGIS Engine中的IColor接口
/// </summary>
/// <param name="color">.NET中的System.Drawing.Color結(jié)構(gòu)表示ARGB顏色</param>
/// <returns>IColor</returns>
public IColor ConvertColorToIColor(Color color)
{
??? IColor pColor = new RgbColorClass();
??? pColor.RGB = color.B * 65536 + color.G * 256 + color.R;
??? return pColor;
}
(6)?????? 調(diào)整所有符號(hào)的顏色
選擇顏色時(shí),我們調(diào)用.NET的顏色對(duì)話框ColorDialog,選定顏色后,修改顏色按鈕的背景色為選定的顏色,以方便預(yù)覽。雙擊btnColor按鈕,添加如下代碼:
/// <summary>
/// 顏色按鈕
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnColor_Click(object sender, EventArgs e)
{
??? //調(diào)用系統(tǒng)顏色對(duì)話框
??? if (this.colorDialog.ShowDialog() == DialogResult.OK)
??? {
??????? //將顏色按鈕的背景顏色設(shè)置為用戶選定的顏色
??????? this.btnColor.BackColor = this.colorDialog.Color;
??????? //設(shè)置符號(hào)顏色為用戶選定的顏色
??????? switch (this.axSymbologyControl.StyleClass)
??????? {
??????????? //點(diǎn)符號(hào)
??????????? case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
??????????????? ((IMarkerSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
??????????????? break;
??????????? //線符號(hào)
??????????? case esriSymbologyStyleClass.esriStyleClassLineSymbols:
??????????????? ((ILineSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
??????????????? break;
??????????? //面符號(hào)
??????????? case esriSymbologyStyleClass.esriStyleClassFillSymbols:
??????????????? ((IFillSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
??????????????? break;
??????? }
??????? //更新符號(hào)預(yù)覽
??????? this.PreviewImage();
??? }
}
(7)?????? 調(diào)整面符號(hào)的外框線顏色
同上一步類似,雙擊btnOutlineColor按鈕,添加如下代碼:
?
/// <summary>
/// 外框顏色按鈕
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOutlineColor_Click(object sender, EventArgs e)
{
??? if (this.colorDialog.ShowDialog() == DialogResult.OK)
??? {
??????? //取得面符號(hào)中的外框線符號(hào)
??????? ILineSymbol pLineSymbol = ((IFillSymbol)this.pStyleGalleryItem.Item).Outline;
??????? //設(shè)置外框線顏色
??????? pLineSymbol.Color = this.ConvertColorToIColor(this.colorDialog.Color);
??????? //重新設(shè)置面符號(hào)中的外框線符號(hào)
??????? ((IFillSymbol)this.pStyleGalleryItem.Item).Outline = pLineSymbol;
??????? //設(shè)置按鈕背景顏色
??????? this.btnOutlineColor.BackColor = this.colorDialog.Color;
??????? //更新符號(hào)預(yù)覽
??????? this.PreviewImage();
??? }
}
?????? 至此,你可以編譯運(yùn)行程序,看看效果如何,是不是感覺(jué)很不錯(cuò)了?我們已經(jīng)能夠修改符號(hào)的參數(shù),自定義符號(hào)了。
?????? 但是,SymbologyControl默認(rèn)加載的是ESRI.ServerStyle文件的樣式,用過(guò)ArcMap的你可能已經(jīng)注意到,ArcMap中的Symbol Selector有一個(gè)“More Symbols”按鈕,可以加載其它的符號(hào)和ServerStyle文件。3sdnMap當(dāng)然“一個(gè)都不能少”。
2.7???? 添加更多符號(hào)菜單
還記得我們?cè)陂_(kāi)始的時(shí)候添加了ContextMenuStrip控件嗎?現(xiàn)在它終于派上用場(chǎng)了。我們要實(shí)現(xiàn)的功能是:單擊“更多符號(hào)”彈出菜單(ContextMenu),菜單中列出了ArcGIS自帶的其它符號(hào),勾選相應(yīng)的菜單項(xiàng)就可以在SymbologyControl中增加相應(yīng)的符號(hào)。在菜單的最后一項(xiàng)是“添加符號(hào)”,選擇這一項(xiàng)時(shí),將彈出打開(kāi)文件對(duì)話框,我們可以由此選擇其它的ServerStyle文件,以加載更多的符號(hào)。
(1)?????? 定義全局變量
在SymbolSelectorFrm中定義如下全局變量,用于判斷菜單是否已經(jīng)初始化。
?//菜單是否已經(jīng)初始化標(biāo)志
bool contextMenuMoreSymbolInitiated = false;
(2)?????? 雙擊“更多符號(hào)”按鈕,添加Click事件。
在此事件響應(yīng)函數(shù)中,我們要完成ServerStyle文件的讀取,將其文件名作為菜單項(xiàng)名稱生成菜單并顯示菜單。代碼如下:
?
/// <summary>
/// “更多符號(hào)”按下時(shí)觸發(fā)的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnMoreSymbols_Click(object sender, EventArgs e)
{
??? if (this.contextMenuMoreSymbolInitiated == false)
??? {
?????? ?string sInstall = ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
??????? string path = System.IO.Path.Combine(sInstall, "Styles");
??????? //取得菜單項(xiàng)數(shù)量
??????? string[] styleNames = System.IO.Directory.GetFiles(path, "*.ServerStyle");
??????? ToolStripMenuItem[] symbolContextMenuItem = new ToolStripMenuItem[styleNames.Length + 1];
??????? //循環(huán)添加其它符號(hào)菜單項(xiàng)到菜單
??????? for (int i = 0; i < styleNames.Length; i++)
??????? {
??????????? symbolContextMenuItem[i] = new ToolStripMenuItem();
??????????? symbolContextMenuItem[i].CheckOnClick = true;
??????????? symbolContextMenuItem[i].Text = System.IO.Path.GetFileNameWithoutExtension(styleNames[i]);
??????????? if (symbolContextMenuItem[i].Text == "ESRI")
??????????? {
??????????????? symbolContextMenuItem[i].Checked = true;
??????????? }
??????????? symbolContextMenuItem[i].Name = styleNames[i];
??????? }
??????? //添加“更多符號(hào)”菜單項(xiàng)到菜單最后一項(xiàng)
??????? symbolContextMenuItem[styleNames.Length] = new ToolStripMenuItem();
??????? symbolContextMenuItem[styleNames.Length].Text = "添加符號(hào)";
??????? symbolContextMenuItem[styleNames.Length].Name = "AddMoreSymbol";
??????? //添加所有的菜單項(xiàng)到菜單
??????? this.contextMenuStripMoreSymbol.Items.AddRange(symbolContextMenuItem);
??????? this.contextMenuMoreSymbolInitiated = true;
??? }
??? //顯示菜單
??? this.contextMenuStripMoreSymbol.Show(this.btnMoreSymbols.Location);
}
(3)?????? 添加contextMenuStripMoreSymbol控件的ItemClicked事件。
當(dāng)單擊某一菜單項(xiàng)時(shí)響應(yīng)ItemClicked事件,將選中的ServerStyle文件導(dǎo)入到SymbologyControl中并刷新。當(dāng)用戶單擊“添加符號(hào)”菜單項(xiàng)時(shí),彈出打開(kāi)文件對(duì)話框,供用戶選擇其它的ServerStyle文件。代碼如下:
?
/// <summary>
/// “更多符號(hào)”按鈕彈出的菜單項(xiàng)單擊事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void contextMenuStripMoreSymbol_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
??? ToolStripMenuItem pToolStripMenuItem = (ToolStripMenuItem)e.ClickedItem;
??? //如果單擊的是“添加符號(hào)”
??? if (pToolStripMenuItem.Name == "AddMoreSymbol")
??? {
??????? //彈出打開(kāi)文件對(duì)話框
??????? if (this.openFileDialog.ShowDialog() == DialogResult.OK)
??????? {
?????????? ?//導(dǎo)入style file到SymbologyControl
??????????? this.axSymbologyControl.LoadStyleFile(this.openFileDialog.FileName);
??????????? //刷新axSymbologyControl控件
??????????? this.axSymbologyControl.Refresh();
??????? }
??? }
??? else//如果是其它選項(xiàng)
??? {
??????? if (pToolStripMenuItem.Checked == false)
??????? {
??????????? this.axSymbologyControl.LoadStyleFile(pToolStripMenuItem.Name);
??????????? this.axSymbologyControl.Refresh();
??????? }
??????? else
??????? {
??????????? this.axSymbologyControl.RemoveFile(pToolStripMenuItem.Name);
??????????? this.axSymbologyControl.Refresh();??????????
??????? }
??? }??????????
}???
2.8???? 編譯運(yùn)行
相信你已經(jīng)盼這一步很久了吧,按照慣例,按下F5吧!大功造成。
以上代碼在AE9.2+VS2005+XP中編譯通過(guò)。
在ArcMap中,單擊圖層右鍵菜單中的“Open Attribute Table”命令,便可彈出屬性數(shù)據(jù)表。本講將完成類似的功能,效果如下:
圖1
數(shù)據(jù)表顯示,我們用了DataGridView控件。DataGridView 控件提供一種強(qiáng)大而靈活的以表格形式顯示數(shù)據(jù)的方式。可以使用 DataGridView 控件來(lái)顯示少量數(shù)據(jù)的只讀視圖,也可以對(duì)其進(jìn)行縮放以顯示特大數(shù)據(jù)集的可編輯視圖。我們可以很方便地把一個(gè)DataTable作為數(shù)據(jù)源綁定到DataGridView控件中。
本講的思路大體如下:首先根據(jù)圖層屬性中的字段創(chuàng)建一個(gè)空的DataTable,然后根據(jù)數(shù)據(jù)內(nèi)容一行行填充DataTable數(shù)據(jù),再將DataTable綁定到DataGridView控件,最后調(diào)用并顯示屬性表窗體。
1.創(chuàng)建屬性表窗體
新建一個(gè)Windows窗體,命名為“AttributeTableFrm.cs”。
從工具箱拖一個(gè)DataGridView控件到窗體,并將其Dock屬性設(shè)置為“Fill”。
添加如下引用:
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
2.創(chuàng)建空DataTable
首先傳入ILayer,再查詢到ITable,從ITable中的Fileds中獲得每個(gè)Field,再根據(jù)Filed設(shè)置DataTable的DataColumn,由此創(chuàng)建一個(gè)只含圖層字段的空DataTable。實(shí)現(xiàn)函數(shù)如下:
/// <summary>
/// 根據(jù)圖層字段創(chuàng)建一個(gè)只含字段的空DataTable
/// </summary>
/// <param name="pLayer"></param>
/// <param name="tableName"></param>
/// <returns></returns>
private static DataTable CreateDataTableByLayer(ILayer pLayer, string tableName)
{
//創(chuàng)建一個(gè)DataTable表
DataTable pDataTable = new DataTable(tableName);
//取得ITable接口
ITable pTable = pLayer as ITable;
IField pField = null;
DataColumn pDataColumn;
//根據(jù)每個(gè)字段的屬性建立DataColumn對(duì)象
for (int i = 0; i < pTable.Fields.FieldCount; i++)
{
pField = pTable.Fields.get_Field(i);
//新建一個(gè)DataColumn并設(shè)置其屬性
pDataColumn = new DataColumn(pField.Name);
if (pField.Name == pTable.OIDFieldName)
{
pDataColumn.Unique = true;//字段值是否唯一
}
//字段值是否允許為空
pDataColumn.AllowDBNull = pField.IsNullable;
//字段別名
pDataColumn.Caption = pField.AliasName;
//字段數(shù)據(jù)類型
pDataColumn.DataType = System.Type.GetType(ParseFieldType(pField.Type));
//字段默認(rèn)值
pDataColumn.DefaultValue = pField.DefaultValue;
//當(dāng)字段為String類型是設(shè)置字段長(zhǎng)度
if (pField.VarType == 8)
{
pDataColumn.MaxLength = pField.Length;
}
//字段添加到表中
pDataTable.Columns.Add(pDataColumn);
pField = null;
pDataColumn = null;
}
return pDataTable;
}
因?yàn)镚eoDatabase的數(shù)據(jù)類型與.NET的數(shù)據(jù)類型不同,故要進(jìn)行轉(zhuǎn)換。轉(zhuǎn)換函數(shù)如下:
/// <summary>
/// 將GeoDatabase字段類型轉(zhuǎn)換成.Net相應(yīng)的數(shù)據(jù)類型
/// </summary>
/// <param name="fieldType">字段類型</param>
/// <returns></returns>
public static string ParseFieldType(esriFieldType fieldType)
{
switch (fieldType)
{
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";
}
}
3.裝載DataTable數(shù)據(jù)
從上一步得到的DataTable還沒(méi)有數(shù)據(jù),只有字段信息。因此,我們要通過(guò)ICursor從ITable中逐一取出每一行數(shù)據(jù),即IRow。再創(chuàng)建DataTable中相應(yīng)的DataRow,根據(jù)IRow設(shè)置DataRow信息,再將所有的DataRow添加到DataTable中,就完成了DataTable數(shù)據(jù)的裝載。
為保證效率,一次最多只裝載2000條數(shù)據(jù)到DataGridView。函數(shù)代碼如下:
/// <summary>
/// 填充DataTable中的數(shù)據(jù)
/// </summary>
/// <param name="pLayer"></param>
/// <param name="tableName"></param>
/// <returns></returns>
public static DataTable CreateDataTable(ILayer pLayer, string tableName)
{
//創(chuàng)建空DataTable
DataTable pDataTable = CreateDataTableByLayer(pLayer, tableName);
//取得圖層類型
string shapeType = getShapeType(pLayer);
//創(chuàng)建DataTable的行對(duì)象
DataRow pDataRow = null;
//從ILayer查詢到ITable
ITable pTable = pLayer as ITable;
ICursor pCursor = pTable.Search(null, false);
//取得ITable中的行信息
IRow pRow = pCursor.NextRow();
int n = 0;
while (pRow != null)
{
//新建DataTable的行對(duì)象
pDataRow = pDataTable.NewRow();
for (int i = 0; i < pRow.Fields.FieldCount; i++)
{
//如果字段類型為esriFieldTypeGeometry,則根據(jù)圖層類型設(shè)置字段值
if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeGeometry)
{
pDataRow = shapeType;
}
//當(dāng)圖層類型為Anotation時(shí),要素類中會(huì)有esriFieldTypeBlob類型的數(shù)據(jù),
//其存儲(chǔ)的是標(biāo)注內(nèi)容,如此情況需將對(duì)應(yīng)的字段值設(shè)置為Element
else if (pRow.Fields.get_Field(i).Type == esriFieldType.esriFieldTypeBlob)
{
pDataRow = "Element";
}
else
{
pDataRow = pRow.get_Value(i);
}
}
//添加DataRow到DataTable
pDataTable.Rows.Add(pDataRow);
pDataRow = null;
n++;
//為保證效率,一次只裝載最多條記錄
if (n == 2000)
{
pRow = null;
}
else
{
pRow = pCursor.NextRow();
}
}
return pDataTable;
}
上面的代碼中涉及到一個(gè)獲取圖層類型的函數(shù)getShapeTape,此函數(shù)是通過(guò)ILayer判斷圖層類型的,代碼如下:
/// <summary>
/// 獲得圖層的Shape類型
/// </summary>
/// <param name="pLayer">圖層</param>
/// <returns></returns>
public static string getShapeType(ILayer pLayer)
{
IFeatureLayer pFeatLyr = (IFeatureLayer)pLayer;
switch (pFeatLyr.FeatureClass.ShapeType)
{
case esriGeometryType.esriGeometryPoint:
return "Point";
case esriGeometryType.esriGeometryPolyline:
return "Polyline";
case esriGeometryType.esriGeometryPolygon:
return "Polygon";
default:
return "";
}
}
4.綁定DataTable到DataGridView
通過(guò)以上步驟,我們已經(jīng)得到了一個(gè)含有圖層屬性數(shù)據(jù)的DataTable。現(xiàn)定義一個(gè)AttributeTableFrm類的成員變量:
public DataTable attributeTable;
通過(guò)以下函數(shù),我們很容易將其綁定到DataGridView控件中。
/// <summary>
/// 綁定DataTable到DataGridView
/// </summary>
/// <param name="player"></param>
public void CreateAttributeTable(ILayer player)
{
string tableName;
tableName = getValidFeatureClassName(player .Name );
attributeTable = CreateDataTable(player,tableName );
this.dataGridView1 .DataSource = attributeTable ;
this.Text = "屬性表[" + tableName + "] " + "記錄數(shù):"+attributeTable.Rows.Count .ToString();
}
因?yàn)镈ataTable的表名不允許含有“.”,因此我們用“_”替換。函數(shù)如下:
/// <summary>
/// 替換數(shù)據(jù)表名中的點(diǎn)
/// </summary>
/// <param name="FCname"></param>
/// <returns></returns>
public static string getValidFeatureClassName(string FCname)
{
int dot = FCname.IndexOf(".");
if (dot != -1)
{
return FCname.Replace(".", "_");
}
return FCname;
}
5.調(diào)用屬性表窗體
通過(guò)1-4步驟,我們封裝了一個(gè)AttributeTableFrm類,此類能夠由ILayer顯示圖層中的屬性表數(shù)據(jù)。那怎么調(diào)用AttributeTableFrm呢?
前面已經(jīng)提到,我們是在TOCControl選中圖層的右鍵菜單中彈出屬性表窗體的,因此我們需要添加一個(gè)菜單項(xiàng)到TOCControl中Layer的右鍵菜單。而在第六講中,我們采用的是AE中的IToolbarMenu實(shí)現(xiàn)右鍵菜單的,故我們還需自定義一個(gè)Command,實(shí)現(xiàn)打開(kāi)屬性表的功能。
以ArcGIS的Base Command為模板新建項(xiàng)“OpenAttributeTable.cs”。
注意:新建Base Command模板時(shí),會(huì)彈出一個(gè)對(duì)話框讓我們選擇模板適用對(duì)象,這時(shí)我們要選擇MapControl、PageLayoutControl,即選擇第二項(xiàng)或者倒數(shù)第二項(xiàng)。
添加如下引用:
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
添加成員變量:
private ILayer m_pLayer;
修改構(gòu)造函數(shù)為:
public OpenAttributeTable(ILayer pLayer)
{
//
// TODO: Define values for the public properties
//
base.m_category = ""; //localizable text
base.m_caption = "打開(kāi)屬性表"; //localizable text
base.m_message = "打開(kāi)屬性表"; //localizable text
base.m_toolTip = "打開(kāi)屬性表"; //localizable text
base.m_name = "打開(kāi)屬性表"; //unique id, non-localizable (e.g. "MyCategory_MyCommand")
m_pLayer = pLayer;
try
{
//
// TODO: change bitmap name if necessary
//
string bitmapResourceName = GetType().Name + ".bmp";
base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
}
}
再在On_Click函數(shù)中添加如下代碼,以創(chuàng)建并打開(kāi)屬性表窗體。
/// <summary>
/// Occurs when this command is clicked
/// </summary>
public override void OnClick()
{
// TODO: Add OpenAttributeTable.OnClick implementation
AttributeTableFrm attributeTable = new AttributeTableFrm();
attributeTable.CreateAttributeTable(m_pLayer);
attributeTable.ShowDialog();
}
至此,我們完成了OpenAttributeTable命令。顯然,我們要在TOCControl的OnMouseDown事件中調(diào)用此命令。
因?yàn)?#xff0c;當(dāng)前選中的圖層參數(shù),即ILayer是通過(guò)OpenAttributeTable的構(gòu)造函數(shù)傳入的,而選中的ILayer是動(dòng)態(tài)變化的,所以我們無(wú)法在窗體初始化的Form1_Load事件中就添加OpenAttributeTable菜單項(xiàng)到右鍵菜單。但我們可以在OnMouseDown事件中動(dòng)態(tài)添加OpenAttributeTable菜單項(xiàng)。
要注意的是,最后我們必須移除添加的OpenAttributeTable菜單項(xiàng),不然每次按下右鍵都會(huì)添加此菜單項(xiàng),將造成右鍵菜單中含有多個(gè)OpenAttributeTable菜單項(xiàng)。
修改TOCControl的OnMouseDown事件的部分代碼如下:
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
//……
//彈出右鍵菜單
if (item == esriTOCControlItem.esriTOCControlItemMap)
m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd);
if (item == esriTOCControlItem.esriTOCControlItemLayer)
{
//動(dòng)態(tài)添加OpenAttributeTable菜單項(xiàng)
m_menuLayer.AddItem(new OpenAttributeTable(layer), -1, 2, true, esriCommandStyles.esriCommandStyleTextOnly);
m_menuLayer.PopupMenu(e.x, e.y, m_tocControl.hWnd);
//移除OpenAttributeTable菜單項(xiàng),以防止重復(fù)添加
m_menuLayer.Remove(2);
}
}
6.編譯運(yùn)行
按下F5,編譯運(yùn)行程序,相信你已經(jīng)實(shí)現(xiàn)了開(kāi)篇處展示的屬性表效果了吧!
以上代碼在Windows XP Sp3 + VS2005 + AE9.2環(huán)境下編譯通過(guò)。
本文實(shí)現(xiàn)的最終效果如下:
圖層標(biāo)注實(shí)現(xiàn)起來(lái)并不復(fù)雜,本例僅做一個(gè)簡(jiǎn)單示范,只加載AE的樣式庫(kù),標(biāo)注選定的字段,旨在拋磚引玉。更高級(jí)的功能,如自定義樣式和修改樣式,由讀者自己實(shí)現(xiàn)。
主要思路:
?加載圖層字段 –> 加載文本樣式 -> 設(shè)置文本樣式
實(shí)現(xiàn)過(guò)程:
?創(chuàng)建標(biāo)注設(shè)置窗體 -> 創(chuàng)建圖層標(biāo)注的Command -> 添加Command到圖層右鍵菜單
9.1創(chuàng)建標(biāo)注設(shè)置窗體
(1)添加一個(gè)Windows窗體,命名為L(zhǎng)abelLayerFrm.cs。添加控件如下:
控件
?Name屬性
?Text屬性
?其它
SymbologyControl
?axSymbologyControl
ComboBox
?cbbField
Button
?btnOK
?確定
?DialogResult設(shè)為OK
Button
?btnCancel
?取消
?DialogResult
設(shè)為Cancel
GroupBox
?groupBox1
?字段
GroupBox
?groupBox2
?符號(hào)
(2)為L(zhǎng)abelLayerFrm類添加兩個(gè)成員變量:
public ILayer pLayer;
private IStyleGalleryItem pStyleGalleryItem;
(3)重載一個(gè)構(gòu)造函數(shù):
?public LabelLayerFrm(ILayer layer)
{
??? InitializeComponent();
??? pLayer = layer;
}
(4) 添加成員函數(shù)ReadRegistry,用于從注冊(cè)表中讀取ArcGIS的安裝路徑。
?/// <summary>
/// 讀取注冊(cè)表中的制定軟件的路徑
/// </summary>
/// <param name="sKey"></param>
/// <returns></returns>
private string ReadRegistry(string sKey)
{
??? //Open the subkey for reading
??? Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey, true);
??? if (rk == null) return "";
??? // Get the data from a specified item in the key.
??? return (string)rk.GetValue("InstallDir");
}
(5)添加LabelLayerFrm窗體的Load事件,以加載圖層字段到下拉模型,加載文本樣式到SymbologyControl控件。
?private void LabelLayerFrm_Load(object sender, EventArgs e)
{
??? //加載圖層字段
??? ITable pTable = pLayer as ITable;
??? IField pField = null;
??? for (int i = 0; i < pTable.Fields.FieldCount; i++)
??? {
??????? pField = pTable.Fields.get_Field(i);
??????? cbbField.Items.Add(pField.AliasName);
??? }
??? cbbField.SelectedIndex = 0;
??? //獲得ArcGIS的安裝路徑
??? string sInstall = ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
??? //加載ESRI.ServerStyle 樣式文件到SymbologyControl
??? this.axSymbologyControl1.LoadStyleFile(sInstall + "\\Styles\\ESRI.ServerStyle");
??? this.axSymbologyControl1.GetStyleClass(esriSymbologyStyleClass.esriStyleClassTextSymbols).SelectItem(0);
}
(6)添加axSymbologyControl1控件的OnItemSelected事件,以設(shè)置選定的樣式。
?private void axSymbologyControl1_OnItemSelected(object sender, ISymbologyControlEvents_OnItemSelectedEvent e)
{
??? pStyleGalleryItem = (IStyleGalleryItem)e.styleGalleryItem;
}
(7)添加確定按扭的Click事件,為選定圖層中的選定的字段以選定的樣式標(biāo)注。
?private void btnOK_Click(object sender, EventArgs e)
{
??? IGeoFeatureLayer pGeoFeatureLayer = pLayer as IGeoFeatureLayer;
??? pGeoFeatureLayer.AnnotationProperties.Clear();//必須執(zhí)行,因?yàn)槔锩嬗幸粋€(gè)默認(rèn)的
??? IBasicOverposterLayerProperties pBasic = new BasicOverposterLayerPropertiesClass();
??? ILabelEngineLayerProperties pLableEngine = new LabelEngineLayerPropertiesClass();
??? ITextSymbol pTextSymbol = new TextSymbolClass();???????????
??? pTextSymbol = (ITextSymbol)pStyleGalleryItem.Item;
??? //你可以在這里修改樣式的顏色和字體等屬性,本文從略
??? //pTextSymbol.Color
??? //pTextSymbol.Font
??? string pLable = "[" + (string)cbbField .SelectedItem + "]";
??? pLableEngine.Expression = pLable;
??? pLableEngine.IsExpressionSimple = true;
??? pBasic.NumLabelsOption = esriBasicNumLabelsOption.esriOneLabelPerShape;
? ??pLableEngine.BasicOverposterLayerProperties = pBasic;
??? pLableEngine.Symbol = pTextSymbol;
??? pGeoFeatureLayer.AnnotationProperties.Add(pLableEngine as IAnnotateLayerProperties);
??? pGeoFeatureLayer.DisplayAnnotation = true;
}
至此,標(biāo)注設(shè)置窗體已經(jīng)完成,如果你編譯通不過(guò),看看是不是忘了添加相關(guān)引用了。
9.2創(chuàng)建圖層標(biāo)注的Command
(1)創(chuàng)建一個(gè)新類,以ArcGIS的BaseCommand為模板,命名為L(zhǎng)abelLayerCmd.cs。
注意:在新建Base Command模板時(shí),會(huì)彈出一個(gè)對(duì)話框讓我們選擇模板適用對(duì)象,這時(shí)我們要選擇MapControl、PageLayoutControl,即選擇第二項(xiàng)或者倒數(shù)第二項(xiàng)。
(2)添加LabelLayerCmd類的成員變量。
?private ILayer pLayer = null;
IMapControl3 pMap;
(3)修改默認(rèn)構(gòu)造函數(shù)如下:
?public LabelLayerCmd(ILayer lyr,IMapControl3 map)
{
??? //
??? // TODO: Define values for the public properties
??? //
??? base.m_category = ""; //localizable text
??? base.m_caption = "標(biāo)注";? //localizable text
??? base.m_message = "標(biāo)注";? //localizable text
??? base.m_toolTip = "標(biāo)注";? //localizable text
??? base.m_name = "標(biāo)注";?? //unique id, non-localizable (e.g. "MyCategory_MyCommand")
??? pLayer = lyr;
??? pMap = map;
??? try
??? {
??????? //
??????? // TODO: change bitmap name if necessary
??????? //
??????? string bitmapResourceName = GetType().Name + ".bmp";
??????? base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
??? }
??? catch (Exception ex)
??? {
??????? System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
??? }
}
(4)修改OnClick函數(shù)為:
?/// <summary>
/// Occurs when this command is clicked
/// </summary>
public override void OnClick()
{
??? // TODO: Add LabelLayerCmd.OnClick implementation
??? LabelLayerFrm labelLyrFrm = new LabelLayerFrm(pLayer);
?? ?labelLyrFrm.ShowDialog();
??? pMap.Refresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
9.3添加Command到圖層右鍵菜單
回到3sdnMap主窗體類,找到axTOCControl1_OnMouseDown事件響應(yīng)函數(shù),修改如下代碼片斷:
?//彈出右鍵菜單
if (item == esriTOCControlItem.esriTOCControlItemMap)
??? m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd);
if (item == esriTOCControlItem.esriTOCControlItemLayer)
{
m_menuLayer.AddItem(new OpenAttributeTable(layer), -1, 2, true , esriCommandStyles.esriCommandStyleTextOnly);
//動(dòng)態(tài)添加圖層標(biāo)注的Command到圖層右鍵菜單
??? m_menuLayer.AddItem(new LabelLayerCmd(layer, m_mapControl), -1, 3, false, esriCommandStyles.esriCommandStyleTextOnly);
??? //彈出圖層右鍵菜單
??? m_menuLayer.PopupMenu(e.x, e.y, m_tocControl.hWnd);
?//移除菜單項(xiàng)
??? m_menuLayer.Remove(3);
??? m_menuLayer.Remove(2);
}
至此,已經(jīng)完成圖層文本標(biāo)注,編譯運(yùn)行吧,是不是看到開(kāi)篇的效果了?
以上代碼在Windows XP Sp3 + VS2005 + AE9.2/9.3環(huán)境下編譯通過(guò)。
ArcEngine,C#數(shù)據(jù)刪除幾種方法和性能比較
By Yanleigis? Landgis@126.com
一、? 幾種刪除方法代碼
1.? 查詢結(jié)果中刪除
? private void Delete1(IFeatureClass PFeatureclass)
??????? {
??????????? IQueryFilter pQueryFilter = new QueryFilterClass();
??????????? pQueryFilter.WhereClause = "objectID<=" + DeleteNum;
??????????? IFeatureCursor pFeatureCursor = PFeatureclass.Search(pQueryFilter, false);??????????? IFeature pFeature = pFeatureCursor.NextFeature();
????????? ??while (pFeature != null)
??????????? {
??????????????? pFeature.Delete();
??????????????? pFeature = pFeatureCursor.NextFeature();
??????????? }
??????????? System.Runtime.InteropServices.Marshal.ReleaseComObject(pQueryFilter);
??????? }
2.? 更新游標(biāo)刪除
private void Delete2(IFeatureClass PFeatureclass)
??????? {
??????????? IQueryFilter pQueryFilter = new QueryFilterClass();
??????????? pQueryFilter.WhereClause = "objectID<=" + DeleteNum;
??????????? IFeatureCursor pFeatureCursor = PFeatureclass.Update(pQueryFilter, false);
??????????? IFeature pFeature = pFeatureCursor.NextFeature();
??????????? while (pFeature != null)
??????????? {
??????????????? pFeatureCursor.DeleteFeature();
??????????????? pFeature = pFeatureCursor.NextFeature();
???? ???????}
??????????? System.Runtime.InteropServices.Marshal.ReleaseComObject(pQueryFilter);
??????? }
3.? 使用DeleteSearchedRows刪除
private void Delete4(IFeatureClass PFeatureclass)
??????? {
??????????? IQueryFilter pQueryFilter = new QueryFilterClass();
??????????? pQueryFilter.WhereClause = "objectID<=" + DeleteNum;
??????????? ITable pTable = PFeatureclass as ITable;
??????????? pTable.DeleteSearchedRows(pQueryFilter);
??????????? System.Runtime.InteropServices.Marshal.ReleaseComObject(pQueryFilter);
??????? }
4.? ExecuteSQL刪除
private void Delete4(IFeatureClass PFeatureclass)
??????? {
??????????? IDataset pDataset = PFeatureclass as IDataset;
??????????? pDataset.Workspace.ExecuteSQL("delete from " + PFeatureclass.AliasName + " where objectid<=" + DeleteNum);
??????? }
二、? 測(cè)試性能和比較
1、?????? 相同的數(shù)據(jù)條件,刪除2000條記錄
2、?????? 測(cè)試代碼
IFeatureLayer pFeatureLayer = axMapControl1.Map.get_Layer(0) as IFeatureLayer;
??????????? IFeatureClass PFeatureClass = pFeatureLayer.FeatureClass;
?????????? ?System.Diagnostics.Stopwatch MyWatch = new System.Diagnostics.Stopwatch();
??????????? MyWatch.Start();
??????????? Delete1(PFeatureClass)
??????????? //Delete2(PFeatureClass);
??????????? //Delete3(PFeatureClass);
??????????? //Delete4(PFeatureClass);
??????????? //Delete5(PFeatureClass);
??????????? MyWatch.Stop();
??????????? MessageBox.Show("刪除時(shí)間:" + MyWatch.ElapsedMilliseconds.ToString() + "毫秒");
3、?????? 測(cè)試情況
測(cè)試方法
?第一次時(shí)間(單位ms)
?第一次時(shí)間(單位ms)
1
?5214ms
?5735ms
2
?299ms
?290Ms
3
?59ms
?28ms
4
?26ms
?26ms
三、? 結(jié)論
1、???????? 使用ExecuteSQL刪除最快,數(shù)據(jù)庫(kù)的效率最高。
2、???????? DeleteSearchedRows和ExecuteSQL屬于批量刪除,性能較優(yōu)。
3、???????? 查詢結(jié)果中刪除,速度最慢,如果你使用這種方法,建立你馬上修改你的程序,因?yàn)槟阍诶速M(fèi)時(shí)間。
4、?????? 小數(shù)據(jù)量記錄數(shù)小于500000條,請(qǐng)使用DeleteSearchedRows或ExecuteSQL,否則使用更新游標(biāo)刪除(方法2),加上進(jìn)度條,這樣界面很友好。
1 概述
緩沖區(qū)分析(Buffer)是對(duì)選中的一組或一類地圖要素(點(diǎn)、線或面)按設(shè)定的距離條件,圍繞其要素而形成一定緩沖區(qū)多邊形實(shí)體,從而實(shí)現(xiàn)數(shù)據(jù)在二維空間得以擴(kuò)展的信息分析方法。緩沖區(qū)應(yīng)用的實(shí)例有如:污染源對(duì)其周圍的污染量隨距離而減小,確定污染的區(qū)域;為失火建筑找到距其500米范圍內(nèi)所有的消防水管等。
2 緩沖區(qū)的基礎(chǔ)
緩沖區(qū)是地理空間,目標(biāo)的一種影響范圍或服務(wù)范圍在尺度上的表現(xiàn)。它是一種因變量,由所研究的要素的形態(tài)而發(fā)生改變。從數(shù)學(xué)的角度來(lái)看,緩沖區(qū)是給定空間對(duì)象或集合后獲得的它們的領(lǐng)域,而鄰域的大小由鄰域的半徑或緩沖區(qū)建立條件來(lái)決定,因此對(duì)于一個(gè)給定的對(duì)象A,它的緩沖區(qū)可以定義為:
P={x | d(x , A)<=r}
(d一般是指歐式距離,也可以是其它的距離,其中r為鄰域半徑或緩沖區(qū)建立的條件)
緩沖區(qū)建立的形態(tài)多種多樣,這是根據(jù)緩沖區(qū)建立的條件來(lái)確定的,常用的對(duì)于點(diǎn)狀要素有圓形,也有三角形、矩形和環(huán)形等;對(duì)于線狀要素有雙側(cè)對(duì)稱、雙側(cè)不對(duì)稱或單側(cè)緩沖區(qū);對(duì)于面狀要素有內(nèi)側(cè)和外側(cè)緩沖區(qū),雖然這些形體各異,但是可以適合不同的應(yīng)用要求,建立的原理都是一樣的。點(diǎn)狀要素,線狀要素和面狀要素的緩沖區(qū)示意圖如下。
3 定制工具的使用
1 打開(kāi)工程GPBufferLayer\CSharp\GpBufferLayer.sln
2 在VS2005內(nèi)選擇重新生成解決方案
3 開(kāi)發(fā)需要添加工具的工程
4 在ToolBarControl上點(diǎn)右鍵,選擇屬性
5 選擇條目,點(diǎn)擊添加
6 在命令類中選擇“自定義工具集”,選擇“緩沖區(qū)分析”,可通過(guò)雙擊或者拖放到工具條上。
7 運(yùn)行程序
8 使用“選擇要素”命令,選擇需要建立緩沖區(qū)的要素(點(diǎn)或線)
9 點(diǎn)擊工具條上的“緩沖區(qū)分析按鈕”,彈出緩沖區(qū)分析對(duì)話框
?????????????????? 選擇要素
選擇緩沖區(qū)分析按鈕
10 選擇緩存分析的圖層,選擇距離及單位,設(shè)置輸出的圖層
11 點(diǎn)擊分析按鈕,當(dāng)出現(xiàn)“分析完成”字樣時(shí),工作完成
12 這時(shí)通過(guò)附加新的圖層,即可看到結(jié)果
4 核心源代碼分析
4.1 BufferSelectedLayerCmd.cs
???? 主要完成定制command的相關(guān)代碼,具體原理可參見(jiàn)《ArcGIS Engine中文開(kāi)發(fā)指南》
4.2 BufferDlg.cs
為緩沖區(qū)分析的輸入對(duì)話框。其中最主要的是“分析”按鈕的處理事件。源代碼及分析如下:
????? double bufferDistance;
??? //轉(zhuǎn)換distance為double類型
????? double.TryParse(txtBufferDistance.Text, out bufferDistance);
????? if (0.0 == bufferDistance)
????? {
??????? MessageBox.Show("Bad buffer distance!");
??????? return;
????? }
????? //判斷輸出路徑是否合法
????? if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(txtOutputPath.Text)) ||
??????? ".shp" != System.IO.Path.GetExtension(txtOutputPath.Text))
????? {
??????? MessageBox.Show("Bad output filename!");
??????? return;
????? }
????? //判斷圖層個(gè)數(shù)
????? if (m_hookHelper.FocusMap.LayerCount == 0)
??????? return;
????? //get the layer from the map
????? IFeatureLayer layer = GetFeatureLayer((string)cboLayers.SelectedItem);
????? if (null == layer)
????? {
??????? txtMessages.Text += "Layer " + (string)cboLayers.SelectedItem + "cannot be found!\r\n";
??????? return;
????? }
????? //scroll the textbox to the bottom
????? ScrollToBottom();
????? txtMessages.Text += "\r\n分析開(kāi)始,這可能需要幾分鐘時(shí)間,請(qǐng)稍候..\r\n";
????? txtMessages.Update();
????? //get an instance of the geoprocessor
????? Geoprocessor gp = new Geoprocessor();
????? gp.OverwriteOutput = true;
??????? //create a new instance of a buffer tool
????? ESRI.ArcGIS.AnalysisTools.Buffer buffer = new ESRI.ArcGIS.AnalysisTools.Buffer(layer, txtOutputPath.Text, Convert.ToString(bufferDistance) + " " + (string)cboUnits.SelectedItem);
????? buffer.dissolve_option = "ALL";//這個(gè)要設(shè)成ALL,否則相交部分不會(huì)融合
????? //buffer.line_side = "FULL";//默認(rèn)是"FULL",最好不要改否則出錯(cuò)
????? //buffer.line_end_type = "ROUND";//默認(rèn)是"ROUND",最好不要改否則出錯(cuò)
?????
????? //execute the buffer tool (very easy :-))
????? IGeoProcessorResult results=null;
?????
????? try
????? {
????????? results = (IGeoProcessorResult)gp.Execute(buffer, null);
????? }
????? catch (Exception ex)
????? {
????????? txtMessages.Text += "Failed to buffer layer: " + layer.Name + "\r\n";
????? }
????? if (results.Status != esriJobStatus.esriJobSucceeded)
????? {
??????? txtMessages.Text += "Failed to buffer layer: " + layer.Name + "\r\n";
????? }
?????
?????? //scroll the textbox to the bottom
????? ScrollToBottom();
????? txtMessages.Text += "\r\n分析完成.\r\n";
????? txtMessages.Text += "-----------------------------------------------------------------------------------------\r\n";
????? //scroll the textbox to the bottom
????? ScrollToBottom();
轉(zhuǎn)載于:https://www.cnblogs.com/zhaokai417/archive/2011/03/03/1969825.html
總結(jié)
以上是生活随笔為你收集整理的arcgis开发常用源码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据仓库经验小结(转)
- 下一篇: telnet小技巧