来自 编程 2019-11-15 01:49 的文章
当前位置: 网上澳门金莎娱乐 > 编程 > 正文

用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图网上澳门金莎娱乐

先上结果:

该文章属于<简书 — 刘小壮>原创,转载请注明:

<简书 — 刘小壮> http://www.jianshu.com/p/41179be5893a

本人现就职于国内某地图导航公司,这篇文章是我前段时间在公司组织技术分享的一个PPT,文章内容也主要由这个PPT的内容为主,通过这篇文章可以很好的帮你了解地图导航这个行业的相关技术。

PPT内容主要包括地图相关专业知识、百度和高德SDK整体框架、数据来源、行业概览等组成。其中关于地图引擎相关的技术知识,我向公司地图引擎开发同事求证过,这个PPT也给他们看过,也帮忙指出了其中的一些问题。

这篇文章主要用于分享,其中如果有什么问题,还请多多指出,谢谢!

网上澳门金莎娱乐 1博客配图

网上澳门金莎娱乐 2

经纬度

网上澳门金莎娱乐 3经纬度

经纬度是一种地理坐标系统,主要用来表示地球的球面坐标系,经纬度可以定位地球的任何一个位置。南北方向的称为纬度,东西方向称为经度

纬度:赤道纬度周长最长,离赤道越远纬度周长越短,也就更加靠近南北极。赤道以南称为南纬,赤道以北称为北纬纬度取值范围是0-90,赤道纬度最小为0,两级最大。

经度:经度也叫子午线,任意两条经线长度相等,起始点都在南北极。经度以本初子午线为区分,以东称为东经,以西称为西经东经为正数,西经为负数。经度取值范围在0-180,本初子午线为0。东经180度也就是西经180度就是白令海峡,白令海峡就是国际换日线,日期相差一天。

按照经度,地球被分为24个时区,每个时区又有分,分又包含秒。

网上澳门金莎娱乐 4

投影

网上澳门金莎娱乐 5投影网上澳门金莎娱乐 6投影

做地图,投影的概念很重要。我们的地球是圆形的,地球的坐标是一个球面坐标,球面坐标是三维坐标,而我们的地图是是二维的,需要将球面的三维坐标转换为平面的二维坐标。

坐标转换久用到了投影的概念,常用的投影有:圆柱投影圆锥投影方位投影,而在我们地图导航中使用墨卡托投影

 

墨卡托投影

网上澳门金莎娱乐 7墨卡托投影

百度、高德、Google都使用墨卡托投影墨卡托投影有一个很大的弊端,就是在高纬度(南纬北纬)地区产生巨大的变形。变形比较严重的地方在于俄罗斯、格林兰岛、非洲、南极洲等高纬度地区。

网上澳门金莎娱乐 8墨卡托投影

上面五个国家分别是:俄罗斯、澳大利亚、中国、巴西、加拿大我们将这五个国家放在一个纬度,来比较这五个国家,发现相差并不太大。但是如果放在上面那张图中,俄罗斯顶好几个中国大小。

国外开发者开发了一个网站,这个网站可以将不同国家拉到同一个纬度,这时候就能显示出真正比例的国家面积。网站地址:http://thetruesize.com/

 

古德投影

网上澳门金莎娱乐 9古德投影

古德投影可以避免地图变形的问题,这种投影将地图分为几个部分,然后沿赤道将几个部分连接在一起。我们发现上面的格林兰岛已经被分为两部分,这种投影并不适合用于开发,而且看起来效果也不太好看。

 

金字塔模型

网上澳门金莎娱乐 10金字塔模型

把一张世界地图显示到手机里是不可能的,所以就引入了金字塔模型的概念(也就是比例尺),我们可以根据不同的缩放比例,显示不同的分辨率。

在地图应用中,我们用手指缩放和放大地图,地图显示大小的变换,都是基于金字塔模型来组织瓦片图的。

  之前 在公司业务中用过java+Selenium+ChromeDriver ,使用起来非常顺手,可以完美模拟真实的用户浏览行为。最近休息的时候想用C#也试一下,于是有了本文。

瓦片坐标系

网上澳门金莎娱乐 11瓦片坐标系

金字塔模型配合使用的就是瓦片坐标系,在不同的缩放等级下,同一块区域瓦片个数也是不一样的。

