6.2 组件式开发:用CSharp拼装桌面GIS


6.2 组件式开发:用 C# 拼装桌面 GIS

本节摘要:组件式开发把 MapGIS 的能力做成一颗颗"零件",用 C# 把零件拼成自己的桌面程序。本节以对象模型为纲——服务器、数据库、要素类、要素四级向下钻取,写一个完整的"图斑统计器":连库、开类、遍历、统计、写回。读懂这四级对象,组件开发就入门了。

对象模型:四级台阶往下钻

组件开发的地图只有一张,对象模型的层级:服务器是入口,代表一个运行的数据服务;数据库是仓库,地理数据库挂在其下;要素类是表格,同构要素的集合;要素是行,一个图斑、一条路。所有组件代码都在这四级台阶上爬上爬下。

# 对象模型四级与口诀 Server 服务器 入口 连上一个就有了一切 └ DataBase 数据库 仓库 空间与属性都在这里 └ FeatureClass 要素类 表 一类要素的同构集合 └ Feature 要素 行 一个图斑 一根线 # 口诀:连服务 开数据库 找要素类 遍历要素 # 每一级都有打开与关闭 配对使用是纪律 不是风格

四级模型的价值在于"一处学会处处会通"。第 2 章建库、第 3 章分析用的数据,与本节代码里操作的是同一套对象,只是入口不同——桌面菜单是给人点的,组件接口是给代码调的。掌握了对象模型,等于拿到了平台的"编程遥控器"。

学习目标

阅读完本节,你应当能够:

  1. 画出对象模型四级结构,说出每级的职责与常用操作
  2. 编写连接数据库并打开指定要素类的稳定代码
  3. 用游标遍历要素,读取几何与属性并做统计
  4. 把计算结果写回要素类的新字段
  5. 识别资源泄漏与连接未关两类典型故障

完整案例:图斑统计器

需求来自耕地保护项目:全县耕地图斑三万八千个,按权属单位汇总面积,并把每个图斑的"是否超阈值"标志写回库里。工具给内业人员用,桌面程序形态——正对组件式的胃口。

第一步,连库开类。 连接部分的代码要防一手"服务没起"的经典事故:

using MapGIS.GeoDataBase; // 数据库对象命名空间 // 连接本地数据服务并打开地理数据库 var server = new Server(); if (!server.Connect("本地服务", "", "")) { MessageBox.Show("数据服务未启动 请先启动服务再运行本工具"); return; // 连不上就退出 别硬走 } var gdb = server.OpenGDB("耕地保护库"); // 打开地理数据库 var fc = gdb.GetXClass(XClsType.Fc, "耕地图斑") as SFeatureCls; if (fc == null) { MessageBox.Show("要素类不存在 检查名称拼写"); return; } // 输出:fc.Ready 为真 表示要素类可用 要素数 fc.Num

第二步,游标遍历与统计。 三万八要素不能一次全读进内存,游标是按批取数的正确姿势:

var stat = new Dictionary<string, double>(); // 权属单位 汇总面积 var cursor = fc.Select(new QueryDef()); // 空条件 全表游标 var f = new Feature(); int n = 0; while (cursor.Next(f) > 0) // 逐条推进 { string owner = f.Fields.GetStr("权属单位"); // 读属性 double area = f.Fields.GetDouble("椭球面积"); if (!stat.ContainsKey(owner)) stat[owner] = 0; stat[owner] += area; // 分组累加 n++; } cursor.Close(); // 游标用完即关 // 输出:n 为 38421 stat 含 217 个权属单位 // 经验:遍历大表时把进度条挂上 三万条也要跑几秒 无反馈会被当死机

第三步,结果写回与展示。 统计值既要导出报表,也要写回图斑做专题符号化的依据:

// 给要素类加一个短整型字段 存超阈值标志 if (fc.Fields.IndexOfField("超阈值") < 0) // 先查有没有 防重复加 { var fld = new FieldDefn("超阈值", FieldType.FldInt16); fc.Fields.Append(fld); } // 按权属均值阈值回写 第二遍游标只写超标的 double threshold = stat.Values.Average() * 1.5; // 阈值取均值一点五倍 var cursor2 = fc.Select(new QueryDef()); var f2 = new Feature(); while (cursor2.Next(f2) > 0) { string owner = f2.Fields.GetStr("权属单位"); bool over = f2.Fields.GetDouble("椭球面积") > threshold; f2.Values.SetItem("超阈值", over ? 1 : 0); // 改字段 cursor2.Update(f2); // 提交回写 } cursor2.Close(); fc.Dispose(); gdb.Dispose(); server.DisConnect(); // 逐级关闭 // 输出:约 6800 个图斑被标记为 1 后续符号化按此字段分级设色

三段代码合起来约五十行,一个能交付内业的工具成型了。复盘它的结构:连接防护、游标遍历、条件回写、逐级关闭——这四件事就是组件开发的基本功,换一个需求(管道检查、林地汇总),骨架原封不动,改的只是字段与逻辑。

⚠️ 常见坑:游标与连接不关。工具跑完图也出来了,但任务管理器里进程的句柄数一路涨,跑几轮后数据库连接池耗尽,全线报错。组件开发的铁律是"谁打开谁关闭",游标、要素类、数据库、服务器四级都要显式释放,用 try 与 finally 包住释放代码更稳。

从工具到系统:组件开发的工程化

图斑统计器是单窗口小工具,真实的组件式项目会长成多窗口、带权限、连服务端的桌面系统。工程化的三个升级方向:界面层用成熟的界面框架组织多窗体与停靠面板,地图控件只是其中一员;数据层把对象模型的访问封装成独立模块,界面不直接碰数据库对象;发布用安装项目把程序连同运行时打包,目标机器免装开发环境。

组件式与 6.3 的服务端开发不是竞争关系。桌面程序做重交互的内业台,服务端做对外共享——一个县域项目两条路线并行,各自吃各自擅长的场景,这在第 7 章的行业案例里会反复见到。

💡 关键直觉:组件式开发的性价比临界点在"交互复杂度"。界面上的拖拽勾选越多、专业编辑动作越多,组件式越值;如果只是查查看,网页就够了,别让 EXE 变成只用来显示地图的昂贵壳子。

  • 四级模型:服务器、数据库、要素类、要素,连开遍关四步口诀
  • 游标遍历:大表按批取数,进度条防"被当死机"
  • 写回纪律:先查字段防重复、条件过滤只改目标、逐条提交
  • 释放铁律:谁打开谁关闭,四级对象显式释放
  • 工程化三升级:界面框架、数据层封装、安装发布
  • 选型临界点:交互重上组件式,只查查看交网页

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U