1. 程式人生 > >arcengine Annotation研究的一些學習資料(轉)

arcengine Annotation研究的一些學習資料(轉)

通過 etc 依賴 pda create blog 保存 poster dst

轉自chanyinhelv原文Annotation研究的一些學習資料

下面是我最近對Annotation研究的一些學習資料,收集於此,供大家學習之用。

一、Annotation要素類介紹

在GeoDatabase中有五種類型的要素類,即點、線、面、標註要素類和註記要素類。註記要素類涉及的較少,這裏不談。本文主要討論標註要素類的特征,即Annotation FeatureClass的特性。

標註要素類是一種專門用於存儲和顯示文本或圖形元素的數據結構,在這之前,我們只談過文本或圖像只能通過MXD的方式來存儲。標註要素類可以是獨立的,也可以與一個要素類相關聯。如果是獨立standalone的要素類,它就是其它要素類的一種背景;一旦與某個要素類相聯系link,那麽標註要素顯示的內容就取決於與之相關的要素。

如果要新建一個標註要素類,無論是直接在工作空間中還是在一個要素數據集中,都需要使用到IFeatureWorkspaceAnno的接口,下面我們通過這個接口的CreateAnnotationClass方法來介紹標註要素類的一系列特性:

public IFeatureClass CreateAnnotationClass (
string Name,
IFields Fields,
UID CLSID,
UID EXTCLSID,
string ShapeFieldName,
string ConfigKeyword,
IFeatureDataset dstFeatureDataset,

IFeatureClass srcFeatureClass,
object annoProperties,
object referenceScale,
object symbolCollection,
bool autoCreate
);

Name是新建的標註要素類的名稱,這個字符串可以隨意設置。
Fields是標註要素類的字段,與其它要素類不同的是,標註要素類的系統字段相當的多,這是因為標註字段涉及到存儲字符和修飾字符的Symbol樣式,因此,我們也不建議用戶自己添加這些難以記憶的字段,在這種情況下,我們可以使用一種簡單的方式實現:

IObjectClassDescription pOCDesc=New AnnotationFeatureClassDescription;
Fields=pOCDesc.RequiredFields;
也許有人會問,如果除了這些系統字段外,我們還有自己的字段怎麽辦?這個很簡單,使用IFieldsEdit的方法再加自定義字段就可以了。

CLSID和EXTCLSID兩個參數也是必須的,它們的含義非常有趣。我們知道,GeoDatabase中的每個對象都有個唯一標識符UID,系統是靠認證這個64位的隨機值來區分不同對象的,同樣的,要素類和要素類的擴展部分也有這麽個標識,只不過在一般情況下我們無法看到這個UID值而已。如何產生這兩個值呢,也很簡單,使用:
CLSID=pOCDesc.InstanceCLSID;
EXTCLSID=pOCDesc.ClassExtensionCLSID;

ShapeFieldName是指一個要素類的Shape字段名,一般都是"SHAPE"。

ConfigKeyword一般不用設置,可以設置為空字符串。

dstFeatureDataset是指一個標註要素類被放置的要素數據集,當然,如果這個標註要素類直接放在工作空間中,這個參數將被設置為null即可。

srcFeatureClass是標註要素類關聯的要素類,如果標註要素類是獨立的,則這個參數也可以為null。

接下來的四個參數的前三個就是關鍵了,可以說,整個要素類的正常顯示就是依賴它們。

二、使用Annotation對象進行要素標註並設置標註位置

