GP开发示例:数据库去重
来源:互联网 发布:淘宝社区茶叶包装盒 编辑:程序博客网 时间:2024/05/16 07:48
这个例子专业讲解基于ArcEngine使用GP开发的过程及遇到的问题。更多GP使用方法:GP使用心得
功能需求:现在外业第一次数据(简称调绘.mdb)和第二次数据(简称检查.mdb)有重复。第二次是在第一次的基础上进行的,即如果调绘.mdb中LCA层有365个要素,检查时发现错误,就删除了11个错误,并新增了43个,共408个,检查.mdb相对于调绘.mdb实际上有354个重复,现在要将重复的删除,mdb中包括点、线、面三种类型的要素类。
软件实现:在ArcGIS里利用工具可以实现,使用按空间位置查询,找出重复的,然后删除即可;由于每个mdb中的要素图层比较多,所以可以使用批处理,批处理时填写参数可以利用Excel快速进行。但是,mdb较多,路径各不相同,图层较多,操作起不比较费时。
程序实现:
1.首先确定用什么工具来实现(先在ArcGIS里做一次):利用空间位置查询选择重复的要素,开启编辑器,删除!
2.设计界面,我每写一个功能,都要把界面整理一下,因为我不想让它很丑就出去见人。这里使用DotNetBar,节省了相当多的时间。
3.因为是直接对数据库进行操作,所以首先就要遍历数据中的要素图层,一般做法是利用GP的ListFeatureClasses方法。
GP.SetEnvironmentValue(
"workspace"
, moreDBPath.Trim());
IGpEnumList pGpEnumList = GP.ListFeatureClasses(
""
,
""
,
""
);
string
strFC = pGpEnumList.Next();
while
(strFC !=
""
)
{
System.Windows.Forms.Application.DoEvents();
Console.WriteLine(strFC);
strFC = pGpEnumList.Next();
}
选择遍历数据库没有问题!
4.利用按位置选择
SelectLayerByLocation SLBL =
new
SelectLayerByLocation();
SLBL.in_layer = moreDB +
"\\"
+ strFC;
SLBL.select_features = referDB +
"\\"
+ strFC;
SLBL.overlap_type =
"ARE_IDENTICAL_TO"
;
GPClass.Execute(SLBL);
//这里使用了自定义的GPClass类,可以直接使用GPExecute
报错ERROR 000368,去官网帮助一查,竟然没有368,这是为什么?但从相邻错误信息来看,应该是哪个参数无效!
再去官网看了按空间位置查询的帮助文档。它说:输入必须是要素图层;不可以是要素类。要素图层?要素类?以前一直把它们看成是一种意思,于是去查一下了帮助,长知识了。
结果Python的示例代码,使用了MakeFeatureLayer来创建要素图层。
//创建要素图层
MakeFeatureLayer MFL =
new
MakeFeatureLayer();
MFL.in_features = moreDB +
"\\"
+ strFC;
MFL.out_layer = strFC +
@"_Lyr"
;
GPClass.Execute(MFL);
//按位置选择
SelectLayerByLocation SLBL =
new
SelectLayerByLocation();
SLBL.in_layer = strFC +
@"_Lyr"
;
SLBL.select_features = referDB +
"\\"
+ strFC;
SLBL.overlap_type =
"ARE_IDENTICAL_TO"
;
GPClass.Execute(SLBL);
GP执行成功,虽然还看不到效果。因为MakeFeatureLayer是临时图层,程序结束就没有了,需要将它导出来:
//复制要素导出
CopyFeatures CF =
new
CopyFeatures();
CF.in_features = strFC +
@"_Lyr"
;
CF.out_feature_class = resultDB +
"\\"
+ strFC;
GPClass.Execute(CF);
现在的问题是是选择类型是ARE_IDENTICAL_TO,如果输入图层中的要素与某一选择要素相同(就几何而言),则会选择这些要素。生成的mdb是重复那一部分,而需要的结果是不重复的那一部分。在ArcGIS里可以通过切换选择来操作。于是想,先把它全部选中,然后将重复的移除。代码:
//创建要素图层
MakeFeatureLayer MFL =
new
MakeFeatureLayer();
MFL.in_features = moreDB +
"\\"
+ strFC;
MFL.out_layer = strFC +
@"_Lyr"
;
GPClass.Execute(MFL);
//选择所有
SelectLayerByAttribute SLBA =
new
SelectLayerByAttribute();
SLBA.in_layer_or_view = strFC +
@"_Lyr"
;
GPClass.Execute(SLBA);
//按位置选择(移除)
SelectLayerByLocation SLBL =
new
SelectLayerByLocation();
SLBL.in_layer = strFC +
@"_Lyr"
;
SLBL.select_features = referDB +
"\\"
+ strFC;
SLBL.overlap_type =
"ARE_IDENTICAL_TO"
;
SLBL.selection_type =
"REMOVE_FROM_SELECTION"
;
GPClass.Execute(SLBL);
//复制要素
CopyFeatures CF =
new
CopyFeatures();
CF.in_features = strFC +
@"_Lyr"
;
CF.out_feature_class = resultDB +
"\\"
+ strFC;
GPClass.Execute(CF);
5.为了增加用户的体验,重写在了一个类,并把新建一个线程来处理:
string
referDB =
""
;
string
moreDB =
""
;
string
resultDB =
""
;
ProgressBarX progress =
null
;
public
NoRepeatClass(
string
_referDB,
string
_moreDB,
string
_resultDB, ProgressBarX _progress)
{
referDB = _referDB;
moreDB = _moreDB;
resultDB = _resultDB;
progress = _progress;
Thread MyThreadOne =
new
Thread(
new
ThreadStart(MainFun));
MyThreadOne.Name =
"NoRepeat"
;
MyThreadOne.IsBackground =
true
;
MyThreadOne.Start();
}
private
void
MainFun()
{
//主程序代码
}
6.为了让用户知道处理的进度,于是添加了进度条,并更新内容为当前处理图层的名称。但这里,不能直接在一个线程里设置主线程的控件属性,于是找了一个函数:
#region 设置控件参数
/// <summary>
/// 设置控件参数
/// </summary>
/// <param name="oControl">控件</param>
/// <param name="propName">参数名称</param>
/// <param name="propValue">参数值</param>
delegate
void
SetControlValueCallback(Control oControl,
string
propName,
object
propValue);
public
static
void
SetControlPropertyValue(Control oControl,
string
propName,
object
propValue)
{
if
(oControl.InvokeRequired)
{
SetControlValueCallback d =
new
SetControlValueCallback(SetControlPropertyValue);
oControl.Invoke(d,
new
object
[] { oControl, propName, propValue });
}
else
{
Type t = oControl.GetType();
System.Reflection.PropertyInfo[] props = t.GetProperties();
foreach
(System.Reflection.PropertyInfo p
in
props)
{
if
(p.Name.ToUpper() == propName.ToUpper())
{
p.SetValue(oControl, propValue,
null
);
}
}
}
}
#endregion
目前的效果如下:
7.为了提高操作效率,增加了路径拖放功能,下面是拖放类:
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows.Forms;
using
System.IO;
namespace
GPTools
{
class
DragClass
{
private
Control control;
private
string
fileType =
""
;
public
DragClass(Control _control,
string
_fileType)
{
//如果控件为空
if
(_control ==
null
)
{
return
;
}
control = _control;
fileType = _fileType;
//设置是否可以拖放
control.AllowDrop =
true
;
//定义拖放事件
control.DragEnter +=
new
DragEventHandler(control_DragEnter);
ontrol.DragDrop +=
new
DragEventHandler(control_DragDrop);
}
private
void
control_DragEnter(
object
sender, DragEventArgs e)
{
if
(e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
}
private
void
control_DragDrop(
object
sender, DragEventArgs e)
{
string
[] files = (
string
[])e.Data.GetData(DataFormats.FileDrop);
foreach
(
string
file
in
files)
{
//判断文件类型
if
(Path.GetExtension(file) == fileType)
{
Console.WriteLine(file);
control.Text = file;
}
}
}
}
}
在初始化主程序后实例化拖放类,一旦拖放就会触发DragEnter事件和DragDrop事件:
DragClass dg =
new
DragClass(
this
.txbReferDB,
".mdb"
);
DragClass dg2 =
new
DragClass(
this
.txbMoreDB,
".mdb"
);
8.因为我们只遍历了检查.mdb中的图层,万一调绘.mdb中没有对应图层怎么,所以,我们得检查,如果没有则跳过。
//创建要素图层
//……
//检查数据
object
dt =
""
;
if
(GPClass.GP.Exists(referDB +
"\\"
+ strFC,
ref
dt))
{
//3.选择所有
//4.按位置选择(移除)
}
//复制要素
//……
10.为了让用户快速进行执行任务,可以在执行按钮上添加Enter事件。
private
void
btnExcute_Enter(
object
sender, EventArgs e)
{
Excute();
}
private
void
Excute()
{
referDBPath = txbReferDB.Text.Trim();
moreDBPath = txbMoreDB.Text.Trim();
resultDBPath = txbResultDB.Text.Trim();
if
(referDBPath.Trim() !=
""
&& moreDBPath.Trim() !=
""
&& resultDBPath.Trim() !=
""
)
{
NoRepeatClass nr =
new
NoRepeatClass(referDBPath, moreDBPath, resultDBPath, progressBar);
}
else
{
MessageBoxEx.EnableGlass =
false
;
MessageBoxEx.Show(
"警告:数据库路径选择有误!\n 请检查数据路径是否正确。"
,
"提示"
);
}
}
- GP开发示例:数据库去重
- GP数据库开发语句
- java HashSet去重示例
- 数据库去重
- 数据库去重问题
- oracle数据库去重
- 数据库数据去重
- 数据库去重
- mysql数据库去重
- 数据库去重
- 数据库去重
- 数据库去重
- 数据库去重
- Mongodb数据库去重
- 数据库去重
- 数据库查询结果去重
- 数据库数据去重方法
- 数据库数据去重方法
- Unicode 字符编码表|汉字Unicode编码的区间为:0x4E00→0x9FA5
- 关于a-- - --a或--a - a--的问题
- android暂停或停止其他音乐播放器的播放
- 浏览器缓存知识小结及应用
- POJ 2566 Bound Found 【Two Pointers】
- GP开发示例:数据库去重
- 一分钟理解js闭包
- java 枚举的原理与使用枚举设计单例
- Case Class
- Oracle 修改BLOB数据
- 天平与假币问题
- A+B Problem(v) 南阳理工ACM 题目844
- operator=重写
- 完善之前的职员信息管理系统(添加了固态存取职员信息,结构优化了些,命名规范了些。。)