瓦片越多就代表这一区域显示越详细,缩放比例也就越大。瓦片坐标系在2D和3D的场景下都会被使用,我们在网络不好的情况下可以看到地图瓦片的加载过程以及瓦片的大小、位置。

  实现原理一样,只是由java换成了C#。(ps:个人感觉就业务开发代码来说,熟悉之后两种语言可以无缝切换。)

坐标加密
  • CLLocationManager中的经纬度加密(WGS-84)
  • MKMapView中的经纬度加密(GCJ-02)
  • 高德SDK中的经纬度加密(GCJ-02)
  • 百度SDK中的经纬度加密(使用GCJ-02再次加密,叫做BD-09)

根据中国法律规定,地图提供商必须对地图经纬度进行偏移,国测局制定了一套加密标准,就是常用的GCJ-02经纬度坐标加密主要有两种格式,GPS坐标系 (WGS-84) 和火星坐标系 (GCJ-02) ,加密算法是开源的,可以搜索到。

国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密。由于每家导航SDK提供方加密都不统一,所以百度、高德、谷歌多家地图数据并不统一,需要再次进行转换。

  事先声明,代码中会采集用户登录咕咚网站之后的个人数据接口,如果此行为损害了咕咚网站的利益,请联系我删除或修改本文(我对采集行为一直本着每一次调用之后sleep的原则,毕竟不是为了把人家的网站搞死)。文中使用的数据是我自己的跑步数据,不涉及到其他用户的数据。

地图定位

网上澳门金莎娱乐 12地图定位

移动端定位方式主要有三种:GPSWi-Fi基站,但是androidiOS还不太一样,android可以让用户选择和设置那种定位方式,但是iOS是由系统为我们选择的,我们没有操作定位方式的权限。iOS不允许有第三方定位,所以现在地图应用都是对系统定位进行的封装。如果有GPS信号,iOS系统会优先选择GPS方式定位,然后是Wi-Fi定位,如果Wi-Fi信号不好就会选择基站定位。

在定位中精确度最高的是GoogleGoogle利用大数据分析,记录每一次利用Google地图的定位。下次再次定位时,直接根据Mac地址等信息进行分析,提高定位精确度。

比较悲催的一个问题就是,有一些比较老的iOS机器,没有GPS定位模块,例如一些老版本iPad,这种设备在没有Wi-Fi的情况下是无法定位的。

  项目结构:为了方便跑友使用,用的winform程序,附nuget包

地理编码和逆地理编码

网上澳门金莎娱乐 13示例图片

地理编码:即地理解析,由详细的结构化地址得到对应的经纬度信息,例如北京市海淀区中关村南大街27号的地址,就可以获取到一个唯一的经纬度信息。

逆地理编码:即逆地理解析,由一个经纬度信息获取一个结构化地址信息,例如lng:116.31985,lat:39.959836经纬度,就可以获取到类似于上面的地理信息。

iOS系统API、高德SDK、百度SDK中,都为我们提供了地理编码逆地理编码API,但是需要注意经纬度的转换,不同地图SDK返回的经纬度加密方式不同,我们在传入经纬度参数和接收经纬度参数时,都需要做转换。

网上澳门金莎娱乐 14

地图数据来源

网上澳门金莎娱乐 15高德网上澳门金莎娱乐 16四维图新

国内比较活跃的数据采集商主要是高德和四维图新两家,百度没有数据采集资质,所以数据主要依赖于四维图新。

四维图新和国家测绘局合作比较密切,数据来源主要是国家测绘局提供,也有部分自己测绘的数据。高德测绘和航拍能力还不错,主要自己测绘数据,部分数据也依赖国测局提供。数据测绘单位互相之间都有合作,会相互购买自己没有的数据。

在中国,谷歌地图或苹果地图等地图开发商,数据来源几乎都是这两家公司。

 

POI数据

网上澳门金莎娱乐 17POI

POI数据是一种矢量数据,包括美食、商店、银行、加油站等都是POI数据,在地图上一般都以气泡或大头针表示。

数据采集可以通过车载GPS摄像机采集,或从服务性互联网企业抓取或购买,由于百度和高德提供了对外的SDK,通过用户使用地图SDK也可以获取一些数据。

百度的地图数据主要依赖于四维图新和道道通,高德地图主要以自采为主。一般这些数据也会和大众点评、携程、口碑等互联网服务商购买,相互之间也会购买POI数据。

 

栅格-2D地图

网上澳门金莎娱乐 18珊格图网上澳门金莎娱乐 19珊格图

2D场景:轻地图应用,简单的位置分享、兴趣点标注、线路展示等。2D模型展示效果不太好,在缩放比例较小的情况下,看起来比较模糊(缩放比例大一些看起来清晰度还可以)。

栅格模型对于某一个地方的描述,是通过很多层图片叠加组成的,每层代表不同信息。栅格模型一般都会先渲染一个底图,然后是在底图的基础上叠加路况、POI等图层。

珊格图都是在服务器预处理的图片,从服务器下载处理好的图片到本地进行拼接即可,由于下载到本地是图片,本地不能再对图层进行更改。对于性能上来说,服务器进行图片合成性能消耗较大,但是客户端性能消耗比较小,内存占用也比较小,用起来会比较流畅。

 以下是form1.cs的代码,删除了部分提示的 MessageBox.Show(),从产品角度来讲,应该添加loading提示和进度条,这里就只放代码了。需要安装最新的chrome浏览器+代码中使用的chromedriver是 v2.9.248315

矢量-3D地图

网上澳门金莎娱乐 20矢量地图网上澳门金莎娱乐 21矢量地图

3D场景:重地图应用,以LBS为核心功能,需要离线地图、更好的渲染效果、app内导航的。比如打车应用、出行导航类应用,3D模型渲染后的效果比较好,一般使用导航功能都必须用这个3D模型

