using Unity.Mathematics;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics.Eventing.Reader;
using BHJD.DEMdll.Public;
using System.Reflection;
using Newtonsoft.Json;
using QuYuSaoMiao.Entity;
using static BHJD.DEMdll.Public.IHttpHelper;

namespace QuYuSaoMiao
{

    public class ContourSearch
    {
        public static DemHelper DemHelper()
         {
                IDbHelper db = Factory.Load("10.130.100.5", "5432", "postgres", "postgres", "rescue_patrol_platform");
             DemHelper ddemHelper = new DemHelper(db);
             return ddemHelper;
         }
        public static double[,] MaxMinPoly(List<double[]> poly)//多边形矩形边界
        {
            List<double> PolyLon = new List<double>();
            List<double> PolyLat = new List<double>();
            foreach (double[] element in poly)
            {
                PolyLon.Add(element[0]);
                PolyLat.Add(element[1]);
            }
            double[,] MM1 = new double[2, 2];
            MM1[0, 0] = PolyLon.Min();//经度最小(西界)
            MM1[0, 1] = PolyLon.Max();//经度最大(东界)
            MM1[1, 0] = PolyLat.Min();//纬度最小(南界)
            MM1[1, 1] = PolyLat.Max();//纬度最大(北界)
            return MM1;
        }

