IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> GPS定位解决偏差 -> 正文阅读

[游戏开发]GPS定位解决偏差

目录

GPS定位解决偏差

开篇

实践

1、解决思路以及步骤

2、实践出真理!

3、上坐标系之间的代码。

希望大家:点赞,留言,关注咯~??? ? ?😘😘😘😘

唠家常

今日推荐都在文章中了


GPS定位解决偏差

开篇

????????大家都知道啊,小黑是靠Unity吃饭的,所以觉得Unity就是万能的,小黑需要什么他就会提供什么,事实证明,Unity确实是很强大,但是他还没有强大到可以知道小黑心里想什么。所以就遇到问了呗。

? ? ? ? 事情是这样的,小黑从前段时间开始,加入了一个项目组,开始是帮着解决一些原生交互啊,或者是另外一些简单的东西吧。但随着时间的推进,小黑稀里糊涂的就成了该项目组成员,彻底进入开发了状态了!!!!开发就开发吧,有一个GPS定位功能之前是另一个项目组同事负责,他告诉我们说是UnityGPS有问题,和实际位置有6公里的偏差,这这这小黑能忍?好歹一年前也是做过GPS相关功能的,于是小黑拿着1年前的知识和他开始了Battle!!!并且叫嚣着:(下方),现在想来,真的想打死我自己。太丢人了😂😂😂😂

? ? ? ? 出自小黑的嘴:我之前做过Demo,GPS是绝对不可能有这么大偏差的,最多800米的偏差,并且还是看什么地图的坐标拾取器!!高德、腾讯、谷歌很厉害,偏差在400米左右,百度最垃圾,偏差在800米左右!!

实践

1、解决思路以及步骤

????????那废话也说了好多了, 就开始学习如何解决吧。

  1. 首先:我们要知道什么是GPS
    GPS从入门到放弃(一) --- GPS基础原理
    GPS从入门到放弃(二) --- GPS时间
    GPS从入门到放弃(三) --- GPS坐标系? ?主要看这个★★★★★
    ?
  2. 第二:知道坐标系后,我们要弄明白为什么会有偏差。
    关于GPS坐标系和地图定位偏差
    借用文章中的话:
    1):获取GPS位置后,为什么在地图上定位不准?
    答? :中国地图采用的坐标系和GPS坐标不是同一个坐标系,所以采用GPS坐标在地图上定位不准。

    2):国外GPS位置和国内GPS位置有差别吗?
    答? :GPS是美国的导航系统,全球通用,手机内置的芯片都是GPS芯片,没有差别。不同的地方是地图有着不同的GPS坐标系。
    ?
  3. 最后:我们明白偏差原因后,就需要解决,那代码在哪呢,正下方咯。
    地图坐标系相互转换(WGS-84、GCJ-02、BD-09)

2、实践出真理!

????????正如第三步骤的文章中所说:我们开发人员一般会用到三种坐标系。

  1. WGS-84原始坐标系
    ????????一般用国际GPS纪录仪记录下来的经纬度,通过GPS定位拿到的原始经纬度,Google和高德地图定位的的经纬度(国外)都是基于WGS-84坐标系的。但是在国内是不允许直接用WGS84坐标系标注的,必须经过加密后才能使用。
  2. GCJ-02坐标系,又名"火星坐标系"
    ? ? ? ? 是我国(中国)国测局独创的坐标体系,由WGS-84加密而成,在国内,必须至少使用GCJ-02坐标系,或者使用在GCJ-02加密后再进行加密的坐标系,如百度坐标系。高德和Google在国内都是使用GCJ-02坐标系,可以说,GCJ-02是国内最广泛使用的坐标系。

  3. BD-09,又名"百度坐标系"
    ? ? ? ?百度坐标系是在GCJ-02坐标系的基础上再次加密偏移后形成的坐标系,只适用于百度地图。(目前百度API提供了从其它坐标系转换为百度坐标系的API,但却没有从百度坐标系转为其他坐标系的API)。

小黑在不同地图的坐标拾取器上边反复测试后,得到以下结果:

? ? ? ? 1、Unity通过API (Input.location) 获取到的正是WGS-84原始坐标系

????????2、高德、腾讯、谷歌(中国) 用的都是GCJ - 02坐标系

????????3、百度自然用的是自家坐标系咯(百度坐标系)。

3、上坐标系之间的代码。

using System;

public class GPSUtil
{
    /// <summary>
    /// Π
    /// 圆周率
    /// </summary>
    private const double PI = 3.14159265358979324;
    private const double X_PI = 3.14159265358979324 * 3000.0 / 180.0;
    private const double A = 6378245.0;
    private const double EE = 0.00669342162296594323;
    private const double LON_BOUNDARY_MIN = 72.004;
    private const double LAT_BOUNDARY_MIN = 0.8293;
    private const double LON_BOUNDARY_MAX = 137.8347;
    private const double LAT_BOUNDARY_MAX = 55.8271;

