http://www.gissky.net- GIS空间站

我要投稿 投稿指南 RSS订阅 网站资讯通告:
搜索: 您现在的位置: GIS空间站 >> 技术专栏 >> ArcGIS >> MapObjects >> 正文

MapObjects地图填充符号库扩展[Dotnet C#]

作者:大吉    文章来源:中国GIS资讯网    点击数:    更新时间:2007-12-3
摘要:各种GIS平台都有自己的符号库用于地物的表示。ESRI的ArcMap中就提供了非常丰富的地图符号库,在安装目录下的Bin\Styles目录中你会发现许多以.Style的文件,这些文件中存储的就是一些符号信息。另外安装目录下的Styles目录中有许多以.ServerStyle为扩展名的文件,这些也是ESRI提供符号库文件,不过这些是专门提供给ArcGis Engine使用的。关于.Style和.ServerStyle的信息访问www.esri.com可以获得更多的信息。通过这些符号库用户可以在ArcMap中制作出各式各样的专题地图。ArcMap中提供的符号信息非常丰富,基本满足了用户的需求,当然在不够用的情况下还可以自己增加符号库中的符号,甚至制作一套自己的符号库。

    在地图制图学中,将所有的地图符号划分为三大类:点状符号、线状符号和面状符号。

    各种GIS平台都有自己的符号库用于地物的表示。ESRI的ArcMap中就提供了非常丰富的地图符号库,在安装目录下的Bin\Styles目录中你会发现许多以.Style的文件,这些文件中存储的就是一些符号信息。另外安装目录下的Styles目录中有许多以.ServerStyle为扩展名的文件,这些也是ESRI提供符号库文件,不过这些是专门提供给ArcGis Engine使用的。关于.Style和.ServerStyle的信息访问www.esri.com可以获得更多的信息。通过这些符号库用户可以在ArcMap中制作出各式各样的专题地图。ArcMap中提供的符号信息非常丰富,基本满足了用户的需求,当然在不够用的情况下还可以自己增加符号库中的符号,甚至制作一套自己的符号库。

    MapObjects是ESRI提供的一组供应用开发人员使用的制图与GIS功能组件。它由一个OLE控件和一系列可编程OLE对象组成。利用MapObjects, 开发人员可以在应用程序中添加制图和GIS功能。由于利用MapObjects组件开发出系统开销小,开发周期也相对短些,因此许多应用系统都采用它。ArcGIS Engine是ESRI ArcGIS 9系列中推出的高级地图应用组件,功能非常强大开发也非常容易,对于MapObjects和ArcGIS Engine ESRI的观点好象是更推荐使用ArcGIS Engine进行开发,不过ArcGIS Engine占系统资源多,普通配置的机器运行ArcGIS Engine开发出来的系统比较慢。

    还是回到符号上来,MapObjects对点、线、面地理要素分别提供了相应的符号。

    1、点符号:MapObjects提供了4个基本的点符号,不过可以通过TrueType字体对点符号进行扩充,如:Wingdings索引为81的符号就是一架小飞机了。可以用造字程序创建自己的TrueType字体符号库,Font Creator Program 是一个TrueType字体造字程序非常好用。另外还可以实现ICustomMarker进行扩充。不过使用TrueType字体比实现ICustomMarker的操作更为有效方便。

    2、线符号:MapObjects只提供5个基本的线符号,需要更多的线型只能自己通过实现ICustomLine接口来扩充。

    3、面符号:MapObjects中包含11中填充的符号。与点、线符号类似可以通过实现ICustomFill进行扩充。

    下面主要讨论Dotnet C# 实现MapObjects面符号的扩充。我们知道WIN API提供了位图画刷,且画刷可以支持彩色相关位图及设备不相关位图。因此我们可以通过位图BITMAP构建画刷进行面区域的填充,如果完全通过底层的WIN API从图片创建BITMAP位图填充的画刷,对于API不太了解的人来说感觉很麻烦。不过还好通过Dotnet框架只需要几个API就可以搞定了,而且还可以很好的对这些符号进行组织,如:增加、删除、编辑、存档等。

    下面是需要用到的WINAPI函数:

 #region 调用Windows API 的GDI函数
[DllImport("gdi32.dll", EntryPoint="PolyPolygon")]
public static extern int PolyPolygon (
 int hdc,
 ref int lpPoint,
 ref int lpPolyCounts,
 int nCount
 );//绘制多边形
[DllImport("gdi32.dll", EntryPoint="CreatePen")]
public static extern int CreatePen (
 int nPenStyle,
 int nWidth,
 int crColor
 );//创建画笔
[DllImport("gdi32.dll", EntryPoint="SelectObject")]
public static extern int SelectObject (
 int hdc,
 int hObject
 ); //将对象[画笔、画刷、位图等]选入指定的设备描述表
[DllImport("gdi32.dll", EntryPoint="DeleteObject")]
public static extern int DeleteObject (
 int hObject
 );//删除对象 释放资源
[DllImport("gdi32.dll", EntryPoint="CreatePatternBrush")]
public static extern int CreatePatternBrush (
 int hBitmap
 );//通过位图创建画刷
#endregion

    为了更好的组织符号信息以及利于复用,可以编写两个可以序列化[Serializable]的类:填充符号:PatternStyle和符号集:StyleContainer

    PatternStyle: 描述符号的基本信息:符号内容即图象[Image]、符号名称[PatternName]、符号描述[PatternDescription]。

    StyleContainer:是一系列PatternStyle的集合,并包含一些增、删、修改PatternStyle的方法以及保存和打开二进字填充样式文件[*.pattern]的静态方法。标明[Serializable]的类在Dotnet中可以方便的进行序列化存储为本地的文件。标明[Serializable]的类的存取:

/// <summary>
/// 读去填充样式文件
/// </summary>
/// <param name="filename">样式文件路径</param>

public static StyleContainer LoadStyles(string filename)
{
 try
 {
  Stream StreamRead = File.OpenRead(filename);
  BinaryFormatter BinaryRead = new BinaryFormatter();
  StyleContainer StyleContainerObj =  BinaryRead.Deserialize(StreamRead) as StyleContainer;
  StreamRead.Close();
  return StyleContainerObj;
 }
 catch
 {
  return null;
 }
}
/// <summary>
/// 保存填充样式文件
/// </summary>
/// <param name="styles">StyleContainer对象</param>
/// <param name="filename">存储文件名</param>

public static void SaveStyles(StyleContainer styles,string filename)
{   
 Stream StreamWrite = File.Create(filename);
 BinaryFormatter BinaryWrite = new BinaryFormatter();
 BinaryWrite.Serialize(StreamWrite,styles);
 StreamWrite.Close();
}

实现ICustomFill接口,主要实现SetupDC、ResetDC和Draw三个函数。

private int g_hOldPen;
private int g_hPen;
private int g_hOldBrush;
private int g_hBrush;
private PatternStyle m_PatternStyle;

#region ICustomFill 成员

public void ResetDC(int hDC)
{
 // TODO:  添加 Polygons.ResetDC 实现
 //释放资源

 if(this.g_hPen != 0)
 {
  SelectObject(hDC,g_hOldPen);
  DeleteObject(g_hPen);    
 }
 if(this.g_hOldBrush != 0)
 {
  SelectObject(hDC,g_hOldBrush);
  DeleteObject(g_hBrush);
 }
}

public void SetupDC(int hDC, double dpi, object pBaseSym)
{
 // TODO:  添加 Polygons.SetupDC 实现
 //边界样式

 ESRI.MapObjects2.Core.Symbol sym = pBaseSym as ESRI.MapObjects2.Core.Symbol;
 g_hPen = CreatePen(sym.Style,sym.Size,(int)sym.Color);   
 //通过GDI+和API从Bitmap创建画刷
 System.Drawing.Bitmap bmp =( System.Drawing.Bitmap)this.m_PatternStyle.Image;    
 int ibmp = bmp.GetHbitmap().ToInt32();
 g_hBrush = CreatePatternBrush(ibmp);
 DeleteObject(ibmp);
}

public void Draw(int hDC, ref int points, ref int partCounts, int numParts)
{
 // TODO:  添加 Polygons.Draw 实现   
 //将画笔、画刷选入当前的设备描述表

 this.g_hOldPen  = SelectObject(hDC, g_hPen);
 this.g_hOldBrush = SelectObject(hDC,g_hBrush);
 //绘制多边形
 PolyPolygon(hDC,ref points,ref partCounts,numParts);
}
#endregion


应用示例:



图一、单一符号填充效果



图二、独立值填充效果

Tags:MapObjects  
责任编辑:gissky
  • 上一篇文章:
  • 下一篇文章: 没有了
  • 关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 中国地图