ArcGIS Engine二次开发一般需要通过桌面产品来制作这些符号,然后通过专门的转换工具转换以后供AE使用。电力GIS应用当中,电力设备种类繁多,设备状态比较复杂,需要用不同的符号来表现电力设备的不通状态,此外电力技术的更新速度很快,新设备种类也不断推陈出新,用户往往要求提供符号定义工具以满足这些需求。本文以配电变压器为例,介绍一种使用ArcGIS
Engine + C#二次开发模式下,可以让用户自己定义设备符号的一种方法。一、符号定义配电变压器符号如下图所示:可以将这个符号分解成四个图元,两段线段,两个圆(圆弧)。用以下结构来描述图元:
publicstructMetaData
{
publicintTyp;
// 图形类型 3:圆弧,0:线段
publicdoubleScale;
// 缩放
publicintOffsX ;
// 偏移(x)
publicintOffsY;
// 偏移(y)
publicdoubleAngle;
// 旋转
publicintx1;
// 图元的第一点位置(x)
publicinty1;
// 图元的第一点位置(y)
publicintx2;
// 图元的第二点位置(x)
publicinty2;
// 图元的第二点位置(y)
publicintx3;
// 图元的第三点位置(x)
publicinty3;
// 图元的第三点位置(y)
publicintx4;
// 图元的第四点位置(x)
publicinty4;
// 图元的第四点位置(y)
}//
线段:第一点:起点坐标, 第二点:终点坐标, 第三点, 第四点为空
// 圆弧:第一点:圆弧所在圆所属矩形的左上角,第二点:圆弧所在圆所属矩形的左右下角,第三点:圆弧起点;第四点:圆弧终点
// 圆弧方向为逆时针,对于圆x3,y3,x4,y4重合可以编写一个绘制简单图元的绘图工具,方便用户绘制这些图元,绘制好的图元存成以上格式,存入到数据库中,以方便系统读入。一、自定义、实现符号类MyMarkerSymbol:1.类的定义:自定义符号需要实现以下四个接口:IMarkerSymbolISymbolICloneIpersistVariantMyMarkerSymbol类定义为:
publicclassMyMarkerSymbol :IMarkerSymbol,ISymbol,IClone,IPersistVariant
{
publicMyMarkerSymbol()
{
//base.New();
Class_Initialize_Renamed();
}}构造函数,需将符号的角度传入。
publicMyMarkerSymbol(doubleange)
{
//base.New();
Class_Initialize_Renamed();
m_Angle = ange;
}//成员变量
privateintm_lPen;
privateintm_lOldPen;
privateintm_lHDC;
privatedoublem_Angle;
privateintm_SymbolIndex;
privateESRI.ArcGIS.Display.IDisplayTransformation m_pDispTrans;
privateintm_lSize;2.接口函数的实现:要实现自定义符号需要实现这四个接口的多个函数,最重要的是ImarkerSymbol的三个函数:SetupDC,Draw和ResetDC。SetupDC用于设置画笔画刷、颜色等信息。
publicvoidSetupDC(inthDC,
ITransformation transformation)
{
// TODO:添加 MyMarkerSymbol.SetupDC 实现
m_lPen = CreatePen(0, 2, System.Convert.ToInt32(m_pColor.RGB));
m_lOldPen = SelectObject(hDC, m_lPen);
m_lHDC = hDC;
m_pDispTrans = (IDisplayTransformation)transformation;
}hDC为画布句柄。ResetDC函数,绘制完成后,进行资源释放和状态回复。
publicvoidResetDC()
{
// TODO:添加 MyMarkerSymbol.ResetDC 实现
SelectObject(m_lHDC, m_lOldPen);
DeleteObject(m_lPen);
m_pDispTrans =null;
m_lHDC = 0;
}Draw函数实现符号的绘制工作:
publicvoidDraw(IGeometry Geometry)
{
// TODO:添加 MyMarkerSymbol.Draw 实现
if(Geometry ==null)
{
return;
}
ESRI.ArcGIS.Geometry.IPoint pPt;
pPt = (IPoint)Geometry;
intx;
inty;
if(m_pDispTrans ==null)
{
x = (int)pPt.X;
y = (int)pPt.Y;
}
else
{
m_pDispTrans.FromMapPoint(pPt,outx,outy);
}
DrawMetas(x,y);
}3.DrawMetas实现:需要在画布上绘制两条直线合两个圆,可以通过调用Windows API函数来实现:
[System.Runtime.InteropServices.DllImport("gdi32")]
privatestaticexternboolLineTo
(inthdc,intx,inty );
[System.Runtime.InteropServices.DllImport("gdi32")]
publicstaticexternboolMoveToEx(inthdc,intx,inty,LPPOINT
lpPoint);
[System.Runtime.InteropServices.DllImport("gdi32")]
publicstaticexternboolArc
(inthdc,intX1,intY1,intX2,intY2,intX3,intY3,intX4,intY4);
4.图元旋转
自定义符号需要按指定角度进行旋转,直线旋转的方法比较简单,以下介绍圆弧的旋转方法:
以圆弧所在圆所属矩形的左上角为例:
旋转前的坐标为(x0,y0),旋转后的坐标为(x1,y1),计算出旋转半径r,alpha,则:
x1 = r*Math.Cos( alpha - mAngle );
y1 = r*Math.Sin( alpha - mAngle );
其他各定点也可以用同样方法计算。
计算出各顶点后调用以下方法绘制圆弧即可:
Arc(m_lHDC,(int)(x1),(int)(y1),(int)(x2),(int)(y2),
(int)(x3),(int)(y3),(int)(x4),(int)(y4));
对于直线段可以用以下方法绘制即可:
LPPOINT prePos=newLPPOINT();
MoveToEx(m_lHDC,(int)x1,(int)y1,prePos);
LineTo(m_lHDC,(int)x2,(int)y2);
三、调用符号
1.使用IsimpleRenderer接口渲染:
//定义render
IsimpleRenderer pSimpleRenderer =newSimpleRendererClass();
//定义自定义符号
MyMarkerSymbol mMyMarkerSymbol =newMyMarkerSymbol();
//渲染
IGeoFeatureLayer m_pGeoFeatureLayer;pSimpleRenderer.Symbol = (ISymbol) mMyMarkerSymbol;
m_pGeoFeatureLayer = (IGeoFeatureLayer)ly;
m_pGeoFeatureLayer.Renderer = (IFeatureRenderer)pSimpleRenderer;2.使用IUniqueValueRenderer接口渲染:IuniqueValueRenderer pRender =newUniqueValueRendererClass();
iAngleField = pFields.FindField("ANGLE");
for(inti=0;i< pFeatCls.FeatureCount(pQueryFilter)
;i++)
{
pFeat = pFeatCursor.NextFeature();
stringx =null;
x = pFeat.get_Value(iField).ToString() ;
dAngle = (double)pFeat.get_Value(iAngleField);
SymbolIndex =int.Parse(pFeat.get_Value(iSymIndexField).ToString());
MyMarkerSymbol sym =newMyMarkerSymbol(dAngle);
pRender.AddValue( x,x, (ISymbol)msy);
}
pLyr.Renderer = (IFeatureRenderer)pRender;以上介绍只能实现比较简单的动态符号,但只要完善其中的函数,就可以实现各种复杂的电力符号,应用到Arcgis Engine应用开发中,实现用户自定义设备符号,系统自动渲染。
在ArcGis
Engine中实现对符号的预览,生成预览图片。使用的时候只要调用SymbolToBitmp(符号,宽,高)就可以返回生成的图片了。关键代码如下:
publicSystem.Drawing.Bitmap SymbolToBitmp(ESRI.ArcGIS.Display.ISymbol pSymbol,intiwidth,intiheight)
{
//根据高宽创建图象
Bitmap bmp =newBitmap(iwidth,iheight);
Graphics gImage = Graphics.FromImage(bmp);
gImage.Clear(Color.White);
doubledpi = gImage.DpiX;
IEnvelope pEnvelope =newEnvelopeClass();
pEnvelope.PutCoords(0,0,(double)bmp.Width,(double)bmp.Height);
tagRECT deviceRect;
deviceRect.left = 0;
deviceRect.right = bmp.Width;
deviceRect.top = 0;
deviceRect.bottom = bmp.Height;
IDisplayTransformation pDisplayTransformation =newDisplayTransformationClass();
pDisplayTransformation.VisibleBounds = pEnvelope;
pDisplayTransformation.Bounds = pEnvelope;
pDisplayTransformation.set_DeviceFrame(refdeviceRect);
pDisplayTransformation.Resolution = dpi;
IGeometry pGeo = CreateSymShape(pSymbol,pEnvelope);
System.IntPtr hdc =newIntPtr();
hdc = gImage.GetHdc();
//将符号的形状绘制到图象中
pSymbol.SetupDC((int)hdc,pDisplayTransformation);
pSymbol.Draw(pGeo);
pSymbol.ResetDC();
gImage.ReleaseHdc(hdc);
gImage.Dispose();
returnbmp;
}
publicESRI.ArcGIS.Geometry.IGeometry CreateSymShape(ISymbol pSymbol,IEnvelope pEnvelope)
{// 根据传入的符号以及外包矩形区域返回对应的几何空间实体(点,线、面)
//判断是否为“点”符号
ESRI.ArcGIS.Display.IMarkerSymbol IMarkerSym;
IMarkerSym = pSymbolasIMarkerSymbol;
if (IMarkerSym !=null)
{
// 为“点”符号则返回IEnvelope的中心点
IArea pArea ;
pArea = pEnvelopeasIArea;
returnpArea.CentroidasIGeometry;
}
else
{
//判断是否为“线”符号
ESRI.ArcGIS.Display.ILineSymbol IlineSym;
ESRI.ArcGIS.Display.ITextSymbol ITextSym;
IlineSym = pSymbolasILineSymbol;
ITextSym = pSymbolasITextSymbol;
if(IlineSym !=null|| ITextSym !=null)
{
//返回45度的对角线
ESRI.ArcGIS.Geometry.IPolyline IpLine;
IpLine =newPolylineClass();
IpLine.FromPoint = pEnvelope.LowerLeft;
IpLine.ToPoint = pEnvelope.UpperRight;
returnIpLineasIGeometry;
}
else
{
//直接返回一个IEnvelope矩形区域
returnpEnvelopeasIGeometry;
}
}
}
分享到:
相关推荐
ARCGIS engine 二次开发中关于地图符号的分类、分级渲染。
Arcgis Engine 添加shp.lyr图层,删除图层,移动图层,更改图例符号,属性查询,鹰眼的实现。
主要包括ArcGIS Engine的地图符号化实例代码和测试数据
能够让初学者使用C#结合arcgis engine实现arcmap功能的二次开发,实现界面的搭建、属性表的构建、符号设计器的设计、鹰眼的实现、右键菜单栏的创建等功能。
教程首先从如何来创建一个ArcGIS Engine桌面应用程序开始,依据GIS的数据获取(几何对象与空间参考)、显示(地图与地图布局、图层符号化、地图输出)、处理(地图查询)、分析(空间分析)主线来进行详细讲解。每一具体的...
基于ArcGIS+Engine的符号化研究与实现
ArcGIS_Engine_C#_实例开发教程
5.ArcGIS Engine基础开发教程(4)— 图层符号化 6.ArcGIS Engine基础开发教程(5)——学习地图查询 7.ArcGIS Engine基础开发教程(6)--学习空间分析 8.ArcGIS Engine基础开发教程(7)——学习地图输出 我只是给大家...
ArcGIS Engine9.2实例开发,地图浏览、鹰眼的实现、图层符号选择器的实现、属性数据表的查询显示、图层文本标注
ArcGIS Engine基础开发教程(5)——学习地图查询 地图查询、统计是一个GIS系统的基本的功能模块,实际上统计功能的前提也是通过查询获取结果以文字或者图表等报表的形式展现查询结果数据。 地图查询有两种类型的查询...
首先分析了已有的关于地图符号库研究的不足之处,在此基础上,基于ArcGIS Engine,采用程序设计和参数设计相结合的方式,对地图符号化模块进行设计,并实现了相关功能:既可对地图中的矢量目标数据(点、线、面、...
文档目录: 1创建第一个ArcGIS Engine桌面应用程序... 6 2几何对象与空间参考... 15 3地图和地图布局... 44 4图层符号化... 64 5地图查询... 91 6.空间分析... 110 7地图输出... 121
ArcGIS_Engine基础开发教程(4)—_学习图层符号化
arcgis箭头符号的平滑类,抗锯齿,实现ISymbol,IMarkerSymbol类
ArcGIS与CAD的应用以及相互之间的转换等内容
研究了ArcGISEngine的人机交互编程接口和空间数据符号化渲染技术, 提出了基于ArcGIS Engine的可扩展地图标绘技术方法, 并实现了一个突发事件应急标绘系统。 系统消息管理模块利用C# ...
arcgis engine开发桌面应用程序,具有鹰眼、符号选择等功能
加载mxd 通过工作空间加载shapefile 工作空间加载栅格数据 拉框放大 多种符号叠加 面符号化 点渲染密度 唯一值渲染 共26个示例代码
由网页教程整理而来,为3DSN原创教程,PDF格式,共48页。教程采用C#语言,以VS2005为开发工具。此教程实用性很强,强调实际演练,是一本...第七讲 图层符号选择器的实现 第八讲 属性数据表的查询显示 教程Bug及优化方案
ArcGIS_Engine C#实例开发教程 第一讲:桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与PageLayoutControl同步 (一) 第三讲 MapControl与PageLayoutControl同步 (二) 第三讲 MapControl与...