Google静态地图如何显示两点之间路线3(url过长–路径简化完结篇)

摘要:
非智能手机浏览器的URL长度限制甚至更糟。在最后一张Google静态地图-如何显示两点之间的路线2中,通过使用Google地理编码API位置路线服务中的折线编码,路线路径的字符长度大大缩短。记住第一张谷歌静态地图——如何通过使用一个点坐标来形成路线来显示两点之间的路线。只要对某些点进行了优化和舍入,字符串就会变短,然后转换为虚线代码。嗯,这个想法似乎是可行的--我们先不考虑如何优化路线。这些拐点是从Google Directions API服务获得的吗??
非智能手机浏览器的URL长度限制更糟糕

在上一篇Google静态地图-如何显示两点之间路线2(url过长问题)中,利用Google Geocoding API位置路线服务中的折线编码,大大缩短了路线path的字符长度。但是,折线编码也是一长串字符也是有长度的,万一折线编码的长度也太长,也会出现url过长的问题。

这个问题也是我在开发项目时遇到的问题,手机种类繁多独自开发的的浏览器也是让我头疼的地方。我们来看看日本的三大运营商au,softbank,docomo中一些非智能手机浏览器的情况:

浏览器长度
i-mode(DoCoMo)512bytes(直接入力時100bytes)
EZweb(au)1024文字?
Yahoo!ケータイ(SoftBank)端末a要素form要素
DN02※1300bytes300bytes
SH02, SH02_a、SH03, SH03_a1024bytes255bytes
3GC※21024bytes1024bytes

这是au,softbank,docomo中非智能手机浏览器url长度限制的情况,可以看出url的长度远远小于PC浏览器限制的长度,尤其是i-Mode才520字节(不是绝对,相对于老的手机)…,折线编码的字符长度肯定会超过的,哎,又回到原点了。

如何优化路线

该怎么办呢?还记得第一篇google静态地图-如何显示两点之间路线中利用一个一个点坐标连成路线的方法吗,只要把这些点优化舍去一部分点,字符串不就短了~再转成折线编码就更短了,恩,看起来这个想法可行~~

我们先不考虑如何优化路线,那些从Google Directions API服务中取的一个一个拐点真的是完全路径吗??经过我测试连成路径之后发现,如果路线距离很长,好像拐点个数有限路线上就显示一部分有拐点,后面的就没了。。。结果就是前一部分是曲线后面就是一条直线。。。,汗!完了,看来原来的方法不行了。

那该怎么办呢,我们回顾下Google静态地图-如何显示两点之间路线2(url过长问题),是利用那个折线编码画出路线的,那我们反过来想想,假如将折线编码转化成一个一个的点坐标,这不就是是完全路径的点集合嘛~~前面那个问题不就解决了。慢!,怎么把折线编码还原成一个一个点坐标集合呢??这不,折线编码其实也是将点集合转换过来的,再转换回去就是了。。。

http://code.google.com/intl/zh-CN/apis/maps/documentation/utilities/polylinealgorithm.html

这是如何点集合转化成折线编码的文章,按照上面算法反过来就可以得到点坐标集合了~呵呵,说的轻巧了,本人算法差,惭愧~以下是网上搜索的代码然后加工下。。(其中的List<GLatLng>就是点集合,这是为了程序需要):

 1 /// <summary>
2 /// 折线编码转点集合
3 /// eg : szmrE}japXrX`zE
4 /// decode : 34.646343,133.86943  34.642247,133.834389
5 /// </summary>
6 /// <param name="str"></param>
7 /// <returns></returns>
8 public static List<GLatLng> DecodePath(string str)
9 {
10 int b = str.Length;
11 decimal dec = str.Length / 2;
12 //GLatLng[] c = new GLatLng[int.Parse(Math.Floor(dec).ToString())];
13 List<GLatLng> c = new List<GLatLng>();
14
15 int d = 0, e = 0, f = 0, g = 0;
16
17 for (; d < b; ++g)
18 {
19 int h = 1, n = 0, q;
20 do
21 {
22 q = str.ToCharArray()[d++] - 63 - 1;
23 h += q << n;
24 n += 5;
25 } while (q >= 31);
26 e += (h & 1) != 0 ? ~(h >> 1) : h >> 1;
27
28 h = 1;
29 n = 0;
30
31 do
32 {
33 q = str.ToCharArray()[d++] - 63 - 1;
34 h += q << n;
35 n += 5;
36 } while (q >= 31);
37 f += (h & 1) != 0 ? ~(h >> 1) : h >> 1;
38 //c[g] = new GLatLng(e * 1.0E-5, f * 1.0E-5);
39 c.Add(new GLatLng(e * 1.0E-5, f * 1.0E-5));
40 }
41
42 //c.Length = g;
43 return c;
44 }

OK,完整的点集合取出来了,如何优化这些点呢?请看这下面一篇文章,当然要感谢下这篇文章的作者,对我帮助很大~

作者:阿修的部落格

文章:如何在Google Static Map上顯示超長路徑?

里面讲述的很详细,我就简单摘抄几个重要的地方~

文章中使用的路线算法是道格拉斯-派克爾法(Ramer–Douglas–Peucker algorithm)

Google静态地图如何显示两点之间路线3(url过长–路径简化完结篇)第1张

credit: 維基百科

道格拉斯-派克爾法的做法就是保留頭尾兩點。將頭尾用一條直線連接,接著找出中間每個點距離這個最大的值b,接著保留這個距離頭尾連接起來的直線最遠的點c。然後設定一個容許值,這個容許值必須小於b。再檢查中間每個點到直線的距離,如果距離大於容許值,就保留這個點。然後用c點,把這條路徑分為兩部分,再依照前面的方法一直做下去。