AO中有兩種方法實現要素標註,一種是自己添加TextElement對象到文檔對象中,另一種就是使用AO提供的Annotation對象,它的功能更加強大和豐富,它以更復雜的方法和屬性對要素圖層進行標註,標註的內容可以保存到地理數據庫中。實現這個要素標註涉及到的對象包括IAnnotateLayerPropertiesCollection對象、IAnnotateLayerProperties對象和ILabelEngineLayerProperties對象,其實現代碼如下:(c#)

public void CreateAnno(IFeatureLayer pFeatureLayer )

{

IGeoFeatureLayer pGeoFLayer = pFeatureLayer as IGeoFeatureLayer;
//得到圖層的標註屬性集合對象
IAnnotateLayerPropertiesCollection pAnnoLayerpRropColl = new AnnotateLayerPropertiesCollectionClass();
pAnnoLayerpRropColl = pGeoFLayer.AnnotationProperties;

//清空這個集合中的對象
pAnnoLayerpRropColl.Clear();

//新建一個圖層標註引擎對象,設置它的屬性
ILabelEngineLayerProperties pLabelEngineLayerProp = new LabelEngineLayerPropertiesClass();
pLabelEngineLayerProp.Expression = "[DYP]";

//創建註記文本的文本符號
ITextSymbol pTextSym = new TextSymbolClass();
pTextSym.Color = GeoTool.GetColor(255, 0, 0);
pTextSym.Size = 10;
IFont font = new StdFontClass();
font.Name = "Times New Roman";
pTextSym.Font = (IFontDisp)font;
pLabelEngineLayerProp.Symbol = pTextSym;

//設置註記文本的位置
IBasicOverposterLayerProperties pBasicOverposeterLayerProp = new BasicOverposterLayerPropertiesClass();
pBasicOverposeterLayerProp.FeatureType = esriBasicOverposterFeatureType.esriOverposterPoint;
pBasicOverposeterLayerProp.FeatureWeight = esriBasicOverposterWeight.esriNoWeight;
pBasicOverposeterLayerProp.LabelWeight = esriBasicOverposterWeight.esriHighWeight;
pBasicOverposeterLayerProp.BufferRatio = 0;

//方式一:標註位於點特征頂部
//pBasicOverposeterLayerProp.PointPlacementOnTop = true;

//方式二:標註環繞點特征
pBasicOverposeterLayerProp.PointPlacementMethod = esriOverposterPointPlacementMethod.esriAroundPoint;
IPointPlacementPriorities pPointPlacement = new PointPlacementPrioritiesClass();
pPointPlacement.AboveCenter = 0;
pPointPlacement.AboveLeft = 0;
pPointPlacement.AboveRight = 0;
pPointPlacement.BelowCenter = 1;
pPointPlacement.BelowLeft = 0;
pPointPlacement.BelowRight = 0;
pPointPlacement.CenterLeft = 0;
pPointPlacement.CenterRight = 0;
pBasicOverposeterLayerProp.PointPlacementPriorities = pPointPlacement;

//方式三:標準旋轉一定角度
//pBasicOverposeterLayerProp.PointPlacementMethod = esriOverposterPointPlacementMethod.esriSpecifiedAngles;
//double[] angle = new double[2];
//angle[0] = 45;
//angle[1] = 90;
//pBasicOverposeterLayerProp.PointPlacementAngles = angle;

pLabelEngineLayerProp.BasicOverposterLayerProperties = pBasicOverposeterLayerProp;

IAnnotateLayerProperties pAnnoLayerProp = (IAnnotateLayerProperties)pLabelEngineLayerProp;
pAnnoLayerpRropColl.Add(pAnnoLayerProp);

pGeoFLayer.DisplayField = pLabelEngineLayerProp.Expression;
pGeoFLayer.DisplayAnnotation = true;

}

三、使用TextElement對象進行要素標註

使用TextElement對象進行要素標註可以控制標註字體的樣式,標註的流程是首先獲取要素圖層中所有要進行標註的要素,然後對各個要素創建TextElement對象,並將其Text設為要素的某個字段屬性,而Geometry是要素包括線的中間點。一下是在三維GlobeControl中的實現代碼如:(c#)

//獲取圖層要素對象

IFeatureCursor pFeatCurso = new FeatureCursorClass();
pFeatCurso = pFeatClass.Search(null, true);
IFeature pFeature = null;
pFeature = pFeatCurso.NextFeature();
while (pFeature != null)
{
//讀取要素
.........................

pFeature = pFeatCurso.NextFeature();
}

以上是有關讀取圖層要素的過程,這裏省略。

添加標註代碼:

說明:pArray中存放的是IGeometry對象

public void AddElement(ArrayList pArray, IGlobeGraphicsLayer pGlobeGraphicsLayer)
{
//刪除上次添加的element
IGraphicsContainer pGraphicsContainer = pGlobeGraphicsLayer as IGraphicsContainer;
pGraphicsContainer.DeleteAllElements();
pGlobeGraphicsLayer.UpdateAllElements();

//設置顯示屬性
IGlobeGraphicsElementProperties pGlobeGraphicsElementProperties = new GlobeGraphicsElementPropertiesClass();
pGlobeGraphicsElementProperties.DrapeElement = true;
pGlobeGraphicsElementProperties.FixedScreenSize = true;
pGlobeGraphicsElementProperties.DrapeQuality = true;
pGlobeGraphicsElementProperties.OrientationMode = esriGlobeGraphicsOrientation.esriGlobeGraphicsOrientationLocal;

int hh;

for (int i = 0; i < pArray.Count; i = i + 2)
{
IGeometry pGeometry = (IGeometry)pArray[i + 1];
IPoint point = new PointClass();
point = GeoTool.GetGeo(pGeometry);


//添加點element對象(設置標註對象形狀)
IElement pElement = new MarkerElementClass(); //定義為標註性對象方便後續設置
ISimpleMarkerSymbol pSimpleMarkerSymbol = new SimpleMarkerSymbolClass(); //設置形狀
pSimpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
IMarkerSymbol pMarkerSymbol = pSimpleMarkerSymbol as IMarkerSymbol; //設置顏色大小
pMarkerSymbol.Color = GeoTool.GetColor(0, 255, 0);
pMarkerSymbol.Size = 5;

pElement.Geometry = point as IGeometry;
IMarkerElement pMarkerElement = pElement as IMarkerElement;
pMarkerElement.Symbol = pMarkerSymbol;
pGlobeGraphicsLayer.AddElement(pElement as IElement, pGlobeGraphicsElementProperties, out hh);

//添加文本element對象(標註的文字部分)
ITextElement pTextElement = new TextElementClass();
ITextSymbol pTextSymbol = new TextSymbolClass();
pTextSymbol.Color = GeoTool.GetColor(255, 0, 0);
pTextSymbol.Size = 10;
IFontDisp pFontDisp = (IFontDisp)new StdFontClass();      //設置字體
pFontDisp.Name = "Times New Roman";
pFontDisp.Bold = true;
pFontDisp.Size = 10;
pTextSymbol.Font = pFontDisp;
pTextSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft;
pTextElement.Symbol = pTextSymbol;
pTextElement.Text = pArray[i].ToString();
((IElement)pTextElement).Geometry = point as IGeometry;
pGlobeGraphicsLayer.AddElement(pTextElement as IElement, pGlobeGraphicsElementProperties, out hh);
}
}

對於二維中要加載TextElement標註,其創建TextElement的方法相同,主要是在於後面加載的方式不同而已,加載到的對象不同而已,三維GlobeControl中是加載到一個IGlobeGraphicsLayer中,二維中則是加載到MapControl的Map對象中。其核心代碼如下:

IMap pMap = axMapControl1.Map;

IActiveView pActiveView = pMap as IActiveView;

IGraphicsContainer pGraphicsContainer = pMap as IGraphicsContainer;

//將元素添加進Map對象中

pGraphicsContainer.AddElement(pElement,0);

pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics,null,null);

arcengine Annotation研究的一些學習資料(轉)