C#二次开发ArcGIS查询功能.docx

上传人:b****2 文档编号:17925319 上传时间:2023-08-05 格式:DOCX 页数:58 大小:593.08KB
下载 相关 举报
C#二次开发ArcGIS查询功能.docx_第1页
第1页 / 共58页
C#二次开发ArcGIS查询功能.docx_第2页
第2页 / 共58页
C#二次开发ArcGIS查询功能.docx_第3页
第3页 / 共58页
C#二次开发ArcGIS查询功能.docx_第4页
第4页 / 共58页
C#二次开发ArcGIS查询功能.docx_第5页
第5页 / 共58页
C#二次开发ArcGIS查询功能.docx_第6页
第6页 / 共58页
C#二次开发ArcGIS查询功能.docx_第7页
第7页 / 共58页
C#二次开发ArcGIS查询功能.docx_第8页
第8页 / 共58页
C#二次开发ArcGIS查询功能.docx_第9页
第9页 / 共58页
C#二次开发ArcGIS查询功能.docx_第10页
第10页 / 共58页
C#二次开发ArcGIS查询功能.docx_第11页
第11页 / 共58页
C#二次开发ArcGIS查询功能.docx_第12页
第12页 / 共58页
C#二次开发ArcGIS查询功能.docx_第13页
第13页 / 共58页
C#二次开发ArcGIS查询功能.docx_第14页
第14页 / 共58页
C#二次开发ArcGIS查询功能.docx_第15页
第15页 / 共58页
C#二次开发ArcGIS查询功能.docx_第16页
第16页 / 共58页
C#二次开发ArcGIS查询功能.docx_第17页
第17页 / 共58页
C#二次开发ArcGIS查询功能.docx_第18页
第18页 / 共58页
C#二次开发ArcGIS查询功能.docx_第19页
第19页 / 共58页
C#二次开发ArcGIS查询功能.docx_第20页
第20页 / 共58页
亲,该文档总共58页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

C#二次开发ArcGIS查询功能.docx

《C#二次开发ArcGIS查询功能.docx》由会员分享,可在线阅读,更多相关《C#二次开发ArcGIS查询功能.docx(58页珍藏版)》请在冰点文库上搜索。

C#二次开发ArcGIS查询功能.docx

C#二次开发ArcGIS查询功能

-CAL-FENGHAI.-(YICAI)-CompanyOne1

 

C#二次开发ArcGIS查询功能

一、ArcGIS简介

ArcGIS是美国ESRI(EnvironmentalSystemsResearchInstitute,Inc.美国环境系统研究所公司)推出的一条为不同需求层次用户提供的全面的、可伸缩的GIS产品线和解决方案。

ESRI是GIS领域的拓荒者和领导者,而ArcGIS也代表了当前GIS行业最高的技术水平。

ArcGIS是一个可伸缩的GIS平台,可以运行在桌面端、服务器端和移动设备上。

它包含了一套建设完整GIS系统的应用软件,这些软件可以互相独立或集成配合使用,为不同需求的用户提供完善的解决之道。

ArcGIS是基于一套共享的GIS组件开发实现的,这套组件被命名为ArcObjects,它包含了大量可编程组件,实现了ArcGIS的全部功能。

因此,ArcObjects可以被认为是ArcGIS产品的核心,熟悉ArcObjects的过程同时也是熟悉ArcGISEngine的过程。

二、ArcGIS开发方法介绍

Gis的开发方法有三种,即独立开发,宿主型二次开发,基于gis组件的二次开发,其中独立开发为底层开发,不依赖于任何gis工具软件,开发难度太大,后两者是基于一种软件的二次开发,这样的二次开发则相对较简单,他的好处也是显而易见的。

Esri公司推出的ArcGIS产品不仅仅包含基础平台软件,也包含供用户二次开发的组件,那么这些组件也包含C/S、B/S、移动端的。

C/S架构主要是应用于局域网方面,一般是安装开发软件,一般情况下机器都不连互联网,主要处理数据编辑、数据入库、地图整饰等对机器性能要求比较高。

B/S架构主要应用于局域网或者互联网,一般情况下使用浏览器,主要是进行数据查询、分析等。

ArcGIS Engine开发工具包是一个基于组件的软件开发产品,用于建立和部署自定义GIS和制图应用程序。

ArcGIS Engine开发工具包不是一个终端用户产品,而是一个应用程序开发人员的工具包。

可以用ArcGIS Engine开发工具包建立基本的地图浏览器或综合、动态的GIS编辑工具。

使用ArcGIS Engine开发工具包,开发人员在建立定制的地图接口方面具有前所未有的灵活性。

开发人员可以使用几个API中的任何一个来建立独一无二的应用程序,或者将ArcGIS Engine组件与其他软件组件组合起来实现地图与用户管理信息之间的协同关系。