GDouglasPeuker.js

如果要在Google Maps API或Google Static Maps API上使用道格拉斯-派克爾法,我們可以直接用Bill Chadwick寫好的GDouglasPeuker.js

算法已经有人写好了,不过是js版的~我们知道有些非智能手机上不支持javascript的,所以要转成C#, 转成C#版也不难 就类型什么的转换下就好了~我就不贴代码了.

好了,优化后的点就可以取出来了~为了字符更短,那么就该把这些点集合再一次转化成折线编码,代码我再贴下吧:

 1 /// <summary>
2 /// 点集合转折线编码
3 /// eg : 34.646343,133.86943|34.642247,133.834389
4 /// encode: szmrE}japXrX`zE
5 /// </summary>
6 /// <param name="points"></param>
7 /// <returns></returns>
8 public static string EncodePoints(List<GLatLng> points)
9 {
10 string _result = "";
11 int plat = 0;
12 int plng = 0;
13
14 foreach (GLatLng item in points)
15 {
16 int late5 = (int)Math.Floor(item.Lat * 1e5);
17 int lnge5 = (int)Math.Floor(item.Lng * 1e5);
18
19 int dlat = late5 - plat;
20 int dlng = lnge5 - plng;
21
22 plat = late5;
23 plng = lnge5;
24
25 _result += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
26 }
27
28 return _result;
29 }
30
31 private static string encodeSignedNumber(int point)
32 {
33
34 int _point_int = point << 1;
35
36 if (point < 0)
37 {
38 _point_int = ~_point_int;
39 }
40 return (encodeNumber(_point_int));
41 }
42
43 private static string encodeNumber(int num)
44 {
45 string resultString = "";
46
47 while (num >= 0x20)
48 {
49 int _block = num & 0x1F;
50 _block = (_block | 0x20) + 63;
51 char _result = (char)_block;
52 resultString += _result;
53 num >>= 5;
54 }
55
56 resultString += (char)(num + 63);
57 return resultString;
58 }

这样,优化的折线编码就出来了~~只要设置那个什么派克爾法算法设置优化距离大小,就可以随意控制路线拐点的个数了,也就可以控制长度了~~这里还是要再次感谢下阿部的文章~

对了,介绍个个折线编码实用工具,这里面大家可以添加个个点后转换成折线编码,哦!对了,刚才的链接是中文的,不知道什么原因那个工具不好用了!!我测试了下英文版的是可以的,大家还是去英文版面的吧

http://code.google.com/intl/en/apis/maps/documentation/utilities/polylineutility.html

免责声明:文章转载自《Google静态地图如何显示两点之间路线3(url过长–路径简化完结篇)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python crosstab和pivot_tableWinAPI: CreateBrushIndirect 根据画刷结构建立画刷下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python学习笔记:字符编码原理和操作详解

一、电脑字符集的历史   1、电脑是如何将二进制与字符对应起来的?     我们知道,电脑底层只认识0和1的二进制数据,为了让电脑可以跟人类互动,我们使用8个二进制位(即1个字节)来对应一个更复杂的数字,     比如:使用二进制“01000001”来指代十进制“65”,也就是大写字母A     实际使用场景中,人类利用键盘打字符“A”时,实际上是打65这...

mysql修改表、字段、库的字符集

在一次导入数据表(MYISAM)的经历:复制过来的表打开后中文出现乱码,肯定是字符集出现了不致的问题,所以从原数据库导出.sql文件,修改其中的创建表的语句,加入字符集DEFAULT CHARSET=gb2312 用这个导入 mysql -uroot -p --default-character-set=gb2312 databasename>E:o...

shellcode xor编码/解码[1]

shellcode的初级变形的一点点总结,大部分搜集、翻译,少量原创 0x01 病毒上重定位问题0x02 shellcode解码0x03 一个unix例子0x04 源码解读0x05 参考 shellcode xor编码/解码器是一种较为初级的shellcode变形的方法,当然它从中采用的方法跟病毒上的方法有些类似 0x01 病毒上重定位问题病毒上的解决重定...

Python中使用中文

这个问题曾在我初学Python的时候令我头疼不已,尤其是目前我们因为各种包的原因还只能使用2.x的版本。在3.x中字符编码已经统一用Unicode了。 Python 默认支持的是ASCII字符,包含了英文字母大小写以及标点符号,用一枚字节表示。中文则使用两枚字节表示。 没兴趣的同学可以绕过这段… 有人可能要问了,我擦,为神马以前说一个汉字的精度越高字节越多...

python3对文件编码的转换处理

  前言:   公司同事邀我一起给SQLSERVER 2008导数, 数据来源有高斯和ORACLE, 数据文件保存格式有UTF-8和GBK。   当我在做测试导入的时候发现SQLSERVER 2008数据库的WITH选项不支持CODEPAGE='65001', 即UTF-8文件编码格式导入。 所以需要把UTF-8编码的文件 统一转换成GBK, 代码如下。...

字符集编码 定长与变长

☯,首先,这并不是图片,这是一个unicode字符,Yin Yang,即阴阳符,码点为U+262F。如果你的浏览器无法显示,可以查看这个链接http://www.fileformat.info/info/unicode/char/262f/index.htm。这与我们要讨论的主题有何关系呢?下面我会谈到。 连续式表示带来的分隔难题 计算机的底层表示 在计...