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);
                }

 

posted @ 2015-03-03 21:14  DayDreamInGIS  阅读(503)  评论(0编辑  收藏  举报