矢量数据是从服务器将地图数据下载下来,然后在客户端进行合成绘制的,所以我们可以对地图的显示进行控制,可定制性更强。矢量图看起来更佳清晰,渲染效果比较好。但是矢量图对手机性能消耗很厉害,手机内存占用比较高,CPUGPU消耗都很大。对于服务器性能消耗就比2D场景性能小一些,因为服务器只是加载原始数据和向客户端进行传输,将合成绘制等这些图层渲染的绘制处理交给客户端来做。提高了客户端灵活性和更好的效果,牺牲了客户端的性能,有利有弊。

  1 using Newtonsoft.Json;
  2 using OpenQA.Selenium;
  3 using OpenQA.Selenium.Chrome;
  4 using System;
  5 using System.Collections.Generic;
  6 using System.ComponentModel;
  7 using System.Data;
  8 using System.Drawing;
  9 using System.IO;
 10 using System.Linq;
 11 using System.Net;
 12 using System.Text;
 13 using System.Threading;
 14 using System.Threading.Tasks;
 15 using System.Windows.Forms;
 16 
 17 namespace GuDongLine
 18 {
 19 public partial class Form1 : Form
 20 {
 21 public Form1()
 22 {
 23 
 24 InitializeComponent();
 25 label2.Text = "请根据提示进行操作,本产品需要最新版本Chrome浏览器支持,网络良好的情况下运行,内部交流,不作为商业软件,如有侵权请扫中间微信二维码联系我。祝各位跑友生活愉快,身体健康,happy PB";
 26 }
 27 delegate void ChangeInvoke(int num);
 28 public int Fun1;
 29 private void button1_Click(object sender, EventArgs e)
 30 {
 31 try
 32 {
 33 Thread thread = new Thread(go);
 34 thread.Start();
 35 
 36 }
 37 catch (Exception)
 38 {
 39 MessageBox.Show("操作异常,请重新打开,或联系我");
 40 }
 41 
 42 }
 43 private void ChangeNum()
 44 {
 45 MessageBox.Show("正在运行请等待!运行完毕后会有提示!");
 46 }
 47 public void go()
 48 {
 49 if (MessageBox.Show("下面请登录咕咚,本软件只会向咕咚官网发送和接受数据,如果发现软件向其他网址发送数据,说明本软件被修改,可能有病毒", "登录咕咚账号", MessageBoxButtons.OKCancel).Equals(DialogResult.OK))
 50 {
 51 ChromeOptions options = new ChromeOptions();
 52 options.AddArguments("--test-type", "--ignore-certificate-errors");
 53 IWebDriver driver = new ChromeDriver(System.Environment.CurrentDirectory, options);
 54 driver.Url = "http://www.codoon.com/home";
 55 Thread.Sleep(10000);
 56 
 57 driver.Navigate().GoToUrl("http://www.codoon.com/gps_sports/my_routes");
 58 
 59 
 60 Thread.Sleep(5000);
 61 int runCount = int.Parse(driver.FindElement(By.Id("current_index")).Text) / 3;
 62 for (int i = 0; i < runCount + 5000; i++)
 63 {
 64 try
 65 {
 66 driver.FindElement(By.ClassName("more_data")).Click();
 67 Thread.Sleep(800);
 68 }
 69 catch (Exception)
 70 {
 71 if (i > runCount + 100)
 72 {
 73 break;
 74 }
 75 
 76 }
 77 }
 78 Thread thread2 = new Thread(ChangeNum);
 79 thread2.Start();
 80 string userId = driver.FindElement(By.ClassName("home_user_header")).GetAttribute("src").Substring(33, 36);
 81 string data = "";
 82 dynamic va = driver.FindElements(By.ClassName("detail_sports_content"));
 83 foreach (IWebElement iwe in va)
 84 {
 85 using (var client = new WebClient())
 86 {
 87 Thread.Sleep(200);
 88 var responseString = client.DownloadString("http://www.codoon.com/gps_sports/route?user_id=" + userId + "&route_id=" + iwe.FindElement(By.TagName("table")).GetAttribute("id") + "&need_next=1&_=1520349266435");
 89 
 90 
 91 var DynamicObject = JsonConvert.DeserializeObject<dynamic>(responseString);
 92 string ss = "";
 93 foreach (var s in DynamicObject.line)
 94 {
 95 ss += ((double)s[1] + 0.0062).ToString() + "," + ((double)s[0] + 0.00135).ToString() + ";";
 96 }
 97 ss = ss.Remove(ss.Length - 1);
 98 data += ss + "&";
 99 }
100 }
101 data = data.Remove(data.Length - 1);
102 driver.Close();
103 string html = @"<!DOCTYPE html><html lang='zh - CN'>
104 <head>
105 
106 <meta charset = 'utf-8'>
107 
108 <meta http - equiv = 'X-UA-Compatible' content = 'IE=edge'>
109 
110 <meta name = 'viewport' content = 'width=device-width, initial-scale=1'>
111 
112 <title> my_all_run_lines </title>
113 
114 <link rel = 'stylesheet' href = 'http://cache.amap.com/lbs/static/main1119.css' />
115 </head>
116 <body>
117 <div id = 'container' class='container'></div>
118 <script src = 'http://webapi.amap.com/loca?key=6ac3f558819c2c4711ea0c0a37192137'></script>
119 <script src='http://a.amap.com/Loca/static/dist/jquery.min.js'></script>
120 <script>
121 
122 var map = Loca.create('container', {
123 key: '1e387d3db027b46a23600cf7f2ed7344',
124 mapStyle: 'amap://styles/grey',
125 features: ['bg', 'road'],
126 zoom: 10
127 });
128 
129 var layer = Loca.visualLayer({
130 container: map,
131 type: 'line',
132 shape: 'line',
133 });
134 
135 $.get('http://a.amap.com/Loca/static/mock/buslines.txt', function (data) {
136 data = '" + data + "';" + "" +
137 "" +
138 "" +
139 "" +
140 "" +
141 "" + @"var lines = data.split('&').map(function (item) {
142 return {
143 linePath: item.split(';').map(function(lnglat) {
144 return lnglat.split(',');
145 })
146 };
147 });
148 
149 layer.setData(lines, {
150 lnglat: 'linePath'
151 });
152 layer.setOptions({
153 style: {
154 opacity: 0.2,
155 lineWidth: 2,
156 stroke: '#b7eff7',
157 }
158 });
159 
160 layer.render();
161 })
162 
163 </script>
164 </body>
165 </html>";
166 
167 string path = System.Environment.CurrentDirectory + "\map.html";
168 File.WriteAllText(path, html);
169 }
170 else
171 {
172 System.Environment.Exit(0);
173 }
174 }
175 
176 }
177 }
178 
179  
三维地图

网上澳门金莎娱乐 22三维地图

三维地图是以三维地图数据为基础开发的,三维地图看起来更佳立体化,地图上可以呈现出立体建筑及阴影的效果,而且地图随着用户的操作,楼宇的角度、阴影等效果也会随之发生变化。

三维地图过渡过程中,也出现过假三维地图。这种地图只能进行平面平移,不能进行旋转操作,是数据平面地图三维地图过渡的产物。

本文由网上澳门金莎娱乐发布于编程,转载请注明出处:用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图网上澳门金莎娱乐

关键词: