实例六-让Micaps支持新数据类型-BLN地图数据

Micaps本身支持几十类数据,如果将所有类型数据的读写显示都模块都放在一起,那将带来如下问题:

  • 代码量太大,代码维护成问题;
  • Micaps以后可能还需要支持更多的数据格式,程序的升级扩充问题;
  • 各种数据支持代码也不能仅靠Micaps开发团队核心人员编写,团队开发问题;
  • 最后,各省还想直接显示他们自己的数据,二次开发问题;

Micaps3.2的策略是利用SharpDevelop的插件框架,将各种数据支持功能都以插件方式提供,一种数据格式一个插件。大家根据Micaps预定义好规则,独立开发插件,扩充性和团队开发问题都得到了解决。二次开发中也可以使用同样方法开发插件让Micaps支持特定的数据格式。

要实现这个功能,插件的代码里首先要解决两个问题:

  • 数据识别问题。当用户打开一个文件(链接、字符串等)后,如何让Micaps识别出数据类型,然后根据数据类型来决定怎么读文件、怎么绘图。

对这个问题,Sharpdevelop已经提供了框架,使用一种叫做DisplayBinding(显示绑定)的插件架构。每个显示绑定插件里首先要实现一个对文件类型的识别函数,Sharpdevelop将系统中所有显示绑定插件排成一个列表,如果自己能识别,则打开显示,不能识别则交个下一个数据支持插件处理。

  • 数据显示问题。读出了数据,如果是要填到地图上,如何与Micaps地图交互?

要将数据显示在地图上,那必然要和Micaps的地图交互。Micaps已提供大量可供调用类,包括图层、绘制函数等,这也是Micaps二次开发的难点,这些内容可查阅《Micaps3.2二次开发手册》。

这一节,我们编写插件为Micaps增加surfer的bln格式地图数据支持功能。

1、Addin文件:

<Pathname="/Workspace/DisplayBindings"><DisplayBinding id="SurferBln"type="Layer"class="SurferBln.SurferBlnDataBindings"/></Path>

显示绑定的扩展点路径为"/Workspace/DisplayBindings";type="Layer"是Micaps新增的一种类型,它表示该数据将以地图图层方式显示;在显示绑定段里指定绑定的类名为"SurferBln.SurferBlnDataBindings",这个类将完成对数据类型的判断、数据显示等动作。

2、代码:

