码迷,mamicode.com
首页 > 其他好文 > 详细

GIS项目设计——MaoEr森林资源管理系统

时间:2016-07-20 11:55:00      阅读:373      评论:0      收藏:0      [点我收藏+]

标签:

这应该是在大学做的最后一个开发项目。
刚刚经历的3S技术应用综合实习,分为三个模块,遥感实习,外业实习,GIS项目设计。时间长度达到11天。
这篇博文记录的主要是GIS项目设计的一些问题及关键步骤。

项目开发环境:

MicroSoft Visual Studio 2010 + ArcGIS Engine 10.0
矢量数据或栅格文件存放在项目所在文件夹下的bin\debug\data文件夹下,图片存放在bin\debug\image文件夹下

数据准备:

将人为小班区划(铅笔画的)的硫酸纸图扫描,生成tiff文件。
在tiff文件中用画图工具(PS)4条相交的直线,生成4个相交点。
在ArcMap中打开文件,输入坐标进行配准。
技术分享
TIFF图像矢量化:
用ArcCatalog生成shape文件,再编辑此文件,画面的方法,进行矢量化。
技术分享

主要菜单:

1.基本内容:林场简介、自然风光、林相图、遥感图;
2.森林区划:林班分布图、小班分布图、小班属性;
3.地形地势:等高线图、坡度图、坡向图;
4.资源管理:交通水系图。
5.森林类别:林种分布图、地类分布图
6.说明:系统说明
7.退出:关闭

Form1是开始界面,Form2是菜单界面,Form3是地图显示界面
技术分享

代码部分:

林相图

将7个shapeFile有顺序的加载到Axmapcontrol中,由道路、河流线、居民点、等高线、林班分布图、小班分布图、边界面所组成。
河流为蓝色,道路为红色,粗度为2 (线的渲染);
居民点的颜色为黑色,面状
类型为esriSFSDiagonalCross (面的简单渲染)
边界面:面的填充方式为空心、边框颜色为白色;
等高线为线状,颜色自定(最好是浅色),粗度为1
林班分布图为空心,外边框颜色自定,外边框粗度为2;
小班分布图按林班号字段按值渲染(面的唯一值渲染)。
全图显示的时候,不显示小班分布图,放大一定比例再显示,比例尺自定(面的比例尺渲染)。

直接调用不同窗口内中的空间出现访问限制时,通过修改Designer.cs中的控件修饰符即可。

面的简单渲染(比如边界面的空心白框)
            IGeoFeatureLayer pGeoFeatureLayer;
            IFeatureLayer pFeatureLayer1 = new FeatureLayerClass();
            pFeatureLayer1 = form3.axMapControl1.Map.get_Layer(0) as IFeatureLayer;
            pGeoFeatureLayer = pFeatureLayer1 as IGeoFeatureLayer;
            ISimpleFillSymbol pFillSymbol1 = new SimpleFillSymbolClass();
            pFillSymbol1.Style = esriSimpleFillStyle.esriSFSNull;
            ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbolClass();
            pSimpleLineSymbol.Color = GetRGB(255,255,255);
            pSimpleLineSymbol.Width = 1;
            //pFillSymbol1.Outline.Width = 1;
            //pFillSymbol1.Outline.Color = GetRGB(255, 255, 255);
            pFillSymbol1.Outline = pSimpleLineSymbol;
            ISimpleRenderer ppSimpleRenderer = new SimpleRendererClass();
            ppSimpleRenderer.Symbol = pFillSymbol1 as ISymbol;
            pGeoFeatureLayer.Renderer = ppSimpleRenderer as IFeatureRenderer;
面的比例尺渲染

