欢迎您来到GIS动力

加入收藏 免费注册 用户登陆 帮助中心
首页 新闻动态 技术专栏 银杏树下 学习考研 软件下载 求职招聘 许愿瓶 节日祝福 用户中心 精彩推荐 资源搜索 地图
专栏导航: AO开发 | SO开发 | ArcGIS桌面 | 超图桌面 | 开发语言 | 数据库 | WebGIS | 银杏文学 | 研究生考题 | FreeMap FreeTalk
   您现在位于: 首页技术专栏ArcGIS应用与开发ArcGIS其它 → 正文
在.NET中使用GDI+为Mapobjects构建三维直方图统计专题
07-11-12 16:11:13 作者:Aji@Gissky.com 出处:中国GIS资讯网
随着社会的发展、科学的进步,地理信息系统(GIS)技术在社会的各个领域中的应用越来越广泛。其中专题图在地理信息系统应用中具有非常重要的作用、专题图的应用大大增强信息表达的直观性。目前在GIS软件领域各种GIS软件平台以及GIS开发组件都提供了丰富的专题图设置功能。
    ESRI公司的GIS开发组件MapObjects中也提供了丰富的专题图功能,如:图表专题(包括直方图和饼图)、独立值、点密度、分类分级等。使用过Mapobjects进行专题开发的人会发现:其中图表专题中Mapobjects提供的图表显示是平面二维的,显示效果极其平淡、没有ArcMap中图表专题里的那种三维立体效果。有没有办法使这些图表象ArcMap中那样显示为三维立体的效果呢?Mapobjects的ChartRenderer中提供了自定义图表的方法,也就是把ChartType设置为ChartTypeConstants中的moCustom,然后把ChartRenderer的CustomChart属性设置为我们自定义图表对象就可以了。
    话是如此,但是任何创建这个自定义图表对象呢,MapObjects 提供了ICustomChart接口,我们要做的就是实现这个接口。在一般的开发语言中我们需要通过底层的API绘图函数来实现其中图形方面的操作,不过在.NET中我们可以使用强大的GDI+来实现这些操作,下面我们以C#.Net为例使用GDI+实现ICustomChart接口,创建美观、大方、直观、立体感强的三维直方图统计专题。

第一步:新建一个C#类库项目CustomChartRenderer(图一)


图一 新建类库项目CustomChartRenderer


第二步:添加程序集的应用。ESRI.MapObjects2.Core 和 ESRI.MapObjects2.Custom并继承 ESRI.MapObjects2.Custom.ICustomChart(图二、三)

图二 添加程序集的应用

图三 对我们创建的类添加对ICustomChart的继承

第三步:添加对ICustomChart继承接口的实现。在.NET开发界面的类试图中找到ICustomChart接口点击右键菜单中的“添加”——>“实现接口”(图四)

图四 添加对ICustomChart接口的实现

    “实现接口”后我们的代码中会多了如下三个函数,我们要做的也就是完成这三个函数在渲染的过程中执行的顺序为 SetupDC——> Draw——> ResetDC。

#region ICustomChart 成员
public void ResetDC( int hDC)
{
  // TODO:   添加 Custom3DBarRenderer.ResetDC 实现
}
public void SetupDC( object Map, object MapLayer, object ChartRenderer, int hDC, double dpi)
{
  // TODO:   添加 Custom3DBarRenderer.SetupDC 实现
}
public void Draw( int hDC, int x, int y, ref double[] values, double normValue, double sizeValue)
{
  // TODO:   添加 Custom3DBarRenderer.Draw 实现
}
#endregion  


第四步:添加成员变量、属性和自定义函数, 自定义函数 Setup3DBarRenderer主要负责 对数据进行预处理和统计计算,计算图表渲染中的最大值,以便根据数值的大小分配直方图柱子的高度。

private int[]    m_iColors;                  //记录直方条的颜色
private float     m_MaxBarHeight = 50;        //直方图的最大高度
private float     m_MinBarHeight = 1;         //直方图的最小高度
private float     m_BarWidth = 10;            //直方图的宽度
private float     m_fTotal = 0;               //用于记录统计字段中的最大直
private
bool      m_blDrawOutline = true;     //是否绘制边框
private System.Drawing.Color m_OutlineColor = System.Drawing.Color.Black; //边框的颜色

public
void Setup3DBarRenderer(ESRI.MapObjects2.Core.MapLayer lyr,ESRI.MapObjects2.Core.ChartRenderer cr)
{
     if(lyr != null && cr != null)
     {              
         //初始化颜色数组根据FieldCount动态创建
         this.m_iColors = new int[cr.FieldCount];
         for( short i=0;i<cr.FieldCount;i++)
         {
              this.m_iColors[i] = int.Parse(cr.get_Color(i).ToString());    
         }
         ESRI.MapObjects2.Core.Recordset rec;
         float fTotal = 0;
         rec = lyr.Records;
         while (!rec.EOF)
         {                   
              for( short i = 0 ; i < cr.FieldCount - 1;i++)
              {
                   float fTemp = float.Parse(rec.Fields.Item(cr.get_Field(i)).ValueAsString);
                   if(fTotal < fTemp)
                   { //保存最大的值 以便计算绘制直方图的高
                       fTotal = fTemp;
                   }
              }                    
              rec.MoveNext();
         }
         this.m_fTotal = fTotal;
     }
}


