由于工作需要,要求使用AE实现对某些气象观测要素(如气温、雨量)等进行IDW插值,经过这段时间的努力,基本功能已经实现。在此感谢一些网上的技术牛人,谢谢他们无私的分享(搜索是件快乐的事情),同时也要感谢自己付出的努力(智慧、查找资料、耐心)。实现过程大致如下:
- IDW插值
- 剪裁(单波段影像)
- 颜色渲染
- 出透明图
下面记录了实现的主要代码,毕竟好记性不如烂笔头。
(一)IDW空间插值的实现
private ESRI.ArcGIS.Geodatabase.IGeoDataset CreateRaster(string filedName, string pPath)
{
IMap pMap = this._mapControl.Map;
IInterpolationOp3 pInterpolationOp = new RasterInterpolationOpClass(); //IInterpolationOp目前已被IInterpolationOp3所取代
//定义工作空间
IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
string pFolder = System.IO.Path.GetDirectoryName(pPath);
string pFileName = System.IO.Path.GetFileName(pPath);
IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(pFolder, 0); //设定地理处理的工作空间
IFeatureWorkspace pFeatureWorkspace = pWorkspace as IFeatureWorkspace;
IFeatureClass oFeatureClass = pFeatureWorkspace.OpenFeatureClass(pFileName);
IFeatureClassDescriptor pFCDescriptor = new FeatureClassDescriptorClass();
pFCDescriptor.Create(oFeatureClass, null, filedName);
IRasterRadius pRadius = new RasterRadiusClass(); //设置搜索半径
object objectMaxDistance = null;
object objectbarrier = null;
object missing = Type.Missing;
pRadius.SetVariable(12, ref missing); //这里设置不同的值,出图的效果(如颜色的深浅等)就不同
//ESRI.ArcGIS.Geodatabase.IWorkspace pShpWorkspace = pWorkspaceFactory.OpenFromFile(tempPath, 0);
object dCellSize = 0.013; //设置栅格精度(输出栅格像元大小)
object snapRasterData = Type.Missing;
IRasterAnalysisEnvironment pEnv = pInterpolationOp as IRasterAnalysisEnvironment;
pEnv.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref dCellSize);
pEnv.OutSpatialReference = pMap.SpatialReference;
//执行插置,产生结果(栅格数据集)
IGeoDataset poutGeoDataset = pInterpolationOp.IDW((IGeoDataset)pFCDescriptor, 2, pRadius, ref missing); //这里参数2为默认的权重值
//控制周围点对于内插值的重要性的距离指数。幂值越高,远数据点的影响会越小。
IRaster pOutRaster = poutGeoDataset as IRaster;
IRasterLayer pOutRasLayer = new RasterLayer();
pOutRasLayer.CreateFromRaster(pOutRaster); //生成栅格数据图层
this._mapControl.AddLayer(pOutRasLayer); //添加生成的图层
return poutGeoDataset; //返回一个GeoDataSet
}
(二)shp图层剪裁栅格数据
private IRaster ShpLayerClipRaster(IFeatureLayer featureLayer, IRaster raster)
{
IFeatureLayer pFeaLyr;
IRasterAnalysisEnvironment pEnv;
IGeoDataset pTempDS;
pFeaLyr = featureLayer;
pTempDS = pFeaLyr.FeatureClass as IGeoDataset;
IConversionOp pConOp = new RasterConversionOpClass();
pEnv = pConOp as IRasterAnalysisEnvironment;
IRasterProps pProp;
pProp = raster as IRasterProps;
object cellSize = 0.01;
pEnv.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref cellSize);
IRasterConvertHelper rsh = new RasterConvertHelperClass();
IRaster tempRaster;
tempRaster = rsh.ToRaster1(pTempDS, "Grid", pEnv);
IRaster pOutRaster;
IExtractionOp pExtrOp = new RasterExtractionOpClass();
pOutRaster = (IRaster)pExtrOp.Raster((IGeoDataset)raster, (IGeoDataset)tempRaster);
//pTempDS = null;
//pConOp = null;
//pFeaLyr = null;
return pOutRaster;
}
(三)栅格数据颜色分级渲染
实现思路如下:
1.定义渲染的一系列接口
2.判断图像是否建立了直方图,如果没有则进行创建
3.定义颜色序列,为渲染提供渲染的方案(自定义色带颜色包括透明效果色以及范围值区间)
4.调用Render方法进行渲染
private void classifyColorToRaster(IRasterLayer pRasterLayer, int classCount, int size)
{
IRasterClassifyColorRampRenderer classifyRender = new RasterClassifyColorRampRenderer();
IRasterRenderer rasterRender = classifyRender as IRasterRenderer;
IRaster pRaster = pRasterLayer.Raster;
IRasterBandCollection pRBandCol = pRaster as IRasterBandCollection;
IRasterBand pRBand = pRBandCol.Item(0);
if (pRBand.Histogram == null) //判断栅格是否计算直方图,没有的话要进行计算
{
pRBand.ComputeStatsAndHist();
}
rasterRender.Raster = pRaster;
classifyRender.ClassCount = classCount;
for (int i = 0; i < classCount; i++)
{
if (i == 0)
{
classifyRender.set_Break(i, double.Parse("1"));
}
if (i == 1)
{
classifyRender.set_Break(i, double.Parse("251"));
}
if (i == 2)
{
classifyRender.set_Break(i, double.Parse("501"));
}
if (i == 3)
{
classifyRender.set_Break(i, double.Parse("751"));
}
if (i == 4)
{
classifyRender.set_Break(i, double.Parse("1001"));
}
if (i == 5)
{
classifyRender.set_Break(i, double.Parse("1251"));
}
if (i == 6)
{
classifyRender.set_Break(i, double.Parse("1501"));
}
if (i == 7)
{
classifyRender.set_Break(i, double.Parse("1751"));
}
if (i == 8)
{
classifyRender.set_Break(i, double.Parse("2001"));
}
if (i == 9)
{
classifyRender.set_Break(i, double.Parse("2251"));
}
}
rasterRender.Update();
/*
IRgbColor pFromColor = new RgbColor() as IRgbColor;
pFromColor.Red = formColorRed;
pFromColor.Green = formColorGreen;
pFromColor.Blue = formColorBlue;
IRgbColor pToColor = new RgbColor() as IRgbColor;
pToColor.Red = toColorRed;
pToColor.Green = toColorGreen;
pToColor.Blue = toColorBlue;
*/
IAlgorithmicColorRamp colorRamp = new AlgorithmicColorRamp() as IAlgorithmicColorRamp;
colorRamp.Size = size;
//colorRamp.FromColor = pFromColor;
//colorRamp.ToColor = pToColor;
bool createColorRamp;
colorRamp.CreateRamp(out createColorRamp);
IFillSymbol fillSymbol = new SimpleFillSymbol() as IFillSymbol;
for (int i = 0; i < classifyRender.ClassCount; i++)
{
if(i == 0)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 255;
tc.Green = 255;
tc.Blue = 128;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "250"); //这里设置0是要整数显示
}
if (i == 1)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 128;
tc.Green = 255;
tc.Blue = 128;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "500"); //这里设置0是要整数显示
}
if (i == 2)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 128;
tc.Green = 255;
tc.Blue = 255;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "750"); //这里设置0是要整数显示
}
if (i == 3)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 0;
tc.Green = 128;
tc.Blue = 255;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "1000"); //这里设置0是要整数显示
}
if (i == 4)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 255;
tc.Green = 128;
tc.Blue = 192;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "1250"); //这里设置0是要整数显示
}
if (i == 5)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 255;
tc.Green = 0;
tc.Blue = 0;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "1500"); //这里设置0是要整数显示
}
if (i == 6)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 255;
tc.Green = 0;
tc.Blue = 255;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "1750"); //这里设置0是要整数显示
}
if (i == 7)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 255;
tc.Green = 128;
tc.Blue = 64;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "2000"); //这里设置0是要整数显示
}
if (i == 8)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 0;
tc.Green = 64;
tc.Blue = 128;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "2250"); //这里设置0是要整数显示
}
if (i == 9)
{
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 255;
tc.Green = 255;
tc.Blue = 0;
fillSymbol.Color = tc as IColor;
classifyRender.set_Symbol(i, fillSymbol as ISymbol);
classifyRender.set_Label(i, classifyRender.get_Break(i).ToString("0") + "-" + "2500"); //这里设置0是要整数显示
}
}
pRasterLayer.Renderer = rasterRender;
//*********************************使栅格图层呈现透明效果*******************************************
//ILayerEffects pLayerEffects = pRasterLayer as ILayerEffects;
//pLayerEffects.Transparency = 50;
//*************************************************************************************************
this._mapControl.AddLayer(pRasterLayer);
this._mapControl.ActiveView.Refresh();
}
(四)导出透明效果图片(PNG格式)
private void ExportMapByAbsPath(IActiveView activeView, string path) //导出透明效果图片
{
IExport export = new ExportPNGClass();
IExportImage exportImg;
IExportPNG exportPNG;
int resolution = 96;
export.Resolution = resolution;
exportImg = export as IExportImage;
exportImg.ImageType = esriExportImageType.esriExportImageTypeTrueColor; //定义输出图片颜色模式为24位真彩色
exportPNG = export as IExportPNG;
//exportImg.BackgroundColor.RGB = exportPNG.TransparentColor.RGB;
ESRI.ArcGIS.Display.IRgbColor tc = new ESRI.ArcGIS.Display.RgbColor();
tc.Red = 255;
tc.Green = 255;
tc.Blue = 0;
exportImg.BackgroundColor = tc as IColor; //设置输出图片的背景色
exportPNG.TransparentColor = tc as IColor; //设置输出图片的透明色
tagRECT exportRect = activeView.ExportFrame;
IEnvelope envelop = new EnvelopeClass();
envelop.PutCoords(exportRect.left, exportRect.top, exportRect.right, exportRect.bottom);
export.PixelBounds = envelop;
export.ExportFileName = path;
int hDC = export.StartExporting();
IEnvelope pVisbounds = null;
ITrackCancel ptrac = null;
//导出
activeView.Output(hDC, (int)export.Resolution, ref exportRect, pVisbounds, ptrac);
//结束导出
export.FinishExporting();
//清理导出类
export.Cleanup();
}
(五)调用上述方法
private void exportMapBtn_Click(object sender, EventArgs e) //实现了shp文件剪裁插值结果(栅格)
{
string filedName = "RES1_4M0_I";
string pPath = System.Windows.Forms.Application.StartupPath + @"\china_basic_map\省会城市.shp";
CreateRaster(filedName, pPath);
IRasterLayer pRasterLayer = this._mapControl.get_Layer(0) as RasterLayer;
IFeatureLayer featureLayer = this._mapControl.get_Layer(2) as IFeatureLayer;
IRaster raster = pRasterLayer.Raster;
IRaster resultRaster = ShpLayerClipRaster(featureLayer, raster);
IRasterLayer resultRasterLayer = new RasterLayer();
resultRasterLayer.CreateFromRaster(resultRaster);
classifyColorToRaster(resultRasterLayer, 10, 10);
//***************************该删除方式有待改善*************************************
this._mapControl.DeleteLayer(1);
this._mapControl.DeleteLayer(1);
this._mapControl.DeleteLayer(1);
//*********************************************************************************
ExportMapByAbsPath(this._mapControl.ActiveView, "d:\\abc.png"); //输出png格式图片
this._mapControl.DeleteLayer(0);
}
(六)目前任然存在的问题以及下一步的需求,后续有待解决
1.License偶尔报错(概率很小)
2.自定义色带时,初始值设置为0时,颜色渲染有问题,只要比0大便不会出现此问题
3.剪裁时需先调整范围,才能使剪裁范围最全面,效果最优
4.清理缓存,提高运行效率
5.Janus Form为试用版,最好要找到破解版
6.代码优化(组织思维、重构)
7.数据接入方式
8.定时出图(分钟级、小时级、日级、周级、月级、旬级、年级)