比如小班,空心渲染和唯一值渲染的组合。在写程序之前应该将这7个shapefile全部定义投影坐标系,使用ArcToolbox中数据管理,投影与变换,定义高斯-克吕格投影,北京54坐标系

            IFeatureLayer pFeatureLayer = form3.axMapControl1.get_Layer(0) as IFeatureLayer;
            IGeoFeatureLayer pGeoFeatureLayer1;
            pGeoFeatureLayer1 = pFeatureLayer as IGeoFeatureLayer;        
            IUniqueValueRenderer pUniqueValueRenderer = new UniqueValueRendererClass();
            //IUniqueValueRenderer pUniqueValueRenderer11 = new UniqueValueRendererClass();
            ITable pTable;
            pTable = pGeoFeatureLayer1 as ITable;    

            int fieldNumber;
            fieldNumber = pTable.FindField("林班号");
            pUniqueValueRenderer.FieldCount = 1;
            pUniqueValueRenderer.set_Field(0, "林班号");
            IRandomColorRamp pColorRamp = new RandomColorRampClass();
            pColorRamp.StartHue = 20;
            pColorRamp.MinValue = 100;
            pColorRamp.MinSaturation = 20;
            pColorRamp.EndHue = 360;
            pColorRamp.MaxValue = 100;
            pColorRamp.MinSaturation = 30;

            pColorRamp.Size = 100;
            bool bture = true;
            pColorRamp.CreateRamp(out bture);

            IEnumColors pEnumRamp;
            pEnumRamp = pColorRamp.Colors as IEnumColors;
            IColor pNextUniqueColor;
            pNextUniqueColor = null;

            IQueryFilter pQueryFileter = new QueryFilterClass();
            pQueryFileter.AddField("林班号");

            ICursor pCursor;
            pCursor = pTable.Search(pQueryFileter, true) as ICursor;
            IRow pNextRow;
            pNextRow = pCursor.NextRow();

            while (pNextRow != null)
            {

                IRowBuffer pNextRowBuffer;
                pNextRowBuffer = pNextRow as IRow;
                string codeValue = pNextRowBuffer.get_Value(fieldNumber).ToString();
                pNextUniqueColor = pEnumRamp.Next();
                if (pNextUniqueColor == null)
                {
                    pEnumRamp.Reset();
                    pNextUniqueColor = pEnumRamp.Next();

                }
                ISimpleFillSymbol pSym = new SimpleFillSymbolClass();
                pSym.Color = pNextUniqueColor;
                pUniqueValueRenderer.AddValue(codeValue, "小班号", pSym as ISymbol);
                pNextRow = pCursor.NextRow();
            }
            //pGeoFeatureLayer1.Renderer = pUniqueValueRenderer as IFeatureRenderer;
            /////////  比例尺渲染   //////////////////////////////////////////////////////////// 
            // 1:60000  1:240000

            ISimpleRenderer pSRenderer = new SimpleRendererClass();
            ISimpleFillSymbol pSFSymbol = new SimpleFillSymbolClass();
            pSFSymbol.Style = esriSimpleFillStyle.esriSFSNull;
            pSRenderer.Symbol = pSFSymbol as ISymbol;
            IScaleDependentRenderer pScaleRenderer = new ScaleDependentRendererClass();
            pScaleRenderer.AddRenderer(pUniqueValueRenderer as IFeatureRenderer);
            pScaleRenderer.AddRenderer(pSRenderer as IFeatureRenderer);

            pScaleRenderer.Break[0] = 10000;  // 在大于1:10000内用唯一值渲染器
            pScaleRenderer.Break[1] = 20000;  // 在1:10000 和 1:20000内用空心简单渲染器
            //pScaleRenderer.set_Break(0, 160000);
            //pScaleRenderer.set_Break(1, 14587);
            pGeoFeatureLayer1.Renderer = pScaleRenderer as IFeatureRenderer;
关于线的渲染

比如道路为红色,粗度为2:

            IGeoFeatureLayer pGeoFeatrueLayer_path;
            IFeatureLayer pFeatureLayer_path = new FeatureLayerClass();
            pFeatureLayer_path = form3.axMapControl1.Map.get_Layer(0) as IFeatureLayer;
            pGeoFeatrueLayer_path = pFeatureLayer_path as IGeoFeatureLayer;
            ISimpleLineSymbol pLineSymbol_path = new SimpleLineSymbolClass();
            pLineSymbol_path.Color = GetRGB(255, 0, 0);
            pLineSymbol_path.Width = 2;
            ISimpleRenderer pSimpleRenderer_path = new SimpleRendererClass();
            pSimpleRenderer_path.Symbol = pLineSymbol_path as ISymbol;
            pGeoFeatrueLayer_path.Renderer = pSimpleRenderer_path as IFeatureRenderer;
遥感图

AxMapControl1和AxPageLayout1联动:

private void CopyToPageLayout()
        {
            IObjectCopy objectCopy = new ObjectCopyClass();
            object CopyFromMap = axMapControl1.Map;
            object copiedMap = objectCopy.Copy(CopyFromMap);
            object copyToMap = axPageLayoutControl1.ActiveView.FocusMap;
            objectCopy.Overwrite(copiedMap, ref copyToMap);
            axPageLayoutControl1.ActiveView.Refresh();
        }
        private void axPageLayoutControl1_OnAfterScreenDraw(object sender, IPageLayoutControlEvents_OnAfterScreenDrawEvent e)
        {
            IActiveView pActiveView = (IActiveView)axPageLayoutControl1.ActiveView.FocusMap;
            IDisplayTransformation displayTransformation = pActiveView.ScreenDisplay.DisplayTransformation;
            displayTransformation.VisibleBounds = axMapControl1.Extent;
            axPageLayoutControl1.ActiveView.Refresh();
            CopyToPageLayout();
        }
加载非shape图像文件

加载遥感图tif文件,需要使用IRasterLayer:

            Form3 form3 = new Form3();
            IRasterLayer pRasterLayer;
            pRasterLayer = new RasterLayerClass();
            IRasterLayer pRasterLayer2;
            pRasterLayer2 = new RasterLayerClass();
            pRasterLayer.CreateFromFilePath(Application.StartupPath + "\\image\\遥感.tif");
            pRasterLayer2.CreateFromFilePath(Application.StartupPath + "\\image\\遥感.tif"); //遥感.tif
            form3.axMapControl1.AddLayer(pRasterLayer as ILayer);
            form3.axMapControl2.AddLayer(pRasterLayer2 as ILayer);

            form3.axTOCControl1.SetBuddyControl(form3.axMapControl1);
            form3.axToolbarControl1.SetBuddyControl(form3.axMapControl1);
            //GeoLoadMap.CopyMapFromMapControlToPageLayoutControl(form3.axMapControl1, form3.axPageLayoutControl1);
            //form3.axPageLayoutControl1.Refresh();
            form3.Show();

小班分布图

技术分享

把shapefile按照小班号标注:
            pGeoFeatureLayer1.Renderer = pUniqueValueRenderer as IFeatureRenderer;
            IFeatureLayer pFeatureLayer2;
            pFeatureLayer2 = new FeatureLayerClass();
            pFeatureLayer2 = form3.axMapControl1.get_Layer(0) as IFeatureLayer;
            IGeoFeatureLayer pGeoFeatureLayer2;
            pGeoFeatureLayer2 = pFeatureLayer2 as IGeoFeatureLayer;
            IAnnotateLayerPropertiesCollection pAnnotate;
            pAnnotate = pGeoFeatureLayer2.AnnotationProperties;
            pAnnotate.Clear();
            IAnnotateLayerProperties pAnnoPro;
            ILineLabelPosition pLinePosintion;
            ILineLabelPlacementPriorities pLinePrio;
            IBasicOverposterLayerProperties pBasic;
            ITextSymbol pText = new TextSymbolClass();
            stdole.StdFont pFont = new stdole.StdFontClass();
            pFont.Name = "Verdana";
            pFont.Size = 8;
            pText.Font = pFont as stdole.IFontDisp;
            IHsvColor pHsvColor;
            pHsvColor = new HsvColorClass();
            pHsvColor.Hue = 336;
            pHsvColor.Saturation = 100;
            pHsvColor.Value = 15;
            pText.Color = pHsvColor;
            pLinePosintion = new LineLabelPositionClass();
            pLinePosintion.Parallel = false;
            pLinePosintion.Perpendicular = true;
            pLinePrio = new LineLabelPlacementPrioritiesClass();
            pBasic = new BasicOverposterLayerPropertiesClass();
            pBasic.FeatureType = esriBasicOverposterFeatureType.esriOverposterPolyline;
            pBasic.LineLabelPlacementPriorities = pLinePrio;
            pBasic.LineLabelPosition = pLinePosintion;
            ILabelEngineLayerProperties pEngine;
            pEngine = new LabelEngineLayerPropertiesClass();
            pEngine.Symbol = pText;
            pEngine.BasicOverposterLayerProperties = pBasic;
            pEngine.Expression = "[ID]";
            pAnnoPro = pEngine as IAnnotateLayerProperties;
            pAnnotate.Add(pAnnoPro);
            pGeoFeatureLayer2.DisplayAnnotation = true;
            form3.axMapControl2.AddLayer(form3.axMapControl1.get_Layer(0));

小班属性

查看小班属性表。自己用了个简单粗暴的办法,直接在Arcmap中将属性表导出,再转成html文件,使用新建一个窗体table,它包含窗体控件webBrowser。查看即可。

            table ff = new table();
            ff.webBrowser1.Navigate(Application.StartupPath + "\\Output_wei2.mht");
            ff.Show();

计算地理距离

定义鼠标双击事件,显示双击点的地理坐标。可以计算出选择的两点之间的地理距离

IPoint p1 = new PointClass();
        IPoint p2 = new PointClass();
        IPoint p3 = new PointClass();
        public static double error = 1e-7; 
        private double points_dis(IPoint p1,IPoint p2)
        {
            double dis = (p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y);
            dis = Math.Sqrt(dis);
            return dis;
        }
        private void Form3_Load(object sender, EventArgs e)
        {
            p3.PutCoords(-9999999, -9999999);
            p1 = p3;
            p2 = p3;
        }
 private void axMapControl2_OnDoubleClick(object sender, IMapControlEvents2_OnDoubleClickEvent e)
        {
            if (points_dis(p1, p3) < error)
            {
                IPoint pp = new PointClass();
                pp.PutCoords(e.mapX, e.mapY);
                p1=pp;
                text_point1.Text = "X: " + p1.X+", Y: "+p1.Y;
            }
            else if (points_dis(p2, p3) < error)
            {
                IPoint pp = new PointClass();
                pp.PutCoords(e.mapX, e.mapY);
                p2 = pp;
                text_point2.Text = "X: " + p2.X + ", Y: " + p2.Y;

                distance.Text = "" + points_dis(p2, p1);
                p1 = p3;
                p2 = p3;
            }
        }        

分级渲染

等高线图是由边界面、等高线2个图层组成。等高线图层按高程变化进行分类渲染,要求BreakCount=5,头尾颜色自定。(分级渲染)

            IGeoFeatureLayer pGeoFeature;
            IFeatureLayer pFeatureLayer = new FeatureLayerClass();
            pFeatureLayer = form3.axMapControl1.Map.get_Layer(0) as IFeatureLayer;
            pGeoFeature = pFeatureLayer as IGeoFeatureLayer;
            ITable pTable;
            pTable = pGeoFeature as ITable;
            string classBreaksField = "GAOCHENGZH";//要渲染的字段名称
            object dataValues;
            object dataFrequency;
            ITableHistogram tableHistogram = new BasicTableHistogramClass();
            IBasicHistogram basicHistogram = (IBasicHistogram)tableHistogram;
            tableHistogram.Field = classBreaksField;
            tableHistogram.Table = pTable;
            basicHistogram.GetHistogram(out dataValues, out dataFrequency);
            int classesNumber = 5;
            IClassifyGEN classifyGEN = new EqualIntervalClass();
            classifyGEN.Classify(dataValues, dataFrequency, ref classesNumber);

            double[] classes = (double[])classifyGEN.ClassBreaks;
            int classCount = classes.GetUpperBound(0);
            //设置着色对象的分级数据
            IClassBreaksRenderer classBreaksRenderer = new ClassBreaksRendererClass();
            classBreaksRenderer.Field = "GAOCHENGZH";
            classBreaksRenderer.BreakCount = classCount;
            classBreaksRenderer.SortClassesAscending = true;
            //产生分级着色需要的颜色带对象的起止颜色对象
            IAlgorithmicColorRamp pColorRamp = new AlgorithmicColorRampClass();
            pColorRamp.FromColor = GetHSV(60, 100, 96);
            pColorRamp.ToColor = GetHSV(0, 100, 96);
            pColorRamp.Size = classCount;
            pColorRamp.Algorithm = esriColorRampAlgorithm.esriCIELabAlgorithm;
            bool aaa = true;
            pColorRamp.CreateRamp(out aaa);
            //获得颜色
            IEnumColors pEnumColors;
            pEnumColors = pColorRamp.Colors;
            pEnumColors.Reset();
            IColor pColor;
            ISimpleLineSymbol pLineSymbol;
            int breakIndex;
            //需要注意的是分级着色对象中的symbol和break的下标都是从0开始
            for (breakIndex = 0; breakIndex < classCount - 1; breakIndex++)
            {
                pColor = pEnumColors.Next();
                pLineSymbol = new SimpleLineSymbolClass();
                pLineSymbol.Color = pColor;
                pLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
                classBreaksRenderer.set_Symbol(breakIndex, pLineSymbol as ISymbol);
                classBreaksRenderer.set_Break(breakIndex, classes[breakIndex]);
            }

            pGeoFeature.Renderer = classBreaksRenderer as IFeatureRenderer;

            form3.axTOCControl1.SetBuddyControl(form3.axMapControl1);
            form3.axToolbarControl1.SetBuddyControl(form3.axMapControl1);