代码中主要是实现Addin文件里指定的SurferBln.SurferBlnDataBindings,该类必须实现接口ILayerDisplayBinding:

 public class SurferBlnDataBindings : ILayerDisplayBinding{#region ILayerDisplayBinding 成员/// <summary>/// 判读传入的文件名是否能被本插件打开/// </summary>/// <param name="filename">文件名</param>/// <returns>可以打开:true,不能打开:false</returns>public bool CanCreateForFile(string filename){//本插件能打开后缀为bln的文件return Path.GetExtension(filename).ToLower() == ".bln";}/// <summary>/// 创建bln图层并加入地图/// </summary>/// <param name="file"></param>/// <returns></returns>public ILayer CreateLayerForFile(OpenedFile file){//取得当前视图,转换为Micaps地图视图var mainRenderView = WorkspaceSingleton.Workspace.ActiveViewContent as IMicapsMainView;//如果当前视图是地图,则加载图层if (mainRenderView != null){//创建bln图层BlnChart Chart = new BlnChart();//用它创建Micaps图层绑定对象MicapsDataLayerWrapper layer = new MicapsDataLayerWrapper(Chart);//给图层的地图对象赋值Chart.Map = mainRenderView.Map;//加载数据layer.Load(file, file.OpenRead());file.CloseIfAllViewsClosed();layer.LayerName = Chart.Description();return layer;}return null;            } #endregion}

ILayerDisplayBinding接口包含两个函数:

  • bool CanCreateForFile(string filename);用来判断该插件能打开的文件。
  • ILayer CreateLayerForFile(OpenedFile file);打开文件,创建图层。
    上面的代码里,BlnChart是我们新建的一个类,用来读取和显示bln文件。该类从C_ChartBase类继承,主要实现以下成员:
  • string ReadFile(string filename):读取解析bln文件。
  • void Draw(GLGraphics g):绘图。
<pre name="code" class="csharp">using System;
using System.Collections.Generic;
using System.Text;
using nmc.micaps3;
using System.Drawing;
using System.IO;namespace SurferBln
{class BlnChart : C_ChartBase{private BlnProperty _Property = new BlnProperty();public override void AddLayer(System.Collections.ArrayList list){LayerZOrder layer_order = new LayerZOrder();layer_order.obj = this;layer_order.zOrder = 31;list.Add(layer_order);}string _Description = "Surfer Bln格式数据";public override string Description(){return _Description;}public override void Draw(GLGraphics g){float x, y;List<PointF> pts;foreach (MapModel mo in MapObjects)//判断地图元素类型,仅显示线状数据if (mo.ObjectType == ShapeType.PolyLine){pts = new List<PointF>();foreach (PointF ptf in mo.Points){map.MemTY(ptf.X, ptf.Y, out x, out y);PointF xy = new PointF(x,y);pts.Add(xy);}g.DrawLines(_Property.LineColor, pts.ToArray());}}//map.MemTY(107, 33, out x, out y);//g.DrawEllipse(_Property.LineColor, x, y, 300, 300);}public override object GetPropertyInstance(){return _Property;}public override DateTime NextDateTime(){throw new NotImplementedException();}public override DateTime PreviousDateTime(){throw new NotImplementedException();}public override string ReadDB(object parameter){throw new NotImplementedException();}protected IList<MapModel> MapObjects = new List<MapModel>();public override string ReadFile(string filename){using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)){using (StreamReader ws = new StreamReader(fs, Encoding.Default)){while (!ws.EndOfStream){//数据行string line = "";//读取地图元素头,并跳过空行do{line = ws.ReadLine();}while (string.IsNullOrEmpty(line));//分隔数据行string[] items = line.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);//点数int n = Convert.ToInt16(items[0]);//地图元素MapModel mo = new MapModel();//地图元素头为两个if (items.Length > 1){int t = Convert.ToInt16(items[1]);if (t == 1){//线mo.ObjectType = ShapeType.PolyLine;}else{//面mo.ObjectType = ShapeType.Polygon;}}else{//线mo.ObjectType = ShapeType.PolyLine;}//地图元素点数mo.Points = new System.Drawing.PointF[n];//读取经纬度for (int i = 0; i < n; i++){PointF ptf = new PointF();line = "";//读入一行,并跳过空行do{line = ws.ReadLine();}while (string.IsNullOrEmpty(line));//分隔数据行items = line.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);//有两项时if (items.Length == 2){//经纬度ptf.X = Convert.ToSingle(items[0]);ptf.Y = Convert.ToSingle(items[1]);mo.Points[i] = ptf;}}//加入到列表MapObjects.Add(mo);}}fs.Close();}_Description = Path.GetFileName(filename);return "Success";}public override string ReadXmlFile(string filename){throw new NotImplementedException();}protected static int z_order = 31;public override int Z_Order{get{return z_order;}set{z_order = value;}}}/// <summary>/// 地图数据实体类/// </summary>public class MapModel //: DrawObject{/// <summary>/// 构造函数/// </summary>public MapModel(){}private ShapeType _ObjectType = 0;/// <summary>/// 对象类型/// </summary>public ShapeType ObjectType{get { return _ObjectType; }set { _ObjectType = value; }}private string _Id;/// <summary>/// 对象ID/// </summary>public string Id{get { return _Id; }set { _Id = value; }}private RectangleF _Rect;/// <summary>/// 对象最大矩形范围/// </summary>        public RectangleF Rect{get{return _Rect;}set { _Rect = value; }}private PointF[] _Points;/// <summary>/// 对象点数组/// </summary>public PointF[] Points{get { return _Points; }set { _Points = value; }}}/// <summary>/// 地图元素类型/// </summary>public enum ShapeType : int{/// <summary>/// 空/// </summary>Null = 0,/// <summary>/// 点/// </summary>Point = 1,/// <summary>/// 线/// </summary>PolyLine = 3,/// <summary>/// 面/// </summary>Polygon = 5,};
}

总结一下,显示自定义格式数据时,Addin文件从扩展点路径"/Workspace/DisplayBindings"扩展,指定数据绑定类,代码中,实现数据绑定类接口IlayerDisplayBinding的两个方法,一个方法判断我们的插件是否能识别打开的文件,当文件能打开时,将调用另一个方法打开文件建立新图层,另外,需要新建一个继承C_ChartBase的类,它实现读取文件和绘图功能。

下图为打开bln地图的效果,为了显示更清楚,我隐去了Micaps自带的基础地图:

海南的bln县界与Micaps叠加:

       其实,Micaps3.2完全没必要自己再定义一套图层显示绑定,直接使用SharpDevelop的IdisplayBinding接口就行了,甚至写一个适配器直接使用Micaps3.1的原有插件。

Micaps3.2二次开发实例教程-11相关推荐

  1. Micaps3.2二次开发实例教程-8

    第八节        实例三:浮动窗口开发 Micaps3.2给用户的第一印象是窗口的布局方式发生了变化,它使用目前软件十分流行的浮动窗口,即界面上各部分都是可以拖动停靠重新布局的. 当然这还是利用S ...

  2. objectarx用户交互_AutoCAD2010二次开发实例教程(附光盘ObjectARX)

    导语 AutoCAD软件二次开发牵涉的面非常广,不可能在一本书中将其完全论述.王文波和邹清源等编著的<AutoCAD2010二次开发实例教程>把AutoCAD软件二次开发的内容归为实体对象 ...

  3. ArcGIS二次开发基础教程(11):网络分析之最短路径分析

    ArcGIS二次开发基础教程(11):网络分析之最短路径分析 最短路径分析 这里直接调用了在mdb中建立好的网络数据集 //全局变量 private INetworkDataset my_networ ...

  4. 计算机辅助设计二次开发案例教程,计算机辅助设计二次开发案例教程ch03.ppt

    <计算机辅助设计二次开发案例教程ch03.ppt>由会员分享,可在线阅读,更多相关<计算机辅助设计二次开发案例教程ch03.ppt(14页珍藏版)>请在人人文库网上搜索. 1. ...

  5. 《深入浅出AutoCAD.NET二次开发》教程(含光盘)

    <深入浅出AutoCAD.NET二次开发>教程(含光盘)-中国建筑工业出版社出版 一本系统介绍.NET环境二次开发AutoCAD的教程,适合工程技术人员作为入门读物也适合研发工程师作为工作 ...

  6. python对abaqus本构二次开发_基于Python的Abaqus二次开发实例讲解

    第 1 页 共 11 页 基于 Python 的 Abaqus 二次开发实例讲解 ( asian58 2013.6.26 ) 基于 Python 的 Abaqus 的二次开发便捷之处在于: 1 .所有 ...

  7. Python 语言 SAP2000 二次开发 实例

    目 录 Blog Links Remarks Example Blog Links DalNur | 博客总目录 Python语言 SAP2000 二次开发 -- 概述 Python语言 SAP200 ...

  8. HTC VIVE开发实例教程-邵伟-专题视频课程

    HTC VIVE开发实例教程-1971人已学习 课程介绍         HTC VIVE开发实例视频培训教程,我们相信学习VR技术与学习任何其它技术具有相通性,通过一定的刻意练习,后发现一个方法论和 ...

  9. 基于python的abaqus二次开发_基于PYTHON的ABAQUS二次开发实例讲解

    第 1 页 共 11 页 基于 Python 的 Abaqus 二次开发实例讲解 ( asian58 2013.6.26 ) 基于 Python 的 Abaqus 的二次开发便捷之处在于: 1 .所有 ...

  10. wordpress php教程 pdf,wordpress二次开发全能教程.pdf

    wordpress 二次开发全能教程 1. 根据分类来制定导航条 A. 修改页面 header.php! <?php wp_list_categories('title_li='); ?> ...

最新文章

  1. CentOS7 php7.0 升级到php7.3
  2. 深度学习利器:TensorFlow与NLP模型
  3. 绝了!华为、H3C、锐捷交换机配置命令大全
  4. shell(希尔)排序
  5. matlab实现谱聚类法图像分割代码,一种基于谱聚类的图像分割方法与系统与流程...
  6. ofo 辟谣“月盈利百万”;苹果回应向腾讯传输数据;Python 3.8.0 发布 | 极客头条...
  7. [洛谷P2463][SDOI2008]Sandy的卡片
  8. mac 2k显示器字体发虚_亲身实践:Mac mini 搭配戴尔显示器体验
  9. 如何在OTN网站下载Grid方法(Oracle RAC)
  10. 【javaWeb微服务架构项目——乐优商城day14】——购物车(实现未登录状态的购物车,实现登陆状态下的购物车,实现未登录状态的购物车合并到登录状态)
  11. 随手写的一个小程序,将gz压缩文件读取到内存中 并用base64编码 及相关解码
  12. 贷款逾期,征信记录五年之内可以消除?
  13. Image Segmentation
  14. {转载}circos绘图(2)
  15. 排列组合之插板法及变形
  16. PAT 甲级1116 1117 1118 1119 解题报告
  17. Postman接口测试工具
  18. Python 1~500 求和(循环遍历求和,高斯求和,定义函数求和)
  19. 数据库设计优化(来自十年经验架构师的课堂)
  20. HTML5 drag和drop的亲手实践

热门文章

  1. springboot 简单集成mybatis 及所遇到问题解决方法
  2. 风口下的追逐:AI正在驾驶、客服、教育领域疾驰
  3. OpenStack修改Guest用户密码——利用Qemu guest agent实现
  4. 直流屏控母和合母有什么区别
  5. Linux容器的安装链接
  6. 实现百度搜索实时热点爬虫
  7. Linux基础入门(详细教程)
  8. This Week in Spring - July 9, 2013
  9. php 硬盘序号_怎么查看电脑硬盘序列号
  10. SDH(标准DH)和MDH(改进DH)