好久没写东西了,最近单位有个项目要用到地图。先说说需求:
(1) 雷达位于地图上的某个点,目标在雷达探测范围内发行时可以显示目标的运动轨迹
(2)整个系统在不连网的环境下运行。
刚开始接到这个需求,感觉蛮简单的,现在的地图应用这么成熟,应该两三于就搞定了。事实上,估计错了。
先来说说我那时的思路吧,大休上分两个阶段。
(一)MapX阶段: 既然要在内网运行,首先在线的地图如百度,Google,51map, 等 就排除了,我直接 去查的关于MapX的资料。
方法挺简单,就是在gst地图上添加一个临时图层,在临时图层上放置雷达图标,并画出目标轨迹,增加自绘图层,绘出比例尺。
缺点: 没有当时项目中要求的那个城市地图数据, 虽然可以自己做地图,但时间成本高,又不舍得花钱买。最后从网上下了一个全国地图,3G多,凑合能用,但定位不准,偏差有点多。
(二) Google Map阶段: 由于采用MAPX,效果实在不佳,打算重新看下Google 百度等在线地图。对比了几家如Google, 百度, 51map , mapbar等 ,最后决定用Google地图。至于原因,主要是由于个人情怀吧。
国内可以访问 Google 地图,但是不能访问 Google map api, 这真是天朝的一大特色,都赶得上朝鲜了,其实还有更奇葩的。只好买了个VPN帐户,才顺利访问GOOGLE MAP API。 Google 地图的开发包括三个方面,如图
如果在线开发的话,要先申请个Google 开发的一个Key, 本地调试时用的域名在申请时一定要填上,否则用其它域名无法访问。
要想在内网使用,必须把地图部署在本地上。先来看地图数据,Google 地图数据其实是 Google Tiles ,俗称瓷片。网上找的瓷片下载程序,要么收费,要么有水印,还不全。没办法,在研究 了瓷片的相关知识后自己写了一个瓷片下载程序。主要的一个代码如下。
const string urlpath = "http://mt2.google.cn/vt/[email protected]&hl=zh-CN&gl=cn&x={0}&y={1}&z={2}&s=Galil";
//根据经纬度坐标以及缩放等级获取像素坐标 private Pixel getPixelFromLatLngZoom(double lng, double lat, double zoom) { double pow = Math.Pow(2, zoom); Pixel pixel = new Pixel(); pixel.X = ((lng + 180) / 360) * pow; double sinLatitude = Math.Sin(lat * Math.PI / 180); double temp = Math.Log((1 + sinLatitude) / (1 - sinLatitude)); pixel.Y = Math.Abs((0.5 - temp / (4 * Math.PI)) * pow); return pixel; }
根据经纬度和要缩放的级别得出瓷片的地图坐标,先从google 地图上查找出需要的城市的左上角的经纬 度和右下角的经纬度,利用上述函数求出坐标,然后把在这个坐标范围里每一级的所有图片都下载下来,格式为png的,我当时共下载了16级,google map共22级,下载时,通过Fidder抓包,分析 这样,地图数据就有了。
然后可以找离线版的API, 找了好多个版本,最后终于在一个叫太乐地图的demo里发现了google map 离线版的API,版本号应该是3.8.6,这个版本的一个问题是在地图中添加Marker时没有默认的图标,需要手动在hmtl页面增加这个图标路径。这样离线API的问题也解决了
最后通过网页编程访问地图数据,这时就不需要KEY了,然后能过在MFC中使用webbrowser控件,来将网页嵌套进去。
有需要相关资料的可以与我联系: [email protected]