无人机海图调用介绍——算法

主要的海图调用过程和思路上一篇文章已经介绍

本文将介绍下该Demo中的一些函数和数值模式(源码比较乱,前后几种方式实现都在一起,仅供参考)

工程介绍:VS2013,C#实现,其中用到projNet库

1、通过程序运行的前后来介绍:

Form1_Load(初始化加载)

private void Form1_Load(object sender, EventArgs e)
        {
            //将窗口置顶并始终显示在右下角
            SetWindowPos(this.Handle, -1, 0, 0, 0, 0, 1 | 2);
            win_X = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - this.Width;
            win_Y = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height - this.Height;
            this.SetDesktopLocation(win_X, win_Y);

            //设置界面
            this.MinimizeBox = false;
           // this.OnFormClosed = false;
            this.MaximizeBox = true;
            //设置加载皮肤
            path = System.Environment.CurrentDirectory + "\\UAVShowWindow\\";
            skin.SkinFile = path + "SportsBlack.ssk";
            skin.Active = true;            
            //
            image_file = System.Environment.CurrentDirectory +"\\"+ "20.PNG";
            image_1 = Image.FromFile(image_file);

           // Image
            p_label_map = 0;           
        }

海图层级变化

public void ScaleLevel_ValueChanged(object sender, EventArgs e)//EventArgs e
        {
            //鼠标放大缩小地图
            p_CenterX = p_LUpointX + 0.5 * (p_RUpointX - p_LUpointX);
            p_CenterY = p_LDpointY + 0.5 * (p_LUpointY - p_LDpointY);

            //m_Cpoint = Tran_TW.WorldToTilePos(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
            //鼠标放大缩小地图        
            double l_x = (double)p_picMou_x;
            double l_y = (double)p_picMou_y;
            p_CenterX = p_LUpointX + (l_x / pictureBox1.Width) * (p_RUpointX - p_LUpointX);
            p_CenterY = p_LUpointY - (l_y / pictureBox1.Height) * (p_LUpointY - p_LDpointY);

            //m_Cpoint = Tran_TW.WorldToTilePos(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
            Vector2D m_point = new Vector2D(0, 0);
            m_point = TransformTileWorld.CalculationNum(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
            m_Cpoint.X = (float)m_point.X;
            m_Cpoint.Y = (float)m_point.Y;
           // p_TileIndex = TransformTileWorld.calculateTileIndex(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
            
            if (MapConfig != null)
            {
                int level = (int)ScaleLevel.Value;
                MapConfig.DefaultLevel = level;
                CreatCacheDir();
                //DoMethod("ReloadMap");
                //DoMethod("ReadLoadMap");
                DoMethod("ReadWMSMap2");
            }
            p_label_map = 1;
        }

海图加载变换函数ReadWMSMap2

1)记录海图瓦片坐标及显示位置

2)CoordRange(I_x, I_y, i, j);   //记录图像范围大小

扫描二维码关注公众号,回复: 2815216 查看本文章

3)海图加载(通过海图坐标进行加载)

 try
                    {
                        int row = j - startr;
                        //MapConfig.MapUrl = "http://localhost:9999/landsea/tile/TMS/getTile/cmap/full/{" + s_z + "}/{" + s_y + "}/{" + s_x + "}.png";
                        string filename = s_z + "/" + s_x + "/" + s_y + ".png";
                        //stream = new System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(filename));
                        if (!System.IO.File.Exists(filename))
                        {                            
                            string picurl = "http://localhost:9999/landsea/tile/TMS/getTile/cmap/full/" + filename;
                            req = HttpWebRequest.Create(picurl) as System.Net.HttpWebRequest;
                            req.AllowAutoRedirect = true;
                            req.KeepAlive = false;
                            req.Timeout = 10000;
                            req.ServicePoint.ConnectionLeaseTimeout = 10000;
                            req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
                            req.Headers.Add("Accept-Encoding: gzip, deflate, sdch");
                            req.Headers.Add("Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4");
                            req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0";
                            using (res = req.GetResponse() as System.Net.HttpWebResponse)
                            {
                                using (stream = res.GetResponseStream())
                                {
                                    image = Image.FromStream(stream);
                                    targetgraphic = Graphics.FromImage(bitmap);                                  
                                    Rectangle destRect = new Rectangle((1-j) * (p_w2-2), (i) * (p_h2-1), p_w2, p_h2);                                  
                                    targetgraphic.DrawImage(image, destRect, new Rectangle(0,0,256,256), GraphicsUnit.Pixel);
                                    stream.Close();
                                }
                                targetgraphic = null;


                                stream = null;
                                res.Close();
                            }
                            res = null;
                        }


                    }

4)海图缓存处理

if (this.pictureBox1.InvokeRequired)
                        {
                            UpdateUI update = delegate { pictureBox1.Image = (Bitmap)bitmap.Clone(); };
                            pictureBox1.Invoke(update);
                        }
                        else
                        {
                            pictureBox1.Image = (Bitmap)bitmap.Clone();
                        }

2、重要函数类介绍

TransformTileWorld坐标转换

