程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 基於GMap.Net的地圖解決方案

基於GMap.Net的地圖解決方案

編輯:C#入門知識

一 地圖的加載與顯示

關於GMap的介紹與使用可以看我以前的文章:

GMap.Net開發之在WinForm和WPF中使用GMap.Net地圖插件

GMap.Net是.Net下一個地圖控件,可以基於Http協議加載各個公司的地圖,如Google,Bing,ArcGIS的,主要原理是通過解析各個公司的地圖服務的URL,傳入相應的參數得到對應的切片底圖(Tiled map),如一個高德地圖的GMapProvider的實現如下:

using System; using GMap.NET; using GMap.NET.MapProviders; using GMap.NET.Projections; namespace GMapProvidersExt { public abstract class AMapProviderBase : GMapProvider { public AMapProviderBase() { MaxZoom = null; RefererUrl = "http://www.amap.com/"; //Copyright = string.Format("©{0} 高德 Corporation, ©{0} NAVTEQ, ©{0} Image courtesy of NASA", DateTime.Today.Year); } public override PureProjection Projection { get { return MercatorProjection.Instance; } } GMapProvider[] overlays; public override GMapProvider[] Overlays { get { if (overlays == null) { overlays = new GMapProvider[] { this }; } return overlays; } } } public class AMapProvider : AMapProviderBase { public static readonly AMapProvider Instance; readonly Guid id = new Guid("EF3DD303-3F74-4938-BF40-232D0595EE88"); public override Guid Id { get { return id; } } readonly string name = "AMap"; public override string Name { get { return name; } } static AMapProvider() { Instance = new AMapProvider(); } public override PureImage GetTileImage(GPoint pos, int zoom) { try { string url = MakeTileImageUrl(pos, zoom, LanguageStr); return GetTileImageUsingHttp(url); } catch (Exception ex) { return null; } } string MakeTileImageUrl(GPoint pos, int zoom, string language) { var num = (pos.X + pos.Y) % 4 + 1; //string url = string.Format(UrlFormat, num, pos.X, pos.Y, zoom); string url = string.Format(UrlFormat, pos.X, pos.Y, zoom); return url; } //static readonly string UrlFormat = "http://webrd04.is.autonavi.com/appmaptile?x={0}&y={1}&z={2}&lang=zh_cn&size=1&scale=1&style=7"; static readonly string UrlFormat = "http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={0}&y={1}&z={2}"; } } View Code

如下為高德地圖的顯示:

通過類似的辦法,可以實現加載Google、騰訊的地圖,百度的地圖也可以加載,但是因為百度采用自己的加偏算法(BD-09),導致加載的地圖顯示偏差大,當在不同的地圖間切換時,無法正確顯示。。

二 Marker的顯示與操作

GMapMarker為地圖上要顯示的數據元素,繼承GMapMarker可以實現自己想要的地圖元素效果,如下顯示自定義元素的樣式:

關於自定義Marker,可以看這篇文章:GMap.Net開發之自定義Marker,通過C# GDI+可以實現自己想要的各種圖標樣式和顯示效果。

三 圖形的顯示與操作

在地圖上手動畫各種多邊形,來實現類似“電子圍欄”的功能,可以使用GMapPolygon。

如下為我實現的圓形(Circle)、矩形(Rectangle)、多邊形(Polygon)和折線段(Polyline):

關於畫多邊形,可以看我以前的這篇文章:GMap.Net開發之在地圖上添加多邊形,手動畫多邊形時可以實時查看效果,畫完的多邊形隨地圖放大(縮小)而放大(縮小)。

實現類似百度地圖“測距”的功能:

通過點、線和提示框可以實現類似百度地圖的“測距”功能,點擊紅色的“X”,實現刪除這次測距。

四 地址解析與路徑查找

地址解析:GMap中的地址解析主要用到GeocodingProvider中的如下方法:

//根據關鍵字得到一組坐標
GeoCoderStatusCode GetPoints(string keywords, out List<PointLatLng> pointList); 

//根據關鍵字得到一個坐標
PointLatLng? GetPoint(string keywords, out GeoCoderStatusCode status);

//根據坐標得到一組地址
GeoCoderStatusCode GetPlacemarks(PointLatLng location, out List<Placemark> placemarkList);

//根據坐標得到一個地址
Placemark GetPlacemark(PointLatLng location, out GeoCoderStatusCode status);

路徑查找:GMap中的路徑查找主要用到RoutingProvider的如下方法:

//avoidHighways:是否避免走高速公路
//walkingMode:是否步行
//zoom:查找路徑時的zoom,貌似越大路徑越准確

//根據起止點start、end和當前的zoom查找路徑
MapRoute GetRoute(PointLatLng start, PointLatLng end, bool avoidHighways, bool walkingMode, int Zoom);

//根據出發點地址start、目的點地址end和當前的zoom查找路徑
MapRoute GetRoute(string start, string end, bool avoidHighways, bool walkingMode, int Zoom);

接口使用方式:

RoutingProvider rp = mapControl.MapProvider as RoutingProvider;
GeocodingProvider gp = mapControl.MapProvider as GeocodingProvider;

GeocodingProvider和RoutingProvider都是通過當前的MapProvider轉換得到的,也就是說如果要在加載的地圖上實現地址解析與路徑查找,就需要實現加載地圖的三大接口:

GMapProvider接口:用於顯示地圖。

RoutingProvider:用於路徑查找。

GeocodingProvider:用於地址解析。

關於地址解析與路徑查找的使用:GMap.Net開發之地址解析與路徑查找

五 地圖糾偏

中國國內的地圖都是經過“加偏”處理的,所以被稱為“火星坐標”。

現在主流的坐標系是WGS84坐標系,即地球坐標系,國際上通用的坐標系,經過國家測繪局要求采用GCJ02算法加偏後即為“火星坐標”,百度在“火星坐標”的基礎上又采用了自己的加偏算法BD09加偏後,得到“百度坐標”,國內的搜狗坐標系、圖吧坐標系等,估計也是在GCJ02基礎上加密而成的。

而現在Google中國、騰訊和高德采用的是WGS84經過GCJ02算法加偏後的“火星坐標”。

通過GPS設備采集到的坐標一般是沒有經過“加偏”處理的WGS84坐標,所以放到國內地圖上顯示會有誤差,可以把采集到的坐標也通過加偏算法加偏後再放到地圖上顯示,就可以得到對應的地點。

如下是經過加偏算法加偏後處理的情況:

如上使用Google中國地圖,現在采用的算法在地圖1-16級可以基本沒有誤差,誤差很小,當然和采集設備采集的點的准確度也有關系。

當地圖放大超過16級時候,就出現了誤差,但誤差也就在幾米:

六 中國行政區域邊界

有中國各個省市的邊界數據,就可以實現行政區域的顯示:

如下顯示江蘇省和南京市的行政邊界:

PS:現在手上有全國的各個省市縣的行政邊界,但是有幾個縣/區級的沒有。

七 地圖下載與緩存

GMap會自動在本地緩存一些訪問過的地圖,默認是不刪除的,所以當訪問的地圖區域越多時,本地的地圖緩存也就越大。

當然你也可以手動下載地圖到本地數據庫(支持SQLite、MySQL、MsSQL、PostgreSQL),如下所示:

緩存到本地的離線地圖數據就可以作為地圖數據包使用。

 

 參考:

https://greatmaps.codeplex.com/

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved