using System; using System.Collections.Generic; using System.Linq; using System.Text; using GeoScene.Data; using GeoScene.Engine; using GeoScene.Globe; using System.Windows.Forms; using System.Data; namespace Cyberpipe { class ClassGSOTool { /// <summary> /// 红线审核 /// </summary> /// <param name="table"></param> /// <param name="redSH"></param> /// <param name="selectFeatures"></param> /// <param name="m_globeControl"></param> /// <param name="listPipelineLayers"></param> /// <param name="lineStruct"></param> /// <param name="featsList"></param> /// <returns></returns> public static DataTable CalculateRedLineResult(out DataTable table, bool redSH, GSOFeatures selectFeatures, GSOGlobeControl m_globeControl, List<GSOLayer> listPipelineLayers, out List<MainFrm.LineStruct> lineStruct, out List<GSOFeatures> featsList) { featsList = null; lineStruct = null; table = null; if (selectFeatures.Length == 0) { MessageBox.Show("请选择地块红线!", "提示"); return null; } try { Calculate(out table,selectFeatures, listPipelineLayers, m_globeControl, out lineStruct, out featsList); } catch (Exception ex) { redSH = false; LogError.PublishError(ex); MessageBox.Show("没有红线数据,请先导入地块红线!", "提示"); } return table; } /// <summary> /// 红线审核算法过程 /// </summary> /// <param name="table"></param> /// <param name="selectFeatures"></param> /// <param name="listPipelineLayers"></param> /// <param name="m_globeControl"></param> /// <param name="lineStruct"></param> /// <param name="featsList"></param> private static void Calculate(out DataTable table,GSOFeatures selectFeatures,List<GSOLayer> listPipelineLayers, GSOGlobeControl m_globeControl, out List<MainFrm.LineStruct> lineStruct,out List<GSOFeatures> featsList) { GSOLayer pointLayer = null; GSOLayer layer = null; featsList = new List<GSOFeatures>(); lineStruct = new List<MainFrm.LineStruct>(); table = new DataTable(); table.Columns.Add("红线编号"); table.Columns.Add("管线类型"); table.Columns.Add("侵占面积" + "\\m³"); table.Columns.Add("侵入长度" + "\\m"); table.Columns.Add("侵入管线数量"); table.Columns.Add("侵入附属物个数"); for (int f = 0; f < selectFeatures.Length; f++) { GSOGeoPolyline3D polyline = selectFeatures[f].Geometry as GSOGeoPolyline3D; GSOGeoPolygon3D polygon = new GSOGeoPolygon3D(); polygon.AddPart(polyline[0]); GSOFeature featurePolygon = new GSOFeature(); featurePolygon.Geometry = polygon; #region for (int j = 0; j < listPipelineLayers.Count; j++) { layer = listPipelineLayers[j]; pointLayer = m_globeControl.Globe.Layers.GetLayerByCaption(layer.Caption + "附属物");//管线附属物计算 GSOFeatures feats = null; if (pointLayer != null) { feats = pointLayer.FindFeaturesInPolygon(polygon, false); if (feats.Length != 0) { featsList.Add(feats); } } MainFrm.LineStruct lStruct = new MainFrm.LineStruct(); //获取不完全包含在面中的所有线 GSOFeatures features = layer.FindFeaturesInPolygon(polygon, false); //获取完全包含在面中的所有线 GSOFeatures featuresTrue = layer.FindFeaturesInPolygon(polygon, true); features = getFeaturesByFilter(features, "编号"); featuresTrue = getFeaturesByFilter(featuresTrue, "编号"); for (int ft = 0; ft < features.Length; ft++) { lStruct.layerName = layer.Caption; lStruct.layerCode = features[ft].GetFieldAsString("编号"); lStruct.hxName = selectFeatures[f].Name; lineStruct.Add(lStruct); } double lengthTotal = 0.0; double areaMin = 0.0; areaMin = CalculateMinArea(features, featuresTrue, featurePolygon); lengthTotal = CalculateLength(features, featuresTrue, featurePolygon); /* #region 求面积 //获取面中所有对象组成的切割面的长线 GSOFeature polygonFeature = getLineFromGSOFeatures(features, featuresTrue); if (polygonFeature != null && polygonFeature.Geometry != null) { GSOFeatures polygonFs = new GSOFeatures(); int polygoRresult = 0; GSODataEngineUtility.GSLineClipPolygon(polygonFeature, featurePolygon, out polygonFs, out polygoRresult); ///////////////////////判断面积问题/////////////////////// if (polygoRresult == 3) { areaMin = double.MaxValue; for (int mm = 0; mm < polygonFs.Length; mm++) { GSOFeature featurePolgyon = polygonFs[mm]; if (featurePolgyon.Geometry.Type == EnumGeometryType.GeoPolygon3D) { GSOGeoPolygon3D polygonAnalysis = featurePolgyon.Geometry as GSOGeoPolygon3D; double areaPolygon = polygonAnalysis.Area; if (areaPolygon < areaMin) { areaMin = areaPolygon; } } } } } #endregion #region 求长度 for (int m = 0; m < features.Length; m++) { GSOFeature feature = features[m]; if (feature != null && feature.Geometry != null && feature.Geometry.Type == EnumGeometryType.GeoPolyline3D) { bool isFullInPolygon = false; for (int n = 0; n < featuresTrue.Length; n++) { if (feature.ID == featuresTrue[n].ID) { isFullInPolygon = true; break; } } if (isFullInPolygon == true) { GSOGeoPolyline3D line = feature.Geometry as GSOGeoPolyline3D; double lineLength = line.GetSpaceLength(false, 6378137); lengthTotal += lineLength; } else { GSOFeatures fs = new GSOFeatures(); int result = 0; GSODataEngineUtility.GSPolygonClipLine(feature, featurePolygon, out fs, out result); if (result == 1) { for (int k = 0; k < fs.Length; k++) { GSOFeature featureline = fs[k]; if (featureline != null && featureline.Geometry != null && featureline.Geometry.Type == EnumGeometryType.GeoPolyline3D) { GSOGeoPolyline3D lineAnalysis = featureline.Geometry as GSOGeoPolyline3D; double length = lineAnalysis.GetSpaceLength(false, 6378137); lengthTotal += length; } } } } } else { //MessageBox.Show("没有找到切割面的线对象!"); } } #endregion */ if (areaMin != 0 || lengthTotal != 0) { int lineCount = 0; for (int ls = 0; ls < lineStruct.Count; ls++) { if (lineStruct[ls].layerName == layer.Caption && lineStruct[ls].hxName == selectFeatures[f].Name) lineCount++; } DataRow row = table.NewRow(); row[0] = selectFeatures[f].Name; row[1] = layer.Caption; row[2] = areaMin.ToString("0.000"); row[3] = lengthTotal.ToString("0.000"); row[4] = lineCount; row[5] = feats.Length; table.Rows.Add(row); } } #endregion } } /// <summary> /// 计算侵入面积 /// </summary> /// <param name="features"></param> /// <param name="featuresTrue"></param> /// <param name="featurePolygon"></param> /// <returns></returns> private static double CalculateMinArea(GSOFeatures features, GSOFeatures featuresTrue, GSOFeature featurePolygon) { double areaMin = 0; //获取面中所有对象组成的切割面的长线 GSOFeature polygonFeature = getLineFromGSOFeatures(features, featuresTrue); if (polygonFeature != null && polygonFeature.Geometry != null) { GSOFeatures polygonFs = new GSOFeatures(); int polygoRresult = 0; GSODataEngineUtility.GSLineClipPolygon(polygonFeature, featurePolygon, out polygonFs, out polygoRresult); ///////////////////////判断面积问题/////////////////////// if (polygoRresult == 3) { areaMin = double.MaxValue; for (int mm = 0; mm < polygonFs.Length; mm++) { GSOFeature featurePolgyon = polygonFs[mm]; if (featurePolgyon.Geometry.Type == EnumGeometryType.GeoPolygon3D) { GSOGeoPolygon3D polygonAnalysis = featurePolgyon.Geometry as GSOGeoPolygon3D; double areaPolygon = polygonAnalysis.Area; if (areaPolygon < areaMin) { areaMin = areaPolygon; } } } } } return areaMin; } /// <summary> /// 计算侵入长度 /// </summary> /// <param name="features"></param> /// <param name="featuresTrue"></param> /// <param name="featurePolygon"></param> /// <returns></returns> private static double CalculateLength(GSOFeatures features, GSOFeatures featuresTrue, GSOFeature featurePolygon) { double lengthTotal = 0; for (int m = 0; m < features.Length; m++) { GSOFeature feature = features[m]; if (feature != null && feature.Geometry != null && feature.Geometry.Type == EnumGeometryType.GeoPolyline3D) { bool isFullInPolygon = false; for (int n = 0; n < featuresTrue.Length; n++) { if (feature.ID == featuresTrue[n].ID) { isFullInPolygon = true; break; } } if (isFullInPolygon == true) { GSOGeoPolyline3D line = feature.Geometry as GSOGeoPolyline3D; double lineLength = line.GetSpaceLength(false, 6378137); lengthTotal += lineLength; } else { GSOFeatures fs = new GSOFeatures(); int result = 0; GSODataEngineUtility.GSPolygonClipLine(feature, featurePolygon, out fs, out result); if (result == 1) { for (int k = 0; k < fs.Length; k++) { GSOFeature featureline = fs[k]; if (featureline != null && featureline.Geometry != null && featureline.Geometry.Type == EnumGeometryType.GeoPolyline3D) { GSOGeoPolyline3D lineAnalysis = featureline.Geometry as GSOGeoPolyline3D; double length = lineAnalysis.GetSpaceLength(false, 6378137); lengthTotal += length; } } } } } else { //MessageBox.Show("没有找到切割面的线对象!"); } } return lengthTotal; } /// <summary> /// 去除集合中重复的管线 /// </summary> /// <param name="features"></param> /// <param name="fieldName"></param> /// <returns></returns> private static GSOFeatures getFeaturesByFilter(GSOFeatures features, string fieldName) { if (features == null) return null; GSOFeatures featuresGet = new GSOFeatures(); for (int i = 0; i < features.Length; i++) { GSOFeature featureFromFS = features[i]; string fieldValueFromFS = featureFromFS.GetValue(fieldName).ToString().Trim(); bool isHas = false; for (int j = featuresGet.Length - 1; j >= 0; j--) { GSOFeature featureFromFSGet = featuresGet[j]; string fieldValueFromFSGet = featureFromFSGet.GetValue(fieldName).ToString().Trim(); if (fieldValueFromFS.Equals(fieldValueFromFSGet)) { isHas = true; break; } } if (isHas == false) { featuresGet.Add(featureFromFS.Clone()); } } return featuresGet; } /// <summary> /// 获取切割面的线 /// </summary> /// <param name="features">不完全包含在面中的所有线</param> /// <param name="featuresTrue">完全包含在面中的所有线</param> /// <returns>线</returns> private static GSOFeature getLineFromGSOFeatures(GSOFeatures features, GSOFeatures featuresTrue) { //1. 当线对象数组的长度为0时,返回空 if (features.Length == 0) { return null; } //2. 当线对象数组的长度为1时,返回这条线 if (features.Length == 1) { return features[0]; } //3. 当线对象数组的长度大于1时,计算所有线组成的最长线 //3.1 获取所有不完全包含在面中的对象selectFeatures GSOFeatures selectFeatures = new GSOFeatures(); for (int a = 0; a < features.Length; a++) { selectFeatures.Add(features[a].Clone()); } //3.2 删除features中完全包含在面中的线,获取和面的边界相交的线对象 for (int a = 0; a < featuresTrue.Length; a++) { for (int b = 0; b < features.Length; b++) { if (featuresTrue[a].ID == features[b].ID) { features.Remove(b); break; } } } //3.3 如果和面的边界相交的线的数量为0,返回空 if (features.Length == 0) { return null; } //3.4 获取第一条和面的边界相交的线featureInOutPolygon GSOFeature featureInOutPolygon = features[0]; //3.5 从所有的线中删除featureInOutPolygon for (int a = 0; a < selectFeatures.Length; a++) { if (selectFeatures[a].ID == featureInOutPolygon.ID) { selectFeatures.Remove(a); break; } } //listPS存储所有从featureInOutPolygon出发的点的集合 List<GSOPoint3ds> listPS = new List<GSOPoint3ds>(); //3.5 获取与featureInOutPolygon相连的线的集合 GSOGeoPolyline3D line = featureInOutPolygon.Geometry as GSOGeoPolyline3D; if (line != null && line.PartCount > 0) { GSOPoint3d lineStart = line[0][0]; GSOPoint3d lineEnd = line[0][line[0].Count - 1]; #region//获取和featureInOutPolygon的起点相连的线 GSOFeatures fsStart = new GSOFeatures(); for (int n = 0; n < selectFeatures.Length; n++) { GSOGeoPolyline3D newLine = selectFeatures[n].Geometry as GSOGeoPolyline3D; if (newLine != null && newLine.PartCount > 0) { GSOPoint3d newLineStart = newLine[0][0]; GSOPoint3d newLineEnd = newLine[0][newLine[0].Count - 1]; if (lineStart.X == newLineEnd.X && lineStart.Y == newLineEnd.Y) { GSOPoint3ds psAdd = new GSOPoint3ds(); for (int k = newLine[0].Count - 1; k >= 0; k--) { psAdd.Add(newLine[0][k]); } newLine[0] = psAdd; fsStart.Add(selectFeatures[n]); } else if (lineStart.X == newLineStart.X && lineStart.Y == newLineStart.Y) { fsStart.Add(selectFeatures[n]); } } } #endregion #region//获取和featureInOutPolygon的终点相连的线 GSOFeatures fsEnd = new GSOFeatures(); for (int n = 0; n < selectFeatures.Length; n++) { GSOGeoPolyline3D newLine = selectFeatures[n].Geometry as GSOGeoPolyline3D; if (newLine != null && newLine.PartCount > 0) { GSOPoint3d newLineStart = newLine[0][0]; GSOPoint3d newLineEnd = newLine[0][newLine[0].Count - 1]; if (lineEnd.X == newLineStart.X && lineEnd.Y == newLineStart.Y) { fsEnd.Add(selectFeatures[n]); } else if (lineEnd.X == newLineEnd.X && lineEnd.Y == newLineEnd.Y) { GSOPoint3ds psAdd = new GSOPoint3ds(); for (int k = newLine[0].Count - 1; k >= 0; k--) { psAdd.Add(newLine[0][k]); } newLine[0] = psAdd; fsEnd.Add(selectFeatures[n]); } } } #endregion //3.6 将featureInOutPolygon的所有点和与之起点相连的线的所有点组成一个点的集合并添加到listPS中 if (fsStart.Length > 0 && fsEnd.Length == 0) { for (int m = 0; m < fsStart.Length; m++) { GSOGeoPolyline3D lineFsStart = fsStart[m].Geometry as GSOGeoPolyline3D; if (lineFsStart != null && lineFsStart.PartCount > 0) { GSOPoint3ds psAdd = new GSOPoint3ds(); for (int k = line[0].Count - 1; k >= 0; k--) { psAdd.Add(line[0][k]); } for (int k = 0; k < lineFsStart[0].Count; k++) { psAdd.Add(lineFsStart[0][k]); } listPS = getFeaturesPoints(fsStart[m], lineFsStart[0][lineFsStart[0].Count - 1], selectFeatures, psAdd, listPS); } } } //3.6 将featureInOutPolygon的所有点和与之终点相连的线的所有点组成一个点的集合并添加到listPS中 else if (fsStart.Length == 0 && fsEnd.Length > 0) { for (int n = 0; n < fsEnd.Length; n++) { GSOGeoPolyline3D lineFsEnd = fsEnd[n].Geometry as GSOGeoPolyline3D; if (lineFsEnd != null && lineFsEnd.PartCount > 0) { GSOPoint3ds psAdd = new GSOPoint3ds(); for (int k = 0; k < line[0].Count - 1; k++) { psAdd.Add(line[0][k]); } for (int k = 0; k < lineFsEnd[0].Count; k++) { psAdd.Add(lineFsEnd[0][k]); } //获取线fsEnd[n]的另一个端点相连的线并记录该线的点的集合 listPS = getFeaturesPoints(fsEnd[n], lineFsEnd[0][lineFsEnd[0].Count - 1], selectFeatures, psAdd, listPS); } } } } //3.7 获取所有以featureInOutPolygon为起点的点的集合组成的线中的最长的线 double maxLength = 0; GSOFeature featureNew = new GSOFeature(); for (int h = 0; h < listPS.Count; h++) { GSOGeoPolyline3D lineNew = new GSOGeoPolyline3D(); lineNew.AddPart(listPS[h]); GSOLabel label = new GSOLabel(); label.Text = h.ToString(); featureNew.Label = label; double length = lineNew.GetSpaceLength(true, 6378137); if (length > maxLength) { featureNew.Geometry = lineNew; } } return featureNew; } /// <summary> /// 获取与点相连的所有线以及线的点的集合 /// </summary> /// <param name="featureSelect">选定的点所在的线</param> /// <param name="lineStart">选定的点</param> /// <param name="selectFeatures">面中不完全包含的除起点线之外所有的线</param> /// <param name="ps">选定的点所在的点的集合</param> /// <param name="listPS">所有以选定线为起点的点的集合</param> /// <returns></returns> private static List<GSOPoint3ds> getFeaturesPoints(GSOFeature featureSelect, GSOPoint3d lineStart, GSOFeatures selectFeatures, GSOPoint3ds ps, List<GSOPoint3ds> listPS) { GSOFeatures fsStart = new GSOFeatures(); for (int n = 0; n < selectFeatures.Length; n++) { if (featureSelect.ID == selectFeatures[n].ID) { continue; } GSOGeoPolyline3D newLine = selectFeatures[n].Geometry as GSOGeoPolyline3D; if (newLine != null && newLine.PartCount > 0) { GSOPoint3d newLineStart = newLine[0][0]; GSOPoint3d newLineEnd = newLine[0][newLine[0].Count - 1]; if (lineStart.X == newLineEnd.X && lineStart.Y == newLineEnd.Y) { GSOPoint3ds psAdd = new GSOPoint3ds(); for (int k = newLine[0].Count - 1; k >= 0; k--) { psAdd.Add(newLine[0][k]); } newLine[0] = psAdd; fsStart.Add(selectFeatures[n]); } else if (lineStart.X == newLineStart.X && lineStart.Y == newLineStart.Y) { fsStart.Add(selectFeatures[n]); } } } if (fsStart.Length > 0) { for (int m = 0; m < fsStart.Length; m++) { GSOGeoPolyline3D lineFsStart = fsStart[m].Geometry as GSOGeoPolyline3D; if (lineFsStart != null && lineFsStart.PartCount > 0) { GSOPoint3ds psAdd = ps.Clone(); for (int k = 0; k < lineFsStart[0].Count; k++) { psAdd.Add(lineFsStart[0][k]); } listPS = getFeaturesPoints(fsStart[m], lineFsStart[0][lineFsStart[0].Count - 1], selectFeatures, psAdd, listPS); } } } else { listPS.Add(ps); } return listPS; } } }