Shapefile文件是ArcGIS存储矢量要素的标准格式,要读写Shapefile最简单的方法当然是基于ArcObject(或者ArcEngine)开发,不过网上也有一些开源的解译Shapefile的代码都是值得参考的,lz曾经用到过一个,源码已经贴到下边,有兴趣的可以下载看看(来源已经记不清了,如果这是您的代码请联系我),下边是两种方法的代码,其实代码很简单,但由于经常会用到所以记下来以便日后查阅。直接上代码。
打开Shapefile:
public static IFeatureClass GetShpFile(string filePath, string fileName) { IFeatureWorkspace featureWorkspace; IFeatureClass featureClass; featureWorkspace = GetShapeWorkspace(filePath) as IFeatureWorkspace; try { featureClass = featureWorkspace.OpenFeatureClass(fileName); } catch { featureClass = null; } System.Runtime.InteropServices.Marshal.ReleaseComObject(featureWorkspace); return featureClass; }
public static IWorkspace GetShapeWorkspace(string filePath) { IWorkspace workspace; IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactoryClass(); workspace = workspaceFactory.OpenFromFile(filePath, 0); System.Runtime.InteropServices.Marshal.ReleaseComObject(workspaceFactory); workspaceFactory = null; return workspace; }
向Shapefile中添加要素(一点元素为例):
public bool AddPointsToLayer(ILayer pLayer, List<IPoint> listPoint) { IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer; if (pFeatureLayer == null) { System.Windows.Forms.MessageBox.Show(pLayer.Name + "不是矢量图层!"); return false; } IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass; if (pFeatureClass.ShapeType != esriGeometryType.esriGeometryPoint) { System.Windows.Forms.MessageBox.Show(pLayer.Name + "不是点图层!"); return false; } IFeatureCursor pFeatureCursor = pFeatureClass.Insert(true); IFeatureBuffer pFeatureBuffer = null; foreach (var p in listPoint) { pFeatureBuffer = pFeatureClass.CreateFeatureBuffer(); IFeature pNewFeature = pFeatureBuffer as IFeature; pNewFeature.Shape = p as IGeometry; pNewFeature.set_Value(pNewFeature.Fields.FindField("Name"), "point1"); //pNewFeature.Store(); pFeatureCursor.InsertFeature(pFeatureBuffer); } pFeatureCursor.Flush(); return true; }
读取Shapefile的开源代码点击这里下载,下边是读取代码:
private void openShapeFile() { //Create the dialog allowing the user to select the "*.shp" and the "*.dbf" files OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; if (!(ofd.ShowDialog() ?? false)) return; //Get the file info objects for the SHP and the DBF file selected by the user FileInfo shapeFile = null; FileInfo dbfFile = null; foreach (FileInfo fi in ofd.Files) { if (fi.Extension.ToLower() == ".shp") { shapeFile = fi; } if (fi.Extension.ToLower() == ".dbf") { dbfFile = fi; } } //Read the SHP and DBF files into the ShapeFileReader ShapeFile shapeFileReader = new ShapeFile(); if (shapeFile != null && dbfFile != null) { shapeFileReader.Read(shapeFile, dbfFile); } else { HtmlPage.Window.Alert("Please select a SP and a DBF file to proceed."); return; } //Add the shapes from the shapefile into a graphics layer named "shapefileGraphicsLayer" //the greaphics layer should be present in the XAML or created earlier GraphicsLayer graphicsLayer = MyMap.Layers["shapefileGraphicsLayer"] as GraphicsLayer; foreach (ShapeFileRecord record in shapeFileReader.Records) { Graphic graphic = record.ToGraphic(); if (graphic != null) graphicsLayer.Graphics.Add(graphic); } }
直接拖拽打开:
private void MyMap_Drop(object sender, DragEventArgs e) { try { //获取拖放到地图上的文件信息 IDataObject dataObject = e.Data as IDataObject; FileInfo[] files = dataObject.GetData(DataFormats.FileDrop) as FileInfo[]; //判断拖放的文件是否为.shp和.dbf FileInfo shapeFile = null; FileInfo dbfFile = null; foreach (FileInfo fi in files) { if (fi.Extension.ToLower() == ".shp") shapeFile = fi; if (fi.Extension.ToLower() == ".dbf") dbfFile = fi; } // 读取Shapefile数据 ShapeFile shapeFileReader = new ShapeFile(); if (shapeFile != null && dbfFile != null) { shapeFileReader.Read(shapeFile, dbfFile); } else { MessageBox.Show("请将.dbf和.shp文件同时拖放到地图上!"); return; } IList<Graphic> lstGraphics = new List<Graphic>(); foreach (ShapeFileRecord record in shapeFileReader.Records) { //将从Shapefile中读取的记录转换为Graphic Graphic graphic = record.ToGraphic(); //若没有空间参考将会报错,默认设置为地图参考 if (graphic.Geometry.SpatialReference == null) graphic.Geometry.SpatialReference = MyMap.SpatialReference; if (graphic != null) lstGraphics.Add(graphic); } // 如果空间参考不一致,可能需要投影 if (lstGraphics.Count > 0) { GeometryService projectTask = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); projectTask.ProjectCompleted += new EventHandler<GraphicsEventArgs>(projectTask_ProjectCompleted); projectTask.Failed += new EventHandler<TaskFailedEventArgs>(projectTask_Failed); //将平面坐标转换为经纬度 projectTask.ProjectAsync(lstGraphics, MyMap.SpatialReference); } } catch (Exception ex) { MessageBox.Show("拖放文件错误:" + ex.ToString()); } }