首先在Google API上所描述的算法如下
下面说明了对此类有符号值进行编码的步骤
取初始有符号值
将其取十进制值乘以 e并取整
将十进制值转换为二进制值请注意负值必须求反并以值填充字节边界
变换二进制值
如果原来的十进制值是负数则对以下编码求反
将该二进制值分为 位一组的块(从右侧开始):
将这些 位一组的块倒序放置
如果后面还有一个位块则将每个值与 x 进行或操作 (OR)
将每个值转换为十进制
将每个值加上
将每个值转换为其对应的 ASCII 字符
`~oia@
下表显示了编码点的一些示例将编码显示为距离原来点的一系列偏移值
示例
点( )( )( )
纬度 经度 E 表示的纬度 E 表示的经度 纬度变化 经度变化 编码后的纬度 编码后的经度 编码点
+ _p~iF ~ps|U _p~iF~ps|U
+ _ulL nnqC _ulLnnqC
+ _mqN vxq`@ _mqNvxq`@
编码折线_p~iF~ps|U_ulLnnqC_mqNvxq`@
自己写的Java代码如下(参考了一个网上流传的C语言版本但是那个版本里面对第条描述的理解有误即encode(double)这个函数里的while的退出条件)
private String encode(double point) {
//取十进制乘以e
int _point_int = (int) (point*e);
//对二进制低位补
_point_int = _point_int<<;
//如果原来的数是负数则求反
if( point < ) {
_point_int = ~_point_int;
}
String resultString = ;
while ( _point_int>>> > ) {//如果位块后面还有一个位块
int _block = _point_int&xF;//将二进制数分为位一组的块倒序处理
_block = (_block|x)+;
char _result = (char) _block;
resultString +=_result;
_point_int = _point_int>>>;
}
resultString += (char)(_point_int+);
return resultString;
}
private String encodeLatLng(double lat double lng) {
String _lat = thisencode(lat);
String _lng = thisencode(lng);
return _lat+_lng;
}
private String encodeLatLng(String lat String lng) {
double _lat = DoubleparseDouble(lat);
double _lng = DoubleparseDouble(lng);
return thisencodeLatLng(_lat _lng);
}
private String encodeLine(String line) {
String [] _points = null;
String _result = ;
BigDecimal _lat_temp = new BigDecimal();
BigDecimal _lng_temp = new BigDecimal();
_points = linesplit(;);
for (String _point : _points) {
String [] _latlng = _pointsplit();
BigDecimal _lat = BigDecimalvalueOf(DoubleparseDouble(_latlng[]));
BigDecimal _lng = BigDecimalvalueOf(DoubleparseDouble(_latlng[]));
double _lat_disp = _latsubtract(_lat_temp)doubleValue();
double _lng_disp = _lngsubtract(_lng_temp)doubleValue();
_result += thisencodeLatLng(_lat_disp_lng_disp);
_lat_temp = _lat;
_lng_temp = _lng;
}
return _result;
}
其中encode(double)这个函数是实现的折线编码算法剩余三个函数是一些辅助函数其中最后一个encodeLine(String)函数只需传入一个类似的字符串即可返回最后的经过编码的字符串