/// <summary> /// 读取要素数据,存入数据到TProjInfo实例中 /// </summary> /// <param name="features"></param> /// <returns></returns> public static TProjInfo GetProjInfoFromFeatures(Feature[] features) { var txtInfo = new TProjInfo(); GetAttrDescriptPart(features, txtInfo); //获取“属性描述” for (int i = 0; i < features.Length; i++) //获取“地块坐标” { var feature = features[i]; var geometry = feature.GetGeometryRef(); if (geometry == null || geometry.IsEmpty()) { throw new Exception("几何图形为空!"); } TPolygon tPolygon = GetBlockInfoHeader(feature, i + 1); //地块头部属性信息 tPolygon.Rings.AddRange(GetRingInfo(geometry)); //地块各个环的点信息 if (tPolygon.AttributeValues[0] == "0") { tPolygon.AttributeValues[0] = tPolygon.Rings.Sum(v => v.XyPair.Count).ToString(); } txtInfo.Polygons.Add(tPolygon); } return(txtInfo); }
/// <summary> /// 创建shp文件,将项目坐标信息写入shp文件中 /// </summary> /// <param name="tProjInfo"></param> /// <param name="shpFilePath"></param> /// <returns></returns> public static void ToShpFile(TProjInfo tProjInfo, string shpFilePath) { var dataSource = CreateShapefileSource(shpFilePath); //创建shp数据源 var layer = CreateRedLineLayer(dataSource, tProjInfo.Wkid, shpFilePath); //创建图层 ToLayer(tProjInfo, layer); //数据写入图层 dataSource.FlushCache(); layer.SyncToDisk(); dataSource.Dispose(); }
/// <summary> /// 创建shp文件,将项目坐标信息写入shp文件中 /// </summary> /// <param name="tProjInfo"></param> /// <param name="shpFilePath"></param> /// <returns></returns> public static void ToShpFile(TProjInfo tProjInfo, string shpFilePath) { var dataSource = CreateShapefileSource(shpFilePath); //创建shp数据源 var layer = CreateRedLineLayer(dataSource, tProjInfo.Wkid, shpFilePath); //创建图层 ToLayer(tProjInfo, layer); //数据写入图层 dataSource.FlushCache(); layer.SyncToDisk(); dataSource.Dispose(); Modify_Prj_To_Gauss_Kruger(shpFilePath);//将prj文件中的“墨卡托”字符替换成“高斯克吕格” }
/// <summary> /// 使多边形(每个环)首尾坐标一致 /// </summary> private static void CheckRepairPolygon(TProjInfo txtInfo) { foreach (TPolygon obj in txtInfo.Polygons) { foreach (var ring in obj.Rings) { var xyPair = ring.XyPair; if (xyPair[0][0] != xyPair[xyPair.Count - 1][0] || xyPair[0][1] != xyPair[xyPair.Count - 1][1]) { xyPair.Add(new[] { xyPair[0][0], xyPair[0][1] }); } } } }
/// <summary> /// 将项目坐标信息转成TXT规范文本 /// </summary> /// <returns></returns> public static string ToText(TProjInfo projInfo) { StringBuilder sb = new StringBuilder(); if (projInfo.ProjectDict.Count > 0)//项目信息 { sb.AppendLine("[项目信息]"); foreach (var pair in projInfo.ProjectDict) { sb.AppendLine(pair.Key + "=" + pair.Value); } } if (projInfo.PropertyDict.Count > 0) //属性描述 { sb.AppendLine("[属性描述]"); foreach (var pair in projInfo.PropertyDict) { sb.AppendLine(pair.Key + "=" + pair.Value); } } if (projInfo.Polygons.Count > 0) //地块坐标 { var precision = projInfo.PropertyDict["精度"].Replace("1", "0"); //eg:配置中精度显示为0.001,X和Y坐标输出格式为0.000 sb.AppendLine("[地块坐标]"); foreach (TPolygon polygon in projInfo.Polygons) { for (int i = 0; i < polygon.AttributeValues.Count; i++) { sb.Append(polygon.AttributeValues[i] + ","); } sb.AppendLine("@"); for (int i = 0; i < polygon.Rings.Count; i++) { var ring = polygon.Rings[i]; var ringIndex = i + 1; for (int j = 0; j < ring.XyPair.Count; j++) { var pt = ring.XyPair[j]; sb.AppendFormat("J{0},{1},{2},{3}{4}", j + 1, ringIndex, pt[0].ToString(precision), pt[1].ToString(precision), Environment.NewLine); } } } sb.Remove(sb.Length - 1, 1);//移除最后一个换行符 } return(sb.ToString()); }
/// <summary> /// 读取txt坐标文件,存入数据到TProjInfo实例中 /// </summary> /// <param name="txtPath">txt文件路径</param> /// <param name="isAddProjZone">是否在Y坐标值上添加投影分带带号</param> /// <returns></returns> public static TProjInfo GetProjInfoFromTxt(string txtPath, bool isAddProjZone = false) { var txtInfo = new TProjInfo(); var lines = File.ReadAllLines(txtPath, FileEncode.GetEncoding(txtPath)); var txtFlag = ETxtContent.NoDefine; TPolygon polygon = null; for (int i = 0; i < lines.Length; i++) { try { var line = lines[i]; if (SetStrFlag(line, ref txtFlag)) { continue; } if (txtFlag == ETxtContent.Project) { txtInfo.AddProjectDict(line); } else if (txtFlag == ETxtContent.Property) { txtInfo.AddPropertyDict(line); } else if (txtFlag == ETxtContent.Coordinate) { string[] strArray = line.Split(','); if (line.Contains("@")) { polygon = new TPolygon(); polygon.AddAttribute(strArray); txtInfo.Polygons.Add(polygon); } else if (strArray.Length == 4) { var strY = isAddProjZone ? txtInfo.ProjZone + strArray[3] : strArray[3]; polygon.AddXY(Convert.ToInt32(strArray[1]), Convert.ToDouble(strArray[2]), Convert.ToDouble(strY)); } } } catch (Exception ex) { throw new Exception($"读取坐标文件第{i}行发生错误:{ex.Message}"); } } CheckRepairPolygon(txtInfo); return(txtInfo); }
/// <summary> /// 将项目坐标信息写入指定图层中 /// (要求图层依次包含以下字段:界址点数,地块面积,地块编号,地块名称,几何类型,图幅号,地块用途,地类编码) /// </summary> /// <param name="tProjInfo"></param> /// <param name="layer"></param> public static void ToLayer(TProjInfo tProjInfo, Layer layer) { FeatureDefn featureDefn = layer.GetLayerDefn(); //创建XMID字段,写入guid以区分项目 var guid = Guid.NewGuid().ToString(); const string strXmid = "XMID"; if (featureDefn.GetFieldIndex(strXmid) < 0) { layer.CreateField(new FieldDefn(strXmid, FieldType.OFTString), 1); } //创建Feature foreach (TPolygon polygon in tProjInfo.Polygons) { Feature feature = new Feature(featureDefn); for (int i = 0; i < polygon.AttributeValues.Count; i++) { feature.SetField(i, polygon.AttributeValues[i]); } feature.SetField(strXmid, guid); bool first = true; StringBuilder polygonWkt = new StringBuilder("POLYGON("); foreach (TRing ring in polygon.Rings) { StringBuilder sbRingWkt = new StringBuilder((first ? "" : ",") + "("); first = false; bool ringFirst = true; foreach (double[] doubles in ring.XyPair) { sbRingWkt.Append((ringFirst ? "" : ",") + doubles[1] + " " + doubles[0]); ringFirst = false; } sbRingWkt.Append(")"); polygonWkt.Append(sbRingWkt); } polygonWkt.Append(")"); Geometry geometry = Geometry.CreateFromWkt(polygonWkt.ToString()); feature.SetGeometry(geometry); layer.CreateFeature(feature); } layer.SyncToDisk(); }
/// <summary> /// 获取属性描述部分 /// </summary> /// <param name="features"></param> /// <param name="txtInfo"></param> private static void GetAttrDescriptPart(Feature[] features, TProjInfo txtInfo) { //获取“属性描述” if (features.Length == 0) { throw new Exception("要素记录为空!"); } var feature1 = features[0]; var fieldDefns = feature1.GetDefnRef(); foreach (var field in CfgRedlineTxt.AttrFields) { var index = fieldDefns.GetFieldIndex(field.FieldName); txtInfo.PropertyDict.Add(field.AliasName, index > -1 ? feature1.GetFieldAsString(index) : field.DefaultValue); } //检验几何类型 var geometry1 = feature1.GetGeometryRef(); if (geometry1 == null || geometry1.IsEmpty()) { throw new Exception("几何图形为空!"); } var geoType = geometry1.GetGeometryType(); if (geoType != wkbGeometryType.wkbMultiPolygon && geoType != wkbGeometryType.wkbMultiPolygon25D && geoType != wkbGeometryType.wkbPolygon && geoType != wkbGeometryType.wkbPolygon25D) { throw new Exception("图形不是多边形!"); } var subGeometry = geometry1.GetGeometryRef(0); if (subGeometry.GetGeometryType() == wkbGeometryType.wkbPolygon) { subGeometry = subGeometry.GetGeometryRef(0); } if (subGeometry.GetGeometryType() != wkbGeometryType.wkbLineString && subGeometry.GetGeometryType() != wkbGeometryType.wkbLineString25D) { throw new Exception("图形不是多边形!"); } //检查坐标系、带号 var spatialRef = geometry1.GetSpatialReference(); if (spatialRef == null) { throw new Exception("无法识别坐标系,请先对数据设置正确坐标系!"); } //获取坐标系WKID(GDAL获取坐标系的功能不稳定,当获取不到WKID时通过配置获取坐标系,通过X坐标获取带号) var wkid = GetWkid(spatialRef); var geoSpatialRef = CfgRedlineTxt.GeoSpatialRefs.GetGeoSpatialRef(wkid); if (geoSpatialRef == null) { spatialRef.ExportToWkt(out var wkt); geoSpatialRef = CfgRedlineTxt.GeoSpatialRefs.GetGeoSpatialRef(wkt); } if (geoSpatialRef != null) { txtInfo.PropertyDict["坐标系"] = geoSpatialRef.AliasNames[0]; if (wkid != -1) { txtInfo.PropertyDict["带号"] = geoSpatialRef.GetProjZone(wkid).ToString(); } else { txtInfo.PropertyDict["带号"] = subGeometry.GetX(0).ToString().Substring(0, 2); } } }
/// <summary> /// 将项目坐标信息写到TXT文件中(编码默认GB2312) /// </summary> /// <param name="filePath">txt文件路径</param> /// <param name="projInfo">红线项目信息</param> /// <param name="encoding">txt文件编码,若值为null,则设定为GB2312</param> public static void ToTxtFile(string filePath, TProjInfo projInfo, Encoding encoding = null) { var content = ToText(projInfo); File.WriteAllText(filePath, content, encoding ?? Encoding.GetEncoding("GB2312")); }