<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          自學(xué)HarmonyOS應(yīng)用開發(fā)(54)- 校正定位偏差

          上一篇文章已經(jīng)介紹了如果獲取當(dāng)前所在位置的方法,這種方法存在一個(gè)問題:和實(shí)際位置之前存在500米左右的偏差。


          原因調(diào)查

          經(jīng)過一番調(diào)查,結(jié)論是gps信號(hào)使用的是WGS-84坐標(biāo)系,而高德地圖使用的是GCJ-02火星坐標(biāo)系,只有經(jīng)過坐標(biāo)變換才能顯示正確的位置。這方面的文章網(wǎng)上有很多,這里采用以下博客文章中的代碼:

          https://www.cnblogs.com/blogger-Li/p/11616835.html

          代碼如下:

          // 本代碼引用自Hugo_nice下面的博客文章// https://www.cnblogs.com/blogger-Li/p/11616835.htmlpackage xwg.harmony.stopwatch;
          import java.math.BigDecimal;import java.math.RoundingMode;
          /** * gps糾偏算法,適用于google,高德體系的地圖 */public abstract class GpsUtil {
          private final static double a = 6378245.0; private final static double pi = 3.1415926535897932384626; private final static double ee = 0.00669342162296594323;
          /** * 計(jì)算地球上任意兩點(diǎn)(經(jīng)緯度)距離 * * @param lat1 * 第一點(diǎn)緯度 * @param lng1 * 第一點(diǎn)經(jīng)度 * @param lat2 * 第二點(diǎn)緯度 * @param lng2 * 第二點(diǎn)經(jīng)度 * @return 返回距離 單位:米 */ public static double distance(double lat1, double lng1, double lat2, double lng2) { double a, b, R; R = 6378137; // 地球半徑 lat1 = lat1 * Math.PI / 180.0; lat2 = lat2 * Math.PI / 180.0; a = lat1 - lat2; b = (lng1 - lng2) * Math.PI / 180.0; double d; double sa2, sb2; sa2 = Math.sin(a / 2.0); sb2 = Math.sin(b / 2.0); d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2)); return d; }
          /** * Description: WGS-84 to GCJ-02 <BR> * * @author dsn * @date 2017年10月24日 下午2:09:27 * @param latitude * 緯度 * @param longitude * 經(jīng)度 * @return [緯度,經(jīng)度] * @version 1.0 */ public static double[] toGCJ02Point(double latitude, double longitude) { double[] dev = calDev(latitude, longitude); double retLat = latitude + dev[0]; double retLon = longitude + dev[1]; return new double[] { retLat, retLon }; }
          /** * Description: WGS-84 to GCJ-02 <BR> * * @author dsn * @date 2017年10月24日 下午2:09:27 * @param latitude * 緯度 * @param longitude * 經(jīng)度 * @param scale * 經(jīng)緯度保留小數(shù)位數(shù) * @return [緯度,經(jīng)度] * @version 1.0 */ public static double[] toGCJ02Point(double latitude, double longitude, int scale) { double[] dev = calDev(latitude, longitude); double retLat = latitude + dev[0]; double retLon = longitude + dev[1]; return new double[] { new BigDecimal(retLat).setScale(scale, RoundingMode.DOWN).doubleValue(), new BigDecimal(retLon).setScale(scale, RoundingMode.DOWN).doubleValue() }; }
          /** * Description:GCJ-02 to WGS-84 <BR> * * @author dsn * @date 2017年10月24日 下午2:09:54 * @param latitude * 緯度 * @param longitude * 經(jīng)度 * @return [緯度,經(jīng)度] * @version 1.0 */ public static double[] toWGS84Point(double latitude, double longitude) { double[] dev = calDev(latitude, longitude); double retLat = latitude - dev[0]; double retLon = longitude - dev[1]; dev = calDev(retLat, retLon); retLat = latitude - dev[0]; retLon = longitude - dev[1]; return new double[] { retLat, retLon }; }
          private static double[] calDev(double wgLat, double wgLon) { if (isOutOfChina(wgLat, wgLon)) { return new double[] { 0, 0 }; } double dLat = calLat(wgLon - 105.0, wgLat - 35.0); double dLon = calLon(wgLon - 105.0, wgLat - 35.0); double radLat = wgLat / 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); return new double[] { dLat, dLon }; }
          private static boolean isOutOfChina(double lat, double lon) { if (lon < 72.004 || lon > 137.8347) return true; if (lat < 0.8293 || lat > 55.8271) return true; return false; }
          private static double calLat(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 calLon(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; }}


          偏移調(diào)整

          public void setLocation(double long_deg, double lat_deg){    double ret[] = GpsUtil.toGCJ02Point(lat_deg, long_deg);    latitude = ret[0];    longitude = ret[1];    invalidate();}

          在設(shè)定經(jīng)緯度之前,調(diào)用轉(zhuǎn)換方法即可。經(jīng)過轉(zhuǎn)換之后的位置和實(shí)際位置之間的偏差可以在幾十米范圍之內(nèi)。


          參考代碼

          完整代碼可以從以下鏈接下載:

          https://github.com/xueweiguo/Harmony/tree/master/StopWatch


          參考資料

          GCJ-02火星坐標(biāo)系和WGS-84坐標(biāo)系轉(zhuǎn)換關(guān)系:

          https://www.cnblogs.com/blogger-Li/p/11616835.html

          獲取設(shè)備的位置信息:

          https://developer.harmonyos.com/cn/docs/documentation/doc-guides/device-location-info-0000000000031900


          作者著作介紹

          《實(shí)戰(zhàn)Python設(shè)計(jì)模式》是作者去年3月份出版的技術(shù)書籍,該書利用Python 的標(biāo)準(zhǔn)GUI 工具包tkinter,通過可執(zhí)行的示例對(duì)23 個(gè)設(shè)計(jì)模式逐個(gè)進(jìn)行說明。這樣一方面可以使讀者了解真實(shí)的軟件開發(fā)工作中每個(gè)設(shè)計(jì)模式的運(yùn)用場景和想要解決的問題;另一方面通過對(duì)這些問題的解決過程進(jìn)行說明,讓讀者明白在編寫代碼時(shí)如何判斷使用設(shè)計(jì)模式的利弊,并合理運(yùn)用設(shè)計(jì)模式。

          對(duì)設(shè)計(jì)模式感興趣而且希望隨學(xué)隨用的讀者通過本書可以快速跨越從理解到運(yùn)用的門檻;希望學(xué)習(xí)Python GUI 編程的讀者可以將本書中的示例作為設(shè)計(jì)和開發(fā)的參考;使用Python 語言進(jìn)行圖像分析、數(shù)據(jù)處理工作的讀者可以直接以本書中的示例為基礎(chǔ),迅速構(gòu)建自己的系統(tǒng)架構(gòu)。




          覺得本文有幫助?請(qǐng)分享給更多人。

          關(guān)注微信公眾號(hào)【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!

          面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>



          瀏覽 52
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成片网站| 美女裸体网站久久久 | 特级茜茜人体444WWW | 久久久久亚洲AV色欲av | www.168亚洲毛片基地 |