三、数据库设计

1、数据库的建立

通过ArcCatalog创建个人地理数据库>>要素集>>要素类>>编辑属性

2、数据表的设计

(1)房屋

字段名称

字段解释

类型

长度

备注

ID

ID号

Long

Name

名称

Char

20

Owner

所有者

Char

20

Layers

层数

Integer

20

Material

材质

Char

20

Add

地址

Char

40

BuildArea

建筑面积

Float

Remark

备注

Char

40

(2)道路

字段名称

字段解释

类型

长度

备注

ID

ID号

Long

Name

名称

Char

20

Material

铺设材料

Char

20

Width

道路宽度

Float

Remark

备注

Char

40

等等

四、地理数据入库(地图扫描矢量化方法介绍)

1、打开ArcMap,添加“影像配准”工具栏。

把需要进行配准的影像—“校内平面图测绘14级.dwg”添加到ArcMap中,会发现“影像配准”工具栏中的工具被激活。

2、在“影像配准”工具栏上,点击“添加控制点(add control point)”按钮。

使用该工具在扫描图上精确到找一个控制点点击,然后鼠标右击输入该点实际的坐标位置。

用相同的方法,在影像上增加多个控制点(大于3个),输入它们的实际坐标。

点击“影像配准”工具栏上的“查看链接表(view link table)”按钮。

对于误差较大的控制点,可以删除然后重新采集。

3、打开ArcCatalog.在指定目录下,鼠标右击,在“新建”中,选择“个人Geodatabase”。

并修改该Geodatabase数据库的名称。

右击新建要素集并为要素集设置投影坐标系。

右击新建要素类,选择要素类型,并为要素命名,添加要素属性字段“Name”等。

这样便建好了一个点,线或面要素

4、在ArcMap中编辑工作条上点击开始编辑,这时会弹出来一个窗口选择要素,然后在已经配准后的图像上选择相应的要素类型一一绘制,右击图层控件上的某个要素图层打开属性表可以编辑属性。

5、将矢量化好后的图层导出为(*.mxd)文件。

五、功能设计(流程图)

六、程序运行界面介绍

1、用户登录界面

2、主程序界面

3、属性查询界面

4、三角网及泰森多边形

七、程序解析说明

1、用户登录界面程序解析说明

用户登录设计思路:

(1)用户输入用户名和密码,用户名不能为空,密码不能为空。

(2)密码在五分钟之内连续输错三次,用户名被锁定,30分钟后才能再次登录。

(3)若密码输错次数小于3次,则从最后一次输错时刻算起,五分钟之后用户登录错误次数归零。

(4)用户注册,数据库中检索此用户,若用户存在则提示用户名已存在,反之注册成功,需重新登录。

重点代码解析:

使用参数化查询避免注入漏洞攻击,用户信息存储在SQLServer数据库的T_User表中

//只用来执行查询结果较少的sql

publicstaticDataSetExecuteDataSet(stringsql,paramsSqlParameter[]parameters)

{

using(SqlConnectionconn=newSqlConnection(ConStr))

{

conn.Open();

using(SqlCommandcmd=conn.CreateCommand())

{

cmd.CommandText=sql;

cmd.Parameters.AddRange(parameters);

//SqlDataAdapter如同一个适配器,过渡桥梁的作用

SqlDataAdapteradapter=newSqlDataAdapter(cmd);

DataSetdataset=newDataSet();

adapter.Fill(dataset);

returndataset;

}

}

}

当用户输错三次以上并且时间少于30分钟时不允许登陆,TimeSpants=DateTime.Now-date;用于存储间隔时间

if(errortimes>=3)

