3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

arcgis开发常用源码

發(fā)布時(shí)間:2025/7/25 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 arcgis开发常用源码 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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)用方式都類似,如下所示:

?// 定義
ICommand command = new ControlsSaveAsDocCommandClass();
// 創(chuàng)建
command.OnCreate(m_controlsSynchronizer.ActiveControl);
// 調(diào)用
command.OnClick();

希望你可以舉一反三,去實(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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

日本熟妇人妻xxxxx人hd | 国产猛烈高潮尖叫视频免费 | 在线天堂新版最新版在线8 | 夜夜高潮次次欢爽av女 | 97资源共享在线视频 | 亚洲一区二区三区含羞草 | 亚洲人成无码网www | 丝袜美腿亚洲一区二区 | 亚洲中文字幕无码一久久区 | 一本色道婷婷久久欧美 | 丰满少妇高潮惨叫视频 | 男女超爽视频免费播放 | 少妇性荡欲午夜性开放视频剧场 | 亚洲精品一区三区三区在线观看 | 无码福利日韩神码福利片 | 亚洲精品久久久久久久久久久 | 日韩精品乱码av一区二区 | 成人无码影片精品久久久 | 国产办公室秘书无码精品99 | 国产午夜无码视频在线观看 | 午夜男女很黄的视频 | 国产精品久久久久无码av色戒 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 久久精品女人的天堂av | 人人妻人人藻人人爽欧美一区 | 国产莉萝无码av在线播放 | 日韩欧美成人免费观看 | 亚洲精品久久久久中文第一幕 | 日日噜噜噜噜夜夜爽亚洲精品 | 日日天日日夜日日摸 | 久久综合给合久久狠狠狠97色 | 国产亚洲欧美在线专区 | 99久久久无码国产精品免费 | 性生交大片免费看女人按摩摩 | 亚洲精品国产精品乱码视色 | 亚洲毛片av日韩av无码 | 亚洲中文字幕av在天堂 | 亚洲男人av天堂午夜在 | 日日碰狠狠丁香久燥 | 亚洲人成网站免费播放 | 熟女少妇在线视频播放 | www国产精品内射老师 | 熟妇女人妻丰满少妇中文字幕 | 色欲av亚洲一区无码少妇 | 国产精品美女久久久久av爽李琼 | 国产超碰人人爽人人做人人添 | 性做久久久久久久久 | 激情国产av做激情国产爱 | 精品熟女少妇av免费观看 | 久久国产36精品色熟妇 | 亚洲午夜久久久影院 | 自拍偷自拍亚洲精品被多人伦好爽 | 亚洲国产精品毛片av不卡在线 | 亚洲伊人久久精品影院 | 国产精品va在线播放 | 亚洲色www成人永久网址 | 精品久久久久久人妻无码中文字幕 | 日本精品高清一区二区 | 精品无码一区二区三区的天堂 | 曰本女人与公拘交酡免费视频 | 玩弄人妻少妇500系列视频 | 亚洲最大成人网站 | 日本饥渴人妻欲求不满 | 亚洲精品综合一区二区三区在线 | 97精品人妻一区二区三区香蕉 | 97se亚洲精品一区 | 一本色道久久综合亚洲精品不卡 | 高潮毛片无遮挡高清免费 | 全黄性性激高免费视频 | 久久aⅴ免费观看 | 精品国产青草久久久久福利 | 日韩人妻无码一区二区三区久久99 | 国产综合在线观看 | 色 综合 欧美 亚洲 国产 | 日日夜夜撸啊撸 | 婷婷六月久久综合丁香 | ass日本丰满熟妇pics | 野外少妇愉情中文字幕 | 18无码粉嫩小泬无套在线观看 | 真人与拘做受免费视频一 | 欧美日本精品一区二区三区 | 国产香蕉尹人视频在线 | 精品 日韩 国产 欧美 视频 | 国产亚洲人成在线播放 | 亚洲国产欧美日韩精品一区二区三区 | 永久免费精品精品永久-夜色 | 波多野42部无码喷潮在线 | 偷窥村妇洗澡毛毛多 | 亚洲精品一区二区三区四区五区 | 久久99精品国产麻豆 | 鲁一鲁av2019在线 | 无码人妻精品一区二区三区下载 | 人人澡人人透人人爽 | 日本一区二区更新不卡 | 欧美 日韩 亚洲 在线 | 天堂无码人妻精品一区二区三区 | 97se亚洲精品一区 | 波多野42部无码喷潮在线 | 无人区乱码一区二区三区 | 亚洲成熟女人毛毛耸耸多 | 国产精品高潮呻吟av久久 | 国产熟妇高潮叫床视频播放 | 未满小14洗澡无码视频网站 | 亚洲国产精品一区二区第一页 | 亚洲国产欧美国产综合一区 | 精品无码av一区二区三区 | 一本色道久久综合亚洲精品不卡 | 黑人玩弄人妻中文在线 | 日本丰满护士爆乳xxxx | 无码人妻出轨黑人中文字幕 | 中文字幕无码热在线视频 | 精品国产一区av天美传媒 | 亚洲一区二区三区在线观看网站 | 亚洲aⅴ无码成人网站国产app | 久久午夜无码鲁丝片 | 色窝窝无码一区二区三区色欲 | 一本色道婷婷久久欧美 | 久久人人爽人人爽人人片av高清 | 国产在线一区二区三区四区五区 | 国产真实乱对白精彩久久 | 东京热一精品无码av | 日日橹狠狠爱欧美视频 | 狂野欧美性猛xxxx乱大交 | 香蕉久久久久久av成人 | 国产成人精品视频ⅴa片软件竹菊 | 国产亚洲视频中文字幕97精品 | 国产精品亚洲综合色区韩国 | 高中生自慰www网站 | 天堂在线观看www | 国产精品无码一区二区三区不卡 | 色一情一乱一伦一视频免费看 | 熟妇人妻无乱码中文字幕 | 亚洲色成人中文字幕网站 | 成人影院yy111111在线观看 | 亚洲天堂2017无码中文 | 日本精品人妻无码免费大全 | 撕开奶罩揉吮奶头视频 | a片免费视频在线观看 | 免费国产黄网站在线观看 | 中文字幕无码乱人伦 | 精品无人区无码乱码毛片国产 | 国产成人精品视频ⅴa片软件竹菊 | 日本大乳高潮视频在线观看 | 国产成人av免费观看 | 精品人妻中文字幕有码在线 | 九九热爱视频精品 | 黑人粗大猛烈进出高潮视频 | 中文无码伦av中文字幕 | 久久人人爽人人爽人人片av高清 | 东京热男人av天堂 | 免费男性肉肉影院 | 内射爽无广熟女亚洲 | 国内少妇偷人精品视频免费 | 天天躁夜夜躁狠狠是什么心态 | 欧美成人免费全部网站 | 国产成人精品三级麻豆 | 亚洲精品欧美二区三区中文字幕 | 免费中文字幕日韩欧美 | 亚洲乱码日产精品bd | 亚洲成av人片天堂网无码】 | 久久人人爽人人爽人人片av高清 | 妺妺窝人体色www婷婷 | 亚洲国产午夜精品理论片 | 蜜桃av抽搐高潮一区二区 | 97久久精品无码一区二区 | 欧洲精品码一区二区三区免费看 | 最新版天堂资源中文官网 | 国产精品毛片一区二区 | 成人无码影片精品久久久 | 丝袜足控一区二区三区 | 亚洲精品鲁一鲁一区二区三区 | 国产乱子伦视频在线播放 | 亚洲日本在线电影 | 日本高清一区免费中文视频 | 日韩少妇白浆无码系列 | 国产亚洲欧美日韩亚洲中文色 | 久久久婷婷五月亚洲97号色 | 美女极度色诱视频国产 | 亚洲色成人中文字幕网站 | 无码国产色欲xxxxx视频 | 国产亚洲tv在线观看 | 国产亚洲精品久久久久久国模美 | 精品久久久久久亚洲精品 | av无码久久久久不卡免费网站 | 人妻无码αv中文字幕久久琪琪布 | 久久久精品成人免费观看 | 精品厕所偷拍各类美女tp嘘嘘 | 色欲久久久天天天综合网精品 | 强伦人妻一区二区三区视频18 | 国产精品久久久 | 最近中文2019字幕第二页 | 亚洲精品综合一区二区三区在线 | 夜夜影院未满十八勿进 | 无码成人精品区在线观看 | 久久精品国产大片免费观看 | 97夜夜澡人人双人人人喊 | 中文字幕乱码人妻无码久久 | 婷婷六月久久综合丁香 | 亚洲国产精华液网站w | 亚洲 欧美 激情 小说 另类 | 玩弄中年熟妇正在播放 | 久久精品女人的天堂av | 国产黑色丝袜在线播放 | 精品一区二区三区无码免费视频 | 一区二区三区乱码在线 | 欧洲 | 国产电影无码午夜在线播放 | 乱码av麻豆丝袜熟女系列 | 国产va免费精品观看 | 午夜精品一区二区三区在线观看 | 性做久久久久久久免费看 | 激情国产av做激情国产爱 | 色婷婷久久一区二区三区麻豆 | 正在播放老肥熟妇露脸 | 中文字幕无码日韩欧毛 | 99久久精品日本一区二区免费 | 精品一区二区不卡无码av | 99久久久无码国产精品免费 | 亚洲s码欧洲m码国产av | 精品国产成人一区二区三区 | 欧美精品免费观看二区 | 狠狠噜狠狠狠狠丁香五月 | 免费观看的无遮挡av | 波多野结衣乳巨码无在线观看 | 国产精品高潮呻吟av久久 | 麻豆国产人妻欲求不满 | 午夜嘿嘿嘿影院 | 波多野结衣 黑人 | 亚洲人亚洲人成电影网站色 | 亚洲人成人无码网www国产 | 国产特级毛片aaaaaa高潮流水 | 欧美真人作爱免费视频 | 天天综合网天天综合色 | 亚洲七七久久桃花影院 | 三上悠亚人妻中文字幕在线 | 狂野欧美性猛xxxx乱大交 | 老太婆性杂交欧美肥老太 | 国产情侣作爱视频免费观看 | 无码乱肉视频免费大全合集 | 人人妻人人澡人人爽欧美精品 | 在线播放免费人成毛片乱码 | 18禁黄网站男男禁片免费观看 | 国产三级久久久精品麻豆三级 | 蜜桃视频韩日免费播放 | 2019nv天堂香蕉在线观看 | 国产人成高清在线视频99最全资源 | 亚洲综合无码一区二区三区 | 久久久久久九九精品久 | 激情国产av做激情国产爱 | 亚洲日韩av片在线观看 | а√天堂www在线天堂小说 | 天堂а√在线地址中文在线 | 国产无套粉嫩白浆在线 | 无码av最新清无码专区吞精 | 久久 国产 尿 小便 嘘嘘 | 亚洲精品久久久久中文第一幕 | 国产亚洲精品久久久久久久 | 国产午夜福利亚洲第一 | 国产在线无码精品电影网 | 无码人妻出轨黑人中文字幕 | 亚洲精品综合五月久久小说 | 少妇性l交大片欧洲热妇乱xxx | 女人色极品影院 | 中文字幕av日韩精品一区二区 | 秋霞特色aa大片 | 久久久久亚洲精品男人的天堂 | 在线精品国产一区二区三区 | 日韩人妻无码一区二区三区久久99 | 久久人人97超碰a片精品 | 亚洲精品成人福利网站 | 久久精品国产精品国产精品污 | 国产超碰人人爽人人做人人添 | 欧美日本精品一区二区三区 | 国产精品va在线观看无码 | 三上悠亚人妻中文字幕在线 | 欧美人与物videos另类 | 无码人妻少妇伦在线电影 | 久久国产精品偷任你爽任你 | 国产人妻精品一区二区三区不卡 | 成人av无码一区二区三区 | 一本久久a久久精品vr综合 | 无码免费一区二区三区 | 日韩精品无码一区二区中文字幕 | 中文字幕av日韩精品一区二区 | 青春草在线视频免费观看 | 爱做久久久久久 | 日韩人妻无码一区二区三区久久99 | 国产无套内射久久久国产 | 免费乱码人妻系列无码专区 | 色五月丁香五月综合五月 | 99久久久无码国产aaa精品 | 久9re热视频这里只有精品 | 亚洲成a人一区二区三区 | 天天摸天天碰天天添 | 5858s亚洲色大成网站www | 亚洲日韩乱码中文无码蜜桃臀网站 | 午夜丰满少妇性开放视频 | 偷窥村妇洗澡毛毛多 | 欧洲美熟女乱又伦 | 亚洲啪av永久无码精品放毛片 | 国产色视频一区二区三区 | yw尤物av无码国产在线观看 | 77777熟女视频在线观看 а天堂中文在线官网 | 亚洲精品久久久久中文第一幕 | 国产真实夫妇视频 | 青草青草久热国产精品 | 欧洲熟妇精品视频 | 精品午夜福利在线观看 | 欧美日韩精品 | 久久综合九色综合97网 | 97精品人妻一区二区三区香蕉 | 国产精品久久久久无码av色戒 | 国内精品人妻无码久久久影院蜜桃 | 久久久亚洲欧洲日产国码αv | 亚洲伊人久久精品影院 | 久久人人爽人人爽人人片ⅴ | 国产69精品久久久久app下载 | 中文字幕人妻丝袜二区 | 天堂亚洲2017在线观看 | 欧美 日韩 人妻 高清 中文 | 亚洲欧美中文字幕5发布 | 一区二区传媒有限公司 | 国产热a欧美热a在线视频 | 欧洲美熟女乱又伦 | 亚无码乱人伦一区二区 | 午夜精品一区二区三区在线观看 | 无遮无挡爽爽免费视频 | 久久精品国产亚洲精品 | 国产精品人妻一区二区三区四 | 无码精品国产va在线观看dvd | 人人爽人人澡人人高潮 | 又大又紧又粉嫩18p少妇 | 婷婷丁香六月激情综合啪 | 午夜福利不卡在线视频 | 免费看男女做好爽好硬视频 | 亚洲中文无码av永久不收费 | 人妻少妇精品久久 | 成人精品一区二区三区中文字幕 | 中文字幕无线码 | 国产熟妇高潮叫床视频播放 | 日本护士毛茸茸高潮 | 欧美人与物videos另类 | 日韩欧美群交p片內射中文 | 思思久久99热只有频精品66 | 欧美日韩久久久精品a片 | 曰韩少妇内射免费播放 | 亚洲欧美中文字幕5发布 | 精品乱码久久久久久久 | 午夜福利一区二区三区在线观看 | 午夜无码人妻av大片色欲 | 天天躁日日躁狠狠躁免费麻豆 | 亚洲中文字幕在线无码一区二区 | 麻豆蜜桃av蜜臀av色欲av | 欧美人与动性行为视频 | 亚洲国产精品一区二区第一页 | 少妇厨房愉情理9仑片视频 | 成人一在线视频日韩国产 | 久久久久成人精品免费播放动漫 | 亚洲爆乳精品无码一区二区三区 | 131美女爱做视频 | 欧美日韩综合一区二区三区 | 成人无码影片精品久久久 | 麻豆国产人妻欲求不满谁演的 | 99久久人妻精品免费一区 | 色五月丁香五月综合五月 | 麻豆成人精品国产免费 | 亚洲爆乳大丰满无码专区 | 亚洲中文字幕无码一久久区 | 亚洲欧洲中文日韩av乱码 | 国产午夜福利100集发布 | 黑森林福利视频导航 | 波多野结衣av在线观看 | 丝袜人妻一区二区三区 | 国产欧美精品一区二区三区 | 婷婷五月综合激情中文字幕 | 乌克兰少妇xxxx做受 | 亚洲人成影院在线无码按摩店 | 久久婷婷五月综合色国产香蕉 | 国产激情无码一区二区app | 亚洲熟妇色xxxxx欧美老妇 | 天堂一区人妻无码 | 男人的天堂2018无码 | 日本护士xxxxhd少妇 | 午夜时刻免费入口 | 精品久久久无码人妻字幂 | 亚洲熟妇自偷自拍另类 | 国产av无码专区亚洲awww | 国内少妇偷人精品视频免费 | 亚洲精品国产精品乱码不卡 | 欧美性黑人极品hd | 国产精品自产拍在线观看 | 狠狠噜狠狠狠狠丁香五月 | 国产av一区二区三区最新精品 | 国产精品99爱免费视频 | 亚洲小说图区综合在线 | 欧洲熟妇色 欧美 | 亚洲成av人片在线观看无码不卡 | 精品久久8x国产免费观看 | 日本爽爽爽爽爽爽在线观看免 | 人妻人人添人妻人人爱 | 色偷偷人人澡人人爽人人模 | 性生交大片免费看l | 国产又粗又硬又大爽黄老大爷视 | 亚洲日韩av一区二区三区四区 | 日韩无码专区 | 精品人妻中文字幕有码在线 | 亚洲区欧美区综合区自拍区 | 无遮挡啪啪摇乳动态图 | 无码国产色欲xxxxx视频 | 亚洲综合无码久久精品综合 | 精品久久久久香蕉网 | 国内精品久久久久久中文字幕 | 三上悠亚人妻中文字幕在线 | 国产成人无码av片在线观看不卡 | 高潮毛片无遮挡高清免费视频 | 少妇激情av一区二区 | 狠狠cao日日穞夜夜穞av | 麻豆精品国产精华精华液好用吗 | 亚洲精品成a人在线观看 | 欧美一区二区三区视频在线观看 | 九九在线中文字幕无码 | 亚洲熟妇色xxxxx欧美老妇 | 国产精品亚洲lv粉色 | 久久综合九色综合97网 | 小泽玛莉亚一区二区视频在线 | 成人亚洲精品久久久久软件 | 夜夜影院未满十八勿进 | 久久人人爽人人人人片 | 少妇人妻大乳在线视频 | 日本www一道久久久免费榴莲 | 欧美黑人性暴力猛交喷水 | 无套内谢的新婚少妇国语播放 | 成年美女黄网站色大免费视频 | 国产亚洲精品久久久久久大师 | 影音先锋中文字幕无码 | 国产亚洲精品久久久久久大师 | 小泽玛莉亚一区二区视频在线 | 久久久久av无码免费网 | 国产精品igao视频网 | 国产极品美女高潮无套在线观看 | 国产精品亚洲一区二区三区喷水 | 亚洲伊人久久精品影院 | 国产真实伦对白全集 | 国产精品99久久精品爆乳 | 亚洲国产高清在线观看视频 | 波多野结衣一区二区三区av免费 | 亚洲人成网站在线播放942 | 在线播放免费人成毛片乱码 | 野外少妇愉情中文字幕 | 久久综合给合久久狠狠狠97色 | 日本丰满护士爆乳xxxx | 人妻少妇被猛烈进入中文字幕 | 国产精品第一国产精品 | 亚洲一区二区三区四区 | 国产人妖乱国产精品人妖 | 天海翼激烈高潮到腰振不止 | 亚洲成熟女人毛毛耸耸多 | 国产免费无码一区二区视频 | 一区二区传媒有限公司 | 少妇的肉体aa片免费 | 国产麻豆精品一区二区三区v视界 | 一本久久a久久精品亚洲 | 人人妻人人澡人人爽人人精品浪潮 | 久久天天躁狠狠躁夜夜免费观看 | 久久天天躁狠狠躁夜夜免费观看 | 四虎影视成人永久免费观看视频 | 亚洲国产日韩a在线播放 | 18无码粉嫩小泬无套在线观看 | 爆乳一区二区三区无码 | 国产熟女一区二区三区四区五区 | 亚洲精品中文字幕 | 国产成人精品必看 | 精品人妻中文字幕有码在线 | 亚洲 日韩 欧美 成人 在线观看 | 国产亚洲精品精品国产亚洲综合 | 无码av岛国片在线播放 | a片免费视频在线观看 | 欧美熟妇另类久久久久久多毛 | 国产性生交xxxxx无码 | 精品无码av一区二区三区 | 久久国产精品萌白酱免费 | 露脸叫床粗话东北少妇 | 啦啦啦www在线观看免费视频 | 国产成人久久精品流白浆 | 亚洲熟妇色xxxxx欧美老妇y | 无码帝国www无码专区色综合 | 欧美 日韩 人妻 高清 中文 | 内射老妇bbwx0c0ck | 国产精品内射视频免费 | 亚洲成a人一区二区三区 | 亚洲一区二区三区国产精华液 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产人妻久久精品二区三区老狼 | 亚洲第一无码av无码专区 | 亚洲啪av永久无码精品放毛片 | 永久黄网站色视频免费直播 | 黄网在线观看免费网站 | 欧美性猛交xxxx富婆 | 国产一区二区三区日韩精品 | 欧洲熟妇精品视频 | 成人av无码一区二区三区 | 婷婷丁香五月天综合东京热 | 国产亚洲人成a在线v网站 | 无码国产色欲xxxxx视频 | 欧洲极品少妇 | 亚洲国产精品久久人人爱 | 色情久久久av熟女人妻网站 | 国产精品久久久久7777 | 国内精品九九久久久精品 | 麻豆国产丝袜白领秘书在线观看 | 国产精品美女久久久久av爽李琼 | 午夜理论片yy44880影院 | 亚洲日本在线电影 | 人妻插b视频一区二区三区 | 丝袜美腿亚洲一区二区 | 无码免费一区二区三区 | 无码人妻黑人中文字幕 | 强奷人妻日本中文字幕 | 给我免费的视频在线观看 | 国产精品亚洲专区无码不卡 | 成人影院yy111111在线观看 | 中文无码精品a∨在线观看不卡 | 夜先锋av资源网站 | 国产成人无码a区在线观看视频app | 国产精品无套呻吟在线 | 97人妻精品一区二区三区 | 成人动漫在线观看 | 欧美日韩一区二区三区自拍 | 丰满肥臀大屁股熟妇激情视频 | 天堂在线观看www | 国产精品99爱免费视频 | 久久综合给合久久狠狠狠97色 | 日本大乳高潮视频在线观看 | 久久精品中文字幕大胸 | 国产精品高潮呻吟av久久4虎 | 精品一区二区三区波多野结衣 | 久久亚洲国产成人精品性色 | 天天摸天天透天天添 | 欧洲美熟女乱又伦 | 亚洲狠狠色丁香婷婷综合 | 老司机亚洲精品影院无码 | 亚洲春色在线视频 | 少妇无套内谢久久久久 | 久久综合狠狠综合久久综合88 | 国产片av国语在线观看 | 精品久久综合1区2区3区激情 | 亚洲精品一区二区三区四区五区 | 久久久久国色av免费观看性色 | 未满小14洗澡无码视频网站 | 亚洲精品午夜无码电影网 | 99精品国产综合久久久久五月天 | а√资源新版在线天堂 | aⅴ亚洲 日韩 色 图网站 播放 | 久久久www成人免费毛片 | 国产另类ts人妖一区二区 | √8天堂资源地址中文在线 | 欧美丰满老熟妇xxxxx性 | 18精品久久久无码午夜福利 | 欧美 亚洲 国产 另类 | 亚洲国产精品无码久久久久高潮 | 久久99久久99精品中文字幕 | 免费播放一区二区三区 | 一本精品99久久精品77 | 亚洲理论电影在线观看 | 欧美人妻一区二区三区 | 麻豆国产丝袜白领秘书在线观看 | 欧美性色19p | 中国大陆精品视频xxxx | 亚洲精品午夜无码电影网 | 免费无码肉片在线观看 | 国产无av码在线观看 | 欧美性生交xxxxx久久久 | 成人一在线视频日韩国产 | 国产特级毛片aaaaaaa高清 | 欧美精品免费观看二区 | 日韩精品一区二区av在线 | 欧美性生交活xxxxxdddd | 青青青爽视频在线观看 | 成人精品视频一区二区三区尤物 | 日韩精品无码免费一区二区三区 | 国产手机在线αⅴ片无码观看 | 欧美激情内射喷水高潮 | www国产亚洲精品久久网站 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产精品无码成人午夜电影 | 少妇人妻大乳在线视频 | 色窝窝无码一区二区三区色欲 | а√天堂www在线天堂小说 | 思思久久99热只有频精品66 | 欧美午夜特黄aaaaaa片 | 最近免费中文字幕中文高清百度 | 蜜桃无码一区二区三区 | 日本xxxx色视频在线观看免费 | 国产情侣作爱视频免费观看 | 在线精品亚洲一区二区 | 99麻豆久久久国产精品免费 | 亚洲s码欧洲m码国产av | 曰本女人与公拘交酡免费视频 | 国产特级毛片aaaaaaa高清 | 97资源共享在线视频 | 欧美变态另类xxxx | 最近免费中文字幕中文高清百度 | 精品成在人线av无码免费看 | 久久久亚洲欧洲日产国码αv | www国产亚洲精品久久网站 | 女高中生第一次破苞av | 日本va欧美va欧美va精品 | 中文字幕 亚洲精品 第1页 | 中文字幕无码乱人伦 | 国产精品第一区揄拍无码 | 中文字幕无码av激情不卡 | 99久久精品国产一区二区蜜芽 | 亚洲欧洲无卡二区视頻 | 国产av一区二区三区最新精品 | 天干天干啦夜天干天2017 | 熟女少妇在线视频播放 | 国产 精品 自在自线 | 我要看www免费看插插视频 | 国产内射爽爽大片视频社区在线 | 国内精品一区二区三区不卡 | 欧美变态另类xxxx | 一本久道久久综合狠狠爱 | 精品人妻人人做人人爽 | 国产av剧情md精品麻豆 | 亚洲乱码日产精品bd | 天堂一区人妻无码 | 精品偷自拍另类在线观看 | 午夜丰满少妇性开放视频 | 日本一卡2卡3卡四卡精品网站 | 成人亚洲精品久久久久软件 | 六十路熟妇乱子伦 | 人人澡人摸人人添 | 久久久久久久人妻无码中文字幕爆 | 高潮毛片无遮挡高清免费 | 国产卡一卡二卡三 | 精品厕所偷拍各类美女tp嘘嘘 | 久久国产劲爆∧v内射 | аⅴ资源天堂资源库在线 | 欧美老妇交乱视频在线观看 | 色五月丁香五月综合五月 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 在教室伦流澡到高潮hnp视频 | 久久婷婷五月综合色国产香蕉 | 奇米影视888欧美在线观看 | 老子影院午夜精品无码 | 日日橹狠狠爱欧美视频 | 综合网日日天干夜夜久久 | 国产精华av午夜在线观看 | 欧美自拍另类欧美综合图片区 | 国产精品高潮呻吟av久久 | 亚洲va中文字幕无码久久不卡 | 精品国产乱码久久久久乱码 | 97精品国产97久久久久久免费 | 黑人玩弄人妻中文在线 | 国产办公室秘书无码精品99 | 国产sm调教视频在线观看 | 97人妻精品一区二区三区 | 内射巨臀欧美在线视频 | 5858s亚洲色大成网站www | 人人妻人人澡人人爽人人精品浪潮 | 国产精品99久久精品爆乳 | 日韩亚洲欧美中文高清在线 | 国产亚洲欧美在线专区 | 午夜精品一区二区三区的区别 | 亚洲日本一区二区三区在线 | 台湾无码一区二区 | 日本熟妇乱子伦xxxx | 日本一区二区三区免费播放 | 久久午夜夜伦鲁鲁片无码免费 | 久久国产精品萌白酱免费 | 国产极品美女高潮无套在线观看 | 最近的中文字幕在线看视频 | 亚洲爆乳大丰满无码专区 | 蜜桃av抽搐高潮一区二区 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 国产乱人无码伦av在线a | 亚洲日韩乱码中文无码蜜桃臀网站 | 欧美日韩一区二区三区自拍 | 国内老熟妇对白xxxxhd | 成人三级无码视频在线观看 | 2019午夜福利不卡片在线 | 国产亚洲日韩欧美另类第八页 | 国产av一区二区精品久久凹凸 | 欧美日韩精品 | 夜精品a片一区二区三区无码白浆 | 欧美日韩久久久精品a片 | 亚洲中文字幕成人无码 | 少妇邻居内射在线 | 天堂在线观看www | 国产熟妇高潮叫床视频播放 | 欧美猛少妇色xxxxx | 国产乱人伦偷精品视频 | 高潮喷水的毛片 | 国产精品18久久久久久麻辣 | 天堂无码人妻精品一区二区三区 | 国产成人精品视频ⅴa片软件竹菊 | 亚洲日韩精品欧美一区二区 | 国产精品无码成人午夜电影 | 亚洲欧美中文字幕5发布 | 女人和拘做爰正片视频 | 亚洲狠狠色丁香婷婷综合 | 东北女人啪啪对白 | 2020最新国产自产精品 | 亚洲欧美日韩综合久久久 | 国产精品无码成人午夜电影 | 又大又黄又粗又爽的免费视频 | 日本丰满护士爆乳xxxx | 狠狠噜狠狠狠狠丁香五月 | 人人妻人人澡人人爽欧美一区 | 免费无码的av片在线观看 | 好爽又高潮了毛片免费下载 | 欧美国产日韩久久mv | 精品国产一区二区三区av 性色 | 成人欧美一区二区三区黑人免费 | 精品乱码久久久久久久 | 国产后入清纯学生妹 | 国产精品理论片在线观看 | 久久伊人色av天堂九九小黄鸭 | 久久久中文久久久无码 | 国产极品美女高潮无套在线观看 | 亚洲精品一区二区三区在线观看 | 亚洲精品午夜国产va久久成人 | 俺去俺来也在线www色官网 | 丝袜足控一区二区三区 | 亚洲a无码综合a国产av中文 | 未满小14洗澡无码视频网站 | 国产性生大片免费观看性 | 日日橹狠狠爱欧美视频 | av无码不卡在线观看免费 | 欧美黑人巨大xxxxx | 成人试看120秒体验区 | 人人妻人人澡人人爽欧美一区九九 | 亚洲成av人影院在线观看 | 亚洲人成影院在线无码按摩店 | 在线精品国产一区二区三区 | 成人无码精品1区2区3区免费看 | 国产午夜精品一区二区三区嫩草 | 国产精品人妻一区二区三区四 | 狠狠cao日日穞夜夜穞av | 好男人www社区 | 国产成人无码一二三区视频 | 无码吃奶揉捏奶头高潮视频 | 久久久久99精品成人片 | 色 综合 欧美 亚洲 国产 | 亚洲一区二区三区偷拍女厕 | 丰满人妻精品国产99aⅴ | 国产成人精品视频ⅴa片软件竹菊 | а√资源新版在线天堂 | 国产成人无码av一区二区 | 久久 国产 尿 小便 嘘嘘 | 纯爱无遮挡h肉动漫在线播放 | 天堂无码人妻精品一区二区三区 | 爱做久久久久久 | 国产人妻精品一区二区三区不卡 | 女人高潮内射99精品 | 性欧美疯狂xxxxbbbb | 中国女人内谢69xxxxxa片 | 国产日产欧产精品精品app | 久久亚洲精品中文字幕无男同 | 熟女少妇在线视频播放 | 精品国产aⅴ无码一区二区 | 无人区乱码一区二区三区 | 狠狠色噜噜狠狠狠7777奇米 | 性欧美疯狂xxxxbbbb | 真人与拘做受免费视频一 | 亚洲一区二区观看播放 | 久久久中文字幕日本无吗 | 六月丁香婷婷色狠狠久久 | 在线精品国产一区二区三区 | 一本色道婷婷久久欧美 | 久久久中文字幕日本无吗 | 精品午夜福利在线观看 | 成年美女黄网站色大免费视频 | 强伦人妻一区二区三区视频18 | 久久这里只有精品视频9 | 亚洲一区二区三区播放 | 精品无码av一区二区三区 | 性啪啪chinese东北女人 | 亚洲欧美日韩综合久久久 | 久久人人97超碰a片精品 | 无码乱肉视频免费大全合集 | 日本一卡二卡不卡视频查询 | 午夜熟女插插xx免费视频 | 国产一区二区三区日韩精品 | 日日干夜夜干 | 娇妻被黑人粗大高潮白浆 | 精品无码一区二区三区爱欲 | 熟妇人妻无乱码中文字幕 | 国语精品一区二区三区 | 亚洲码国产精品高潮在线 | 欧美 日韩 人妻 高清 中文 | 男人的天堂av网站 | 又大又硬又黄的免费视频 | 精品无人区无码乱码毛片国产 | 高清无码午夜福利视频 | 亚洲精品鲁一鲁一区二区三区 | 国产午夜视频在线观看 | 97夜夜澡人人爽人人喊中国片 | 精品国产青草久久久久福利 | 亚洲欧美国产精品久久 | 亚洲成av人综合在线观看 | 欧美第一黄网免费网站 | 国产欧美亚洲精品a | 丰满少妇人妻久久久久久 | 久久99精品久久久久婷婷 | 中文字幕av日韩精品一区二区 | 精品久久综合1区2区3区激情 | 午夜福利试看120秒体验区 | 欧美老妇与禽交 | 久久人人爽人人人人片 | 东京热男人av天堂 | 巨爆乳无码视频在线观看 | 又大又黄又粗又爽的免费视频 | 性生交大片免费看女人按摩摩 | 强伦人妻一区二区三区视频18 | 国产精品久久久久9999小说 | 无码吃奶揉捏奶头高潮视频 | 国产激情无码一区二区app | 久久99久久99精品中文字幕 | 亚洲爆乳大丰满无码专区 | 欧美xxxx黑人又粗又长 | 成人一在线视频日韩国产 | 麻豆国产人妻欲求不满谁演的 | 日本一卡2卡3卡四卡精品网站 | 日产精品高潮呻吟av久久 | 欧美日韩一区二区综合 | 3d动漫精品啪啪一区二区中 | 亚洲成av人影院在线观看 | 日日躁夜夜躁狠狠躁 | 免费观看激色视频网站 | 成年美女黄网站色大免费全看 | 国产农村乱对白刺激视频 | 无码人妻丰满熟妇区毛片18 | 精品国产国产综合精品 | 亚洲熟妇色xxxxx亚洲 | 人妻夜夜爽天天爽三区 | 性欧美熟妇videofreesex | 免费国产黄网站在线观看 | 国产午夜亚洲精品不卡 | 精品无码成人片一区二区98 | 无码人妻出轨黑人中文字幕 | 久在线观看福利视频 | 久9re热视频这里只有精品 | 熟女少妇在线视频播放 | 又黄又爽又色的视频 | 日产国产精品亚洲系列 | 亚洲一区二区三区 | 亚洲精品一区二区三区在线观看 | 野狼第一精品社区 | 精品无码一区二区三区爱欲 | 又大又硬又爽免费视频 | 色欲av亚洲一区无码少妇 | 国产乱人伦av在线无码 | 搡女人真爽免费视频大全 | 欧美日韩综合一区二区三区 | 亚洲成av人在线观看网址 | 精品国产麻豆免费人成网站 | 亚洲色成人中文字幕网站 | 丰满少妇女裸体bbw | 亚洲国产av精品一区二区蜜芽 | 色综合久久久无码网中文 | 性欧美牲交在线视频 | 亚洲成av人片在线观看无码不卡 | 国产精品久免费的黄网站 | 国内综合精品午夜久久资源 | 亚洲精品久久久久久久久久久 | 香港三级日本三级妇三级 | 国产精品美女久久久久av爽李琼 | 久久久久成人精品免费播放动漫 | 亚洲精品久久久久久久久久久 | 美女毛片一区二区三区四区 | 中国大陆精品视频xxxx | 国产成人一区二区三区在线观看 | 久久精品国产亚洲精品 | 精品国产乱码久久久久乱码 | 日日鲁鲁鲁夜夜爽爽狠狠 | 日日橹狠狠爱欧美视频 | 性做久久久久久久免费看 | 中文字幕乱妇无码av在线 | 日韩人妻无码中文字幕视频 | 荫蒂被男人添的好舒服爽免费视频 | 亚洲狠狠色丁香婷婷综合 | 秋霞特色aa大片 | 亚洲一区二区三区偷拍女厕 | 香港三级日本三级妇三级 | 婷婷色婷婷开心五月四房播播 | 欧美第一黄网免费网站 | 国产一区二区不卡老阿姨 | 强辱丰满人妻hd中文字幕 | 亚洲啪av永久无码精品放毛片 | 美女毛片一区二区三区四区 | 久久精品无码一区二区三区 | 久久国产36精品色熟妇 | 精品国产福利一区二区 | 97人妻精品一区二区三区 | 国产综合在线观看 | 亚洲色无码一区二区三区 | 日本一卡2卡3卡四卡精品网站 | 无码精品人妻一区二区三区av | 熟妇女人妻丰满少妇中文字幕 | 亚洲七七久久桃花影院 | 国产精品美女久久久久av爽李琼 | 少妇性l交大片欧洲热妇乱xxx | 久久aⅴ免费观看 | 久久综合香蕉国产蜜臀av | 强伦人妻一区二区三区视频18 | 中国大陆精品视频xxxx | 亚洲欧洲日本无在线码 | 无码精品国产va在线观看dvd | 欧美放荡的少妇 | 欧美三级a做爰在线观看 | 欧美性猛交内射兽交老熟妇 | 精品国产国产综合精品 | 狂野欧美性猛交免费视频 | 在线播放亚洲第一字幕 | 曰韩无码二三区中文字幕 | 国产精品久久久午夜夜伦鲁鲁 | 亚洲国产成人av在线观看 | 亚洲精品午夜国产va久久成人 | 国产精品igao视频网 | 国产精品美女久久久久av爽李琼 | 久久午夜无码鲁丝片午夜精品 | 三上悠亚人妻中文字幕在线 | 国产美女极度色诱视频www | 精品无码成人片一区二区98 | 天天拍夜夜添久久精品 | 免费网站看v片在线18禁无码 | 久久久国产一区二区三区 | 激情亚洲一区国产精品 | 精品国产一区av天美传媒 | 蜜桃av抽搐高潮一区二区 | 亚洲 激情 小说 另类 欧美 | 性欧美大战久久久久久久 | 久久久久av无码免费网 | 国产精品办公室沙发 | 日日摸夜夜摸狠狠摸婷婷 | 中文字幕乱码亚洲无线三区 | 中文毛片无遮挡高清免费 | 久久99精品国产麻豆蜜芽 | 国产 浪潮av性色四虎 | 成人亚洲精品久久久久 | 青青久在线视频免费观看 | 久久国产精品_国产精品 | 久久精品国产日本波多野结衣 | 亚洲精品一区三区三区在线观看 | 少妇久久久久久人妻无码 | 色婷婷综合中文久久一本 | 中文字幕乱码人妻无码久久 | 欧美三级不卡在线观看 | 国产农村妇女高潮大叫 | 天干天干啦夜天干天2017 | 国产精品久久久 | 久久久久av无码免费网 | 国产 精品 自在自线 | www国产精品内射老师 | 久久www免费人成人片 | 欧美高清在线精品一区 | 少妇人妻av毛片在线看 | 国产精品亚洲lv粉色 | 亚洲精品欧美二区三区中文字幕 | 精品无码av一区二区三区 | 亚洲欧美精品aaaaaa片 | 国产无遮挡又黄又爽免费视频 | 国产人妻精品一区二区三区不卡 | 国产成人综合在线女婷五月99播放 | 国产精品18久久久久久麻辣 | 无码人妻久久一区二区三区不卡 | 久久国产精品偷任你爽任你 | 无码中文字幕色专区 | 中文字幕无码免费久久99 | 18禁黄网站男男禁片免费观看 | 捆绑白丝粉色jk震动捧喷白浆 | 久久久久久亚洲精品a片成人 | 日日摸夜夜摸狠狠摸婷婷 | 色欲av亚洲一区无码少妇 | 久久久久国色av免费观看性色 | 久久国产36精品色熟妇 | 国产精品.xx视频.xxtv | 任你躁在线精品免费 | 欧美激情内射喷水高潮 | 97精品人妻一区二区三区香蕉 | 成人三级无码视频在线观看 | 5858s亚洲色大成网站www | 亚洲精品午夜无码电影网 | 99re在线播放 | aⅴ在线视频男人的天堂 | 亚洲精品一区二区三区在线 | 嫩b人妻精品一区二区三区 | 国产精品资源一区二区 | 国产在热线精品视频 | 无码国内精品人妻少妇 | 激情综合激情五月俺也去 | 人人超人人超碰超国产 | 亚洲第一网站男人都懂 | 国产精品国产自线拍免费软件 | 最新版天堂资源中文官网 | 国产精品美女久久久网av | 撕开奶罩揉吮奶头视频 | 国模大胆一区二区三区 | 日日碰狠狠躁久久躁蜜桃 | 日日橹狠狠爱欧美视频 | 无码人妻精品一区二区三区下载 | 人人爽人人澡人人人妻 | 欧美真人作爱免费视频 | 午夜精品久久久内射近拍高清 | 亚洲国产精品一区二区第一页 | 久久99精品久久久久久 | aⅴ在线视频男人的天堂 | 无码精品人妻一区二区三区av | 少妇无码吹潮 | 欧美高清在线精品一区 | 人人妻人人藻人人爽欧美一区 | 装睡被陌生人摸出水好爽 | 99er热精品视频 | 国产亚洲精品久久久久久国模美 | av无码电影一区二区三区 | 亚洲中文字幕成人无码 | 少妇人妻大乳在线视频 | 色欲人妻aaaaaaa无码 | 成人精品一区二区三区中文字幕 | 欧美性色19p | 色婷婷久久一区二区三区麻豆 | 成人无码视频在线观看网站 | 国产精品对白交换视频 | 又黄又爽又色的视频 | 亚洲精品一区二区三区四区五区 | 理论片87福利理论电影 | 丰满少妇熟乱xxxxx视频 | 国产精品久久久久久久影院 | 天天摸天天透天天添 | 中文字幕无码av激情不卡 | 国产在热线精品视频 | 国产精品毛多多水多 | 亚洲高清偷拍一区二区三区 | 亚洲一区二区观看播放 | 中文字幕乱码中文乱码51精品 | 国产在线精品一区二区高清不卡 | 麻豆md0077饥渴少妇 | 又大又黄又粗又爽的免费视频 | 中文字幕日韩精品一区二区三区 | 嫩b人妻精品一区二区三区 | 久久亚洲中文字幕无码 | 午夜精品久久久久久久久 | 日日碰狠狠丁香久燥 | 国产又粗又硬又大爽黄老大爷视 | 国产艳妇av在线观看果冻传媒 | 少妇高潮一区二区三区99 | 国产成人无码av在线影院 | 激情国产av做激情国产爱 | 少妇的肉体aa片免费 | 精品欧洲av无码一区二区三区 | 久久国产劲爆∧v内射 | 成人免费视频在线观看 | 亚洲熟悉妇女xxx妇女av | 国产精品丝袜黑色高跟鞋 | 女人被爽到呻吟gif动态图视看 | 亚洲国产精品久久久久久 | 成人片黄网站色大片免费观看 | 亚洲第一无码av无码专区 | 国产熟女一区二区三区四区五区 | 国产精品久久久久影院嫩草 | 蜜桃视频韩日免费播放 | 午夜免费福利小电影 | 无码人妻丰满熟妇区毛片18 | 中文字幕av日韩精品一区二区 | 狂野欧美性猛交免费视频 | 欧美人与禽猛交狂配 | 国产福利视频一区二区 | 丰满妇女强制高潮18xxxx | 未满小14洗澡无码视频网站 | 牛和人交xxxx欧美 | 国产精品久久久久无码av色戒 | 国产人妻精品一区二区三区 | 国产高清不卡无码视频 | 国精品人妻无码一区二区三区蜜柚 | 九九在线中文字幕无码 | 精品国偷自产在线视频 | 国产超碰人人爽人人做人人添 | 国产偷抇久久精品a片69 | 精品国精品国产自在久国产87 | 思思久久99热只有频精品66 | 粗大的内捧猛烈进出视频 | 欧美35页视频在线观看 | 中文字幕乱码中文乱码51精品 | 亚洲精品国产精品乱码视色 | 国产亚洲视频中文字幕97精品 | 少妇邻居内射在线 | √天堂资源地址中文在线 | 亚洲成色在线综合网站 | 天堂一区人妻无码 | 无码人妻出轨黑人中文字幕 | 未满小14洗澡无码视频网站 | 樱花草在线社区www | 国产精品人妻一区二区三区四 | 国产午夜精品一区二区三区嫩草 | 久久久久免费精品国产 | 麻豆md0077饥渴少妇 | 性欧美牲交在线视频 | 亚洲gv猛男gv无码男同 | 狂野欧美激情性xxxx | 无码吃奶揉捏奶头高潮视频 | 午夜理论片yy44880影院 | 国产成人亚洲综合无码 | 国产一区二区三区四区五区加勒比 | 日本肉体xxxx裸交 | 国产亚洲精品久久久久久国模美 | 国产激情无码一区二区 | 国産精品久久久久久久 | 图片小说视频一区二区 | 亚洲国产一区二区三区在线观看 | 欧美激情一区二区三区成人 | 国产高潮视频在线观看 | 成人精品天堂一区二区三区 | 精品偷拍一区二区三区在线看 | √天堂资源地址中文在线 | 色爱情人网站 | 欧美兽交xxxx×视频 | 特大黑人娇小亚洲女 | 欧美日韩一区二区免费视频 | 人妻少妇被猛烈进入中文字幕 | 久久久成人毛片无码 | 亚洲色成人中文字幕网站 | 扒开双腿吃奶呻吟做受视频 | 西西人体www44rt大胆高清 | 欧美怡红院免费全部视频 | 日本精品人妻无码免费大全 | 波多野结衣av在线观看 | 国内少妇偷人精品视频免费 | 爽爽影院免费观看 | 日日摸日日碰夜夜爽av | 久久久精品人妻久久影视 | 久久人人爽人人爽人人片av高清 | 亚洲国产精品久久久天堂 | 国内丰满熟女出轨videos | 又紧又大又爽精品一区二区 | 欧美放荡的少妇 | 女人被爽到呻吟gif动态图视看 | 精品水蜜桃久久久久久久 | 国产精品高潮呻吟av久久4虎 | 国产绳艺sm调教室论坛 | 亚洲熟妇色xxxxx欧美老妇y | 亚洲国精产品一二二线 | 国产欧美亚洲精品a | 欧美性生交活xxxxxdddd | 377p欧洲日本亚洲大胆 | 日本熟妇大屁股人妻 | 日韩精品成人一区二区三区 | 任你躁国产自任一区二区三区 | 日日鲁鲁鲁夜夜爽爽狠狠 | 自拍偷自拍亚洲精品10p | 国产激情综合五月久久 | 日本又色又爽又黄的a片18禁 | 网友自拍区视频精品 | 中文字幕乱妇无码av在线 | 亚洲国产精品毛片av不卡在线 | 人人妻人人澡人人爽欧美一区九九 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 国产特级毛片aaaaaa高潮流水 | 国产成人无码av片在线观看不卡 | 奇米影视888欧美在线观看 | 久久午夜无码鲁丝片 | 午夜理论片yy44880影院 | 国产一区二区三区影院 | 一本久久a久久精品vr综合 | 国产做国产爱免费视频 | 精品无码国产一区二区三区av | 国产成人精品优优av | a片在线免费观看 | 蜜桃臀无码内射一区二区三区 | 精品久久久无码中文字幕 | 国产精品va在线播放 | 国产乡下妇女做爰 | 国产成人无码a区在线观看视频app | 亚洲国产精品毛片av不卡在线 | 久久精品中文字幕大胸 | 强开小婷嫩苞又嫩又紧视频 | 红桃av一区二区三区在线无码av | 亚洲熟妇色xxxxx亚洲 | 亚洲s码欧洲m码国产av | 蜜臀aⅴ国产精品久久久国产老师 | 国产国语老龄妇女a片 | 97无码免费人妻超级碰碰夜夜 | 欧美老妇交乱视频在线观看 | 国产人妻久久精品二区三区老狼 | 噜噜噜亚洲色成人网站 | 午夜精品一区二区三区在线观看 | 少妇人妻偷人精品无码视频 | 夜夜高潮次次欢爽av女 | 成人三级无码视频在线观看 | 亚洲s色大片在线观看 | 国产亚洲日韩欧美另类第八页 | 亚洲区欧美区综合区自拍区 | 性开放的女人aaa片 | 日日摸日日碰夜夜爽av | 亚洲 日韩 欧美 成人 在线观看 | 国内精品久久毛片一区二区 | 国内少妇偷人精品视频 | 99精品久久毛片a片 | 国产成人无码区免费内射一片色欲 | 日韩精品无码一本二本三本色 | 熟妇激情内射com | 熟女少妇人妻中文字幕 | 免费网站看v片在线18禁无码 | 蜜桃av抽搐高潮一区二区 | 4hu四虎永久在线观看 | 亚洲色偷偷男人的天堂 | 人妻少妇精品无码专区二区 | 亚洲码国产精品高潮在线 | 日韩精品a片一区二区三区妖精 | 亚洲成熟女人毛毛耸耸多 | 中文字幕av日韩精品一区二区 | 蜜臀av无码人妻精品 | 久久久国产一区二区三区 | 麻豆蜜桃av蜜臀av色欲av | 亚洲成a人一区二区三区 | 亚洲 另类 在线 欧美 制服 | 国产绳艺sm调教室论坛 | 亚洲中文字幕在线无码一区二区 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 亚洲爆乳大丰满无码专区 | 狠狠cao日日穞夜夜穞av | 在线播放亚洲第一字幕 | 欧美成人家庭影院 | 丝袜人妻一区二区三区 | 亚洲区小说区激情区图片区 | 国产精品资源一区二区 | 国产色在线 | 国产 | 久久久久久av无码免费看大片 | 人人妻在人人 | 99久久精品日本一区二区免费 | 台湾无码一区二区 | 双乳奶水饱满少妇呻吟 | 亚洲日韩精品欧美一区二区 | 久久久久久a亚洲欧洲av冫 | 亚洲小说春色综合另类 | 日韩少妇白浆无码系列 | 国产精品嫩草久久久久 | 久久99久久99精品中文字幕 | aa片在线观看视频在线播放 | 人妻熟女一区 | 色婷婷综合激情综在线播放 | 狠狠噜狠狠狠狠丁香五月 | 99久久久国产精品无码免费 | 国产精品嫩草久久久久 | 亚洲欧美综合区丁香五月小说 | 色欲人妻aaaaaaa无码 | 人人澡人人透人人爽 | 婷婷五月综合激情中文字幕 | 色一情一乱一伦一区二区三欧美 | yw尤物av无码国产在线观看 | 国产亚洲精品久久久ai换 | 日本又色又爽又黄的a片18禁 | 日本免费一区二区三区最新 | 国产精品对白交换视频 | 午夜福利一区二区三区在线观看 | 一本久久a久久精品亚洲 | 亚洲国产欧美日韩精品一区二区三区 | 色五月丁香五月综合五月 | 成人无码影片精品久久久 | 水蜜桃色314在线观看 | 日产国产精品亚洲系列 | 亚洲色欲色欲欲www在线 | 久久综合狠狠综合久久综合88 | 永久免费观看美女裸体的网站 | 色综合久久久无码网中文 | 国产香蕉尹人综合在线观看 | 亚洲日韩乱码中文无码蜜桃臀网站 | 十八禁视频网站在线观看 | 久久99国产综合精品 | 欧美三级不卡在线观看 | 黑人巨大精品欧美一区二区 | √8天堂资源地址中文在线 | 国产精品内射视频免费 | 精品亚洲韩国一区二区三区 | 国产av剧情md精品麻豆 | 中文字幕无线码 | 欧美老熟妇乱xxxxx | 日本又色又爽又黄的a片18禁 | 国产精品办公室沙发 | 欧美亚洲日韩国产人成在线播放 | 国产亚洲人成a在线v网站 | 久久精品视频在线看15 | 亚洲乱码中文字幕在线 | 人妻少妇精品久久 | 国产舌乚八伦偷品w中 | 久久久久se色偷偷亚洲精品av | 99久久久无码国产精品免费 | 久久熟妇人妻午夜寂寞影院 | 亚洲色www成人永久网址 | 国产成人无码av片在线观看不卡 | 婷婷色婷婷开心五月四房播播 | 性色欲网站人妻丰满中文久久不卡 | 天堂久久天堂av色综合 | 久久久精品456亚洲影院 | 97夜夜澡人人双人人人喊 | 久久国产自偷自偷免费一区调 | 俺去俺来也www色官网 | 国产高清av在线播放 | 在线观看国产一区二区三区 | 六月丁香婷婷色狠狠久久 | 精品国产乱码久久久久乱码 | 国产亚av手机在线观看 | 国产成人无码a区在线观看视频app | 无码一区二区三区在线 | 精品无码av一区二区三区 | 久久五月精品中文字幕 | 亚洲经典千人经典日产 | 婷婷六月久久综合丁香 | 国产真实乱对白精彩久久 | 久热国产vs视频在线观看 | 国产香蕉尹人视频在线 | av小次郎收藏 | 国产成人精品久久亚洲高清不卡 | 免费播放一区二区三区 | 水蜜桃色314在线观看 | 国产真实伦对白全集 | 99re在线播放 | 亚洲日本一区二区三区在线 | 国产成人精品无码播放 | 人人妻人人澡人人爽精品欧美 | 亚洲精品国产品国语在线观看 | 久久久久人妻一区精品色欧美 | 精品一区二区不卡无码av | 国产福利视频一区二区 | 5858s亚洲色大成网站www | 久久国语露脸国产精品电影 | 日本乱偷人妻中文字幕 | 中文字幕乱码人妻二区三区 | 丰满人妻一区二区三区免费视频 | 捆绑白丝粉色jk震动捧喷白浆 | 自拍偷自拍亚洲精品被多人伦好爽 | www国产亚洲精品久久久日本 | 丰满人妻翻云覆雨呻吟视频 | 国产精品igao视频网 | 成熟人妻av无码专区 | 国产亚洲精品久久久久久久久动漫 | 最新国产乱人伦偷精品免费网站 | 国精产品一区二区三区 | 久久国产劲爆∧v内射 | 日本欧美一区二区三区乱码 | 国产人妻人伦精品1国产丝袜 | 小泽玛莉亚一区二区视频在线 | 波多野结衣 黑人 | 色婷婷欧美在线播放内射 | 在线a亚洲视频播放在线观看 | 亚洲一区av无码专区在线观看 | 色欲人妻aaaaaaa无码 | 精品无码一区二区三区爱欲 | 国产乱人偷精品人妻a片 | 一本无码人妻在中文字幕免费 | 亚洲成a人一区二区三区 | 国产亚洲精品久久久久久大师 | 99精品国产综合久久久久五月天 | 欧洲vodafone精品性 | 在线 国产 欧美 亚洲 天堂 | 欧美人与动性行为视频 | 成人亚洲精品久久久久软件 | 一二三四在线观看免费视频 | 真人与拘做受免费视频一 | 一本色道婷婷久久欧美 | 亚洲s色大片在线观看 | 亚洲中文字幕在线观看 | 国产内射爽爽大片视频社区在线 | 国产在线aaa片一区二区99 | 日本熟妇大屁股人妻 | 在线精品国产一区二区三区 | 天天爽夜夜爽夜夜爽 | 国产97在线 | 亚洲 | 扒开双腿疯狂进出爽爽爽视频 | 欧美日韩综合一区二区三区 | 久久综合激激的五月天 | 国产激情无码一区二区app | 国产真实乱对白精彩久久 | 精品 日韩 国产 欧美 视频 | 日日天日日夜日日摸 | 日韩精品久久久肉伦网站 | 久久久av男人的天堂 | 欧美三级不卡在线观看 | 国产精品a成v人在线播放 | 亚欧洲精品在线视频免费观看 | 国精产品一区二区三区 | 欧美兽交xxxx×视频 | 青青青手机频在线观看 | 国产精品无码成人午夜电影 | 永久免费精品精品永久-夜色 | 天海翼激烈高潮到腰振不止 | 无码中文字幕色专区 | 久久久av男人的天堂 | 风流少妇按摩来高潮 | 国产一区二区三区日韩精品 | 成人性做爰aaa片免费看不忠 | 小泽玛莉亚一区二区视频在线 | 无码福利日韩神码福利片 | 中文字幕无码人妻少妇免费 | 精品少妇爆乳无码av无码专区 | 在线播放无码字幕亚洲 | 狂野欧美激情性xxxx | 99er热精品视频 | 2019nv天堂香蕉在线观看 | 国产精品久久久久久久影院 | 最新版天堂资源中文官网 | 久久人人爽人人人人片 | 曰韩少妇内射免费播放 | 久久人人爽人人人人片 | 麻豆果冻传媒2021精品传媒一区下载 | 欧洲美熟女乱又伦 | 国产精品无码一区二区桃花视频 | 六月丁香婷婷色狠狠久久 | 小泽玛莉亚一区二区视频在线 | 亚洲国产高清在线观看视频 | 爱做久久久久久 | 一本大道久久东京热无码av | 日本护士xxxxhd少妇 | 啦啦啦www在线观看免费视频 | 亚洲欧洲日本综合aⅴ在线 | 国产精品久久久 | 久久久久免费精品国产 | 99国产精品白浆在线观看免费 | 又粗又大又硬毛片免费看 | 欧美性生交xxxxx久久久 | 日日麻批免费40分钟无码 | 欧美成人高清在线播放 | 精品无码成人片一区二区98 | 国产午夜福利100集发布 | 国産精品久久久久久久 | 粉嫩少妇内射浓精videos | 色综合久久中文娱乐网 | 国产电影无码午夜在线播放 | 在线欧美精品一区二区三区 | 色噜噜亚洲男人的天堂 | 国产成人综合在线女婷五月99播放 | 十八禁视频网站在线观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 亚洲狠狠婷婷综合久久 | 扒开双腿疯狂进出爽爽爽视频 | 强奷人妻日本中文字幕 | 久久精品无码一区二区三区 | 欧美变态另类xxxx | 水蜜桃亚洲一二三四在线 | 亚洲娇小与黑人巨大交 | 人妻有码中文字幕在线 | а天堂中文在线官网 | 成人三级无码视频在线观看 | 中文精品久久久久人妻不卡 | 精品 日韩 国产 欧美 视频 | 亚洲日韩一区二区三区 | 欧美国产日产一区二区 | 强辱丰满人妻hd中文字幕 | 亚洲精品久久久久久一区二区 | 国产偷自视频区视频 | 久久久久成人片免费观看蜜芽 | 少妇高潮喷潮久久久影院 | 亚洲中文无码av永久不收费 | 77777熟女视频在线观看 а天堂中文在线官网 | 免费人成在线视频无码 | 亚洲成av人在线观看网址 | 国产精品久久久久影院嫩草 | 久久人人爽人人爽人人片ⅴ | 97夜夜澡人人爽人人喊中国片 | av小次郎收藏 | 国产精品嫩草久久久久 | 欧美日韩亚洲国产精品 | 国产精品久久福利网站 | 少妇性俱乐部纵欲狂欢电影 | 疯狂三人交性欧美 | 伊在人天堂亚洲香蕉精品区 | 亚洲国产欧美日韩精品一区二区三区 | 日本丰满熟妇videos | 欧美变态另类xxxx | 中文毛片无遮挡高清免费 | 欧美精品免费观看二区 | 亲嘴扒胸摸屁股激烈网站 | 日韩 欧美 动漫 国产 制服 | 又大又黄又粗又爽的免费视频 | 老熟妇仑乱视频一区二区 | 亚洲成av人影院在线观看 | 日韩视频 中文字幕 视频一区 | 日日摸夜夜摸狠狠摸婷婷 | 国产人妻大战黑人第1集 | 亚洲色欲久久久综合网东京热 | 精品人妻中文字幕有码在线 | 图片小说视频一区二区 | 在线播放无码字幕亚洲 | 久久亚洲中文字幕精品一区 | 丰满少妇熟乱xxxxx视频 | 亚洲乱码中文字幕在线 | 久久久久久av无码免费看大片 | 激情五月综合色婷婷一区二区 | 婷婷五月综合激情中文字幕 | 久久午夜无码鲁丝片午夜精品 | 中文字幕乱码中文乱码51精品 | 中文字幕中文有码在线 | 亚洲一区av无码专区在线观看 | 国产无套内射久久久国产 | 亚洲一区二区三区四区 | 狠狠噜狠狠狠狠丁香五月 | 99久久99久久免费精品蜜桃 | 国产精品无码一区二区桃花视频 | 动漫av一区二区在线观看 | 成人精品视频一区二区三区尤物 | 国产一区二区三区日韩精品 | 国产精品99久久精品爆乳 | 无码午夜成人1000部免费视频 | 国产精品久久久av久久久 | 老太婆性杂交欧美肥老太 | 无码国产乱人伦偷精品视频 | 国产无遮挡吃胸膜奶免费看 | 无码任你躁久久久久久久 | 久久综合给合久久狠狠狠97色 | 精品人妻av区 | 国产两女互慰高潮视频在线观看 | 人妻与老人中文字幕 | 四虎影视成人永久免费观看视频 | 亚洲欧美国产精品专区久久 | 中文字幕乱码亚洲无线三区 | 国产精品久久福利网站 | 久久午夜无码鲁丝片午夜精品 | 天天燥日日燥 | 波多野结衣aⅴ在线 | 99久久精品日本一区二区免费 | v一区无码内射国产 | 蜜桃臀无码内射一区二区三区 | 特级做a爰片毛片免费69 | 亚洲娇小与黑人巨大交 | 999久久久国产精品消防器材 | 国内精品久久毛片一区二区 | 清纯唯美经典一区二区 | 国产成人无码区免费内射一片色欲 | 国产人妻精品一区二区三区不卡 | 中文字幕无码热在线视频 | 中文字幕乱妇无码av在线 | 亚洲人亚洲人成电影网站色 | 久久久中文字幕日本无吗 | 台湾无码一区二区 | 亚洲精品综合五月久久小说 | 女高中生第一次破苞av | 乌克兰少妇性做爰 | 久久久久久久女国产乱让韩 | 国内精品九九久久久精品 | 强辱丰满人妻hd中文字幕 | 久久久中文久久久无码 | 久久久久成人精品免费播放动漫 | 7777奇米四色成人眼影 | 天天躁日日躁狠狠躁免费麻豆 | 天天拍夜夜添久久精品大 | 双乳奶水饱满少妇呻吟 | 亚洲精品一区二区三区在线观看 | ass日本丰满熟妇pics | 亚洲国产日韩a在线播放 | 少妇人妻大乳在线视频 | 日韩成人一区二区三区在线观看 | 久久亚洲日韩精品一区二区三区 | 国产精品久久久 | 一本久道久久综合狠狠爱 | 日本一区二区三区免费高清 | 国产舌乚八伦偷品w中 | 国产精品久久久久久亚洲毛片 | 亚洲综合无码久久精品综合 | 又大又黄又粗又爽的免费视频 | 日本免费一区二区三区最新 | 夜夜高潮次次欢爽av女 | 亚洲日本在线电影 | 在线a亚洲视频播放在线观看 | 久久精品一区二区三区四区 | 中文字幕久久久久人妻 | 亚洲精品一区二区三区在线 | 无码精品国产va在线观看dvd | av无码不卡在线观看免费 | 青春草在线视频免费观看 | 午夜熟女插插xx免费视频 | 精品欧洲av无码一区二区三区 | 久久午夜夜伦鲁鲁片无码免费 | 丁香啪啪综合成人亚洲 | 在线观看国产一区二区三区 | 亚洲中文字幕无码中文字在线 | а√资源新版在线天堂 | 亚洲国产精品成人久久蜜臀 | 久久伊人色av天堂九九小黄鸭 | 国产成人无码av片在线观看不卡 | 国产精品美女久久久久av爽李琼 | 欧美野外疯狂做受xxxx高潮 | 国产精品高潮呻吟av久久 | 久久99国产综合精品 | 久久久婷婷五月亚洲97号色 | 国产免费久久精品国产传媒 | 少妇厨房愉情理9仑片视频 | 日韩精品一区二区av在线 | 国产精品久久国产三级国 | 久久久久人妻一区精品色欧美 | 国产精品久久国产精品99 | 蜜臀aⅴ国产精品久久久国产老师 | 成人试看120秒体验区 | 伊人色综合久久天天小片 | 又大又黄又粗又爽的免费视频 | 樱花草在线播放免费中文 | 在线 国产 欧美 亚洲 天堂 | 日本熟妇大屁股人妻 | 亚洲啪av永久无码精品放毛片 | 日本一卡2卡3卡四卡精品网站 | 伊人久久大香线蕉av一区二区 | 欧美丰满少妇xxxx性 | 无码人妻出轨黑人中文字幕 | 亚洲精品一区三区三区在线观看 | 亚洲人成网站免费播放 | 日韩精品无码一本二本三本色 | 牛和人交xxxx欧美 | av小次郎收藏 | 国产亚洲精品久久久久久久 | 四虎国产精品免费久久 | 纯爱无遮挡h肉动漫在线播放 | 玩弄人妻少妇500系列视频 | 亚洲aⅴ无码成人网站国产app | 亚洲 日韩 欧美 成人 在线观看 | 日本乱人伦片中文三区 | 亚欧洲精品在线视频免费观看 | 欧美三级不卡在线观看 | 在线观看国产午夜福利片 | 波多野结衣av一区二区全免费观看 | 无码av中文字幕免费放 | 成人精品视频一区二区 | 久久久久久久女国产乱让韩 | 日本精品久久久久中文字幕 | 真人与拘做受免费视频一 | 日欧一片内射va在线影院 | 日本免费一区二区三区最新 | 蜜桃视频韩日免费播放 | 国产亚av手机在线观看 | 未满成年国产在线观看 | 精品乱码久久久久久久 | 欧美日本精品一区二区三区 | 又大又黄又粗又爽的免费视频 | 免费无码av一区二区 | 高清无码午夜福利视频 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 亚洲码国产精品高潮在线 | 鲁鲁鲁爽爽爽在线视频观看 | 欧美日韩在线亚洲综合国产人 | 久久国产劲爆∧v内射 | 精品人妻av区 | 国产无套粉嫩白浆在线 | 无码中文字幕色专区 | 双乳奶水饱满少妇呻吟 | 日韩av激情在线观看 | 久久久婷婷五月亚洲97号色 | 国产电影无码午夜在线播放 | 国产两女互慰高潮视频在线观看 | 18精品久久久无码午夜福利 | 久久人人爽人人爽人人片ⅴ | 青草青草久热国产精品 | 日韩精品无码一区二区中文字幕 | 特黄特色大片免费播放器图片 | 四虎影视成人永久免费观看视频 | 人妻与老人中文字幕 | 免费国产黄网站在线观看 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 人人妻人人澡人人爽人人精品浪潮 | 欧洲极品少妇 | 中文字幕av无码一区二区三区电影 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 欧美人与物videos另类 | 狠狠色丁香久久婷婷综合五月 | 2020久久香蕉国产线看观看 | 国产成人无码av片在线观看不卡 | 少妇久久久久久人妻无码 | 久久久久人妻一区精品色欧美 | 色婷婷香蕉在线一区二区 | 国产精品亚洲lv粉色 | 久久久久亚洲精品中文字幕 | 婷婷六月久久综合丁香 | 久久久久av无码免费网 | 欧美日韩一区二区三区自拍 | 午夜性刺激在线视频免费 | 精品无码国产一区二区三区av | 久激情内射婷内射蜜桃人妖 | 精品人妻中文字幕有码在线 | 国产激情无码一区二区app | 乱码午夜-极国产极内射 |