WorldToTilePos和TileToWorldPos是Google转换公式,这样子转换过来显示没问题,但存在位置偏移,因为海图的坐标原点不在0,0,而是0.00 221194.08

坐标转换

 //4326转3395
        public static Vector2D lonLatToMercator(Vector2D lonLat)
        {
            Vector2D mercator = new Vector2D();

            IProjectedCoordinateSystem toCS = CoordinateSystemWktReader.Parse(s3395) as IProjectedCoordinateSystem;   //定义海图坐标系
          //  ICoordinateSystem fromCS = SridReader.GetCSbyID(4326);      //定义Google坐标系
            IProjectedCoordinateSystem fromCS = CoordinateSystemWktReader.Parse(geo3857) as IProjectedCoordinateSystem;
            GeographicCoordinateSystem GeofromCS = (GeographicCoordinateSystem)fromCS.GeographicCoordinateSystem;

            List<double[]> pts = new List<double[]>();
            double[] xy = new double[] { lonLat.X, lonLat.Y };
            pts.Add(xy);
            List<double[]> results = new List<double[]>();


            results = new List<double[]>();
            try
            {
                CoordinateTransformationFactory ctfac = new CoordinateTransformationFactory();
                ICoordinateTransformation trans = ctfac.CreateFromCoordinateSystems(GeofromCS, toCS);
                results = trans.MathTransform.TransformList(pts);
                //bRes = true;
                mercator.X = results[0][0];
                mercator.Y = results[0][1];

            }
            catch (SystemException sysEx)
            {              
            }


            return mercator;
        }

//3395转4326,3395投影坐标转4326经纬度坐标
        public static Vector2D MercatorTolonLat(Vector2D mercator) 
        {
            Vector2D lonLat = new Vector2D();
            IProjectedCoordinateSystem fromCS = CoordinateSystemWktReader.Parse(s3395) as IProjectedCoordinateSystem;   //定义海图坐标系
            ICoordinateSystem toCS = SridReader.GetCSbyID(4326);      //定义Google坐标系

            List<double[]> pts = new List<double[]>();
            double[] xy = new double[] { mercator.X, mercator.Y };
            pts.Add(xy);
            List<double[]> results = new List<double[]>();


            results = new List<double[]>();
            try
            {
                CoordinateTransformationFactory ctfac = new CoordinateTransformationFactory();
                ICoordinateTransformation trans = ctfac.CreateFromCoordinateSystems(fromCS, toCS);
                results = trans.MathTransform.TransformList(pts);
                //bRes = true;
                lonLat.X = results[0][0];
                lonLat.Y = results[0][1];

            }
            catch (SystemException sysEx)
            {
            }

            return lonLat;
        }

其中用到了projNet库

以下为不同坐标参数:

public static string s3395 = "PROJCS[\"WGS 84 / World Mercator\","
            + "GEOGCS[\"WGS 84\","
            + "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],"
            + "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
            + "UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],"
            + "PROJECTION[\"Mercator_1SP\"],"
            + "PARAMETER[\"standard_parallel_1\",0],"
            + "PARAMETER[\"latitude_of_origin\",2],"
            + "PARAMETER[\"central_meridian\",0],"
            + "PARAMETER[\"scale_factor\",1],"
            + "PARAMETER[\"false_easting\",0],"
            + "PARAMETER[\"false_northing\",0],"
            + "UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],"
            + "AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],AUTHORITY[\"EPSG\",\"3395\"]]";

        public static string geo900913 = "PROJCS[\"Google Maps Global Mercator\","
           + "GEOGCS[\"WGS 84\","
           + "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,0,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],"
           + "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
           + "UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],"
           + "PROJECTION[\"Mercator_2SP\"],"
           + "PARAMETER[\"standard_parallel_1\",0],"
           + "PARAMETER[\"latitude_of_origin\",0],"
           + "PARAMETER[\"central_meridian\",0],"
           + "PARAMETER[\"false_easting\",0],"
           + "PARAMETER[\"false_northing\",0],"
           + "UNIT[\"Meter\",1],"
           +"EXTENSION[\"PROJ4\",\"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs\"],AUTHORITY[\"EPSG\",\"900913\"]]";

        public static string geo3857 = "PROJCS[\"WGS 84 / Pseudo-Mercator\","
            + "GEOGCS[\"WGS 84\","
            + "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],"
            + "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
            + "UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],"
            + "PROJECTION[\"Mercator_1SP\"],"
            + "PARAMETER[\"central_meridian\",0],"
            + "PARAMETER[\"scale_factor\",1],"
            + "PARAMETER[\"false_easting\",0],"
            + "PARAMETER[\"false_northing\",0],"
            + "UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],"
            + "AXIS[\"X\",EAST],AXIS[\"Y\",NORTH],"
            + "EXTENSION[\"PROJ4\",\"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs\"],AUTHORITY[\"EPSG\",\"3857\"]]";


内部转换函数大家可以去关注源码,上述介绍主要方便大家理解源码方便些,因为实在太乱啦!

源码位置:

http://download.csdn.net/download/u011326478/10247483



猜你喜欢

转载自blog.csdn.net/u011326478/article/details/79295352