原發表於ESRI中國社區,轉過來。我的社區帳號:jhlong
----------------------------------------我是分割線,下面才是正文--------------------------------------------------------
1.說明
6周年征文
似乎就我這一篇ArcEngine開發的,搞開發的很少么?還是搞開發的都不善於言語?歡迎做ArcEngine開發的交流心得。
ArcGis里的注記,個人認為常用的有:
1.圖層標注如arcmap里圖層右鍵屬性-labels內的label。這些有不少高級注記功能,其實ArcEngine都可以實現。看到論壇里也有不少沒解決的於此相關的問題。具體看下面代碼。
2.屏幕element。這類有文本、點、線、面等,且可設置各種樣式和符號。這些不保存在數據庫中,可以通過保存mxd的方式進行保存。
3.注記圖層。就是IAnnoClass,存於數據庫的注記。
以下代碼也是針對以上3種注記類型進行說明。
個人文字描述不是太好,所以不多說,主要是代碼加注釋。需要時去找對應的大標題下的內容即可,總體不難理解。
文檔看起來排版有點亂,附上下載,下載的可能不是最新的,以本帖為准。
http://pan.baidu.com/share/link?shareid=104303&uk=305065349
CSDN下載:
http://download.csdn.net/detail/jhlong12345/4768967
【初級】ArcEngine注記處理專題.zip (45.79 KB)
新浪愛問下載:http://ishare.iask.sina.com.cn/f/34753842.html
值此論壇6周年之際,發出來慶祝論壇生日快樂。
主要適合初學者,也有一些高級功能及不常用的。自行選擇。
代碼應該都可以直接復制粘貼使用,不能用時請自己思考,還不行可以pm我。
如果看的過程中有任何疑問,請pm我。回帖也可以,但有可能漏掉。
初次寫這種文章,如果有不對的或需要補充或描述不清晰的地方,煩請大家告知。
如果覺得對你有用,請多多支持。
6周年征文
似乎就我這一篇ArcEngine開發的,搞開發的很少么?還是搞開發的都不善於言語?歡迎做ArcEngine開發的交流心得。
ArcGis里的注記,個人認為常用的有:
1.圖層標注如arcmap里圖層右鍵屬性-labels內的label。這些有不少高級注記功能,其實ArcEngine都可以實現。看到論壇里也有不少沒解決的於此相關的問題。具體看下面代碼。
2.屏幕element。這類有文本、點、線、面等,且可設置各種樣式和符號。這些不保存在數據庫中,可以通過保存mxd的方式進行保存。
3.注記圖層。就是IAnnoClass,存於數據庫的注記。
以下代碼也是針對以上3種注記類型進行說明。
個人文字描述不是太好,所以不多說,主要是代碼加注釋。需要時去找對應的大標題下的內容即可,總體不難理解。
文檔看起來排版有點亂,附上下載,下載的可能不是最新的,以本帖為准。
http://pan.baidu.com/share/link?shareid=104303&uk=305065349
CSDN下載:
http://download.csdn.net/detail/jhlong12345/4768967

