标签:
这应该是在大学做的最后一个开发项目。
刚刚经历的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();
}
加载遥感图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();
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();
标签:
原文地址:http://blog.csdn.net/thearcticocean/article/details/51965340