做GIS二次开发,不论用什么语言或二次开发工具,只要对图形的操作,都会涉及到空间参考的问题,至于空间参考的基础知识我就不再强调了!在做栅格裁剪的时候,也会涉及到空间参考的问题,主要有一下几个地方,有栅格图的空间参考、矢量图的空间参考、剪裁后栅格图的空间参考,最好这三个参考是一致的,如果不一致就要让他一致,以下为例子代码:pRaster为原栅格图,pPolygon为矢量图的上的某个面要素的最大外环。以原栅格图为参考基准。重点在于投影空间参考!
//多边形裁剪 、矩形裁剪 public void CutByPolygon(ILayer layer, IGeometry clipGeo,string m_Path,string m_CutType) { IRasterLayer pRasterLayer = layer as IRasterLayer; IRaster pRaster = pRasterLayer.Raster; IRasterProps pProps = pRaster as IRasterProps; object cellSizeProvider = pProps.MeanCellSize().X; IGeoDataset pInputDataset = pRaster as IGeoDataset; //修改矢量图要素空间参考 clipGeo.Project(pInputDataset.SpatialReference); IExtractionOp pExtractionOp = new RasterExtractionOpClass(); IRasterAnalysisEnvironment pRasterAnaEnvir = pExtractionOp as IRasterAnalysisEnvironment; pRasterAnaEnvir.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref cellSizeProvider); object extentProvider = clipGeo.Envelope; object snapRasterData = Type.Missing; pRasterAnaEnvir.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref extentProvider, ref snapRasterData); //投影栅格空间参考 rstAnalysisEnvironment.OutSpatialReference = pProps.SpatialReference; IGeoDataset pOutputDataset = null; switch (m_CutType) { case "多边形裁剪": pOutputDataset = pExtractionOp.Polygon(pInputDataset, clipGeo as IPolygon, true); break; case "矩形裁剪": pOutputDataset = pExtractionOp.Rectangle(pInputDataset, clipGeo.Envelope as IEnvelope, true); break; } IRaster clipRaster; //裁切后得到的IRaster if (pOutputDataset is IRasterLayer) { IRasterLayer rasterLayer = pOutputDataset as IRasterLayer; clipRaster = rasterLayer.Raster; } else if (pOutputDataset is IRasterDataset) { IRasterDataset rasterDataset = pOutputDataset as IRasterDataset; clipRaster = rasterDataset.CreateDefaultRaster(); } else if (pOutputDataset is IRaster) { clipRaster = pOutputDataset as IRaster; //增加阈值设定 IRasterProps temRastPro = clipRaster as IRasterProps; temRastPro.NoDataValue = pProps.NoDataValue; temRastPro.PixelType = pProps.PixelType; } else { return; } //保存新裁剪结果 string wpath = System.IO.Path.GetDirectoryName(m_Path); string wname = System.IO.Path.GetFileName(m_Path); string wtpype = System.IO.Path.GetExtension(m_Path); string pFormat = "TIFF"; switch (wtpype) { case ".bmp": pFormat = "BMP"; break; case ".tiff": case ".tif": pFormat = "TIFF"; break; case ".img": pFormat = "IMAGINE Image"; break; case ".jpg": pFormat = "JPG"; break; } IWorkspaceFactory pWKSF = new RasterWorkspaceFactoryClass(); IWorkspace pWorkspace = pWKSF.OpenFromFile(wpath, 0); ISaveAs2 pSaveAs = clipRaster as ISaveAs2; pSaveAs.SaveAs(wname, pWorkspace, pFormat); MessageBox.Show("影像裁切完成!!!", "消息提示"); }
还有一种方法,但不建议使用,就是彻底修改矢量图的空间参考:
/// <summary> /// 改变图层的空间参考 /// </summary> /// <param name="pFeatureLayer">图层</param> /// <param name="pGeoType">空间参考类型</param> private void ChangeLayerRef(IFeatureLayer pFeatureLayer, ISpatialReference pSRF) { try { IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass; //QI到IGeoDataset IGeoDataset pGeoDataset = pFeatureClass as IGeoDataset; //ISchemaLock schemaLock = (ISchemaLock)pGeoDataset; //schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); //QI到IGeoDatasetSchemaEdit IGeoDatasetSchemaEdit pGeoDatasetSchemaEdit = pGeoDataset as IGeoDatasetSchemaEdit; if (pGeoDatasetSchemaEdit.CanAlterSpatialReference) { ////创建SpatialReferenceEnvironmentClass对象 //ISpatialReferenceFactory2 pSpaRefFactory = new SpatialReferenceEnvironmentClass(); ////创建地理坐标系对象 //IGeographicCoordinateSystem pNewGeoSys = pSpaRefFactory.CreateGeographicCoordinateSystem(gcsType);//4214代表Beijing1954 //pGeoDatasetSchemaEdit.AlterSpatialReference(pNewGeoSys); pGeoDatasetSchemaEdit.AlterSpatialReference(pSRF); } } catch (Exception Err) { MessageBox.Show(Err.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } }