地圖數據的加載
一、加載Shapefile數據
Shapefile文件是目前主流的一種空間數據的文件存儲方式,也是不同GIS軟件進行數據格式轉換常用的中間格式。加載Shapefile數據的方式有兩種:①通過工作空間加載。②通過MapControl控件的AddShapefile方法加載。
1、通過工作空間加載Shapefile文件
通過工作空間加載Shapefile文件主要用到IMap、ILayer、IFeatureLayer和IFeatureClass四個接口。
1)IMap接口
IMap接口是對地圖進行操作的起點,主要用於管理Map對象中的圖層對象、要素選擇集和空間參考等對象。使用IMap接口,可以獲取Map對象中的圖層個數,對圖層進行添加、刪除,還可以利用IMap接口實現查詢的高亮的顯示。
2)ILayer接口
ILayer接口是圖層對象的通用接口,它提供了操作圖層的屬性和方法,可用於所有的圖層,如要素圖層(FeatureLayer)、柵格圖層(RasterLayer)和圖形圖層集合(CompositeGraphicsLayer)等
3)IFeatureLayer
IFeatureLayer接口繼承自ILayer接口,提供了訪問基於矢量數據圖層的屬性和方法,圖層的數據可以是GeoDatabase、ShapeFile或者Coverage數據。如果使用FeatureLayer組件類,還可以通過IGeoFeatureLayer接口獲取更多的屬性和方法。IGeoFeatureLayer接口除了完全包含IFeatureLayer接口的屬性和方法外,還提供了更多的控制要素圖層的屬性和方法,如注記屬性(AnnotationPropperties)、注記顯示設置(DisplayAnnotation)等。
4)IFeatureClass接口
IFeatureClass接口是獲取和設置要素類屬性的主要接口。如獲取要素類的類型,得到滿足某個查詢條件的要素個數,或在要素類中創建一個新的功能等。
注意事項:Map、Layer、FeatureLayer三者之間的關系如下:Map是很多圖層的集合,就像ArcMap的MXD文檔一樣,可以很多Layer;Layer是圖層對象,是數據的外殼,必須建立在數據的基礎上才有意義;FeatureLayer是具體的要素圖層,需要經過Layer添加到Map中進行顯示。
FeatureLayer、FeatureClass之間的區別:
1)FeatureLayer是加載在地圖文檔中的矢量數據層,只是要素類的表現形式。FeaturClass是一組空間實體的集合,在數據表中存儲了統一的屬性和行為,每一個FeatureClass都有一個Geometry類型。
2)FeatureLayer接口繼承自ILayer接口,IFeatureClass接口繼承自IClass接口。
3)FeatureLayer可以創建自己的對象,而FeatureClass不行;FeatureLayer、FeatureClass的獲取方法如下:
IFeatureLayer pFeatureLayer=mainMapControl.get_layer(0) as IFeatureLayer;
IFeatureClass pFeatureClass=pFeatureLayer.FeatureClass;
具體的代碼展示:
OpenFileDialog pOpenFileDialog = new OpenFileDialog(); pOpenFileDialog.CheckFileExists = true;//值檢查 pOpenFileDialog.Title = "打開Shape文件"; pOpenFileDialog.Filter = "Shape文件(*.Shp)|*.shp"; pOpenFileDialog.ShowDialog(); //獲取文件路徑 //分別實例化接口對象 IWorkspaceFactory pWorkspaceFactory; IFeatureWorkspace pFeatureWorkspace; IFeatureLayer pFeatureLayer; string pFullPath = pOpenFileDialog.FileName;// if (pFullPath == "") return; int pIndex = pFullPath.LastIndexOf("\\"); string pFilePath = pFullPath.Substring(0, pIndex);//文件路徑 string pFileName = pFullPath.Substring(pIndex + 1);//文件名 //實例化ShapefileWorkspaceFactory工作空間,打開Shapefile文件 pWorkspaceFactory = new ShapefileWorkspaceFactory(); pFeatureWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(pFilePath, 0); //創建實例化要素集 IFeatureClass pFeatureClass = pFeatureWorkspace.OpenFeatureClass(pFileName); pFeatureLayer = new FeatureLayer(); pFeatureLayer.FeatureClass = pFeatureClass; pFeatureLayer.Name = pFeatureLayer.FeatureClass.AliasName; ClearAllData();//刪除所有已加載的數據 mainMapControl.Map.AddLayer(pFeatureLayer); mainMapControl.ActiveView.Refresh();//進行地圖的刷新 //同步鷹眼 // SynchronizeEye();
2.通過MapControl的AddShapefile方法加載Shapefile文件
用MapControl控件的AddShapefile方法同樣可加載Shapefile文件,這樣省去了建立工作空間、數據集等步驟。調用該方法需要傳入兩個參數,分別是文件路徑和不帶擴展名的文件名。調用方法如下:
mainMapControl.AddShapefile(string Path,string filename);
二、加載柵格數據
柵格數據是GIS的數據源之一,主要有衛星影像、航空影像、掃描的地圖和圖片等。常見的柵格數據格式有:bmp、tif、jpg等。這幾種柵格數據的工作空間是其所在的文件夾。添加柵格數據主要用到IRasterPyramid3、IRasterLayer等接口。
1)IRasterPyramid3接口
IRasterPyramid接口提供了對柵格數據集的 金字塔屬性的訪問,Present屬性用於判斷柵格數據集是否存在金字塔,Create方法用於為柵格數據創建金字塔。
2)IRasterLayer接口
IRasterLayer接口繼承ILayer接口,CreateFromDataset方法用於已有的柵格數據集對象創建圖層,CreateFromRaster方法用於已有柵格對象創建圖層,Raster屬性用於獲取IRasterLayer接口中的Raster對象,DisplayResolutionFactor屬性用於設置柵格數據的分辨率。
在實際的加載柵格文件的時候,需要引用ESRI。ArcGIS.DataSourcesRaster命名空間。思路:
(1)用IWorkspaceFactory接口的OpenFromFile方法獲取柵格文件的工作區。
(2)用IRasterWorkspace接口的OpenRasterDataset方法獲取柵格文件的數據集,實例化柵格文件對象,並對柵格數據集是否具有金字塔進行判斷(如果柵格文件不具有金字塔就創建金字塔,可以大大提高數據量圖像的顯示效率)。
(3)創建RasterLayer類的實例pRasterLayer,並定義其數據集。
(4)使用MapControl控件的AddLayer方法將pRasterLayer添加至當前圖層。
具體代碼:
////添加柵格數據 OpenFileDialog pOpenFileDialog = new OpenFileDialog(); pOpenFileDialog.CheckFileExists = true; pOpenFileDialog.Title = "打開Raster文件"; pOpenFileDialog.Filter = "柵格文件(*.*)|*.bmp;*.tif;*.jpg;*.img|(*.bmp)|*.bmp|(*.tif)|*.tif|(*.jpg)|*.jpg|(*.img)|*.img"; pOpenFileDialog.ShowDialog(); string pRasterFileName = pOpenFileDialog.FileName; if (pRasterFileName == "") return; string pPath = System.IO.Path.GetDirectoryName(pRasterFileName);//定義文件路徑 string pFileName = System.IO.Path.GetFileName(pRasterFileName);//定義文件名,獲取路徑中選擇的文件名 IWorkspaceFactory pWorkspaceFactory = new RasterWorkspaceFactory();//實例化工作空間工廠接口對象,用於實例工作空間對象 IWorkspace pWorkspace = pWorkspaceFactory.OpenFromFile(pPath ,0);//獲取柵格文件的工作區 IRasterWorkspace pRasterWorkspace = pWorkspace as IRasterWorkspace;//實例柵格空間對象 IRasterDataset pRasterDataset = pRasterWorkspace.OpenRasterDataset(pFileName );//獲取柵格文件的數據集,實例化柵格文件對象 //影像金字塔的判斷與創建 IRasterPyramid3 pRasPyrmid;//定義金字塔對象 pRasPyrmid = pRasterDataset as IRasterPyramid3; if (pRasPyrmid != null) { if (!(pRasPyrmid.Present))///判斷是否具有金字塔 { pRasPyrmid.Create();//創建金字塔 } } IRaster pRaster; pRaster = pRasterDataset.CreateDefaultRaster(); IRasterLayer pRasterLayer;//定義柵格圖層 pRasterLayer = new RasterLayer();//實例化柵格圖層類 pRasterLayer.CreateFromRaster(pRaster);//創建獲取柵格數據集 ILayer pLayer = pRasterLayer as ILayer;//實例化圖層對象繼承於柵格圖層 mainMapControl.AddLayer(pLayer ,0); }
三、加載CAD數據
CAD數據是GIS常用的一種數據源,很多GIS格式的數據都是從CAD文件轉換而來的。對於ArcGIS Engine來說,有兩種方式使用CAD數據:①作為要素圖層,用矢量數據來使用;②作為地圖背景,以柵格數據來使用。對於前者,ArcGIS Engine使用與FeatureLayer一樣的方法來管理,對於后者采用CadLayer對象管理。
1.CAD文件作為矢量圖層加載
當一個CAD文件被看作是一個矢量圖層,表現為四種要素類型:即點、線、多邊形和注記。這種區分並不是按照CAD文件本身的圖層來做的,而是簡單的考慮.dwg文件中的幾何形體對象的類型。如一個dwg文件中有多個圖層,而且這些圖層都是線類型,那么他們將會區別地合並在一個要素圖層中。點、線和多變形作為要素數據時,可以使用FeatureLayer對象,單CAD文件中的文字標注需要使用一個專門的注記圖層(Annotation)而不是要素圖層。
CAD作為矢量加載時有分層加載和整幅加載。
1)分幅加載
實現的思路:
①CAD數據可以分為點、線、面和注記,他們可以分別被加載到MapControl中,與加載其他數據一樣,首先定義一個工作空間,用CADWorkspaceFactoryClass實例化工作空間,並打開相應的工作空間。
②創建FeatureLayers的實例,定義數據集,使用IMap接口的AddLayer方法將要素圖層添加至當前地圖。
代碼如下:
///進行CAD數據的分層添加 OpenFileDialog pOpenFileDialog = new OpenFileDialog(); pOpenFileDialog.Title = "打開CAD數據文件"; pOpenFileDialog.Filter = "CAD(*.dwg)|*.dwg"; pOpenFileDialog.ShowDialog(); string pFullPath = pOpenFileDialog.FileName; if (pFullPath == "") return; //獲取文件名和文件路徑 int pIndex = pFullPath.LastIndexOf("\\"); string pFilePath = pFullPath.Substring(0,pIndex ); string pFileName = pFullPath.Substring(pIndex +1); IWorkspaceFactory pWorkspaceFactory = new CadWorkspaceFactory(); IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(pFilePath, 0); //加載CAD文件中的線文件 IFeatureClass pFeatureClass = pFeatureWorkspace.OpenFeatureClass(pFileName +":polyline"); IFeatureLayer pFeatureLayer = new FeatureLayer(); pFeatureLayer.Name = pFileName; pFeatureLayer.FeatureClass = pFeatureClass; ClearAllData();//新增刪除數據 mainMapControl.Map.AddLayer(pFeatureLayer); mainMapControl.ActiveView.Refresh();
2)整幅圖加載
實現的思路:將CAD作為整幅圖加載時,在得到的相應的工作空間之后對CAD文件中的要素進行遍歷,並判斷是否為注記圖層,如果是注記則需要使用CadAnnotationLayer對象。
代碼如下:
////整幅圖添加CAD文件數據 OpenFileDialog pOpenFileDialog = new OpenFileDialog(); pOpenFileDialog.Title = "打開CAD數據文件"; pOpenFileDialog.Filter = "CAD(*.dwg)|*.dwg"; pOpenFileDialog.ShowDialog(); string pFullPath = pOpenFileDialog.FileName; if (pFullPath == "") return; //獲取文件名和文件路徑 int pIndex = pFullPath.LastIndexOf("\\"); string pFilePath = pFullPath.Substring(0, pIndex); string pFileName = pFullPath.Substring(pIndex + 1); //打開CAD數據集 IWorkspaceFactory pWorkspaceFactory = new CadWorkspaceFactory(); pFeatureWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(pFilePath, 0); //打開一個要素集 IFeatureDataset pFeaturDataset = pFeatureWorkspace.OpenFeatureDataset(pFileName ); //IFeatureClassContainer可以管理IFeatureDataset中的每一個要素 IFeatureClassContainer pFeatuerClassContainer = (IFeatureClassContainer)pFeaturDataset; ClearAllData(); //對CAD文件中的要素進行遍歷處理 for (int i = 0; i < pFeatuerClassContainer.ClassCount; i++) { IFeatureClass pFeatureClass = pFeatuerClassContainer.get_Class(i); //如果是注記就添加注記層 if (pFeatureClass.FeatureType == esriFeatureType.esriFTCoverageAnnotation) { pFeatureLayer = new ESRI.ArcGIS.Carto.CadAnnotationLayerClass(); pFeatureLayer.Name = pFeatureClass.AliasName; pFeatureLayer.FeatureClass = pFeatureClass; mainMapControl.Map.AddLayer(pFeatureLayer); } //如果是點線面則添加要素層 else { pFeatureLayer = new FeatureLayer(); pFeatureLayer.Name = pFeatureClass.AliasName; pFeatureLayer.FeatureClass = pFeatureClass; mainMapControl.Map.AddLayer(pFeatureLayer); } mainMapControl.ActiveView.Refresh(); } //同步鷹眼 //SynchronizedEagleEye; }
2、CAD文件作為柵格圖層加載
在很多的情況下CAD數據僅僅用作背景顯示而不參與矢量分析,這時候可以將CAD文件以柵格圖層的方式加載,這時需要使用ICADLayer和ICadDrawingDataset兩個接口。
1)ICadLayer接口:主要提供了對CAD文件屬性信息的訪問,如圖名name、可見性visible等。
2)ICadDrawingDataset接口:提供了對CAD數據集成員的訪問,可以通過ICadLayer接口的CadDrawingDataset 屬性獲取CAD數據。
3)實現的思路:
①用IWorkspaceFactory接口的OpenFromFile方法獲得CAD文件為工作區。
②用ICadDrawingWorkspace接口的OpenCadDrawingDataset方法獲得CAD文件的數據集,並將其值賦值給CadLayerClass類的實例化對象pCadLayer添加至當前地圖。
具體的代碼如下:
IWorkspaceFactory pCadWorkspaceFactory; IWorkspace pWorkspace; ICadDrawingWorkspace pCadDrawingWorkspace; ICadDrawingDataset pCadDrawingDataset; ICadLayer pCadLayer; OpenFileDialog pOpenFileDialog = new OpenFileDialog(); pOpenFileDialog.Title = "打開CAD數據文件"; pOpenFileDialog.Filter = "CAD(*.dwg)|*.dwg"; pOpenFileDialog.ShowDialog(); string pFullPath = pOpenFileDialog.FileName; if (pFullPath == "") return; //獲取文件名和文件路徑 int pIndex = pFullPath.LastIndexOf("\\"); string pFilePath = pFullPath.Substring(0, pIndex); string pFileName = pFullPath.Substring(pIndex + 1); pCadWorkspaceFactory = new ESRI.ArcGIS.DataSourcesFile.CadWorkspaceFactoryClass(); pWorkspace = pCadWorkspaceFactory.OpenFromFile(pFilePath,0); pCadDrawingWorkspace=(ICadDrawingWorkspace)pWorkspace ; //獲得CAD文件的數據集 pCadDrawingDataset = pCadDrawingWorkspace.OpenCadDrawingDataset(pFileName ); pCadLayer = new CadLayerClass(); pCadLayer.CadDrawingDataset = pCadDrawingDataset; mainMapControl.Map.AddLayer(pCadLayer); mainMapControl.ActiveView.Refresh(); }