鹰眼

放大、缩小等和鹰眼功能的配合(假设大的control1在左边,小的control2在右边。使用放大功能在control1中用矩形画一个区域,此时触发onMouseDown事件,control1的封装边界Extent发生改变。接着触发新的事件OnExtentUpdated,在control2中画矩形,产生鹰眼。)

        private void 放大ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomIn;
            flag = 1;
        }

        private void 缩小ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerZoomOut;
            flag = 2;
        }

        private void 移动ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            axMapControl1.MousePointer = esriControlsMousePointer.esriPointerPan;
            flag = 3; 
        }

        private void 全图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            axMapControl1.Extent = axMapControl2.FullExtent;
        }

        private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e)
        {
            IEnvelope envelope = (IEnvelope)e.newEnvelope;
            IGraphicsContainer graphicsContainer = axMapControl2.Map as IGraphicsContainer;
            IActiveView activeView = graphicsContainer as IActiveView;
            //在绘图前,清除axMapControl2中的任何图形元素
            graphicsContainer.DeleteAllElements();
            IElement element = new RectangleElementClass();
            element.Geometry = envelope;
            //设置鹰眼图中的红线
            //产生一个线符号对象
            ILineSymbol outLineSymbol = new SimpleLineSymbolClass();
            outLineSymbol.Width = 2;
            outLineSymbol.Color = GetColor(255, 0, 0, 255);
            //设置颜色属性
            //设置填充符号的属性
            IFillSymbol fillSymbol = new SimpleFillSymbolClass();
            fillSymbol.Color = GetColor(9, 0, 0, 0);
            fillSymbol.Outline = outLineSymbol;
            IFillShapeElement fillShapeElement = element as IFillShapeElement;
            fillShapeElement.Symbol = fillSymbol;
            graphicsContainer.AddElement((IElement)fillShapeElement, 0);
            activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }

        private IRgbColor GetColor(int r, int g, int b, int t)
        {
            IRgbColor rgbColor = new RgbColorClass();
            rgbColor.Red = r;
            rgbColor.Green = g;
            rgbColor.Blue = b;
            rgbColor.Transparency = (byte)t;
            return rgbColor;
        }

        private void axMapControl1_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
        {
            if (flag == 1) axMapControl1.Extent = axMapControl1.TrackRectangle();
            else if (flag == 2)
            {
                IEnvelope pEnvelope = axMapControl1.Extent;
                pEnvelope.Expand(2, 2, true);
                axMapControl1.Extent = pEnvelope;
            }
            else if (flag == 3) axMapControl1.Pan();
        }

技术分享

坡度图与坡向图

坡度图和坡向图是由等高线和边界面生成DEM,然后提取坡度图和坡向图。
技术分享

其他

交通水系图是由边界面、道路、河流线或面共3个图层组成。
为了使得Axcontrol1和Axcontrol2的内容完全一样,应该在渲染的时候就同时渲染两者。
对于栅格图像可以使用栅格渲染,但在完成这个系统的时候我直接用ArcMap导出成tif图像文件加载进来了。
控制整个系统直接退出: Application.Exit();

GIS项目设计——MaoEr森林资源管理系统

标签:

原文地址:http://blog.csdn.net/thearcticocean/article/details/51965340

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!