Newer
Older
GHFX_REFACTOR / RedLineAnalysisTool.cs
xiaowei on 23 Nov 2016 15 KB 修改导出EXCEL类
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;
        }

    }
}