新浪愛問下載:http://ishare.iask.sina.com.cn/f/34753842.html
值此論壇6周年之際,發出來慶祝論壇生日快樂。
主要適合初學者,也有一些高級功能及不常用的。自行選擇。
代碼應該都可以直接復制粘貼使用,不能用時請自己思考,還不行可以pm我。
如果看的過程中有任何疑問,請pm我。回帖也可以,但有可能漏掉。
初次寫這種文章,如果有不對的或需要補充或描述不清晰的地方,煩請大家告知。
如果覺得對你有用,請多多支持。
請勿用於商業用途,請免費轉載和分享,轉載請注明作者和出處。
目錄
1.說明 1
2.准備工作 2
2.1創建一個自定義顏色IRgbColor 2
2.2添加Element到地圖窗口 2
2.3字體不隨地圖縮放變化 2
3.為圖層增加注記表達式 2
4.注記表達式轉圖層要素 5
5.創建注記圖層要素 6
6.創建文本注記TextElement 7
6.1創建一個字體 7
6.2創建文本注記樣式 8
6.3.創建文本注記 8
7.創建面注記PolygonElement 8
7.1根據4點創建一個面 8
7.2.創建面符號 9
7.3.創建PolygonElement 9
8.創建線注記LineElement 9
8.1根據2點創建一條線 9
8.2.創建線符號 10
8.3.創建線注記 10
9創建一個點狀注記(MarkerElement) 10
9.1根據XY創建一個點 10
9.2.創建MarkerElement 11
10.符號 11
內容整理自我的博客: http://jhlong12345.blog.163.com/ ... 631292012625336861/ 。
2.准備工作
2.1創建一個自定義顏色IRgbColor
下面會用到,很簡單的一個小函數
/// <summary> /// 自定義顏色,3個0是黑色,3個255是白色/// </summary> /// <param name="r">紅,取值0—255,下同</param> /// <param name="g">綠.</param> /// <param name="b">藍</param> /// <returns>IRgbColor</returns> /// <remarks></remarks> private static IRgbColor ColorCustom(int r, int g, int b) { IRgbColor myColor = new RgbColor(); myColor.Red = r; myColor.Blue = b; myColor.Green = g; return myColor; }
創建完Element后,用下面這句就可以加到當前地圖窗口了。
(pMap as IGraphicsContainer) .AddElement(ele, 0);
2.3字體不隨地圖縮放變化
IMAP的ReferenceScale方法設置為0時,無論地圖如何縮放,字體大小的屏幕距離不變,地圖距離隨比例尺變化。設置為其他比例尺如10000時,字體的地圖距離就保持比例尺為10000時的高度,屏幕距離一直隨比例尺變化。
3.為圖層增加注記表達式
從注記表達式的文本文件中程序里讀取並動態地增加注記。label expression 可以為簡單的或vb腳本等。[]內的是字段名稱。
例如:
Function FindLabel ([BH],[BM],[KD],[XZ]) FindLabel = FormatNumber([KD],2,true,false,false) if (IsNull([XZ]) or ([XZ] = "")) then FindLabel = [BH] &"/"& [BM]&chr(13)&chr(10)&FindLabel if left([XZ],1)=1 or left([XZ],1)=2 then FindLabel = [BH]&"G/"&[BM]&chr(13)&chr(10)&FindLabel if left([XZ],1)=3 or left([XZ],1)=4 then FindLabel = [BH] &"/"&[BM]&chr(13)&chr(10)&FindLabel End Function
[XZ]
這里的接口很少用,但是合理利用的話可以達到ArcMap里的高級效果
代碼如下:
/// <summary> /// 圖層增加注記表達式 /// </summary> /// <param name="map">The map.</param> /// <param name="tcname">The tcname.</param> public static void AddAnno(ILayer plyr , string tcname) { if (!System.IO.File.Exists(注記文件存儲路徑)) return; IGeoFeatureLayer pGeoFeaLayer = (plyr as IFeatureLayer) as IGeoFeatureLayer; IAnnotateLayerPropertiesCollection pAnoLayPC = pGeoFeaLayer.AnnotationProperties; pAnoLayPC.Clear(); ILabelEngineLayerProperties pAnnoLayerProps = new LabelEngineLayerPropertiesClass(); (pAnnoLayerProps.BasicOverposterLayerProperties as IOverposterLayerProperties2).TagUnplaced = false; ////是否覆蓋,對應Arcmap:layer properties-》labels-》placement properties-》conflict detection ::place overlapping labels pAnnoLayerProps.SymbolID = 0; IBasicOverposterLayerProperties4 blp = pAnnoLayerProps.BasicOverposterLayerProperties asIBasicOverposterLayerProperties4; //blp.PointPlacementMethod = esriOverposterPointPlacementMethod.esriAroundPoint; blp.NumLabelsOption = esriBasicNumLabelsOption.esriOneLabelPerShape; ////每個圖形只標注一個 label properties--palcement properties--duplicate labels blp.PolygonPlacementMethod = esriOverposterPolygonPlacementMethod.esriAlwaysHorizontal; //// label properties--palcement properties--polygon settings // blp.PlaceOnlyInsidePolygon = true; ////保證在圖形內部 label properties--palcement properties--only place label inside polygon string annoExpression = GetAnnoExpression(注記文件存儲路徑); if (annoExpression.ToUpper().IndexOf("FUNCTION") >= 0) pAnnoLayerProps.IsExpressionSimple = false; else pAnnoLayerProps.IsExpressionSimple = true; //對應aArcMap的advanced選項 pAnnoLayerProps.Expression = annoExpression; pAnnoLayerProps.Symbol = CreateTextSymbol(); pGeoFeaLayer.DisplayAnnotation = true; } /// <summary> /// 根據注記文件存儲路徑獲取標注表達式 /// </summary> /// <param name="tcname">The tcname.</param> /// <returns></returns> public static string GetAnnoExpression(string注記文件存儲路徑) { StreamReader sr = new StreamReader(注記文件存儲路徑); string annoExpression = string.Empty; while (!sr.EndOfStream) { string text = sr.ReadLine(); if (annoExpression == string.Empty) annoExpression = text; else annoExpression = annoExpression + "\r\n" + text; } return annoExpression; }
這段代碼參見幫助文檔,無需多解釋,根據需要使用。
public static void ConvertLabelsToGDBAnnotationSingleLayer(IMap pMap, int layerIndex, bool featureLinked, stringlogpath) { string tcmc = string.Empty; try { IConvertLabelsToAnnotation pConvertLabelsToAnnotation = new ConvertLabelsToAnnotationClass(); ITrackCancel pTrackCancel = new CancelTrackerClass(); //Change global level options for the conversion by sending in different parameters to the next line. pConvertLabelsToAnnotation.Initialize(pMap, esriAnnotationStorageType.esriDatabaseAnnotation, esriLabelWhichFeatures.esriAllFeatures, true, pTrackCancel, null); ILayer pLayer = pMap.get_Layer(layerIndex); IGeoFeatureLayer pGeoFeatureLayer = pLayer as IGeoFeatureLayer; if (pGeoFeatureLayer != null) { IFeatureClass pFeatureClass = pGeoFeatureLayer.FeatureClass; IDataset pDataset = pFeatureClass as IDataset; tcmc = GtMap.JNCommon.Engine.GetPureName(pDataset.Name); IFeatureWorkspace pFeatureWorkspace = pDataset.Workspace as IFeatureWorkspace; //Add the layer information to the converter object. Specify the parameters of the output annotation feature class here as well. pConvertLabelsToAnnotation.AddFeatureLayer(pGeoFeatureLayer, tcmc + "ZJ", pFeatureWorkspace, pFeatureClass.FeatureDataset, featureLinked, true, true, true, true, ""); //Do the conversion. pConvertLabelsToAnnotation.ConvertLabels(); string errorInfo = pConvertLabelsToAnnotation.ErrorInfo; if (!string.IsNullOrEmpty(errorInfo)) LogWrite(logpath, errorInfo); //IEnumLayer pEnumLayer = pConvertLabelsToAnnotation.AnnoLayers; //Turn off labeling for the layer converted. pGeoFeatureLayer.DisplayAnnotation = false; //Add the result annotation layer to the map. //pMap.AddLayers(pEnumLayer, true); //Refresh the map to update the display. IActiveView pActiveView = pMap as IActiveView; pActiveView.Refresh(); iConvertCnt++; if (iConvertCnt < 6) { IFeatureClass cls = pFeatureWorkspace.OpenFeatureClass(tcmc + "ZJ"); if (cls != null) { if ((cls.FeatureCount(null) == 0) && (pFeatureClass.FeatureCount(null) > 0)) { pGeoFeatureLayer.DisplayAnnotation = true; ConvertLabelsToGDBAnnotationSingleLayer(pMap, layerIndex, featureLinked, logpath); } } } } } catch (System.Exception ex) { } }
創建完文本注記TextElement后,可以選擇以屏幕注記的形式加到屏幕上,也可以通過下面的方式轉為注記圖層要素:
IFeatureClass annocls = 獲取注記圖層 IDataset pDataset = annocls as IDataset; ITransactions pTransactions = pDataset.Workspace as ITransactions; pTransactions.StartTransaction(); IFDOGraphicsLayerFactory pFDOGLFactory = new FDOGraphicsLayerFactoryClass(); ILayer tmpLayer = pFDOGLFactory.OpenGraphicsLayer(pDataset.Workspace as IFeatureWorkspace, annocls.FeatureDataset, pDataset.Name); IFDOGraphicsLayer pFDOGLayer = tmpLayer as IFDOGraphicsLayer; IElementCollection pElementColl = new ElementCollectionClass(); pFDOGLayer.BeginAddElements(); ……………………………… //創建text element pElementColl.Add(element, 0); ……………………………. ////每新增100個提交下,最后再提交下。防止過多轉換失敗 if ((pElementColl != null) && (pElementColl.Count == 100)) { pFDOGLayer.DoAddElements(pElementColl, 0); pFDOGLayer.EndAddElements(); pElementColl.Clear(); pTransactions.CommitTransaction(); pTransactions.StartTransaction(); pFDOGLayer.BeginAddElements(); } if (pElementColl.Count > 0) pFDOGLayer.DoAddElements(pElementColl, 0); pFDOGLayer.EndAddElements(); pElementColl.Clear(); pTransactions.CommitTransaction();
6.1創建一個字體
/// <summary> /// 字體設置 /// </summary> /// <param name="size">The size.</param> /// <param name="fontname">The fontname.</param> /// <returns> /// IFontDisp /// </returns> public static stdole.IFontDisp GetIFontDisp(float size, string fontname) { string fontFamilyName = fontname; FontStyle fontStyle = FontStyle.Regular; Font font = new Font(fontFamilyName, size, fontStyle); return OLE.GetIFontDispFromFont(font) as stdole.IFontDisp; }
/// <summary> ///文本注記樣式 /// </summary> /// <param name="geometry">標注點,一個點即可</param> /// <param name="text">標注內容</param> /// <returns> /// IElement /// </returns> public static ITextSymbol GetTextElement(IGeometry geometry, string text) { ITextSymbol textSymbol = new TextSymbolClass(); textSymbol.Color = ColorCustom(0, 0, 0); ////不可以直接修改textSymbol.Font.Bold等屬性,無效 stdole.IFontDisp font = GetIFontDisp(9F, "宋體"); font .Bold = false; font .Italic = false; font .Strikethrough = false; font .Underline = false; textSymbol.Font = font; textSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft; ////水平 textSymbol.VerticalAlignment = esriTextVerticalAlignment.esriTVATop; ; ////垂直 return textSymbol ; }
ITextElement textElement = new TextElementClass(); textElement.ScaleText = true; textElement.Symbol = GetTextElement(); textElement.Text = text; IElement element = textElement as IElement; element.Geometry = geometry;
7.1根據4點創建一個面
/// <summary> /// 根據4個點創建圖形,點序要順時針 /// </summary> /// <param name="pnt1">點1</param> /// <param name="pnt2">點2</param> /// <param name="pnt3">點3</param> /// <param name="pnt4">點4</param> /// <returns>IPolygon</returns> public static IPolygon CreatePolygonBy4Points(IPoint pnt1, IPoint pnt2, IPoint pnt3, IPoint pnt4) { IPointCollection pPntCol = new PolygonClass(); object missing = Type.Missing; ////順時針添加 pPntCol.AddPoint(pnt1, ref missing, ref missing); pPntCol.AddPoint(pnt2, ref missing, ref missing); pPntCol.AddPoint(pnt3, ref missing, ref missing); pPntCol.AddPoint(pnt4, ref missing, ref missing); pPntCol.AddPoint(pnt1, ref missing, ref missing); //// 為保持首尾相聯,故將第一個點再添加一次 return pPntCol as IPolygon; }
/// <summary> /// 創建 面 符號 /// </summary> /// <param name="r">The r.</param> /// <param name="g">The g.</param> /// <param name="b">The b.</param> /// <returns>ISimpleFillSymbol</returns> public static ISimpleFillSymbol CreateGeoSymbol(int r, int g, int b) { ISimpleFillSymbol psymbol = new SimpleFillSymbolClass() as ISimpleFillSymbol; psymbol.Color = ColorCustom(r, g, b); psymbol.Outline.Color = ColorCustom(r, g, b); return psymbol; }
IElement pele = new PolygonElementClass(); pele.Geometry = pGeoCol as IGeometry; (pele as IFillShapeElement).Symbol = CreateGeoSymbol(r, gD, b); (pmap as IGraphicsContainer).AddElement(pele, 0);
8.1根據2點創建一條線
/// <summary> /// 創建線 /// </summary> /// <param name="pnt1">The PNT1.</param> /// <param name="pnt2">The PNT2.</param> public static void CreateLine( IPoint pnt1, IPoint pnt2) { IPolyline pline = new PolylineClass(); pline.FromPoint = pnt1; pline.ToPoint = pnt2; }
/// <summary> /// 創建 線 符號 /// </summary> /// <param name="r">The r.</param> /// <param name="g">The g.</param> /// <param name="b">The b.</param> /// <returns>ILineSymbol</returns> /// <remarks></remarks> private static ILineSymbol CreateLineSymbol(int r, int g, int b) { ILineSymbol psymbol = new SimpleLineSymbolClass() as ILineSymbol; psymbol.Color = ColorCustom(r, g, b); psymbol.Width = 1; return psymbol; }
IElement pele = new LineElementClass(); pele.Geometry = pPolyline as IGeometry; (pele as ILineElement).Symbol = CreateLineSymbol(r, g, b); (pmap as IGraphicsContainer).AddElement(pele, 0);
9.1根據XY創建一個點
/// <summary> /// 根據x y創建新點 /// </summary> /// <param name="dX">x坐標值</param> /// <param name="dY">y坐標值</param> /// <returns>返回點要素</returns> /// <remarks></remarks> public static IPoint GetPntFromXY(double dX, double dY) { IPoint pPnt = new PointClass(); pPnt.PutCoords(dX, dY); return pPnt; }
IElement pele = new MarkerElementClass(); pele.Geometry = GetPntFromXY(x, y); IMarkerSymbol sym = new SimpleMarkerSymbolClass(); sym.Color = ColorCustom(rDefault, gDefault, bDefault); sym.Size = 4; (pele as IMarkerElement).Symbol = sym;
Element創建好后可以賦個符號。這一塊主要是符號化相關的東西,不做詳細介紹,只簡單創建一個。
ISimpleFillSymbol pSFillSym = new SimpleFillSymbolClass(); pSFillSym.Style = esriSimpleFillStyle.esriSFSHollow; ISimpleLineSymbol pLineSymbol = new SimpleLineSymbolClass(); pLineSymbol.Style=esriSimpleLineStyle.esriSLSNull; pSFillSym.Outline = pLineSymbol; ISimpleMarkerSymbol Symbol = new SimpleMarkerSymbolClass(); (pSymbol as IMarkerSymbol).Size = 3;