        public static bool isinpoly(double[] zuobiao, List<double[]> poly, DemHelper demHelper)//已经替换成在边界内算法
        {
            double[,] polyOut = MaxMinPoly(poly);
            if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] || zuobiao[1] >= polyOut[1, 1])
            { return false; }
            else
            {
                string polystring = "MULTIPOLYGON(((";
                foreach (double[] element in poly)
                {
                    double e0 = element[0];
                    double e1 = element[1];
                    polystring = polystring + element[0] + " " + element[1] + ",";

                }
                polystring = polystring + poly[0][0] + " " + poly[0][1] + ")))";
                string pointstring = "POINT (" + zuobiao[0] + " " + zuobiao[1] + ")";
                // Console.WriteLine("isinpoly?");
                //Console.WriteLine(pointstring+polystring);
                string r1 = demHelper.doDetermine(pointstring, polystring);
                // Console.WriteLine(r1);
                //double[,] polyOut = MaxMinPoly(poly);
                //if (zuobiao[0] <= polyOut[0, 0] || zuobiao[0] >= polyOut[0, 1] || zuobiao[1] <= polyOut[1, 0] || zuobiao[1] >= polyOut[1, 1])
                // { return false; }
                // else
                //{
                return (r1 == "True" ? true : false);
                // }
            }





        }
        //格点生成方法:输入前四个为经纬度上下限,数组为多边形,后两个是经纬度分辨率。输出0经,1纬,2高,3是否被侦察的【01】变量。
        public static List<double[]> NPGenerate(double lonmin, double lonmax, double latmin, double latmax, List<double[]> juxing, double netscalelon, double netscalelat, DemHelper demHelper)

        {
            Console.WriteLine("格点生成");

            List<double[]> netpoints = new List<double[]>();
            for (double[] netpointprev = new double[3] { lonmin, latmax, 0 }; netpointprev[1] >= latmin; netpointprev[1] = netpointprev[1] - netscalelat)
            {
                for (netpointprev[0] = lonmin; netpointprev[0] <= lonmax; netpointprev[0] = netpointprev[0] + netscalelon)
                {

                    if (isinpoly(netpointprev, juxing, demHelper) == true)
                    {
                        double HH = 0;//需要替换为该点【netpointprev[0], netpointprev[1]】高程
                        double[] netpointtemp = new double[3] { netpointprev[0], netpointprev[1], HH };
                        //netpointtemp = netpointprev;
                        netpoints.Add(netpointtemp);
                    }
                }
            }
            return netpoints;

        }
        //格点初始化
        public static List<bool> NPprem(List<double[]> NPcoo)
        {
            List<bool> NPprem0 = new List<bool>();
            int i = 0;
            foreach (double[] element in NPcoo)
            {
                //object[] NPrentemp = new object[4] { element[0], element[1], element[2], false };
                NPprem0.Add(false);
                i++;
            }
            return NPprem0;
        }

        //格点显示,可以不用
        public static void ListPoints(List<double[]> NPtoRead)
        {
            int i1 = 0;
            int i2 = 0;
            int i3;
            int irow;
            int iLine = 1;
            Console.Write("{");
            foreach (double[] element in NPtoRead)
            {
                if (i1 != 0 && element[1] != NPtoRead[i1 - 1][1])
                {
                    i3 = i1 - 1;
                    irow = i3 - i2 + 1;
                    i2 = i1;
                    iLine++;
                    Console.Write("<本行格点数:" + irow + ">}" + Environment.NewLine + "{");
                }
                string lontax = element[0].ToString("F5");
                string lattax = element[1].ToString("F5");
                Console.Write("【E" + lontax + " | N" + lattax + " | h" + element[2] + "】\t");
                i1++;
            }
            i3 = i1 - 1;
            irow = i3 - i2 + 1;
            i2 = i1;
            Console.Write("<本行格点数:" + irow + ">}" + Environment.NewLine);
            int numberP = NPtoRead.Count;
            Console.WriteLine("行数:" + iLine + ";格点数量:" + numberP);
        }
        //两点间距计算,输出米
        public static double distance(double[] P1, double[] P2, DemHelper demHelper)
        {

            //double DL = 6371.004 * Math.Acos(Math.Sin(Math.PI / 180 * P1[1]) * Math.Sin(Math.PI / 180 * P2[1]) + Math.Cos(Math.PI / 180 * P1[1]) * Math.Cos(Math.PI / 180 * P2[1]) * Math.Cos(Math.PI / 180 * (P1[0] - P2[0]))) * 1000;
            //double D = Math.Pow(Math.Pow(DL, 2) + Math.Pow(P1[2] - P2[2], 2), 0.5);
            //return D;
            double3 p1 = new double3();
            double3 p2 = new double3();
            p1.x = P1[0];
            p1.y = P1[1];
            p1.z = P1[2];
            p2.x = P2[0];
            p2.y = P2[1];
            p2.z = P2[2];


            double D1 = demHelper.getDistance(p1, p2);
            //double DD1 = D1;
            //Console.WriteLine("距离:" + D1);
            return D1;

        }
        //两点间高度角计算,从P1到P2
        public static double angleH(double[] P1, double[] P2, DemHelper demHelper)
        {

            if (P1[2] == P2[2])
            { return 0; }
            else if (P1[0] == P2[0] && P1[1] == P2[1])
            {
                if (P1[2] < P2[2])
                { return 90; }
                else { return -90; }
            }
            else
            {
                //if (P1[2] < P2[2])
                //{
                double angleH = Math.Asin((P2[2] - P1[2]) / distance(P1, P2, demHelper)) * (180 / Math.PI);
                return angleH;
                //}
                //else
                //{
                //    double angleH = Math.Asin((P2[2] - P1[2]) / distance(P1, P2)) * (180 / Math.PI);
                //    return angleH;
                //}
            }
        }

        //MoveTo,输入单位坐标、目标坐标,输出时步结束时的单位坐标
        public static double[] MoveTo(double[] aircraft, double[] target, double V, double TimeStep, DemHelper demHelper)
        {
            double[] direction = { (target[0] - aircraft[0]) / distance(aircraft, target, demHelper), (target[1] - aircraft[1]) / distance(aircraft, target, demHelper), (target[2] - aircraft[2]) / distance(aircraft, target, demHelper) };
            double[] delta = { direction[0] * V * TimeStep, direction[1] * V * TimeStep, direction[2] * V * TimeStep };
            double[] next = { aircraft[0] + delta[0], aircraft[1] + delta[1], aircraft[2] + delta[2] };

            return next;
        }
        public static bool isBlocked(double[] P1, double[] P2, DemHelper demHelper)//是否被地形遮挡
        {

            double3 p1 = new double3();
            double3 p2 = new double3();
            p1.x = P1[0];
            p1.y = P1[1];
            p1.z = P1[2];
            p2.x = P2[0];
            p2.y = P2[1];
            p2.z = P2[2];
            //string r2 = demHelper.doIntervisibility(p1, p2);//这三行代码用于运行判定
            // Console.WriteLine(r2);
            //return (r2 == "True" ? false : true);
            return false;
        }
        //是否符合观察条件
        public static bool IsInSight(double[] aircraft, double[] netpoint, double LSight, double angleH0, double angleH1, DemHelper demHelper)//-90,-45

        {
            if (distance(aircraft, netpoint, demHelper) <= LSight && angleH0 <= angleH(aircraft, netpoint, demHelper) && angleH1 >= angleH(aircraft, netpoint, demHelper) && isBlocked(aircraft, netpoint, demHelper) == false)
            { return true; }
            else
            { return false; }
        }


        //路径生成,输入区域边界,扫描线间距,扫描高度
        public static List<double[]> scanroute(List<double[]> poly, double ScanRange, double hSC, bool isRealHeight, bool isSurround, int SurroundNum, DemHelper demHelper)
        {
            List<double[]> scanroute = new List<double[]>();
            double HH = 1;//需要替换为该点高程
            if (isSurround == false)
            {

                double[,] RactEdge = MaxMinPoly(poly);

                double[] searchpoint = { RactEdge[0, 0] + 0.5 * (ScanRange / (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360)), RactEdge[1, 0], HH + hSC };
                bool isLastIn = false;
                int ZF = 1;
                if (isinpoly(searchpoint, poly, demHelper) == true)
                {
                    scanroute.Add(searchpoint);
                    isLastIn = true;
                }
                searchpoint[1] = searchpoint[1] + ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
                for (; ; searchpoint[1] = searchpoint[1] + ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360)))
                {
                    double[] searchpoint1 = { searchpoint[0], searchpoint[1] - ZF * 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360)), isRealHeight == true ? HH + hSC : hSC };
                    double[] searchpoint0 = { searchpoint[0], searchpoint[1], isRealHeight == true ? HH + hSC : hSC };
                    if (isinpoly(searchpoint, poly, demHelper) == true && isLastIn == false)
                    {
                        scanroute.Add(searchpoint1);
                        isLastIn = true;
                    }
                    else if (isLastIn == true && isinpoly(searchpoint, poly, demHelper) == false)
                    {
                        scanroute.Add(searchpoint0);
                        isLastIn = false;
                        if (ZF == 1)
                        {
                            searchpoint[0] = searchpoint[0] + ScanRange / (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360);
                            searchpoint[1] = RactEdge[1, 1] + 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
                        }
                        else
                        {
                            searchpoint[0] = searchpoint[0] + ScanRange / (6371004 * Math.Cos(RactEdge[1, 0] * Math.PI / 180) * 2 * Math.PI / 360);
                            searchpoint[1] = RactEdge[1, 0] - 0.5 * (ScanRange / (6371004 * 2 * Math.PI / 360));
                        }
                        ZF = -ZF;
                    }
                    if (searchpoint[0] > RactEdge[0, 1])
                    { break; }
                }

                return scanroute;
            }
            else
            {


                int len = poly.Count;
                for (int i = 0; i < len; i++)
                {
                    double[] p = poly[i];
                    double[] p1 = poly[i == 0 ? len - 1 : i - 1];
                    double[] p2 = poly[i == len - 1 ? 0 : i + 1];
                    double v1EW = (p1[0] - p[0]) * (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
                    double v1SN = (p1[1] - p[1]) * (6371004 * 2 * Math.PI / 360);
                    double n1 = Math.Sqrt(v1EW * v1EW + v1SN * v1SN);
                    v1EW /= n1;
                    v1SN /= n1;

                    double v2EW = (p2[0] - p[0]) * (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
                    double v2SN = (p2[1] - p[1]) * (6371004 * 2 * Math.PI / 360);
                    double n2 = Math.Sqrt(v2EW * v2EW + v2SN * v2SN);
                    v2EW /= n2;
                    v2SN /= n2;

                    if (v1EW != v2EW)
                    {
                        double l = -ScanRange / Math.Sqrt((1 - (v1EW * v2EW + v1SN * v2SN)) / 2);

                        double vEW = v1EW + v2EW;

                        double vSN = v1SN + v2SN;

                        double n = l / Math.Sqrt(vEW * vEW + vSN * vSN);
                        vEW *= n;
                        vSN *= n;
                        double VEW = vEW / (6371004 * Math.Cos(p[1] * Math.PI / 180) * 2 * Math.PI / 360);
                        double VSN = vSN / (6371004 * 2 * Math.PI / 360);

                        double[] searchpoint = { p[0] + VEW, p[1] + VSN, isRealHeight == true ? HH + hSC : hSC };//H需替换为该点高程

                        scanroute.Add(searchpoint);
                    }
                }
                int len2 = scanroute.Count;
                if (SurroundNum >= 2)
                {
                    for (int i = 2; i <= SurroundNum; i++)
                    {
                        for (int j = 0; j < len2; j++)
                        {
                            scanroute.Add(scanroute[j]);
                        }
                    }

                }

                return scanroute;

            }
        }
        //航线转object
        public static List<object[]> RouteInput(string TurningPointName, List<double[]> TurningPointLocation, string TurningPointType, double TurningPointVelocity, double SegmentFlightFuelConsumption, double SegmentFlightTime, double TurningRadius)
        {
            List<object[]> SCIP = new List<object[]>();
            int i = 0;
            foreach (double[] element in TurningPointLocation)
            {
                object[] SCIPtemt = { $"{TurningPointName}{i}", element, $"{TurningPointType}", TurningPointVelocity, SegmentFlightFuelConsumption, SegmentFlightTime, TurningRadius };
                SCIP.Add(SCIPtemt);
                i++;
            }

            return SCIP;
        }
        //扫描线显示,不用管
        public static void ListscanRoute(List<double[]> SCtoRead)
        {
            Console.WriteLine("【showSC】");
            foreach (double[] element in SCtoRead)
            {
                string lontax = element[0].ToString("F5");
                string lattax = element[1].ToString("F5");
                Console.WriteLine("【E" + lontax + " | N" + lattax + " | h" + element[2] + "】\t");
            }
        }
        //最高点输入(等待替换)
        public static double[] TopInPloy(List<double[]> poly)
        {
            double[] Top = new double[3] { 113.999, 39.9995, 220 };
            return Top;
        }

        public static List<List<double[]>> ContourInPoly()
        {
            List<List<double[]>> ContourAdded = new List<List<double[]>>();
            List<double[]> ContourAdding = new List<double[]>();

            ContourAdding.Add(new double[3] { 113.9992, 39.9997, 100 });
            ContourAdding.Add(new double[3] { 113.9992, 39.9993, 100 });
            ContourAdding.Add(new double[3] { 113.9988, 39.9993, 100 });
            ContourAdding.Add(new double[3] { 113.9988, 39.9997, 100 });
            ContourAdded.Add(ContourAdding);
            ContourAdding.Clear();

            ContourAdding.Add(new double[3] { 113.9991, 39.9996, 200 });
            ContourAdding.Add(new double[3] { 113.9991, 39.9994, 200 });
            ContourAdding.Add(new double[3] { 113.9989, 39.9994, 200 });
            ContourAdding.Add(new double[3] { 113.9989, 39.9996, 200 });
            ContourAdded.Add(ContourAdding);

            return ContourAdded;
        }

        public static List<object[]> ContourCatalogue()
        //输出:0-编号
        //1-(double)海拔高度
        //2-是否为环线
        //3-是否被搜索过
        //4-被分割的第一个多边形(若为环线只放第一个,第二个空着)
        //5-被分割的第二个多边形,
        //顺序与等高线对应
        {
            List<double[]> Area1 = new List<double[]>();
            List<double[]> Area2 = new List<double[]>();
            Area1.Add(new double[2] { 113.9992, 39.9997 });
            Area1.Add(new double[2] { 113.9992, 39.9993 });
            Area1.Add(new double[2] { 113.9988, 39.9993 });
            Area1.Add(new double[2] { 113.9988, 39.9997 });
            List<object[]> Catalogue = new List<object[]>();
            Catalogue.Add(new object[] { 0, (double)100, true, false, Area1, Area2 });
            Area1.Clear();
            Area2.Clear();

            Area1.Add(new double[2] { 113.9991, 39.9996 });
            Area1.Add(new double[2] { 113.9991, 39.9994 });
            Area1.Add(new double[2] { 113.9989, 39.9994 });
            Area1.Add(new double[2] { 113.9989, 39.9996 });
            Catalogue.Add(new object[] { 1, (double)200, true, false, Area1, Area2 });
            return Catalogue;
        }

        public static double distance1(double[] P1, double[] P2)
        {

            double DL = 6371.004 * Math.Acos(Math.Sin(Math.PI / 180 * P1[1]) * Math.Sin(Math.PI / 180 * P2[1]) + Math.Cos(Math.PI / 180 * P1[1]) * Math.Cos(Math.PI / 180 * P2[1]) * Math.Cos(Math.PI / 180 * (P1[0] - P2[0]))) * 1000;
            double D = Math.Pow(Math.Pow(DL, 2) + Math.Pow(P1[2] - P2[2], 2), 0.5);
            return D;

        }
        public static double Area(List<double[]> Area)//求面积(待替换)
        {
            Area.RemoveAt(Area.Count - 1);
            double EarthRadius = 6371.004; // 地球半径,单位:千米
            double area = 0;
            int count = Area.Count;
            double[] p0 = Area[0];
            for (int i = 0; i < count; i++)
            {
                double[] p1 = Area[i];
                double[] p2 = Area[(i + 1) % count];
                double X1 = EarthRadius * Math.Cos(Math.PI / 180 * p0[1])*2*Math.PI / 360 * (p1[0] - p0[0]);
                double Y1 = EarthRadius * 2 * Math.PI / 360 * (p1[1] - p0[1]);
                double X2 = EarthRadius * Math.Cos(Math.PI / 180 * p0[1]) * 2 * Math.PI / 360 * (p2[0] - p0[0]);
                double Y2 = EarthRadius * 2 * Math.PI / 360 * (p2[1] - p0[1]);
                area +=( X1 * Y2 - X2 * Y1)/2;
            }
            //area = area * EarthRadius * EarthRadius / 2;
            Console.WriteLine("A=" + area);
            return Math.Abs(area);
        }



        /// <summary>
        /// 获取搜寻次序
        /// </summary>
        /// <param name="ContourInPoly">多边形内等高线</param>
        /// <param name="ContourCatalogue">多边形目录</param>
        /// <param name="ContourHighest">最高等高线</param>
        /// <param name="ContourInterval">等高线间隔</param>
        /// <param name="HighestPoint">最高点</param>
        /// <param name="poly">多边形边界</param>
        /// <param name="demHelper">Demhelper</param>
        /// <returns></returns>
       
            public static List<int> ContourOrder(List<List<double[]>> ContourInPoly, List<object[]> ContourCatalogue, double ContourHighest, double ContourLowest, double ContourInterval, double[] HighestPoint, List<double[]> poly, DemHelper demHelper)
        //核心算法1
        //输入:多边形内等高线,多边形目录,最高等高线,等高线间隔,最高点,多边形边界,Demhelper
        //输出:搜寻次序
        {
            //总初始化
            int ContourToSearch = -1;
            double ContourHigh = ContourHighest;
            double AreaToSrerch = -1;
            double[] BasePiont = HighestPoint;
            List<int> ContourOrder = new List<int>();
            double Spoly = Area(poly);
            int TotalContour = ContourInPoly.Count;//等高线条数
            double ContourHighestSearching = ContourHighest;
            
                //输出等高线最高点距离
                List<double> DistanceToTop = new List<double>();
            double DTemp = -1;
            foreach (List<double[]> element in ContourInPoly)
            {
                foreach (double[] element1 in element)
                {
                    //找的等高线点数组中,距离最高点距离最近的点
                    if (DTemp < 0 || DTemp > distance1(HighestPoint, element1))
                    {
                        DTemp = distance1(HighestPoint, element1);
                    }
                }
                DistanceToTop.Add(DTemp);
                DTemp = -1;
            }
            //输出element【4】面积
            List<double> Area4 = new List<double>();
            foreach (object[] element in ContourCatalogue)
            {
                Area4.Add(Area((List<double[]>)element[4]));
            }
            //大循环
            for (; ContourOrder.Count <= TotalContour;)
            {
                for (; ; )
                {
                    ContourToSearch = -1;
                    AreaToSrerch = -1;
                    foreach (object[] element in ContourCatalogue)
                    {
                        double[] BasePiont2 = new double[2] { BasePiont[0], BasePiont[1] };
                        bool isin = isinpoly(BasePiont2, (List<double[]>)element[4], demHelper);
                        if ((bool)element[2] == true && (double)element[1] <= ContourHigh + 1 && (double)element[1] >= ContourHigh - 1 && (bool)element[3] == false &&
                            (isin == true)
                            )//遍历最高的环形等高线,若某环线包含该点(含边缘),则搜索该线
                        {

                            ContourToSearch = (int)element[0];
                            break;
                        }
                        //Console.WriteLine("搜索高度"+ ContourHigh);
                        if ((double)element[1] <= ContourHigh+1 && (double)element[1] >= ContourHigh - 1 && (bool)element[3] == false 
                            && (ContourToSearch <0 ||
                            ((AreaToSrerch < 0 || Area4[(int)element[0]] <= AreaToSrerch) && isin== true) ||
                        ((AreaToSrerch < 0 || Spoly - Area4[(int)element[0]] <= AreaToSrerch) && isin != true)
                            ))//遍历最高的开放等高线及不包含点的环状等高线,若其包含该点的部分最小,搜索该线
                        {
                            //Console.WriteLine("点在外搜索");
                            ContourToSearch = (int)element[0];
                            if (isinpoly(BasePiont2, (List<double[]>)element[4], demHelper) == true)
                            { AreaToSrerch = Area4[(int)element[0]]; }
                            else
                            { AreaToSrerch = Spoly - Area4[(int)element[0]]; }

                        }
                        
                    }
                   // Console.WriteLine("ATS=" + AreaToSrerch);
                    if (ContourToSearch == -1)//找不到符合过滤条件的等高线后,结束循环
                    {
                        Console.WriteLine("大循环结束");
                        break;
                        
                    }
                    else//连续搜下一道
                    {
                        ContourOrder.Add(ContourToSearch);
                        Console.WriteLine(ContourToSearch + "," + ContourCatalogue[ContourToSearch][1] + "," +"连续搜索");
                        ContourCatalogue[ContourToSearch][3] = true;
                        BasePiont = ContourInPoly[ContourToSearch][0];//上一级等高线满足搜索后,该级闭合等高线的第一个点,作为下级等高线搜索的初始化点
                        ContourToSearch = -1;
                        ContourHigh = ContourHigh - ContourInterval;
                    }


                }
                double DToTop = -1;
                foreach (object[] element in ContourCatalogue)
                {

                    if ((double)element[1] == ContourHighestSearching && (bool)element[3] == false && (DToTop < 0 || DistanceToTop[(int)element[0]] < DToTop))
                    {
                        DToTop = DistanceToTop[(int)element[0]];
                        ContourToSearch = (int)element[0];
                    }
                }
                if (DToTop >= 0)
                {
                    ContourOrder.Add(ContourToSearch);
                    Console.WriteLine(ContourToSearch + "," + ContourCatalogue[ContourToSearch][1] + "," + "从头搜索");
                    ContourCatalogue[ContourToSearch][3] = true;
                    BasePiont = ContourInPoly[ContourToSearch][0];
                    ContourToSearch = -1;
                    ContourHigh = ContourHighestSearching - ContourInterval;
                }
                else
                {
                    ContourHighestSearching = ContourHighestSearching - ContourInterval;

                }
                if (ContourHighestSearching < ContourLowest)
                {
                    break;
                }
            }
            return ContourOrder;

        }

        public static List<double[]> ContourSearch1(List<double[]> Poly, double interval, int MinLength, double TrueH, int JG, DemHelper demHelper)
        //等高线搜寻整体算法!输入:【边界(wkt格式),等高线高度间隔,最小等高线节点数,真高,输出节点间隔,DemHelper】
        {
            //string wkt = "MULTIPOLYGON(((100.0035 30.9071,100.1728 30.9607,100.3523 30.8667,100.3512 30.6900,100.1569 30.6427,99.9509 30.7802,99.9907 30.8641,100.0035 30.9071)))";
            //数组转string
            string wkt= "MULTIPOLYGON(((";
            int stringcount = 0;
            foreach (double[]polyPiont in Poly)
            {
                wkt += polyPiont[0] + " " + polyPiont[1] ;
                stringcount++;
                if(stringcount<Poly.Count)
                { wkt += ","; }
            }
            wkt += ")))";
            Console.WriteLine(wkt);
            //数组转string end
            List<double[]> routePoints = new List<double[]>();
            List<double[]> juxing1 = new List<double[]>();
            string wktstr = wkt.Replace("MULTIPOLYGON", "").Replace("(", "").Replace(")", "");
            string[] pts = wktstr.Split(",");
            for (int i = 0; i < pts.Count(); i++)// pts.Count()-1
            {
                string[] pt = pts[i].Split(" ");
                double lon = Convert.ToDouble(pt[0]);
                double lat = Convert.ToDouble(pt[1]);
                juxing1.Add(new double[2] { lon, lat });
            }

            //(2)获取多边形内等高线
            HttpCmd cmd = new HttpCmd
            {
                m_RequestType = HttpRequestType.POST,
                m_Addr = "http://10.130.100.5:7785//rescue-platform-service/api/v1/dem/getContoursBywkt",
                m_Args = new List<string> { "wkt", "interval" }
            };

            string jsonstr = "{\"wkt\":\"" + wkt + "\",\"interval\":" + interval + "}";
            IHttpHelper m_HttpHelper = Factory.Load();
            string response = m_HttpHelper.HttpPost(cmd, jsonstr);
            ContourMsg data = JsonConvert.DeserializeObject<ContourMsg>(response);
            List<List<double[]>> ContourInPoly = new List<List<double[]>>();
            if (data == null || data.code != 200)
            {
                Console.WriteLine("******等高线生成出错!******");
                return routePoints;
            }
            List<List<double[]>> ContourAdded = new List<List<double[]>>();
            for (int i = 0; i < data.lstContours.Count; i++)
            {
                List<double[]> ContourAdding = data.lstContours[i].lstPoints;
                ContourInPoly.Add(ContourAdding);
            }

            //(3)获取多边形内最高点              
            List<double> maxPoint = data.maxPoint;
            double[] TopInPloy = new double[3] { maxPoint[0], maxPoint[1], maxPoint[2] };
            Console.WriteLine("******最高点******" + "\r\n" + maxPoint[0] + maxPoint[1] + maxPoint[2]);

            //(4)等高线索引生成
            List<object[]> ContourCatalogue = new List<object[]>();

            for (int i = 0; i < data.lstContours.Count; i++)
            {
                Contour contour = data.lstContours[i];
                List<double[]> lstPoints = contour.lstPoints;
                double elev = contour.elev;
                bool ifclosed = contour.ifclosed;
                List<double[]> Area1 = new List<double[]>();
                List<double[]> Area2 = new List<double[]>();
                for (int j = 0; j < lstPoints.Count; j++)
                {
                    double lon = lstPoints[j][0];
                    double lat = lstPoints[j][1];
                    Area1.Add(new double[2] { lon, lat });
                }
                bool isCircle = false;
                if (ContourInPoly[i][0] == ContourInPoly[i][ContourInPoly[i].Count - 1])
                {
                    isCircle = true;
                }
                bool isTooShort = false;
                if (ContourInPoly[i].Count <= MinLength)
                {
                    isTooShort = true;
                }
                ContourCatalogue.Add(new object[] { i, elev, isCircle, isTooShort, Area1, Area2 });
            }

            //(5)遍历顺序生成
            double maxElev = data.lstContours[0].elev;
            double minElev = data.lstContours[data.lstContours.Count - 1].elev;
            List<int> ContourOrder1 = ContourOrder(ContourInPoly, ContourCatalogue, maxElev, minElev, interval, TopInPloy, juxing1, demHelper);

            //(6)生成航路点集合
            
            string wkt_route = "";

            double[] EndPiont = TopInPloy;
            double[] StartPoint = new double[3];
            //string csvFilePath = "output.csv";//需csv输出则取消注释1/5
            //using (var writer = new StreamWriter(csvFilePath))//需csv输出则取消注释2/5
            //{//需csv输出则取消注释3/5
            foreach (int i in ContourOrder1)
            {
                //Console.WriteLine(i+ ","+ ContourCatalogue[i][1]);
                object[] contourObj = ContourCatalogue[i];
                List<double[]> contourPts = new List<double[]>();
                //等高线起点终点排序算法
                if ((bool)contourObj[2] == true)
                {
                    double Dtemp = -1;
                    int StartPointMark = -1;

                    for (int j = 0; j < ContourInPoly[i].Count; j++)
                    {

                        if (distance1(ContourInPoly[i][j], EndPiont) < Dtemp || Dtemp < 0)
                        {
                            StartPoint = ContourInPoly[i][j];
                            Dtemp =distance1(ContourInPoly[i][j], EndPiont);
                            StartPointMark = j;
                        }
                    }
                    EndPiont = ContourInPoly[i][StartPointMark];//改变终点
                    for (int j1 = StartPointMark; j1 < ContourInPoly[i].Count; j1 += JG)
                    {
                        double[] CIP1 = new double[3] { ContourInPoly[i][j1][0], ContourInPoly[i][j1][1], ContourInPoly[i][j1][2] + TrueH };
                        contourPts.Add(CIP1);
                    }
                    for (int j1 = 0; j1 < StartPointMark; j1 += JG)
                    {
                        double[] CIP1 = new double[3] { ContourInPoly[i][j1][0], ContourInPoly[i][j1][1], ContourInPoly[i][j1][2] + TrueH };
                        contourPts.Add(CIP1);
                    }

                }
                else
                {

                    int StartPointMark = -1;
                    if (distance1(ContourInPoly[i][0], EndPiont) > distance1(ContourInPoly[i][ContourInPoly[i].Count - 1], EndPiont))
                    {
                        StartPointMark = ContourInPoly[i].Count - 1;
                        StartPoint = ContourInPoly[i][ContourInPoly[i].Count - 1];
                        EndPiont = ContourInPoly[i][0];//改变终点
                        for (int j = ContourInPoly[i].Count - 1; j >= 0; j -= JG)
                        {
                            double[] CIP1 = new double[3] { ContourInPoly[i][j][0], ContourInPoly[i][j][1], ContourInPoly[i][j][2] + TrueH };
                            contourPts.Add(CIP1);
                        }
                    }
                    else
                    {
                        StartPointMark = 0;
                        StartPoint = ContourInPoly[i][0];
                        EndPiont = ContourInPoly[i][ContourInPoly[i].Count - 1];//改变终点
                        for (int j = 0; j < ContourInPoly[i].Count; j += JG)
                        {
                            double[] CIP1 = new double[3] { ContourInPoly[i][j][0], ContourInPoly[i][j][1], ContourInPoly[i][j][2] + TrueH };
                            contourPts.Add(CIP1);
                        }
                    }
                }


                for (int k = 0; k < contourPts.Count; k++)
                {
                    double[] item = contourPts[k];
                    routePoints.Add(item);
                    wkt_route += String.Format(",{0} {1} {2}", item[0], item[1], item[2]);
                    //writer.WriteLine(String.Format("{0} ,{1} ,{2}", item[0], item[1], item[2]));//需csv输出则取消注释4/5
                }


            }
            //}//需csv输出则取消注释5/5
            if (wkt_route.StartsWith(","))
            {
                wkt_route = "MULTILINESTRING ((" + wkt_route.Substring(1) + "))";
            }
            Console.WriteLine("******航路点生成******" + "\r\n" + wkt_route);
            ListscanRoute(routePoints);
            return routePoints;
        }





    }
}