ArcGIS栅格图像重分类C#代码实现

本文详细介绍了如何使用ArcGIS平台通过四种不同的方法(NaturalBreaks、EqualInterval、GeometricalInterval、Quantile)对热点商圈分析结果进行重分类,并提供了具体的实现代码和步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做热点商圈分析,在分析出来的结果要对其进行重分类,通过不断尝试,终于实现了以不同方式(NaturalBreaks、EqualInterval、GeometricalInterval、Quantile)进行重分类的功能,现在将其整理分享:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using System.IO;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.GeoAnalyst;

namespace Intensity.Reclassify
{
    public partial class frmReclassify : Form
    {
        //define global varibale
        IWorkspaceFactory pWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
        IWorkspace pWorkspace = null;

        IEnumDataset pEnumDataset = null;
        IEnumDatasetName pEnumDatasetName = null;

        IClassifyGEN mClassify;
        int mClassesNo;//declare reclassify count
        object varNewValues, varNewCounts;//declare variable to store pixel values


        string strFileGDBPath = "";
        string strReclassifyResultPath = "";

        public frmReclassify()
        {
            InitializeComponent();
        }
        /// <summary>
        /// form load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmReclassify_Load(object sender, EventArgs e)
        {
            cmbClassifyMethod.Items.Add("NaturalBreaks");
            cmbClassifyMethod.Items.Add( "EqualInterval");
            cmbClassifyMethod.Items.Add("GeometricalInterval");
            cmbClassifyMethod.Items.Add("Quantile");
        }
        /// <summary>
        /// Select Raster Dataset GDB file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectRasterGDB_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.Description = "打开GDB文件";
            if (DialogResult.OK == dlg.ShowDialog())
            {
                if (Directory.Exists(dlg.SelectedPath))
                {
                    strFileGDBPath = dlg.SelectedPath;
                    txtFileGDBPath.Text = strFileGDBPath;
                }
                else
                {
                    return;
                }
                pWorkspace = pWorkspaceFactory.OpenFromFile(strFileGDBPath, 0);
                pEnumDataset = pWorkspace.get_Datasets(esriDatasetType.esriDTRasterDataset);

                //pRasterWorkspace = pWorkspace as IRasterWorkspace;

                if (pEnumDataset == null)
                {
                    MessageBox.Show("文件地理库中不包含栅格数据,请检查!");
                    return;
                }
            }
        }
        /// <summary>
        /// Select Classify Method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbClassifyMethod_SelectedIndexChanged(object sender, EventArgs e)
        {
            string strMethod = this.cmbClassifyMethod.Text.Trim();
            if (strMethod == "") return;
            switch (strMethod)
            {
                case "EqualInterval":
                    {
                        mClassify = new EqualIntervalClass();
                        break;
                    }
                case "GeometricalInterval":
                    {
                        mClassify = new GeometricalIntervalClass();
                        break;
                    }
                case "NaturalBreaks":
                    {
                        mClassify = new NaturalBreaksClass();
                        break;
                    }
                case "Quantile":
                    {
                        mClassify = new QuantileClass();
                        break;
                    }
                default:
                    {
                        mClassify = new EqualIntervalClass();
                        break;
                    }
            }
        }
        /// <summary>
        /// select Reclassify GDB path
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelectResultPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            dlg.Description = "打开GDB文件";
            if (DialogResult.OK == dlg.ShowDialog())
            {
                if (Directory.Exists(dlg.SelectedPath))
                {
                    strReclassifyResultPath = dlg.SelectedPath;
                    this.txtReclassifyPath.Text = strReclassifyResultPath;
                }
                else
                {
                    return;
                }
                
            }
        }
        /// <summary>
        /// Start to Reclassify the dataset
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOK_Click(object sender, EventArgs e)
        {
            if (this.txtFileGDBPath.Text.Trim() == "" || this.cmbClassifyMethod.Text.Trim() == "" || txtClassifyCount.Text.Trim() == "")
            {
                MessageBox.Show("请先设置重分类条件!");
                return;
            }

            int iReclassifyCount = Convert.ToInt16(this.txtClassifyCount.Text.Trim());
            string strReclassifyMethod = this.cmbClassifyMethod.Text.Trim();

            pEnumDataset.Reset();
            IRasterDataset pRasterDataset = new RasterDatasetClass();
            pRasterDataset = pEnumDataset.Next() as IRasterDataset;
            frmProgress frmPro = new frmProgress();
            frmPro.Show();
            frmPro.TopMost = true;
            frmPro.SetLabel1("正在计算,请等待......");
            frmPro.SetProgressRefresh();
            frmPro.AutoSize = true;
            frmPro.Refresh();

            Application.DoEvents();
            while (pRasterDataset != null)
            {
                IRasterLayer pRasterLayer = new RasterLayerClass();
                pRasterLayer.CreateFromDataset(pRasterDataset);
               

                frmPro.SetLabel1("正在生成" + pRasterLayer.Name + "的Reclassify图,请等待......");
                try
                {
                    ReclassifyRasterLayerAndSave(pRasterLayer, iReclassifyCount, strReclassifyMethod, strReclassifyResultPath, "Reclassify_" + pRasterLayer.Name);

                }
                catch
                {
                    MessageBox.Show(pRasterLayer.Name + "生成Reclassify不成功,请检查!");
                    if (frmPro != null)
                    {
                        frmPro.Close();
                        frmPro.Dispose();
                    }
                }
                pRasterDataset = pEnumDataset.Next() as IRasterDataset;


            }
            frmPro.SetLabel1("Reclassify Complete!");
        }
        /// <summary>
        /// exit the program
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        

    #region Customize method
            private void ReclassifyRasterLayerAndSave(IRasterLayer pRasterLayer, int pClassesNo, string pMethodName, string strOutputPath, string strRasterName)
            {
                try
                {
                    mClassesNo = Convert.ToInt16(this.txtClassifyCount.Text.Trim());

                    IRaster pRaster = pRasterLayer.Raster;
                    IRasterProps rasterProps = (IRasterProps)pRaster;
                    //定义字典集合存放像素值和统计频数

                    Dictionary<double, long> ValueFrequence = new Dictionary<double, long>();

                    //设置栅格数据起始点  
                    IPnt pBlockSize = new Pnt();
                    pBlockSize.SetCoords(rasterProps.Width, rasterProps.Height);
                    //选取整个范围  
                    IPixelBlock pPixelBlock = pRaster.CreatePixelBlock(pBlockSize);
                    //左上点坐标  
                    IPnt tlp = new Pnt();
                    tlp.SetCoords(0, 0);
                    //读入栅格  
                    IRasterBandCollection pRasterBands = pRaster as IRasterBandCollection;
                    IRasterBand pRasterBand = pRasterBands.Item(0);
                    IRawPixels pRawRixels = pRasterBands.Item(0) as IRawPixels;
                    pRawRixels.Read(tlp, pPixelBlock);


                    //将PixBlock的值组成数组  
                    System.Array pSafeArray = pPixelBlock.get_SafeArray(0) as System.Array;

                    for (int y = 0; y < rasterProps.Height; y++)
                    {
                        for (int x = 0; x < rasterProps.Width; x++)
                        {
                            double value = Convert.ToDouble(Convert.ToDouble(pSafeArray.GetValue(x, y)).ToString("##.0000000000"));


                            if (!ValueFrequence.ContainsKey(value))
                            {
                                ValueFrequence.Add(value, 1);
                            }
                            else if (ValueFrequence.ContainsKey(value))
                            {
                                ValueFrequence[value] = ValueFrequence[value] + 1;
                            }


                        }
                    }

                    DataTable dt = initialDatatable();

                    foreach (double dValue in ValueFrequence.Keys)
                    {
                        DataRow pRow = dt.NewRow();
                        pRow["PixelValue"] = dValue;
                        pRow["PixelFrequence"] = long.Parse(ValueFrequence[dValue].ToString());
                        dt.Rows.Add(pRow);
                    }
		    //排序,很重要
                    dt.DefaultView.Sort = "PixelValue asc,PixelFrequence";

                    DataTable ddt = dt.DefaultView.ToTable();
                    int iCount = ddt.Rows.Count;
                    double[] dValues = new double[iCount];
                    long[] lFrequency = new long[iCount];
                    for (int ii = 0; ii < iCount; ii++)
                    {
                        dValues[ii] = Convert.ToDouble(ddt.Rows[ii]["PixelValue"].ToString());
                        lFrequency[ii] = long.Parse(ddt.Rows[ii]["PixelFrequence"].ToString());
                    }

                    varNewValues = dValues as object;
                    varNewCounts = lFrequency as object;


                    if (mClassify == null) return;

                    //mClassify 为IClassifyGEN接口对象,
                    //通过其子类进行初始化实现mClassify = new NaturalBreaksClass();
                    //进行分类(varNewValues--像素值数组;varNewCounts--对应值的个数数组;
                    //pClassesNo--分类级数)
                    mClassify.Classify(varNewValues, varNewCounts, ref pClassesNo);

                    //分类完成,获得断点
                    double[] ClassNum = (double[])mClassify.ClassBreaks;

                    IRasterDescriptor pRD = new RasterDescriptorClass();
                    IReclassOp pReclassOp = new RasterReclassOpClass();
                    IGeoDataset pGeodataset = pRasterLayer.Raster as IGeoDataset;

                    //IRasterAnalysisEnvironment pEnv = pReclassOp as IRasterAnalysisEnvironment;
                    //pEnv.OutWorkspace = pWorkspace;
                    //object objSnap = null;
                    //object objExtent = pGeodataset.Extent;
                    //pEnv.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref objExtent, ref objSnap);
                    //pEnv.OutSpatialReference = pGeodataset.SpatialReference;

                    IRasterLayer pRLayer = new RasterLayerClass();

                    INumberRemap pNumRemap = new NumberRemapClass();
                    for (int i = 0; i < mClassesNo; i++)
                    {
                        pNumRemap.MapRange(ClassNum[i], ClassNum[i + 1], i + 1);
                    }
                    IRemap pRemap = pNumRemap as IRemap;

                    IRaster pOutRaster = pReclassOp.ReclassByRemap(pGeodataset, pRemap, false) as IRaster;

                    pRLayer.CreateFromRaster(pOutRaster);

                    IRasterBandCollection pRasterBandCol = pOutRaster as IRasterBandCollection;
                    IRasterBand pBand = pRasterBandCol.Item(0);
                    IRasterDataset pOutRasterDataset = pBand.RasterDataset;

                    IWorkspaceFactory pp = new FileGDBWorkspaceFactoryClass();
                    IWorkspace ppWorkspace = pp.OpenFromFile(strOutputPath, 0);

                    ISaveAs pSaveAs = pOutRasterDataset as ISaveAs;
                    pSaveAs.SaveAs(strRasterName, ppWorkspace, "GDB");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }

            }

            public IRasterWorkspaceEx OpenFileGDBWorkspace(string sPath)
            {
                IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactoryClass();
                IWorkspace workspace = workspaceFactory.OpenFromFile(sPath, 0);
                IRasterWorkspaceEx rasterWorkspaceEx = (IRasterWorkspaceEx)workspace;
                return rasterWorkspaceEx;
            }

            private DataTable initialDatatable()
            {
                try
                {
                    DataTable dt = new DataTable();
                    DataColumn col = new DataColumn();
                    col.ColumnName = "PixelValue";
                    col.DataType = System.Type.GetType("System.Double");
                    dt.Columns.Add(col);

                    col = new DataColumn();
                    col.ColumnName = "PixelFrequence";
                    col.DataType = System.Type.GetType("System.Int64");
                    dt.Columns.Add(col);

                    return dt;
                }
                catch
                {
                    return null;
                }
            }
    #endregion
    }

