offset.dat

举报
清雨小竹 发表于 2022/09/25 00:53:37 2022/09/25
【摘要】 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.IO; using MySql.Data.MySqlClient; namespace...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using MySql.Data.MySqlClient;

namespace testgps
{

    class Program
    {
       
        static ArrayList m_array;
        const double M_PI = 3.14159265358979323846264338327950288;
        const double M_E = 2.71828182845904523536028747135266250;

        public class MapCoord
        {
            public int lng { set; get; } //12151表示121.51
            public int lat { set; get; } //3130表示31.30
            public int x_off { set; get; } //地图x轴偏移像素值
            public int y_off { set; get; } //地图y轴偏移像素值
        }

        /// <summary>
        /// 自定义比较类
        /// </summary>
        public class myReverserClass : IComparer
        {
            public int Compare(object x, object y)
            {
                MapCoord data1 = (MapCoord)x, data2 = (MapCoord)y;
                int det_lng = data1.lng - data2.lng;
                if (det_lng != 0)
                    return det_lng;
                else
                    return data1.lat - data2.lat;
            }
        }

        //这就需要一个把经纬度转换成地图xy轴坐标的算法:

        private static double lngToPixel(double lng, int zoom)
        {
            return (lng + 180) * (256L << zoom) / 360;
        }

        private static double latToPixel(double lat, int zoom)
        {
            double siny = Math.Sin(lat * M_PI / 180);
            double y = Math.Log((1 + siny) / (1 - siny));
            return (128 << zoom) * (1 - y / (2 * M_PI));
        }


        //xy轴坐标加上对应的地图xy轴的偏移量,最后还要反过来将最终正确的地图xy轴坐标转换成正确的经纬度
        private static double pixelToLng(double pixelX, int zoom)
        {
            return pixelX * 360 / (256L << zoom) - 180;
        }

        private static double pixelToLat(double pixelY, int zoom)
        {
            double y = 2 * M_PI * (1 - pixelY / (128 << zoom));
            double z = Math.Pow(M_E, y);
            double siny = (z - 1) / (z + 1);
            return Math.Asin(siny) * 180 / M_PI;
        }

        /// <summary>
        /// 将字节转化为具体的数据对象
        /// </summary>
        /// <param name="buf"></param>
        /// <returns></returns>
       
        private static MapCoord getMapCoordFromBytes(byte[] buf)
        {
            //数据文档结构是八字节为一个坐标及其偏移量,分别为经度,纬度,x偏移量,y偏移量; 每两字节为一个数据
            MapCoord coord = new MapCoord();
            byte[] b1 = new byte[2], b2 = new byte[2], b3 = new byte[2], b4 = new byte[2];
            Array.Copy(buf, 0, b1, 0, 2);
            Array.Copy(buf, 2, b2, 0, 2);
            Array.Copy(buf, 4, b3, 0, 2);
            Array.Copy(buf, 6, b4, 0, 2);
            coord.lng = System.BitConverter.ToInt16(b1, 0);
            coord.lat = System.BitConverter.ToInt16(b2, 0);
            coord.x_off = System.BitConverter.ToInt16(b3, 0);
            coord.y_off = System.BitConverter.ToInt16(b4, 0);

            string mysqlYunfeng = "server=localhost;port=3306;user id=root;password=admin;database=gps;CharSet=gb2312;";
            string sql = "insert into offset001(lat,log,offx,offy) values(@lat,@log,@offx,@offy)";
            MySqlParameter[] paras = new MySqlParameter[4];
            paras[0] = new MySqlParameter("@lat", coord.lat);
            paras[1] = new MySqlParameter("@log", coord.lng);
            paras[2] = new MySqlParameter("@offx", coord.x_off);
            paras[3] = new MySqlParameter("@offy", coord.y_off);
            MySqlHelper.ExecuteNonQuery(mysqlYunfeng, sql,paras);

            Console.WriteLine(coord.lat);
            return coord;
        }

        public static void  OpenDatFile()
        {
                        //读取数据文件
            //这里读取文件的地方可以单独提出来, 读一次之后保存到内存里, 读取时比较耗时间. 或者放到数据库中去.
            FileStream fs = new FileStream("offset.dat", FileMode.OpenOrCreate, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);
            int size = (int)fs.Length / 8;
            m_array = new ArrayList();
            for (int i = 0; i < size; i++)
            {
                //按八个字节八个字节来读取, 放在MapCoord对象中,并添加到ArrayList中
                byte[] source = br.ReadBytes(8);
                m_array.Add(getMapCoordFromBytes(source));
            }
            br.Close();
            fs.Close();

            return;
         }
        /// <summary>
        /// WGS84(GPS)坐标转火星坐标
        /// </summary>
        /// <param name="lat">纬度</param>
        /// <param name="lng">经度</param>
        public static void WGS2Mars(double lat, double lng)
        {

            //将要查找的坐标放置在MapCoord对象中
            MapCoord search = new MapCoord();
            search.lat = (int)(lat * 100);
            search.lng = (int)(lng * 100);

            myReverserClass rc = new myReverserClass();
            //执行查找, 查询结果将返回array中的索引值
            int x = m_array.BinarySearch(0, m_array.Count, search, rc);
            //取得查找到的结果并进行计算
            MapCoord ret = (MapCoord)m_array[x];
            double pixY = latToPixel(lat, 18);
            double pixX = lngToPixel(lng, 18);

            pixY += ret.y_off;
            pixX += ret.x_off;
            lat = pixelToLat(pixY, 18);
            lng = pixelToLng(pixX, 18);
            //输出校正后的结果
            Console.WriteLine("欢迎来到火星,坐标: lat:{0},lng:{1} !!!", lat, lng);
        }

        static void Main(string[] args)
        {
            OpenDatFile();
            //测试一下
            WGS2Mars(34.782343, 113.769063);
            WGS2Mars(34.782343, 113.769063);
            WGS2Mars(34.782343, 113.769063);
            Console.ReadLine();
        }

    }

}

文章来源: zzzili.blog.csdn.net,作者:清雨小竹,版权归原作者所有,如需转载,请联系作者。

原文链接:zzzili.blog.csdn.net/article/details/13280445

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。