using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel.Channels; using System.Text; using GeoScene.Data; using GeoScene.Engine; using GeoScene.Globe; namespace Cyberpipe { public class RedLineAnalysisTool { public class RedLineResult { private string _layerName; private string _redLineName; private double _minArea; private double _length; private GSOFeatures _lineFeaturesInRedLine; private GSOFeatures _pointFeaturesInRedLine; public GSOFeatures LineFeaturesInRedLine { get { return _lineFeaturesInRedLine; } set { _lineFeaturesInRedLine = value; } } public GSOFeatures PointFeaturesInRedLine { get { return _pointFeaturesInRedLine; } set { _pointFeaturesInRedLine = value; } } public string LayerName { get { return _layerName; } set { _layerName = value; } } public string RedLineName { get { return _redLineName; } set { _redLineName = value; } } public double MinArea { get { return _minArea; } set { _minArea = value; } } public double Length { get { return _length; } set { _length = value; } } } public static List<RedLineResult> redLineResultList=new List<RedLineResult>(); public static List<RedLineResult> Anaylysis(GSOFeatures redLineFeatures, List<string> layerNames, GSOGlobeControl globe) { List<RedLineResult> results = new List<RedLineResult>(); for (int i = 0; i < redLineFeatures.Length; i++) { GSOFeature redLineFeature = redLineFeatures[i]; GSOGeoPolyline3D polyline3D = redLineFeature.Geometry as GSOGeoPolyline3D; if (polyline3D == null) continue; GSOGeoPolygon3D polygon = new GSOGeoPolygon3D(); polygon.AddPart(polyline3D[0]); GSOFeature redLineFeaturePolygon = new GSOFeature(); //创建红线地块polygon redLineFeaturePolygon.Geometry = polygon; foreach (string layerName in layerNames) { RedLineResult redLineResult = new RedLineResult(); redLineResult.LayerName = layerName; redLineResult.RedLineName = redLineFeature.Name; GSOLayer lineLayer = globe.Globe.Layers.GetLayerByCaption(layerName); GSOLayer pointLayer = globe.Globe.Layers.GetLayerByCaption(layerName + "附属物"); if (lineLayer == null) continue; // 保存在红线地块范围内的附属物要素 if (pointLayer != null) { GSOFeatures pFeatures = pointLayer.FindFeaturesInPolygon(polygon, false); if (pFeatures != null && pFeatures.Length > 0) { redLineResult.PointFeaturesInRedLine = pFeatures; } } GSOFeatures lineFeatsInOrCrossPolygon = FindUniqueFeaturesInPolygon(lineLayer, polygon, false, "编号"); GSOFeatures lineFeatsInPolygon = FindUniqueFeaturesInPolygon(lineLayer, polygon, true, "编号"); redLineResult.LineFeaturesInRedLine = lineFeatsInOrCrossPolygon; //保存相交管线信息 redLineResult.Length = GetLength(lineFeatsInOrCrossPolygon, lineFeatsInPolygon, redLineFeaturePolygon); if (redLineResult.Length == 0) continue; /* GSOFeatures combPipeLineFeat = ConnectLine(lineFeatsInOrCrossPolygon); double area = 0; for (int k = 0; k < combPipeLineFeat.Length; k++) { area += GetArea(combPipeLineFeat[k], redLineFeaturePolygon); } redLineResult.MinArea = area;*/ redLineResult.MinArea = 0; results.Add(redLineResult); } } return results; } private static GSOFeatures FindUniqueFeaturesInPolygon(GSOLayer layer, GSOGeoPolygon3D polygon,bool isIn,string fieldName) { GSOFeatures features = layer.FindFeaturesInPolygon(polygon, isIn); if (fieldName == "") { return features; } GSOFeatures uniqueFeatues = new GSOFeatures(); Dictionary<string,GSOFeature> dic= new Dictionary<string,GSOFeature>(); for (int i = 0; i < features.Length; i++) { if(!dic.ContainsKey(features[i].GetValue(fieldName).ToString())) { dic.Add(features[i].GetValue(fieldName).ToString(), features[i]); uniqueFeatues.Add(features[i]); } } return uniqueFeatues; } private static double GetLength(GSOFeatures inOrCrossFeatures, GSOFeatures inFeatures,GSOFeature polygon) { double length = 0; for (int i = 0; i < inOrCrossFeatures.Length; i++) { GSOFeature feat = inOrCrossFeatures[i]; if (feat != null && inFeatures.FindByID(feat.ID) != null) { GSOGeoPolyline3D line = feat.Geometry as GSOGeoPolyline3D; if (line != null) { double lineLength = line.GetSpaceLength(false, 6378137); length += lineLength; } } else { GSOFeatures fs = new GSOFeatures(); int result = 0; GSODataEngineUtility.GSPolygonClipLine(feat, polygon, 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; if (lineAnalysis != null) { double tmp = lineAnalysis.GetSpaceLength(false, 6378137); length += tmp; } } } } } } return length; } private class GSOFeatureWrapper { private GSOFeature _feature; private bool isRevert; public GSOFeature Feature { get { return _feature; } set { _feature = value; } } public bool IsRevert { get { return isRevert; } set { isRevert = value; } } } private class GSOFeaturesWrapper { public List<GSOFeatureWrapper> features; public GSOFeaturesWrapper() { features = new List<GSOFeatureWrapper>(); } public void Add(GSOFeatureWrapper feature) { this.features.Add(feature); } public GSOFeature CombineFeatures() { GSOFeature singleFeature = new GSOFeature(); GSOGeoPolyline3D lineNew = new GSOGeoPolyline3D(); foreach (GSOFeatureWrapper gsoFeatureWrapper in features) { GSOGeoPolyline3D line = gsoFeatureWrapper.Feature.Geometry as GSOGeoPolyline3D; if (line == null) { continue; } GSOPoint3ds point3Ds = new GSOPoint3ds(); if (gsoFeatureWrapper.IsRevert == true) { point3Ds.Add(line[0][line[0].Count - 1]); point3Ds.Add(line[0][0]); } else { point3Ds.Add(line[0][0]); point3Ds.Add(line[0][line[0].Count - 1]); } lineNew.AddPart(point3Ds); } singleFeature.Geometry = lineNew; return singleFeature; } public bool Contains(int id) { foreach (GSOFeatureWrapper gsoFeatureWrapper in features) { if (gsoFeatureWrapper.Feature.ID == id) { return true; } } return false; } public bool Add(GSOFeature feature) { GSOGeoPolyline3D dstLine = feature.Geometry as GSOGeoPolyline3D; GSOPoint3d dstBegPoint3D = dstLine[0][0]; GSOPoint3d dstEndPoint3D = dstLine[0][dstLine[0].Count - 1]; GSOFeatureWrapper feat = new GSOFeatureWrapper(); feat.Feature = feature; foreach (GSOFeatureWrapper gsoFeatureWrapper in features) { GSOGeoPolyline3D srcLine = gsoFeatureWrapper.Feature.Geometry as GSOGeoPolyline3D; GSOPoint3d srcBegPoint3D = srcLine[0][0]; GSOPoint3d srcEndPoint3D = srcLine[0][srcLine[0].Count - 1]; bool isRevert = false; //TODO LIST:精度可能丢失,待测试 if ((srcBegPoint3D.X == dstEndPoint3D.X && srcBegPoint3D.Y == dstEndPoint3D.Y) || (srcEndPoint3D.X == dstBegPoint3D.X && srcEndPoint3D.Y == dstBegPoint3D.Y)) { feat.IsRevert = false; this.features.Add(feat); return true; } else if ((srcBegPoint3D.X == dstBegPoint3D.X && srcBegPoint3D.Y == dstBegPoint3D.Y) || (srcEndPoint3D.X == dstEndPoint3D.X && srcEndPoint3D.Y == dstEndPoint3D.Y)) { feat.IsRevert = true; this.features.Add(feat); return true; } else { continue; } } return false; } } private static GSOFeatures ConnectLine(GSOFeatures inOrCoressFeatures) { if (inOrCoressFeatures.Length == 0) { return null; } if (inOrCoressFeatures.Length == 1) { return inOrCoressFeatures; } List<GSOFeaturesWrapper> featuresWrappers = new List<GSOFeaturesWrapper>(); GSOFeatureWrapper featureWrapper = new GSOFeatureWrapper(); featureWrapper.Feature = inOrCoressFeatures[0]; featureWrapper.IsRevert = false; GSOFeaturesWrapper featuresWrapper = new GSOFeaturesWrapper(); featuresWrapper.Add(featureWrapper); featuresWrappers.Add(featuresWrapper); for (int i = 1; i < inOrCoressFeatures.Length; i++) { bool isConnected = false; GSOFeature feature = inOrCoressFeatures[i]; foreach (GSOFeaturesWrapper gsoFeaturesWrapper in featuresWrappers) { isConnected = gsoFeaturesWrapper.Add(feature); if (isConnected == true) { break; } } if (!isConnected) { GSOFeatureWrapper newFeatureWrapper = new GSOFeatureWrapper(); newFeatureWrapper.Feature = feature; newFeatureWrapper.IsRevert = false; GSOFeaturesWrapper newFeaturesWrapper = new GSOFeaturesWrapper(); newFeaturesWrapper.Add(newFeatureWrapper); featuresWrappers.Add(newFeaturesWrapper); } } /* //输出结果作为比对 String ss = ""; int kk = 0; foreach (GSOFeaturesWrapper gsoFeaturesWrapper in featuresWrappers) { foreach (GSOFeatureWrapper gsoFeatureWrapper in gsoFeaturesWrapper.features) { ss = ss+"组" + kk + " 管线Name" + gsoFeatureWrapper.Feature.Name + " 是否反向:" + gsoFeatureWrapper.IsRevert; } kk++; } */ //构建多线 GSOFeatures lineFeatures = new GSOFeatures(); foreach (GSOFeaturesWrapper gsoFeaturesWrapper in featuresWrappers) { GSOFeature feature = gsoFeaturesWrapper.CombineFeatures(); lineFeatures.Add(feature); } return lineFeatures; } private static double GetArea(GSOFeature pipeLineFeature,GSOFeature redLinePolygonFeat) { if (pipeLineFeature == null || pipeLineFeature.Geometry == null) { return 0; } GSOFeatures polygonFs = new GSOFeatures(); int result = 0; GSODataEngineUtility.GSLineClipPolygon(pipeLineFeature, redLinePolygonFeat, out polygonFs, out result); if (result != 3) { return 0.0; } double 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; if (polygonAnalysis != null) { areaMin = polygonAnalysis.Area < areaMin ? polygonAnalysis.Area : areaMin; } } } return areaMin; } } }