// 公开一些属性以便根据需要进行修改
public float BarWidth { get; set; }
public bool DrawOutline { get; set; }
public float MaxBarHeight { get; set; }
public float MinBarHeight { get; set; }
public Color OutlineColor { get; set; }


第五步 实现继承的接口ESRI.MapObjects2.Custom.ICustomChart中的方法Draw()。

public void Draw( int hDC, int x, int y, ref double[] values, double normValue, double sizeValue)
{
     // TODO:   添加 Custom3DBarRenderer.Draw 实现
     float iBarHeight = 0;
     float iBarWidth   = 0;
     System.Drawing.Graphics g = System.Drawing.Graphics.FromHdc( new System.IntPtr(hDC)); //创建 Graphics 对象
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; //消除图形的锯齿
     System.Drawing.SolidBrush tempBrush = null;
     System.Drawing.Pen pOutLine = new System.Drawing.Pen( new System.Drawing.SolidBrush( this.m_OutlineColor),0.2f);
     iBarWidth   = this.m_BarWidth;
     float CurrentX,CurrentY;
     CurrentX = x - this.m_BarWidth * values.Length / 2;
     CurrentY = y;
     for( int i=0;i<values.Length;i++)
     {
         //创建画刷 并计算矩形的高度
         tempBrush =   new System.Drawing.SolidBrush(System.Drawing.ColorTranslator.FromWin32( this.m_iColors[i]));
         iBarHeight = System.Convert.ToSingle((values[i] * this.m_MaxBarHeight/ this.m_fTotal).ToString());  
         if(iBarHeight < this.m_MinBarHeight)
         {
              iBarHeight = this.m_MinBarHeight;
         }
         if(iBarHeight > this.m_MaxBarHeight)
         {
              iBarHeight = this.m_MaxBarHeight;
         }
         //绘制矩形
         System.Drawing.PointF[] pRect = new System.Drawing.PointF[4];
         pRect[0].X = CurrentX;
         pRect[0].Y = CurrentY;
         pRect[1].X = CurrentX + iBarWidth ;
         pRect[1].Y = CurrentY;
         pRect[2].X = CurrentX + iBarWidth ;
         pRect[2].Y = CurrentY - iBarHeight;
         pRect[3].X = CurrentX;
         pRect[3].Y = CurrentY - iBarHeight;   
         //绘制矩形顶部的阴影
         System.Drawing.PointF[] pTopFill = new System.Drawing.PointF[4];
         pTopFill[0].X = CurrentX;
         pTopFill[0].Y = CurrentY - iBarHeight;
         pTopFill[1].X = CurrentX + iBarWidth ;
         pTopFill[1].Y = CurrentY - iBarHeight;
         pTopFill[2].X = CurrentX + iBarWidth * 3/2 ;
         pTopFill[2].Y = CurrentY - iBarHeight - iBarWidth * 1/2;
         pTopFill[3].X = CurrentX + iBarWidth * 1/2 ;
         pTopFill[3].Y = CurrentY - iBarHeight - iBarWidth * 1/2;             

         CurrentX = CurrentX +iBarWidth;   
         //斜面阴影部分
         System.Drawing.PointF[] pShadow= new System.Drawing.PointF[4];
         pShadow[0].X = CurrentX;
         pShadow[0].Y = CurrentY;
         pShadow[1].X = CurrentX + iBarWidth/2 ;
         pShadow[1].Y = CurrentY - iBarWidth/2;
         pShadow[2].X = CurrentX + iBarWidth/2 ;
         pShadow[2].Y = CurrentY - iBarHeight - iBarWidth * 1/2;
         pShadow[3].X = CurrentX  ;
         pShadow[3].Y = CurrentY - iBarHeight;                 

         //绘制3D图形 包括正面、斜面、顶部
         g.FillPolygon(tempBrush,pRect);                 
         g.FillPolygon( new HatchBrush(HatchStyle.Percent50,tempBrush.Color),pTopFill);
         g.FillPolygon(tempBrush,pShadow);
         //如果设置了绘制边界线 则绘制边界
         if( this.m_blDrawOutline)
         {
               g.DrawPolygon(pOutLine,pRect);
              g.DrawPolygon(pOutLine,pTopFill);
              g.DrawPolygon(pOutLine,pShadow);
         }                       
     }
}


9 7 3 1 2 4 8 :

(本文已被浏览 次)
发布人:admin
推荐给好友:发送给好友
上篇新闻:
下篇新闻:
相关评论
发表我的评论
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  •   相关文章  
    mo中支持滚鼠放大缩小的类
    用mo写的剔除完全重复实体的代码
    MODIS过境时间及相关
    CRS-0184: Cannot communicate with the CRS daemon
    C++开发Mo常用功能代码
    MO显示Tip
    在.NET中给Mapobjects地图控件添加右键菜单

    关于我们友情链接 ┋ 与我在线 ┋ 管理 ┋ TOP
     
    网站当前版本:GisPower CMS V3.0
    『GIS 动力』- http://www.gispower.org/
    联系我们:webmaster#gispower.org
    Copyright (c) 2003-2007 GisPOwer.Org. All Rights Reserved.
     

                   滇ICP备05006901号