上海市的处理结果如下:



ArcGIS Engine栅格数据使用总结 ArcOjects 3D开发方法简介 作者:佚名 文章来源:GIS论坛 点击数:861 更新时间:2009-8-6 一、ArcOjects 3D开发方法简介 众所周知,在ArcGIS 3D分析扩展模块中提供了丰富的三维可视化和分析功能:你可以通过不同的视角查看表面数据,对表面数据进行查询,以及对表面数据进行坡度、坡向、视域分析等操作,进行三维动画模拟等等。其中所涉及的3D对象都是ArcObjects的一部分,针对3D的开发,实际上是ArcObjects的开发,所以具体的开发方法有: 基于ArcScene中内嵌的VBA开发; 通过VB、VC++等兼容COM的开发语言进行开发新的3D组件和功能。 二、基本的3D对象模型 在3D开发中,我们可以用ArcMap对应ArcScene,其中MxDocument对象对应SxDocument对象,Map对象对应着Scene对象,而相对于Display显示对象,在ArcScene中有SceneGraph对象。在对象模型图的顶部是Application对象,从它我们可以执行和应用相关的任务,比如打开文档或者访问和应用相关的其它对象。在VBA中,我们可以直接获得Application对象: Dim pApp as IApplicaiton Set pApp = Application 如果你在VB DLL中实现命令和工具,那么在具体实例化这个类时你可以获得和Application对象挂接的钩子(hook): Implements ICommand Private m_pApp as esriCore.Iapplication Private Sub ICommand_OnCreate(ByVal Hook As Object) Set m_pApp = Hook … End Sub 有了Application对象,你就可以访问它所包含的其它所有对象了。比如可以获得SxDocument对象,而它包含一个Scene对象,Scene对应的SceneGraph对象包含了一个或多个SceneViewer对象,每个SceneViewer对象中有一个Camera对象,它代表了观察点的特性。在Scene对象中可以访问Layer对象和GraphicsLayer3D对象,这两个对象都包含着一个3DProperties对象,用来控制图层中有关三维方面的特性。具体有关对象的特性可以参考联机帮助中对象上提供的接口所属的方法和属性。 三、3D几何模型和定制对象介绍 3D模型可以包括两种:矢量模型和表面模型,表面模型包括TIN和Raster,有关表面模型的创建、数据结构访问和分析在本文中不做介绍。在此只介绍三维矢量模型的生成和访问等。3D矢量模型包括所有含有Z值的几何对象:点、线、面,以及MultiPatch(多片)。其中多片又可以分为:三角条带(Triangle Strip)、三角扇(Triangle Fan)和环(Ring)。 在ArcScene中可以通过二维的点、线、面数据来构建三维模型,通过ArcScene中提供的拉伸功能可以将点要素构建成垂直的线,线要素构建成墙,而多边形要素构建成块,拉伸的值的大小可以是一定常数,也可以是通过要素属性字段中的值计算得出,或者通过数据自身记录的Z值。在ArcObjects中可以通过在Geometry几何对象构建过程中,任意点除了X、Y坐标值,指定坐标Z值来构建三维点、线和面对象;对于多片,则通过构建相应的Multipatch对象,并指定每一个顶点的X、Y和Z值。下面的代码描述了如何由多片来构建一个房子对象,它的房顶由三角扇构建,没有窗户的墙由三角条带构建,带窗户的墙由环构建。 Dim pMultiPatch As esriCore.IMultiPatch Set pMultiPatch = New MultiPatch Dim pGeoCol As esriCore.IGeometryCollection Set pGeoCol = pMultiPatch Dim pPoints As esriCore.IPointCollection Dim pPoint As IPoint ‘创建屋顶 Set pPoints = New esriCore.TriangleFan Set pPoint = New Point pPoint.PutCoords 5, 4 pPoint.Z = 10 pPoints.AddPoint pPoint Set pPoint = New Point pPoint.PutCoords 0, 0 pPoint.Z = 5 pPoints.AddPoint pPoint ‘屋顶的其它顶点: . . . (10, 0, 5); (10, 8, 5); ( 0, 8, 5); ( 0, 0, 5) ‘将扇加到MultiPatch pGeoCol.AddGeometry pPoints ‘为没有窗户的墙创建条带 Set pPoints = New esriCore.TriangleStrip ‘添加条带顶点: . . . (10, 0, 5); (10, 0, 0); (10, 8, 5) . . . (10, 8, 0); ( 0, 8, 5); ( 0, 8, 0) . . . ( 0, 0, 5); ( 0, 0, 0) ‘将条带添加到MultiPatch pGeoCol.AddGeometry pPoints ‘为前面的墙创建外环 Set pPoints = New esriCore.Ring ‘添加外环顶点: . . . (10, 0, 5); (10, 0, 0); (10, 8, 5) . . . (10, 8, 0); ( 0, 8, 5); ( 0, 8, 0) . . . ( 0, 0, 5); ( 0, 0, 0) ‘将外环添加到MultiPatch pGeoCol.AddGeometry pPoints pMultiPatch.PutRingType pPoints, esriMultiPatchOuterRing ‘为前面的墙创建内环 Set pPoints = New esriCore.Ring ‘添加内环顶点: . . .(1, 0, 2);(3, 0, 2);(3, 0, 4);(1, 0, 4);(1, 0, 2) pGeoCol.AddGeometry pPoints pMultiPatch.PutRingType pPoints, esriMultiPatchInnerRing Set pPoints = New esriCore.Ring ‘添加内环顶点: . . .(7, 0, 2);(9, 0, 2);(9, 0, 4);(7, 0, 4);(7, 0, 2) pGeoCol.AddGeometry pPoints pMultiPatch.PutRingType pPoints, esriMultiPatchInnerRing ‘设置Z和M坐标awareness Dim pZAware As esriCore.IZAware Set pZAware = pMultiPatch pZAware.ZAware = True Dim pMAware As esriCore.IMAware Set pMAware = pMultiPatch pMAware.MAware = False 通常,多片是用来描述阴影平面集合,并且可以在其上粘贴影像,也就是贴图。为了粘贴影像,需要在Multipatch的每一个定点上记录纹理坐标。纹理坐标记录为s和t,值为0到1,表示了从x到y方向影像的起点到终点。在ArcObjects中将s和t编码存储在定点的M值中。另外,如果要用Multipatch表达复杂连续的几何对象,比如球体,为了平滑阴影平面之间的转折,需要在Multipatch的每一个顶点上记录它的法向量,同样法向量也是编码后存储在定点的M值中。如下面的代码: Dim pNormal As esriCore.IVector3D Dim pVertex As esriCore.Ipoint Dim m As Double m = 0 . . . Dim pEncoder As IEncode3DProperties Set pEncoder = New GeometryEnvironment pEncoder.PackNormal vNormal, m pEncoder.PackTexture2D s, t, m pVertex.M = m 四、3D渲染和动画功能定制简介
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值