ArcGIS Engine專題地圖渲染器的實現(入門版)
- 2019 年 10 月 30 日
- 筆記
專題地圖(Thematic Map)是著重表示一種或數種自然要素特徵或社會經濟現象的地圖
專題地圖的內容由兩部分構成:
1、專題內容——圖上突出表示的自然或社會經濟現象及其有關特徵
2、地理基礎——用以標明專題要素空間位置與地理背景的普通地圖內容,主要有經緯網、水系、境界、居民地等。
專題地圖製作依據要素的一個或多個不同的屬性欄位,根據欄位值賦予地理對象不同的符號樣式或者顏色,以區分不同屬性值的地理要素。
ArcGIS Engine提供了8種標準的著色方案,每一種方案都對應了一類特徵渲染器(Renderer)。
特徵渲染器是繪製專題地圖的入口。
特徵渲染器使用專題地圖的一般性表示方法,如質底法、點值法、分級比例法等,以目標要素類圖層的某個欄位作為渲染依據,合理渲染不同欄位值的要素,直至一個要素類中的所有要素都被渲染。完成渲染工作,配上製圖要素——比例尺、指北針、圖名、圖例等後輸出,即可完成一幅專題圖的製作。其中,IGeoFeatureLayer的Renderer屬性提供了專題圖渲染的入口。簡言之,通過對目標圖層的Renderer屬性進行渲染即可完成專題圖的渲染工作。
下面將介紹五種渲染器的實現方法
1、簡單符號法渲染器
2、分等級法渲染器
3、唯一值法渲染器
4、比例符號法渲染器
5、點狀密度法渲染器
還剩下三種渲染器以後再實現
6、圖表渲染器
7、分級唯一值法渲染器
8、依比例法渲染器
各類專題圖均用的函數
getRGB(int r, int g, int b)
getGeoLayer(string layerName)
#region 各類專題圖均用的函數 /// <summary> /// 獲得顏色的函數 /// </summary> /// <param name="r">紅色Red</param> /// <param name="g">綠色Green</param> /// <param name="b">藍色Blue</param> /// <returns>返回顏色</returns> private IRgbColor getRGB(int r, int g, int b) { IRgbColor pColor = new RgbColorClass(); pColor.Red = r; pColor.Green = g; pColor.Blue = b; return pColor; } /// <summary> /// 獲取渲染圖層 /// </summary> /// <param name="layerName">圖層名字</param> /// <returns>圖層</returns> private IGeoFeatureLayer getGeoLayer(string layerName) { ILayer pLayer; //定義圖層 IGeoFeatureLayer pGeoFeatureLayer; //定義要素圖層 Geo? //遍歷圖層 for (int i = 0; i < axMapControl1.LayerCount; i++) { pLayer = axMapControl1.get_Layer(i); //若當前圖層不為空且與與layerName的值相同 if (pLayer != null && pLayer.Name == layerName) { //強轉成IGeoFeatureLayer pGeoFeatureLayer = pLayer as IGeoFeatureLayer; //返回pGeoFeatureLayer對象 return pGeoFeatureLayer; } } return null; //返回null } #endregion
1、簡單符號法渲染器
簡單符號法渲染(SimpleRenderer), 用同一個符號繪製所有特徵
①設置簡單填充符號(SimpleFillSymbol)的顏色、樣式、外邊界線等參數
②設置簡單線型符號(SimpleLineSymbol)的樣色和樣式等參數
③實例化簡單渲染(SimpleRender)對象並設置Symbol、Lable、Description等相關參數
④對指定圖層的Render屬性賦值, 完成專題圖製作
⑤刷新主地圖
/// <summary> /// 簡單符號法渲染器(SimpleRenderer), 用同一個符號繪製所有特徵 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void 簡單符號法渲染ToolStripMenuItem_Click(object sender, EventArgs e) { //實例化ISimpleFillSysmbol變數, 提供簡單的填充符號類型 ISimpleFillSymbol pSimpleFillSymbol = new SimpleFillSymbolClass(); //設置填充符號的樣式——為呈45度的交叉線(xxx) ///Horizontal and vertical crosshatch ++++++. pSimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSCross; //設置填充符號的顏色——紅色 pSimpleFillSymbol.Color = getRGB(96, 96, 96); //創建邊線符號變數, 提供簡單的線條符號類型 ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbolClass(); //設置線符號樣式——線呈交替虛線和雙點(_.._.._) //The line has alternating dashes and double dots _.._.._. pSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSDashDotDot; //設置線符號顏色——綠色 pSimpleLineSymbol.Color = getRGB(255, 0, 0); //設置線符號寬度——1.5 pSimpleLineSymbol.Width = 1.5; //將線符號強轉成ISymbol符號變數 ISymbol pSymbol = pSimpleLineSymbol as ISymbol; //設置符號屬性ROP2為二元柵格esriROPNotXOrPen pSymbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen; //設置填充符號外邊界的樣式為pSimpleLineSymbol pSimpleFillSymbol.Outline = pSimpleLineSymbol; //實例化簡單渲染變數 ISimpleRenderer pSimpleRender = new SimpleRendererClass(); //設置pSimpleRender的符號樣式 pSimpleRender.Symbol = pSimpleFillSymbol as ISymbol; //設置標籤名稱, 用於設置圖例 pSimpleRender.Label = "北部灣"; //設置符號描述, 用於設置圖例 pSimpleRender.Description = "簡單渲染"; //定義IGeoFeatureLayer變數, 提供一個要素圖層對成員控制地理特徵渲染的入口, 即Renderer屬性 IGeoFeatureLayer pGeoFeatureLayer; //調用函數獲取渲染圖層 pGeoFeatureLayer = getGeoLayer("北部灣"); if (pGeoFeatureLayer != null) { //調用Renderer屬性, 具體說明如何通過圖層要素渲染器渲染圖層 pGeoFeatureLayer.Renderer = pSimpleRender as IFeatureRenderer; } axMapControl1.Refresh(); //刷新axMapControl1 axTOCControl1.Update(); //更新axTOCControl1 }
2、分等級法渲染器
分等級法渲染器(ClassBreakRenderer), 可以用分級的顏色和符號來繪製
①獲得目標圖層的屬性表後賦值到ITableHistogram對象
②利用IBasicHistogram的GetHistogram方法對屬性表內數據進行統計
③利用IClassifyGEN分級
④實例化分級渲染器(ClassBreakRenderer),渲染所有地圖
⑤賦值目標圖層的Renderer, 完成渲染
⑥刷新地圖
/// <summary> /// 分等級法渲染器(ClassBreakRenderer), 可以用分級的顏色和符號來繪製 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void 分等級法渲染ToolStripMenuItem_Click(object sender, EventArgs e) { //數據分成10個等級 int classCount = 10; //聲明一個ITableHistogram變數 //該變數用於控制從表格中生成的直方圖的樣式 ITableHistogram pTableHistogram; //聲明一個IBasicHistogram變數 //該變數用於控制從不同數據源中生成的直方圖 IBasicHistogram pBasicHistogram; //實例化表格對象 ITable pTable; //獲取生成分級專題圖的目標圖層 IGeoFeatureLayer pGeoFeatureLayer; //獲取渲染圖層 pGeoFeatureLayer = getGeoLayer("北部灣"); //將pGeoFeatureLayer強轉成ILayer ILayer pLayer = pGeoFeatureLayer as ILayer; //將目標圖層(要素類)的屬性表強轉成ITable pTable = pLayer as ITable; //實例化 //BasicTableHistogram採用表對象輸入數據的結構(如自然斷點、分位數)生成直方圖。 pTableHistogram = new BasicTableHistogramClass(); //賦值pTableHistogram的Table屬性欄位 pTableHistogram.Table = pTable; //確定分級欄位 pTableHistogram.Field = "年"; //pTableHistogram強制轉換為IBasicHistogram pBasicHistogram = pTableHistogram as IBasicHistogram; //先統計每個值出現的次數, 輸出結果賦予values, frequencys object values; object frequencys; //out參數可以在一個方法中返回多個不同類型的值 pBasicHistogram.GetHistogram(out values, out frequencys); //創建平均分級對象 IClassifyGEN pClassifyGEN = new QuantileClass(); //用統計結果(values——值, frequences——出現頻率)進行分級, 級別數目為classCount pClassifyGEN.Classify(values, frequencys, ref classCount); double[] classes; classes = pClassifyGEN.ClassBreaks as double[]; //獲得分級結果, 是個雙精度類型數組 //注意:獲得雙精度數組記錄條數出現不可修復性錯誤, 故使用以下程式碼修復該錯誤 double[] myclasses; myclasses = new double[classCount]; //當classes不為null時 if (classes != null) { //遍歷classes, 從後往前移一位 for (int j = 0; j < classCount; j++) { myclasses[j] = classes[j + 1]; } } //定義一個顏色枚舉變數, 通過函數獲取顏色帶 IEnumColors pEnumColors = CreateAlgorithmicColorRamp(myclasses.Length).Colors; IColor color; //聲明並實例化分級渲染器對象類 //該變數提供成員控制漸變色、漸變符號專題圖的製作 IClassBreaksRenderer classBreaksRenderer = new ClassBreaksRendererClass(); //確定分級渲染的屬性欄位 classBreaksRenderer.Field = "年"; //分級數量 classBreaksRenderer.BreakCount = classCount; //指示該專題圖是否按升序顯示 classBreaksRenderer.SortClassesAscending = true; //簡單填充符號(ISimpleFillSymbol) //該變數提供對成員的訪問, 控制簡單的填充符號 ISimpleFillSymbol simpleFillSymbol; //通過一個循環, 給所有渲染的等級附上渲染顏色 for (int i = 0; i < myclasses.Length; i++) { color = pEnumColors.Next(); simpleFillSymbol = new SimpleFillSymbolClass(); simpleFillSymbol.Color = color; //設置填充的樣式(Style)為實體填充 simpleFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid; //指定分級渲染的符號(Symbol) classBreaksRenderer.set_Symbol(i, simpleFillSymbol as ISymbol); //按照分級進行渲染 classBreaksRenderer.set_Break(i, myclasses[i]); } if (pGeoFeatureLayer != null) { //調用Renderer屬性, 具體說明如何通過圖層要素渲染器繪製圖層 pGeoFeatureLayer.Renderer = classBreaksRenderer as IFeatureRenderer; } axMapControl1.Refresh(); //刷新axMapControl1 axTOCControl1.Update(); //更新axTOCControl1 }
需要用到的函數:CreateAlgorithmicColorRamp(int count)
/// <summary> /// 創建規則的顏色帶 /// </summary> /// <param name="count"></param> /// <returns></returns> private IColorRamp CreateAlgorithmicColorRamp(int count) { //創建一個新漸變色帶(AlgorithmicColorRampClass)對象 IAlgorithmicColorRamp algColorRamp = new AlgorithmicColorRampClass(); IRgbColor fromColor = new RgbColorClass(); IRgbColor toColor = new RgbColorClass(); //創建其實顏色對象, 採用三原色定律 fromColor.Red = 255; fromColor.Green = 235; fromColor.Blue = 214; //創建終止顏色對象 toColor.Red = 196; toColor.Green = 10; toColor.Blue = 10; //設置AlgorithmicColorRampClass的起止顏色屬性 algColorRamp.ToColor = toColor; algColorRamp.FromColor = fromColor; //設置梯度類型 algColorRamp.Algorithm = esriColorRampAlgorithm.esriCIELabAlgorithm; //設置顏色帶顏色數量 algColorRamp.Size = count; //創建顏色帶 bool bture = true; algColorRamp.CreateRamp(out bture); return algColorRamp; }
註:out參數可以在一個方法中返回多個不同類型的值
3、唯一值法渲染器
唯一值法渲染器(UniqueValueRender)——根據特徵的某不同屬性值來繪製該特徵的符號
①遍歷要素類
②獲得渲染欄位下的值
③使用IUniqueValueRenderer所提供的Addvalue方法渲染各個值
④賦值目標圖層的Renderer屬性, 完成渲染
⑤刷新地圖
/// <summary> /// 唯一值法渲染器(UniqueValueRender)——根據特徵的某不同屬性值來繪製該特徵的符號 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void 唯一值法渲染ToolStripMenuItem_Click(object sender, EventArgs e) { //定義IGeoFeatureLayer變數, 提供一個要素圖層對成員控制地理特徵的入口 IGeoFeatureLayer geoFeatureLayer = getGeoLayer("北部灣"); //使用查詢的方式, 獲得參與渲染的記錄條數 int get_Count = geoFeatureLayer.FeatureClass.FeatureCount(null); //提供操作唯一值的相關成員 IUniqueValueRenderer uniqueValueRenderer = new UniqueValueRendererClass(); //設置渲染的欄位個數範圍:0~3個 //這裡僅設置1個欄位 uniqueValueRenderer.FieldCount = 1; //設置渲染欄位, 並制定到索引處 //索引從0開始; 設定渲染欄位為"地市名" uniqueValueRenderer.set_Field(0, "地市名"); //簡單填充符號 ISimpleFillSymbol simpleFillSymbol; //獲得指向渲染要素的游標 IFeatureCursor pFtCursor = geoFeatureLayer.FeatureClass.Search(null, false); IFeature pFeature; if (pFtCursor != null) { //定義枚舉顏色帶, 調用函數, 生成隨機顏色帶 IEnumColors enumColors = CreateRandomColorRamp(get_Count).Colors; //查找到"地市名"欄位的索引(index) int fieldIndex = geoFeatureLayer.FeatureClass.Fields.FindField("地市名"); while ((pFeature = pFtCursor.NextFeature()) != null) { //獲取要素值 string nameValue = pFeature.get_Value(fieldIndex).ToString(); //實例化填充符號 //使用填充符號來賦值地圖的背景值 simpleFillSymbol = new SimpleFillSymbolClass(); //給要素附上樣式 simpleFillSymbol.Style = esriSimpleFillStyle.esriSFSSolid; //給要素附上顏色 simpleFillSymbol.Color = enumColors.Next() as IColor; //值和符號對應 uniqueValueRenderer.AddValue(nameValue, "地市", simpleFillSymbol as ISymbol); } } //賦值目標圖層的渲染器屬性 geoFeatureLayer.Renderer = uniqueValueRenderer as IFeatureRenderer; axMapControl1.Refresh(); //刷新axMapControl1 axTOCControl1.Update(); //更新axTOCControl1 }
需要用到的函數:CreateRandomColorRamp(int Number)
/// <summary> /// 創建隨機的顏色條帶 /// </summary> /// <param name="Number"></param> /// <returns></returns> private IColorRamp CreateRandomColorRamp(int Number) { //請注意色度、飽和度、最大值、最小值、隨機種子數等參數的設定 //參數不同, 所產生的色帶也不同 IRandomColorRamp pRandomColorRamp = new RandomColorRampClass(); pRandomColorRamp.StartHue = 0; //開始色度 pRandomColorRamp.EndHue = 360; pRandomColorRamp.MinValue = 99; pRandomColorRamp.MaxValue = 100; pRandomColorRamp.MinSaturation = 15; //最小飽和度 pRandomColorRamp.MaxSaturation = 30; //最大飽和度 pRandomColorRamp.Size = Number; //設置顏色帶數量 pRandomColorRamp.Seed = 23; //隨機數種子 bool bture = true; pRandomColorRamp.CreateRamp(out bture); return pRandomColorRamp; }
4、比例符號法渲染器
比例符號法渲染器(ProportionalSymbolRenderer)——用不同大小的符號繪製要素, 其大小對應某一欄位值的比例。
①統計目標欄位, 獲得相關統計值
②設計標記符號
③補充完整ProportionalSymbolRenderer對象的重要屬性值
④賦值目標圖層的Renderer屬性, 完成渲染
⑤刷新地圖
/// <summary> /// 比例符號法渲染器(ProportionalSymbolRenderer)——用不同大小的符號繪製要素, 其大小對應某一欄位值的比例。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void 比例符號法渲染ToolStripMenuItem_Click(object sender, EventArgs e) { //聲明IGeoFeatureLayer變數, 提供一個要素圖層對成員控制地理特徵的入口 IGeoFeatureLayer geoFeatureLayer; //聲明要素圖層 IFeatureLayer pFtLayer; //聲明專題圖變數 //在利用該方法進行著色時, 需獲得最大和最小標識符號所代表的欄位及其各個數值, 還需要確定每個欄位數值所匹配的著色符號。 IProportionalSymbolRenderer proportionalSymbolRenderer; //聲明表格 ITable table; //聲明游標 ICursor cursor; //用於統計變數 IDataStatistics dataStatistics; //用於存放統計結果 IStatisticsResults statisticsResults; //聲明一個字體對象 stdole.IFontDisp fontDisp; //獲取圖層 geoFeatureLayer = getGeoLayer("北部灣"); //強轉為要素圖層 pFtLayer = geoFeatureLayer as IFeatureLayer; //圖層類型轉換成表 table = geoFeatureLayer as ITable; //獲取游標 cursor = table.Search(null, true); //實例化數據統計對象 dataStatistics = new DataStatisticsClass(); //賦游標給數據統計對象的游標 dataStatistics.Cursor = cursor; //獲取圖層要素中進行專題地圖製圖的欄位名稱, 此實例中所用的數據中欄位名為"年"(2010年GDP增長速率) dataStatistics.Field = "年"; //存放統計結果為統計對象的統計數據 statisticsResults = dataStatistics.Statistics; //如果統計結果不為空 if (statisticsResults != null) { //簡單填充符號 IFillSymbol fillSymbol = new SimpleFillSymbolClass(); //設置顏色 fillSymbol.Color = getRGB(195, 255, 255); //設置簡單線型符號 ISimpleLineSymbol SLS = new SimpleLineSymbolClass(); SLS.Color = getRGB(196, 196, 196);//顏色 SLS.Width = 1.5;//寬度 fillSymbol.Outline = SLS;//外邊界線 //利用ESRI特殊符號調用成員進行填充 ICharacterMarkerSymbol characterMarkerSymbol = new CharacterMarkerSymbolClass(); fontDisp = new stdole.StdFontClass() as stdole.IFontDisp; //調用指定子庫(ESRI Default Marker是子庫名稱) fontDisp.Name = "ESRI Default Marker"; //對characterMarkerSymbol的font屬性 characterMarkerSymbol.Font = fontDisp; //特徵標記符號(Character Marker Symbol)的索引值 //0xB6是C#特殊的16進位表示方法, 換算為十進位值182 characterMarkerSymbol.CharacterIndex = 0xB6; //特徵標記符號的顏色 characterMarkerSymbol.Color = getRGB(253, 191, 110); //設計特徵標記符號的尺寸 characterMarkerSymbol.Size = 18; //實例化一個比例符號渲染器 proportionalSymbolRenderer = new ProportionalSymbolRendererClass(); proportionalSymbolRenderer.ValueUnit = esriUnits.esriUnknownUnits; //獲取渲染欄位 proportionalSymbolRenderer.Field = "年"; //是否啟用顏色補償(默認為否) proportionalSymbolRenderer.FlanneryCompensation = false; //賦值統計數據(比例符號渲染器) //MinDataValue獲取數據中最小值 proportionalSymbolRenderer.MinDataValue = statisticsResults.Minimum; //獲取數據中最大值 proportionalSymbolRenderer.MaxDataValue = statisticsResults.Maximum; //在多邊形特徵上繪製比例標記符號時使用的背景填充符號 proportionalSymbolRenderer.BackgroundSymbol = fillSymbol; //用於繪製具有規格化最小數據值的特徵的符號。 proportionalSymbolRenderer.MinSymbol = characterMarkerSymbol as ISymbol; //目錄和圖例中顯示的符號數為3 proportionalSymbolRenderer.LegendSymbolCount = 3; //創建圖例, 設置完所有屬性後調用。 proportionalSymbolRenderer.CreateLegendSymbols(); //賦值目標圖層的渲染器屬性 geoFeatureLayer.Renderer = proportionalSymbolRenderer as IFeatureRenderer; } axMapControl1.Refresh(); //刷新axMapControl1 axTOCControl1.Update(); //更新axTOCControl1 }
5、點狀密度法渲染器
點狀密度法渲染器(DotDensityRenderer)——在多邊形特徵中繪製不同密度的點
①製作點符號
②使用IDotDensityFillSymbo包裝製作好的符號
③賦值點密度渲染(dotDensityRenderer)的點密度符號(DotDensitySymbol)屬性
④賦值其它參數
⑤賦值目標圖層的Renderer屬性, 完成渲染
⑥刷新地圖
/// <summary> /// 點狀密度法渲染器(DotDensityRenderer)——在多邊形特徵中繪製不同密度的點 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void 點狀密度法渲染ToolStripMenuItem_Click(object sender, EventArgs e) { //聲明IGeoFeatureLayer變數, 提供一個要素圖層對成員控制地理特徵的入口 IGeoFeatureLayer geoFeatureLayer; //定義點密度填充符號變數, 控制點符號的屬性 IDotDensityFillSymbol dotDensityFillSymbol; //定義點密度渲染對象 IDotDensityRenderer dotDensityRenderer; //獲取渲染圖層 geoFeatureLayer = getGeoLayer("北部灣"); //實例化點密度渲染對象 dotDensityRenderer = new DotDensityRendererClass(); //強轉點密度渲染對象並強轉成渲染欄位對象 IRendererFields rendererFields = dotDensityRenderer as IRendererFields; //設置渲染欄位 string field1 = "年"; //向渲染器添加欄位(欄位名、別名) rendererFields.AddField(field1, field1); //實例化點密度填充符號 dotDensityFillSymbol = new DotDensityFillSymbolClass(); dotDensityFillSymbol.DotSize = 4;//設置點的大小 dotDensityFillSymbol.Color = getRGB(0, 255, 0);//設置點的顏色 //將點密度填充符號強轉為符號數組成員 ISymbolArray symbolArray = dotDensityFillSymbol as ISymbolArray; //實例化簡單標記符號 ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass(); //設置點的符號為圓圈 simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle; simpleMarkerSymbol.Size = 4;//設置大小 simpleMarkerSymbol.Color = getRGB(0, 255, 0);//設置顏色 //點符號的外邊不填充顏色 simpleMarkerSymbol.OutlineColor = getNoRGB(); //將簡單標記符號樣式增加到符號數組成員中 symbolArray.AddSymbol(simpleMarkerSymbol as ISymbol); //賦值點密度渲染(dotDensityRenderer)的點密度符號(DotDensitySymbol)屬性 dotDensityRenderer.DotDensitySymbol = dotDensityFillSymbol; //設置渲染密度 dotDensityRenderer.DotValue = 0.003; //設置點密度填充符號的背景色 dotDensityFillSymbol.BackgroundColor = getRGB(255, 255, 255); //創建圖例 dotDensityRenderer.CreateLegend(); //賦值目標圖層的渲染器屬性 geoFeatureLayer.Renderer = dotDensityRenderer as IFeatureRenderer; axMapControl1.Refresh(); //刷新axMapControl1 axTOCControl1.Update(); //更新axTOCControl1 }
需要用到的函數:getNoRGB()
/// <summary> /// 不填充顏色 /// </summary> /// <returns></returns> private IColor getNoRGB() { IRgbColor pColor = new RgbColorClass(); //.NullColor指示此顏色是否為空。true表明顏色為空 pColor.NullColor = true; return pColor;//返回pColor }
謝謝觀看!本人初學GIS二次開發,如果有不對的地方,請多多包涵!