ArcEngine TextElement 定位点的问题
做ArcGIS Add-In开发,需要在ArcMap中数据视图的左上角加一个上标,如果上标与数据中的地名图层重合,则放在右上角.
上标通过ITextElement,IElement,ITextSymbol等接口实现.
想当然的以为文本元素的定位点为左下角点或者右下角点,结果实验了半天,文字注记的位置一直匪夷所思.
以为之间的参数传输错误,下载了个像素三角尺,一边调试一边量屏幕的像素,发现这个定位点似乎是在文字的中下部的位置,
可是在ArcMap中用绘制工具绘制的文本,定位点似乎是在左下角点.
搞不明白,只能想办法解决,解决思路如下:
在屏幕的中间位置绘制TextElement,获取文本元素的Envelope对象,计算该Envelope对象的左上角点至ArcMap的左上角点
的像素坐标差,或Envelope的右上角点至ArcMap的右上角点的像素坐标差,根据计算出的像素坐标差,对之前绘制的TextElement
的定位点进行修正,更新TextElement.经过测试,结果满足要求.
核心代码如下:
IElement pEle = null; pAv = pMap as IActiveView; IGraphicsContainer pgc = pMap as IGraphicsContainer; bool b_Cover = false; if (SetPanel.addUpperTxt) { if (string.IsNullOrEmpty(SetPanel.locationTxt)) { MessageBox.Show("无上标文字,请输入或选择字段后重新截图"); return; } //在当前视图位置左上角绘制上标文字 IPoint pntLocation = new PointClass(); int pixelY =100; //SetPanel.VerOffset + (int)fontsize; int pixelX =100; //SetPanel.HorOffset + (SetPanel.locationTxt.Length) * (int)fontsize; pntLocation = pAv.ScreenDisplay.DisplayTransformation.ToMapPoint(pixelX, pixelY); ITextElement pTxtEle = new TextElementClass(); ITextSymbol ptxtSymbol = new TextSymbolClass(); ptxtSymbol.Font.Name = "宋体"; IRgbColor pColor = new RgbColorClass(); pColor.Blue = 255; pColor.Red = 255; pColor.Green = 0; ptxtSymbol.Color = pColor; ptxtSymbol.Size = fontsize; ptxtSymbol.Font.Bold = true; pTxtEle.Symbol = ptxtSymbol; pTxtEle.Text = SetPanel.locationTxt; pEle = pTxtEle as IElement; pEle.Geometry = pntLocation; pgc.AddElement(pEle, 0); pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics,null,null); IEnvelope pNewEnv = new EnvelopeClass(); pEle.QueryBounds(pAv.ScreenDisplay,pNewEnv); int currentPixelX, currentPixelY; pAv.ScreenDisplay.DisplayTransformation.FromMapPoint(pNewEnv.UpperLeft, out currentPixelX, out currentPixelY); int txtLocationX = pixelX + SetPanel.HorOffset - currentPixelX; int txtLocationY = pixelY + SetPanel.VerOffset - currentPixelY; pEle.Geometry = pAv.ScreenDisplay.DisplayTransformation.ToMapPoint(txtLocationX, txtLocationY); pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); pEle.QueryBounds(pAv.ScreenDisplay, pNewEnv); ISegmentCollection segCol = new PolygonClass(); segCol.SetRectangle(pNewEnv); //判断是否覆盖 if (IsCoverOrNot((IPolygon)segCol, pMap)) { pAv.ScreenDisplay.DisplayTransformation.FromMapPoint(pNewEnv.UpperRight, out currentPixelX, out currentPixelY); ESRI.ArcGIS.esriSystem.tagRECT Rect = pAv.ExportFrame; int activeViewWidth = Rect.right - Rect.left; //定位点校正 txtLocationX = txtLocationX+activeViewWidth-SetPanel.HorOffset-currentPixelX; //txtLocationY = pixelY + SetPanel.VerOffset - currentPixelY; pEle.Geometry = pAv.ScreenDisplay.DisplayTransformation.ToMapPoint(txtLocationX, txtLocationY); pEle.QueryBounds(pAv.ScreenDisplay, pNewEnv); segCol = new PolygonClass(); segCol.SetRectangle(pNewEnv); if (IsCoverOrNot((IPolygon)segCol, pMap)) { b_Cover = true; MessageBox.Show("注记与小地名图层存在压盖,请调整视图"); } } pgc.UpdateElement(pEle); }