Newer
Older
GHFX_REFACTOR / ClassGSOTool.cs
wxn on 2 Nov 2016 26 KB 提交
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;
        }
    }
}