using System; using System.Collections.Generic; using System.Linq; using System.Text; using OSGeo.OGR; using OSGeo.GDAL; using System.Runtime.InteropServices; using System.Threading.Tasks; using GIS.HPU.ZYZ.SHP.DBF; using System.IO; namespace Kingo.Plugin.RasterToKOTilesApp.KoDataBase { public class GdalShapeOperate { private static GdalShapeOperate _instance = null; public static GdalShapeOperate Instance { get { if (_instance == null) _instance = new GdalShapeOperate(); return _instance; } } public object DbfColumn { get; private set; } public Layer CreateShp(string strVectorFile, string layerName, OSGeo.OSR.SpatialReference pSRS) { try { string strDriverName = "Memory"; int count = Ogr.GetDriverCount(); OSGeo.OGR.Driver oDriver = Ogr.GetDriverByName(strDriverName); if (oDriver == null) { return null; } // 创建数据源 DataSource oDS = oDriver.CreateDataSource(strVectorFile + layerName, null); if (oDS == null) { return null; } Layer oLayer = oDS.CreateLayer(layerName, pSRS, wkbGeometryType.wkbPolygon, null); if (oLayer == null) { return null; } else return oLayer; } catch (Exception ex) { return null; } } System.Data.DataTable tableRst = null; public System.Data.DataTable ShapeToDataTable(string shapePath, string layerName = null) { try { string dbfPathS = Path.GetDirectoryName(shapePath) + "\\" + Path.GetFileNameWithoutExtension(shapePath) + ".dbf"; string dbfPath = AppDomain.CurrentDomain.BaseDirectory + Guid.NewGuid().ToString() + ".dbf"; File.Copy(dbfPathS, dbfPath, true); DbfFile dbfFile = new DbfFile(Encoding.GetEncoding(936));//编码 dbfFile.Open(dbfPath, FileMode.Open); //打开数据 DataSource ds = Ogr.Open(shapePath, 0); if (ds == null || ds.GetLayerCount() <= 0) return null; Layer layer = null; if (string.IsNullOrWhiteSpace(layerName)) { layer = ds.GetLayerByIndex(0); } else { layer = ds.GetLayerByName(layerName); } if (layer == null) return null; OSGeo.OGR.Feature feature = null; //tableRst = GetDataTable(layer.GetLayerDefn()); string fidName = layer.GetFIDColumn(); if (string.IsNullOrWhiteSpace(fidName)) fidName = "OBJECTID"; tableRst = GetDataTable(dbfFile.Header); for (int i = 0; i < dbfFile.Header.RecordCount; i++) { DbfRecord dbfRecord = dbfFile.Read(i); fidName = "FID"; int fidIndex = dbfFile.Header.FindColumn(fidName); if (fidIndex < 0) { fidName = "OBJECTID"; fidIndex = dbfFile.Header.FindColumn(fidName); } if (fidIndex < 0) { fidName = "BSM"; fidIndex = dbfFile.Header.FindColumn(fidName); } string bsm = string.Empty; if (fidIndex > -1) { bsm = dbfRecord[fidIndex].Trim(); layer.ResetReading(); layer.SetAttributeFilter(string.Format("{1}='{0}'", bsm, fidName)); } feature = layer.GetNextFeature(); if (feature == null) continue; System.Data.DataRow drNewRow = NewDataRow(dbfRecord, dbfFile.Header, tableRst); OSGeo.OGR.Geometry geometry = feature.GetGeometryRef(); if (geometry == null) continue; drNewRow["SHAPE"] = geometry.Clone(); if (fidIndex > -1) { drNewRow[fidName] = bsm; } tableRst.Rows.Add(drNewRow); } dbfFile.Close(); return tableRst; } catch (Exception ex) { throw ex; } } public System.Data.DataTable GDBToDataTable(string shapePath, string layerName) { try { //打开数据 DataSource ds = null; if (shapePath.ToLower().EndsWith(".gdb") || shapePath.ToLower().EndsWith(".mdb")) { ds = Ogr.Open(shapePath, 0); } else { ds = Ogr.Open(shapePath.Substring(0, shapePath.LastIndexOf("\\")), 0); } if (ds == null || ds.GetLayerCount() <= 0) return null; Layer layer = null; layer = ds.GetLayerByName(layerName); if (layer == null) return null; tableRst = ShapeToDataTable(layer); return tableRst; } catch (Exception ex) { throw ex; } } private System.Data.DataRow NewDataRow(DbfRecord record, DbfHeader header, System.Data.DataTable tableRst) { if (tableRst == null) return null; System.Data.DataRow newRow = tableRst.NewRow(); for (int iField = 0; iField < header.ColumnCount; iField++) { string name = header[iField].Name.ToUpper(); if (name == "SHAPE" || name == "OBJECTID" || name == "FID") continue; if (name == "SHAPE_AREA") name = "SHAPEAREA"; else if (name == "SHAPE_LENGTH") { name = "SHAPELENGTH"; } newRow[name] = record[iField].Trim(); } return newRow; } private System.Data.DataTable GetDataTable(DbfHeader header) { System.Data.DataTable dtNew = new System.Data.DataTable(); for (int i = 0; i < header.ColumnCount; i++) { string name = header[i].Name.ToUpper(); if (name.ToUpper() == "SHAPE") continue; //if (name.ToUpper() == "BSM") //{ // dtNew.Columns.Add("BSM", typeof(Int32)); // continue; //} string colName = name.ToUpper(); if (colName == "SHAPE_AREA") colName = "SHAPEAREA"; else if (colName == "SHAPE_LENGTH") { colName = "SHAPELENGTH"; } switch (header[i].ColumnType) { case GIS.HPU.ZYZ.SHP.DBF.DbfColumn.DbfColumnType.Character: dtNew.Columns.Add(colName, typeof(string)); break; case GIS.HPU.ZYZ.SHP.DBF.DbfColumn.DbfColumnType.Number: dtNew.Columns.Add(colName, typeof(double)); break; case GIS.HPU.ZYZ.SHP.DBF.DbfColumn.DbfColumnType.Boolean: dtNew.Columns.Add(colName, typeof(bool)); break; case GIS.HPU.ZYZ.SHP.DBF.DbfColumn.DbfColumnType.Date: dtNew.Columns.Add(colName, typeof(DateTime)); break; case GIS.HPU.ZYZ.SHP.DBF.DbfColumn.DbfColumnType.Memo: dtNew.Columns.Add(colName, typeof(string)); break; case GIS.HPU.ZYZ.SHP.DBF.DbfColumn.DbfColumnType.Binary: dtNew.Columns.Add(colName, typeof(byte[])); break; case GIS.HPU.ZYZ.SHP.DBF.DbfColumn.DbfColumnType.Integer: dtNew.Columns.Add(colName, typeof(Int32)); break; default: dtNew.Columns.Add(colName, typeof(string)); break; } } dtNew.Columns.Add("SHAPE", typeof(object)); return dtNew; } public System.Data.DataTable ShapeToDataTable(Layer layer) { if (layer == null) return null; OSGeo.OGR.Feature feature = null; tableRst = GetDataTable(layer.GetLayerDefn()); wkbGeometryType layerGeometryType = layer.GetGeomType(); while ((feature = layer.GetNextFeature()) != null) { System.Data.DataRow drNewRow = NewDataRow(feature); OSGeo.OGR.Geometry geometry = feature.GetGeometryRef(); if (geometry == null) continue; drNewRow["SHAPE"] = geometry.Clone(); tableRst.Rows.Add(drNewRow); } return tableRst; } public bool CheckIsExistFeature(string sourcePath, string layerName) { DataSource ds = null; try { //打开数据 ds = Ogr.Open(sourcePath, 0); if (ds == null || ds.GetLayerCount() <= 0) return false; Layer layer = null; if (string.IsNullOrWhiteSpace(layerName)) { layer = ds.GetLayerByIndex(0); } else { layer = ds.GetLayerByName(layerName); } if (layer == null) return false; //return layer.GetFeatureCount(0)>0; return true; } catch { return false; } finally { if (ds != null) { ds.Dispose(); ds = null; } } } /// /// 创建table /// /// /// private System.Data.DataTable GetDataTable(FeatureDefn oDefn) { System.Data.DataTable dtNew = new System.Data.DataTable(); int iFieldCount = oDefn.GetFieldCount(); for (int i = 0; i < iFieldCount; i++) { FieldDefn oField = oDefn.GetFieldDefn(i); FieldType type = oField.GetFieldType(); string name = oField.GetNameRef(); if (name.ToUpper() == "SHAPE" || name.ToUpper() == "OBJECTID" || name.ToUpper() == "FID") continue; if (name.ToUpper() == "SHAPE") continue; string colName = name.ToUpper(); if (colName == "SHAPE_AREA") colName = "SHAPEAREA"; else if (colName == "SHAPE_LENGTH") { colName = "SHAPELENGTH"; } switch (type) { case FieldType.OFTInteger: dtNew.Columns.Add(colName, typeof(Int32)); break; case FieldType.OFTReal: dtNew.Columns.Add(colName, typeof(double)); break; case FieldType.OFTString: dtNew.Columns.Add(colName, typeof(string)); break; default: dtNew.Columns.Add(colName, typeof(string)); break; } //Console.WriteLine("{0}:{1} ({2}.{3})", oField.GetNameRef(), // oField.GetFieldTypeName(oField.GetFieldType()), // oField.GetWidth(), oField.GetPrecision()); } dtNew.Columns.Add("SHAPE", typeof(object)); dtNew.Columns.Add("FID", typeof(double)); return dtNew; } /// /// 创建新行 /// /// /// private System.Data.DataRow NewDataRow(Feature feature) { if (tableRst == null) return null; System.Data.DataRow newRow = tableRst.NewRow(); FeatureDefn oDefn = feature.GetDefnRef(); for (int iField = 0; iField < feature.GetFieldCount(); iField++) { FieldDefn oFieldDefn = oDefn.GetFieldDefn(iField); FieldType type = oFieldDefn.GetFieldType(); string name = oFieldDefn.GetName().ToUpper(); if (name == "SHAPE" || name == "OBJECTID" || name == "FID") continue; if (name == "SHAPE_AREA") name = "SHAPEAREA"; else if (name == "SHAPE_LENGTH") { name = "SHAPELENGTH"; } switch (type) { //case FieldType.OFTBinary: // break; //case FieldType.OFTDate: // //feature.GetFieldAsDateTime(i, // break; //case FieldType.OFTDateTime: // break; //case FieldType.OFTIntegerList: // break; //case FieldType.OFTRealList: // break; //case FieldType.OFTStringList: // break; //case FieldType.OFTTime: // break; //case FieldType.OFTWideString: // break; //case FieldType.OFTWideStringList: // break; case FieldType.OFTInteger: newRow[name] = feature.GetFieldAsInteger(iField); break; case FieldType.OFTReal: newRow[name] = feature.GetFieldAsDouble(iField); break; case FieldType.OFTString: newRow[name] = feature.GetFieldAsString(iField); break; default: newRow[name] = feature.GetFieldAsString(iField); break; } //switch (type) //{ // case caseFieldType.OFTString: // Console.WriteLine("{0}\t",feature.GetFieldAsString(iField)); // break; //caseFieldType.OFTReal: // Console.WriteLine("{0}\t",feature.GetFieldAsDouble(iField)); // break; //caseFieldType.OFTInteger: // Console.WriteLine("{0}\t",feature.GetFieldAsInteger(iField)); // break; //default: // Console.WriteLine("{0}\t",feature.GetFieldAsString(iField)); // break; //} } return newRow; } private string GetSingleGeometry(Geometry geo) { StringBuilder sb = new StringBuilder(); sb.Append("["); //Geometry ge = geo.GetGeometryRef(i); int count = geo.GetPointCount(); for (int j = 0; j < count; j++) { sb.Append("[" + geo.GetX(j) + "," + geo.GetY(j) + "],"); } sb.Remove(sb.Length - 1, 1); sb.Append("],"); return sb.ToString(); } /// /// 获取图层所有字段名称 /// /// /// /// public List GetLayerFieldsName(string shapePath, string layerName = null) { Layer layer = null; try { layer = OpenLayer(shapePath, layerName); if (layer == null) { //KGIS.Framework.Utils.LogAPI.Debug("无法打开图层:" + layerName); return null; } List layerFieldNames = new List(); FeatureDefn oDefn = layer.GetLayerDefn(); int iFieldCount = oDefn.GetFieldCount(); for (int i = 0; i < iFieldCount; i++) { FieldDefn oField = oDefn.GetFieldDefn(i); layerFieldNames.Add(oField.GetName()); } return layerFieldNames; } catch (Exception ex) { //KGIS.Framework.Utils.LogAPI.Debug("GetLayerFieldsName方法异常:" + ex); throw ex; } finally { if (layer != null) layer.Dispose(); } } /// /// 打开图层 /// /// /// /// public Layer OpenLayer(string shapePath, string layerName = null) { Layer layer = null; try { DataSource ds = Ogr.Open(shapePath, 0); if (ds == null || ds.GetLayerCount() <= 0) { //KGIS.Framework.Utils.LogAPI.Debug("ds为空"); return null; } if (string.IsNullOrWhiteSpace(layerName)) { layer = ds.GetLayerByIndex(0); } else { layer = ds.GetLayerByName(layerName); } return layer; } catch (Exception ex) { //KGIS.Framework.Utils.LogAPI.Debug("OpenLayer方法异常" + ex); throw ex; } } } }