    /// <summary>
    /// 是否中国境内坐标
    /// </summary>
    /// <param name="gpsLat"></param>
    /// <param name="gpsLng"></param>
    /// <returns></returns>
    private static bool OutOfChina(double gpsLat, double gpsLng)
    {
        if (gpsLng < LON_BOUNDARY_MIN || gpsLng > LON_BOUNDARY_MAX)
        {
            return true;
        }

        if (gpsLat < LAT_BOUNDARY_MIN || gpsLat > LAT_BOUNDARY_MAX)
        {
            return true;
        }

        return false;
    }

    #region WGS坐标系与GCJ02坐标系互转

    /// <summary>
    /// WGS84坐标系转GCJ02坐标系
    /// </summary>
    /// <param name="wgsLat">WGS坐标,纬度</param>
    /// <param name="wgsLng">WGS坐标,经度</param>
    /// <param name="gcjLat">GCJ02坐标,纬度</param>
    /// <param name="gcjLng">GCJ02坐标,经度</param>
    public static void WGS84_to_GCJ02(double wgsLat, double wgsLng, out double gcjLat, out double gcjLng)
    {
        if (OutOfChina(wgsLat, wgsLng))
        {
            gcjLat = wgsLat;
            gcjLng = wgsLng;
        }
        else
        {
            double dLat = TransformLat(wgsLng - 105.0, wgsLat - 35.0);
            double dLon = TransformLon(wgsLng - 105.0, wgsLat - 35.0);
            double radLat = wgsLat / 180.0 * PI;
            double magic = Math.Sin(radLat);
            magic = 1 - EE * magic * magic;
            double sqrtMagic = Math.Sqrt(magic);
            dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * PI);
            dLon = (dLon * 180.0) / (A / sqrtMagic * Math.Cos(radLat) * PI);
            gcjLat = wgsLat + dLat;
            gcjLng = wgsLng + dLon;
        }
    }

    public static void GCJ02_to_WGS84(double gcjLat, double gcjLng, out double wgsLat, out double wgsLng)
    {
        WGS84_to_GCJ02(gcjLat, gcjLng, out wgsLat, out wgsLng);

        wgsLng = gcjLng * 2 - wgsLng;
        wgsLat = gcjLat * 2 - wgsLat;
    }

    private static double TransformLat(double x, double y)
    {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.Sqrt(Math.Abs(x));
        ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.Sin(y * PI) + 40.0 * Math.Sin(y / 3.0 * PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.Sin(y / 12.0 * PI) + 320 * Math.Sin(y * PI / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    private static double TransformLon(double x, double y)
    {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.Sqrt(Math.Abs(x));
        ret += (20.0 * Math.Sin(6.0 * x * PI) + 20.0 * Math.Sin(2.0 * x * PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.Sin(x * PI) + 40.0 * Math.Sin(x / 3.0 * PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.Sin(x / 12.0 * PI) + 300.0 * Math.Sin(x / 30.0 * PI)) * 2.0 / 3.0;
        return ret;
    }

    #endregion

    #region 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的互转

    public static void GCJ02_to_Bd09(double gcjLat, double gcjLng, out double bdLat, out double bdLng)
    {
        double z = Math.Sqrt(gcjLng * gcjLng + gcjLat * gcjLat) + 0.00002 * Math.Sin(gcjLat * PI);
        double theta = Math.Atan2(gcjLat, gcjLng) + 0.000003 * Math.Cos(gcjLng * PI);
        bdLng = z * Math.Cos(theta) + 0.0065;
        bdLat = z * Math.Sin(theta) + 0.006;
    }


    public static void BD09_to_GCJ02(double bdLat, double bdLng, out double gcjLat, out double gcjLng)
    {
        double x = bdLng - 0.0065, y = bdLat - 0.006;
        double z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * PI);
        double theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * PI);
        gcjLng = z * Math.Cos(theta);
        gcjLat = z * Math.Sin(theta);
    }

    #endregion
}

至此,圆满结束。

????????好了,知识讲了,参考链接也上了,代码更是放出来了,这次相信大家和小黑一样,会GPS的使用了吧!

希望大家:点赞,留言,关注咯~??? ? ?😘😘😘😘


唠家常

  • 小黑的今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加小黑的QQ:841298494,大家一起进步。

今日推荐都在文章中了

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:48:06  更:2021-10-12 23:48:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 2:39:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码