Micaps3.2二次开发实例教程-11
来源:互联网 发布:淘宝店招怎么做全屏 编辑:程序博客网 时间:2024/06/09 12:47
实例六-让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
- Micaps3.2二次开发实例教程-2
- Micaps3.2二次开发实例教程-1
- Micaps3.2二次开发实例教程-3
- Micaps3.2二次开发实例教程-4
- Micaps3.2二次开发实例教程-5
- Micaps3.2二次开发实例教程-6
- Micaps3.2二次开发实例教程-7
- Micaps3.2二次开发实例教程-8
- Micaps3.2二次开发实例教程-9
- Micaps3.2二次开发实例教程-10
- Micaps3.2二次开发实例教程-12
- Micaps3.2二次开发实例教程-13
- Micaps3.2二次开发实例教程-14
- [Net_Ghost] WPF实例教程(2)
- Smarty实例教程(2)
- JavaScript实例教程2
- Smarty实例教程(2)
- android项目在导入后出现了红色感叹号解决方案
- 斜杠与反斜杠的区别
- 3.5.2 TreeWidget控件
- (C语言)常用字符串处理函数
- 学生信息管理系统-错误‘-2147217887’
- Micaps3.2二次开发实例教程-11
- Android应用开发——系统自带样式Android:theme
- How to work
- 第3.2.1节 android基本视图
- Windows下查看进程与线程的相关工具
- Java String,Date类型转换
- UVALive 3635 Pie 二分查找
- VisualVM远程监控
- NSBundle、[NSBundle mainBundle] 详解