{

DateTimedate=(DateTime)row["Lock"];

TimeSpants=DateTime.Now-date;

if(ts.TotalMinutes<=30)

{

MessageBox.Show(@"输入错误次数太多,用户已被锁定,请于30分钟后再登陆,剩余时间

"+(30-ts.TotalMinutes).ToString("0")+"分钟","错误提示",MessageBoxButtons.OK,MessageBoxIcon.Error);

return;

}

else

{

//输错三次后30分钟后更新ErorrTimes=0

SqlHelper.NonQuery(@"UpdateT_UsersetErorrTimes=0whereId=@id",

newSqlParameter("@id",id));

}

}

3、若密码输错次数小于3次,则从最后一次输错时刻算起,五分钟之后用户登录错误次数归零即UpdateT_UsersetErorrTimes=1whereId=@id

TimeSpants=DateTime.Now-Convert.ToDateTime(date);

if(ts.TotalMinutes>5)

{

SqlHelper.NonQuery(@"UpdateT_UsersetErorrTimes=1whereId=@id",

newSqlParameter("@id",id));

}

2、属性查询程序解析说明

重点代码解析:

(1)进入属性查询界面的代码:

通过AttributeQueryForm类的构造函数来存储地图的数据和绑定DataGridView的数据源

AttributeQueryFormattributequery=newAttributeQueryForm(this.axMapControl1,this.dataGridView1);attributequery.ShowDialog();

(2)从主程序axMapControl传值过来的地图数据存储在privateAxMapControlmMapControl;并且在属性查询窗体的ComboBox组合控件cboLayer中添加各个图层名

//图层名称加入cboLayer

this.cboLayer.Items.Add(strLayerName);

通过get_Layer(cboLayer.SelectedIndex)获取选中图层,并将每个图层的字段名显示在名为cboField的ComboBox控件。

strFldName=pFeatureClass.Fields.get_Field(i).Name;

//图层名称加入cboField

this.cboField.Items.Add(strFldName);

(3)属性查询中需要认识学习接口的相关知识,接口是一种规范、功能。

在属性查询中我们需要用到IQueryFilter接口,该接口通过WhereClause属性来获取查询数据,类似于SQL中的where语句。

然后再通过图层的Search方法基于查询条件返回要素游标pFeatureCursor。

如下图,pFeatureCursor指针一开始指向第0层,每调用一下NextFeature()方法,指针就往下移动一格直到指向null

代码示例:

//定义图层,要素游标,查询过滤器,要素

IFeatureLayerpFeatureLayer;

IFeatureCursorpFeatureCursor;

IQueryFilterpQueryFilter;

IFeatureSelectionpFeatureSelection;

IActiveViewactiveview;

IFeaturepFeature;

//获取图层

pFeatureLayer=this.mMapControl.Map.get_Layer(GetLayerindexbyName(cboLayer.Text))asIFeatureLayer;

//如果图层名称不是cboLayer.Text,程序退出

if(pFeatureLayer.Name!

=cboLayer.Text)

return;

//清除上次查询结果

this.mMapControl.Map.ClearSelection();

activeview=this.mMapControl.MapasIActiveView;

//pQueryFilter的实例化

pQueryFilter=newQueryFilterClass();

//设置查询过滤条件

pQueryFilter.WhereClause=""+cboField.Text+"='"+txtValue.Text+"'";

//基于查询条件创建指针并回收

pFeatureCursor=pFeatureLayer.Search(pQueryFilter,true);

//获取查询到的要素

然后再调用DisplayToDataGridDAL类中的方法,将查询出来的要素字段值显示在DataGridView中,DisplayToDataGridDAL类是自己写的一个类(代码见附录)

代码示例:

DisplayToDataGridDAL.Dataview(pFeatureCursor,dataGrid,pFeatureLayer);

高亮并居中显示选中的要素:

activeview.Extent=pFeature.Shape.Envelope;

activeview.Refresh();

3、自定义控件命令解析

以下讲述ArcEngine自定义开发的一些控件命令,如居中放大,居中缩小,拉框放大,拉框缩小,漫游,显示全图等。

基于BaseCommand的功能实现与Button的功能类似,是当鼠标点击按钮的时候,MapControl控件会对其中的命令做出相应响应而无需额外的操作,如ArcMap中的居中放大FixedZoomIn,居中缩小FixedZoomOut,全图FullExtent等。

对于BaseTool来说,点击该功能之后,只是开启一个交互的过程,需要用户再用鼠标、键盘等对地图做进一步交互式的操作,MapControl控件才会予以相应,如ArcMap中的拉框放大ZoomIn、拉框缩小ZoomOut、漫游Pan等。

以FixedZoomIn为例,双击解决方案资源管理器中的FixedZoomIn.cs项,进入该类的代码编写界面。

加入引用“ESRI.ArcGIS.Geometry”,并在该类的最上方添加如下代码:

publicoverridevoidOnClick()

{

//TODO:

AddFixedZoomIn.OnClickimplementation

//获取当前视图范围

IActiveViewpActiveView=m_hookHelper.ActiveView;

IEnvelopepEnvelope=pActiveView.Extent;

//扩大视图范围并刷新视图

pEnvelope.Expand(0.5,0.5,true);

pActiveView.Extent=pEnvelope;

pActiveView.Refresh();

}

在主程序代码中还添加了一个全局变量mTool,以确定选择的是哪个控件命令命令

privatestringmTool;

privatevoidmenuFixedZoomIn_Click(objectsender,EventArgse)

{

//声明与初始化

FixedZoomInfixedZoomin=newFixedZoomIn();

//与MapControl关联

fixedZoomin.OnCreate(this.axMapControl1.Object);

fixedZoomin.OnClick();

}

4、三角网及泰森多边形构建解析

首先在Form窗体上加一个PictureBox控件,在PictureBox的MouseDown事件下通过每次点击获取点的坐标e.X,e.Y

privatevoidpicMap_MouseDown(objectsender,MouseEventArgse)

{

Graphicsg=((PictureBox)sender).CreateGraphics();

g.FillEllipse(Brushes.Black,e.X,e.Y,5,5);

Pointpt=newPoint(e.X,e.Y);

myPoints.Add(pt);

g.Dispose();

}

三角网的构建采用逐点插入法,首先对在鼠标单击事件下获取的点集进行排序,排序时X坐标从小到大排列,若X坐标相同则Y坐标从小到大排列。

构建一个可以包含所有点集的超级三角形,并将超级三角形的三个顶点存入Triangle表中。

从点集中取点判断点是否在三角形内,若点在三角形内,则将该三角形三边存入边列表中,若并从三角形列表中删除该三角形,如此循环,遍历点集里所有的点。

最后删除与超级三角形有共同顶点的三角形及凹边界处三角形

重点代码示例:

if(myPoints.Count<=0)

return;

else

//对点集进行排序,先按X坐标从大到小排序

//X坐标相同的按Y坐标从大到小排序

myPoints=SortPoints(myPoints);

//获得超级三角形

SuperTriangle(myPoints);

inti=0;

while(i

{

Pointpt=myPoints[i];

List>edjest=newList>();

intj=0;

while(triangle.Count!

=0&&triangle.Count-1>=j)

{

boolflag=true;

Listmycircle=Circle(triangle,j);

Pointcenter=(Point)mycircle[0];

doubleradius=(double)mycircle[1];

if(pt.X>(center.X+radius))

{

flag=true;

}

elseif(Inside(pt,mycircle))

{

//edjest=Addnew(traingle,j);

List>ed=Addnew(triangle,j);

edjest.Add(ed[0]);

edjest.Add(ed[1]);

edjest.Add(ed[2]);

triangle.RemoveAt(j);

flag=false;

}

if(flag)

j++;

}

//删除重复的边

edjest=Delete(edjest);

triangle=NewTriangle(pt,edjest);

i++;

}

//删除以超级三角形顶点为顶点的三角形

triangle=SuperDelete(supertriangle);

//删除凹边界处三角形

triangle=TraingleDelete();

using(Graphicsg=this.picMap.CreateGraphics())

{

for(intj=0;j

{

Point[]myPoint=newPoint[3];

myPoint[0]=(Point)triangle[j][0];

myPoint[1]=(Point)triangle[j][1];

myPoint[2]=(Point)triangle[j][2];

g.DrawPolygon(newPen(Brushes.Red,3),myPoint);

}

}

构建泰森多边形需要构建三角网。

找出每个离散点周围的三角形即以该离散点为共同顶点的三角形,按逆时针排列起来以便下一步生成泰森多边形,连接该离散点周围三角形的外接圆的圆心。

三角网边界处的泰森多边形可做垂直平分线与图廓相交,与图廓一起形成泰森多边形。

(代码见附录)

重点代码示例:

//使三角形三个点坐标都按逆时针方向存储

triangle=Thiessen.SortTraingle(triangle);

//存储三角网所有三角形的边

Thiessen.Edge(triangle);

//构成边界的边集合

Thiessen.BorderEdge(Thiessen.allEdge);

//寻找以边界点为顶点的三角形集合

Thiessen.BorderTriangle(Thiessen.borderEdge,triangle);

//除边界点外其他离散点

Thiessen.CenterPoint(myPoints,Thiessen.borderEdge);

//除边界点外其他离散点构成的泰森多边形集合

Thiessen.ThiessenEdge(triangle,Thiessen.centerpoint);

//边界离散点构成的泰森多边形集合

Thiessen.MyBorderTheissen(Thiessen.borderEdge,Thiessen.myBorderTriangle);

using(Graphicsg=this.picMap.CreateGraphics())

{

//绘制除边界点外其他离散点构成的泰森多边形集合

for(inti=0;i

{

g.DrawPolygon(newPen(Brushes.Black,3),Thiessen.myTheissen[i].ToArray());

}

//绘制边界离散点构成的泰森多边形集合

for(inti=0;i

{

g.DrawPolygon(newPen(Brushes.Black,3),Thiessen.myBorderTheissen[i].ToArray());

}

}

八、源代码附录

1、用户登录源码

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Linq;

usingSystem.Text;

usingSystem.Windows.Forms;

usingSystem.Data.SqlClient;

namespaceMyMap

{

publicpartialclassLoginWindow:

Form

{

publicLoginWindow()

{

InitializeComponent();

}

privatevoidbtnLogin_Click(objectsender,EventArgse)

{

if(txtUserName.Text.Length<=0)

{

MessageBox.Show("请输入用户名");

return;

}

if(txtpwdPassword.Text.Length<=0)

{

MessageBox.S

展开阅读全文
相关搜索
资源标签


copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2