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二次開發,如果有不對的地方,請多多包涵!