GPS部標平臺的架構設計(五)-地圖服務算法庫

GPS平臺,須要和各類地圖打交道,須要解決如下的問題:

1.座標偏移,這個不用多說,須要將原始座標加偏,而後在百度地圖或谷歌上顯示出來,須要注意的是百度地圖的加偏是偏上再偏,谷歌、高德地圖等是火星座標;程序員

2.座標解偏,或者糾偏,這個咱們也是須要的,由於當用戶在地圖上畫出的各類區域,標註,發送到後臺存儲的座標都是基於地圖所採用的座標系統,於是是偏移的,這就面臨一個嚴重的問題,由於在部標808協議中,對於區域報警,須要將區域的頂點座標,下發給終端,終端在實際運行中,不斷用GPS座標和區域座標進行比對,來判斷是不是進入區域報警,仍是離開區域報警。若是區域座標是偏移的,那麼判斷出來必然是錯誤的。因此下發前,必需要將偏移的座標逆向再還原成原始的基於wgs84座標系的座標出來。算法

3.區域報警,GPS部標平臺也要求平臺支持區域報警,也就是說,若是終端沒有這個功能,平臺也是能夠本身來分析GPS位置,來進行區域報警。那麼部標平臺就要提供圓形、多邊形、矩形區域的判斷算法。數據庫

4.路線偏移,部標規定部標平臺在過檢測的時候,必需要測試路線偏移報警,因此部標平臺也要提供路線偏移的判斷算法。網絡

5.地理位置,用戶須要知道車輛的地理位置的文字信息,須要知道報警時的具體地點,不少平臺在報表中僅僅顯示了個經緯度座標,這個是很讓人惱火的。因此在後臺須要提供獲取地理位置的接口,在報警的時候,記錄下地理位置。保存到數據庫中,再造成報表顯示。性能

6.一般的GPS平臺,都會提供至少兩個地圖給用戶使用,如百度、四維、谷歌、高德等,咱們的算法必需要使用與全部這些地圖。測試

因此咱們在設計的過程當中,堅定屏棄掉掉遠程調用百度地圖SDK http接口之類的方法,由於沒法容忍Http調用的次數限制、性能損失和網絡問題帶來的Timeout等不可預料的未知錯誤,因此堅定設計一個底層的算法服務庫,提供給其餘開發人員使用,由於是純算法,上本地能夠無限次調用,也不用擔憂性能問題,在開發方法上因爲是直接調用轉換,對於程序員開發效率也是大大提高。google

解決了最難解決的百度座標加偏和反向糾偏的問題,純算法代碼,不調用百度地圖的SDK API,並且提供了百度所沒有的反向糾偏的算法,能夠將手機百度地圖的座標直接反向解析成原始GPS座標(wgs84座標系)。spa

百度地圖、谷歌地圖、高德地圖、四維地圖、GPS終端設備座標直接能夠靈活互轉,不再用受限於遠程調用http接口的性能損失和網絡中斷的麻煩。設計

 

如今提供了一個在線的動態庫(如需購買,離線DLL300元,源碼600元)blog

調用方法以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MapServiceClient;
using MapServiceClient.MapFix;
using GpsNET.CoordService;
using GpsNET;

namespace MapServiceDemo
{
    /**
     *@author www.ltmonitor.com
     *@email speed.zheng@gmail.com
     */
    class Program
    {
        static void Main(string[] args)
        {
            MapServiceClient.MapFix.IMapService service = MapServiceFactory.getMapService();

            double lng1 = 121.111;
            double lat1 = 32.121;
            //獲取地理位置
            String location = service.GetLocation(lng1, lat1);
            Console.WriteLine(location);

            //測試點是否在圓形區域中
            double centerLng = 120;
            double centerLat = 32;//圓心座標
            double radiusByMeter = 100;//圓形半徑,米爲單位
            Boolean isInCircle = service.IsInCircle(lng1, lat1, centerLng, centerLat, radiusByMeter);

            //測試點是否在多邊形中
            MyPointLatLng p = new MyPointLatLng(lat1, lng1);
            MyPointLatLng p1 = new MyPointLatLng(33.12,121.10);
            MyPointLatLng p2 = new MyPointLatLng(33.12, 121.10);
            MyPointLatLng p3 = new MyPointLatLng(33.12, 121.10);
            MyPointLatLng p4 = new MyPointLatLng(33.12, 121.10);
            MyPointLatLng[] points = new MyPointLatLng[]{p1,p2,p3};//多邊形的頂點
            Boolean isInPolygon = service.IsInPolygon(p, points);

            //測試點是否在矩形中,矩形的左上角和右下角的座標必需要輸入正確,不能搞混
            //Boolean isInRect = service.IsInRect(lng1,lat1,lngLeft, latTop,lngRight,latBottom);

            int offset = 12;//路線偏移的最大距離
            Boolean isOnline = service.IsPointOnLine(p, p1, p2, offset);

            //測試座標加偏和解偏
            for (int m = 0; m < 50; m++)
            {
                double lng = 121.122 + m * 0.01;
                double lat = 33.222 + m * 0.01;


                //百度座標加偏
                MyPointLatLng pt1 = service.Fix(lng, lat, "baidu");

                /**
                 *反向還原成原始的GPS座標
                 */
                MyPointLatLng pt2 = service.Reverse(pt1.Lng, pt1.Lat, "baidu");

                /**
                 * 得到兩點之間的偏差距離,單位米
                 */
                double d = service.GetDistanceByMeter(lng, lat, pt2.Lng, pt2.Lat);

                Console.WriteLine("百度座標還原後,兩點之間的偏差精度:" + d + "米");

                //火星座標系(如谷歌,高德)座標加偏
                pt1 = service.Fix(lng, lat, "google");
                /**
                 *反向還原成原始的GPS座標
                 */
                pt2 = service.Reverse(pt1.Lng, pt1.Lat, "google");

                /**
                 * 得到兩點之間的偏差距離,單位米
                 */
                d = service.GetDistanceByMeter(lng, lat, pt2.Lng, pt2.Lat);

                Console.WriteLine("谷歌座標還原後,兩點之間的偏差精度:" + d + "米");

            }


            Console.ReadLine();
        }
    }
}

  原始座標,和通過加偏再解偏後的座標比較,偏差精度在1米左右,很是精確。運行結果以下:

相關文章
相關標籤/搜索