Newer
Older
GHFX_REFACTOR / ClassDoubleScreenCompare.cs
xiaowei on 16 Nov 2016 8 KB 修改双屏分析
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GeoScene.Globe;
using GeoScene.Data;
using GeoScene.Engine;
using System.Drawing;

namespace Cyberpipe
{
    class ClassDoubleScreenCompare
    {
        public static GSOFeature getSameFeatureFromOtherGlobe(GSOFeature feature, 
            GSOGlobeControl globeControl1, GSOGlobeControl globeControl2,double bufferWidth,GSOGeoPolygon3D resPolygon)
        {
            GSOLayer layer;
            GSOFeatures features = new GSOFeatures();

            if (!feature.Dataset.Caption.StartsWith("施工"))
            {
                layer = feature.Dataset.Caption == "供电管线"
                    ? globeControl2.Globe.Layers.GetLayerByCaption("施工电力管线")
                    : globeControl2.Globe.Layers.GetLayerByCaption("施工" + feature.Dataset.Caption);

                GSOFeatures fs = layer.FindFeaturesInPolygon(resPolygon, false);

                for (int i = 0; i < fs.Length; i++)
                {
                    if (isSimilarFeature(feature, fs[i], globeControl1, globeControl2, bufferWidth))
                        features.Add(fs[i]);
                }
            }
            else
            {
                layer = feature.Dataset.Caption == "施工电力管线"
                    ? globeControl1.Globe.Layers.GetLayerByCaption("供电管线")
                    : globeControl1.Globe.Layers.GetLayerByCaption(feature.Dataset.Caption.Replace("施工", ""));

                GSOFeatures fs = layer.FindFeaturesInPolygon(resPolygon, false);

                for (int i = 0; i < fs.Length; i++)
                {
                    if (isSimilarFeature(fs[i], feature, globeControl1, globeControl2, bufferWidth))
                        features.Add(fs[i]);
                }
            }

            return getMostSimilarFeatureFromFeatures(feature, features);

        }


        private static GSOFeature getMostSimilarFeatureFromFeatures(GSOFeature feature, GSOFeatures features)
        {
            double maxLength = 0;
            GSOFeature f = new GSOFeature();
            GSOGeoPolyline3D line = feature.Geometry as GSOGeoPolyline3D;

            if (features.Length == 0) return null;
            if (features.Length == 1)
            {
                f = features[0];
                f.HighLight = true;
            }
            else
            {
                for (int m = 0; m < features.Length; m++)
                {
                    GSOGeoPolyline3D tempSGLine = features[m].Geometry as GSOGeoPolyline3D;

                    double tempLength = tempSGLine.GetSpaceLength(false, 6378137);
                    double lengthAbs = Math.Abs(tempLength - line.GetSpaceLength(false, 6378137));
                    if (m == 0)
                    {
                        f = features[0];
                        f.HighLight = true;
                        maxLength = lengthAbs;
                    }
                    else if (lengthAbs < maxLength)
                    {
                        f = features[m];
                        f.HighLight = true;
                        maxLength = lengthAbs;
                    }
                }
            }
            return f;
        }

        private static bool isSameFeature(GSOFeature feature1, GSOFeature feature2, GSOLayer layer, double bufferWidth)
        {
            GSOGeoPolyline3D line = feature1.Geometry as GSOGeoPolyline3D;
            GSOGeoPolygon3D bufferPolygon = line.CreateBuffer(bufferWidth * 2, true, 5, true, false);

            if (bufferPolygon == null) return false;

            GSOFeatures featuresInLayer = layer.FindFeaturesInPolygon(bufferPolygon, true);

            if (featuresInLayer == null || featuresInLayer.Length <= 0)
                return false;

            for (int i = 0; i < featuresInLayer.Length; i++)
            {
                if (featuresInLayer[i].Name == feature2.Name)
                {
                    return true;
                    break;
                }
            }
            return false;
        }

        private static bool isSimilarFeature(GSOFeature srcFeature, GSOFeature dscFeature, 
            GSOGlobeControl globeControl1,GSOGlobeControl globeControl2,double bufferWidth)
        {
            GSOLayer dscLayer = globeControl2.Globe.Layers.GetLayerByCaption(dscFeature.Dataset.Caption);
            GSOLayer srcLayer = globeControl1.Globe.Layers.GetLayerByCaption(srcFeature.Dataset.Caption);

            if (!isSameFeature(srcFeature, dscFeature, dscLayer, bufferWidth)
                && !isSameFeature(dscFeature, srcFeature, srcLayer, bufferWidth))
                return false;
            return true;
        }

        public static void CalculateDistance(GSOGeoPolyline3D line1, GSOGeoPolyline3D line2,
            out double horizonDistance, out double verticalDistance, GSOGlobeControl globeControl1, GSOGlobeControl globeControl2)
        {
            GSOPoint3d pntIntersect1 = new GSOPoint3d();
            GSOPoint3d pntIntersect2 = new GSOPoint3d();
            GSOPoint3d pntProIntersect1 = new GSOPoint3d();
            GSOPoint3d pntProIntersect2 = new GSOPoint3d();

            verticalDistance = globeControl1.Globe.Analysis3D.ComputeVerticalDistance(line1, line2,
                out pntIntersect1, out pntIntersect2, out pntProIntersect1, out pntProIntersect2, false);
            LabelDistance(pntProIntersect1, pntProIntersect2, verticalDistance, true, "垂直", globeControl1, globeControl2);

            horizonDistance = globeControl1.Globe.Analysis3D.ComputeHorizonDistance(line1, line2,
                out pntIntersect1, out pntIntersect2, out pntProIntersect1, out pntProIntersect2, false);
            LabelDistance(pntProIntersect1, pntProIntersect2, horizonDistance, true, "水平", globeControl1, globeControl2);

        }

        private static GSOPoint3d LabelDistance(GSOPoint3d pntIntersect1, GSOPoint3d pntIntersect2, 
            double distance, bool markerVisible, string label,GSOGlobeControl globeControl1,GSOGlobeControl globeControl2)
        {
            if (pntIntersect1 == null || pntIntersect2 == null)
                return new GSOPoint3d();
            GSOGeoPolyline3D disline = new GSOGeoPolyline3D();
            GSOPoint3ds point3ds = new GSOPoint3ds();
            point3ds.Add(pntIntersect1);
            point3ds.Add(pntIntersect2);
            disline.AddPart(point3ds);

            GSOGeoMarker dismarker = new GSOGeoMarker();
            GSOFeature marker = null;
            GSOFeature line = null;
            createLineStyle(out marker, out line, disline, pntIntersect1, pntIntersect2, distance, label, dismarker);

            line.Visible = marker.Visible = markerVisible;
            globeControl1.Globe.MemoryLayer.AddFeature(line);
            globeControl1.Globe.MemoryLayer.AddFeature(marker);

            globeControl2.Globe.MemoryLayer.AddFeature(line);
            globeControl2.Globe.MemoryLayer.AddFeature(marker);

            return dismarker.Position;
        }

        private static void createLineStyle(out GSOFeature marker, out GSOFeature line, GSOGeoPolyline3D disline,
            GSOPoint3d pntIntersect1, GSOPoint3d pntIntersect2, double distance, string label, GSOGeoMarker dismarker)
        {
            GSOSimpleLineStyle3D style = new GSOSimpleLineStyle3D(); //创建线的风格
            style.LineColor = Color.Red;
            style.LineWidth = 5;          //设置线的宽度为5
            style.VertexVisible = true; 	//显示线的节点
            disline.Style = style;          //把风格添加到线上
            disline.AltitudeMode = EnumAltitudeMode.Absolute;
            line = new GSOFeature();
            line.Geometry = disline;

            dismarker.X = pntIntersect1.X;
            dismarker.Y = pntIntersect1.Y;
            dismarker.Z = (pntIntersect1.Z + pntIntersect2.Z) / 2;
            dismarker.Text = label + distance.ToString("0.00") + "米";
            dismarker.AltitudeMode = EnumAltitudeMode.Absolute;

            GSOMarkerStyle3D styleMarker = new GSOMarkerStyle3D();
            GSOTextStyle styleText = new GSOTextStyle();
            styleText.IsSizeFixed = true;
            styleText.ForeColor = Color.Red;
            styleText.FontSize = 20;
            styleMarker.TextStyle = styleText;
            dismarker.Style = styleMarker;

            marker = new GSOFeature();
            marker.Geometry = dismarker;
        }

    }
}