编码折线算法格式

对于任何给定的点集,编码折线都会存储两种类型的编码信息:点的纬度和经度,以及显示这些点时的最大缩放级别。级别使用无符号的值进行编码,而点坐标需要使用带符号的值,因此编码过程对于每种情况会略有不同。下面是此过程的说明。如果仅有几个静态点,您也可使用互动式折线编码实用程序

纬度和经度编码

编码过程使用我们所熟悉的 Base64 编码方案将二进制值转换为一系列 ASCII 字符的字符代码:为确保这些字符能够正常显示,在将其转换为 ASCII 之前,我们使用 63(ASCII 字符“?”)对编码值进行了求和。该算法还会通过检查每个字节组的最不显著位检查给定点的附加字符代码;如果该位设为 1,则该点尚未完全构造完毕,还必须提供附加数据。

此外,为了节省空间,点仅包含距离上个点的偏移值(第一个点除外)。所有点都采用 Base64 编码为带符号的整数,因为纬度和经度是带符号的值。折线中的编码格式需要以合理精度表示分别代表纬度和精度的两个坐标。假设最大经度为 +/- 180 度,精度为 5 个小数位(180.00000 到 -180.00000),则这将需要一个 32 位的带符号二进制整数值。

请注意,在字符串语义中,反斜线被解释为转义字符。。在字符串语义中,此实用程序的任何输出都应将反斜线字符转换为双反斜线。

下面说明了为此类带符号值进行编码的步骤。

  1. 取初始有符号值:
    -179.9832104
  2. 将其取十进制值乘以 1e5,并取整:
    -17998321
  3. 将十进制值转换为二进制值。请注意,必须通过对二进制值求反并在结果中添加 1 的方法,使用负值的二补码来计算负值:
    00000001 00010010 10100001 11110001
    11111110 11101101 01011110 00001110
    11111110 11101101 01011110 00001111
  4. 将二进制值左移 1 位:
    11111101 11011010 10111100 00011110
  5. 如果原来的十进制值是负值,则对以下编码求反:
    00000010 00100101 01000011 11100001
  6. 将该二进制值分为 5 位一组的块(从右侧开始):
    00001 00010 01010 10000 11111 00001
  7. 将这些 5 位一组的块倒序放置:
    00001 11111 10000 01010 00010 00001
  8. 如果后面还有一个位块,则将每个值与 0x20 进行“或”操作 (OR):
    100001 111111 110000 101010 100010 000001
  9. 将每个值转换为十进制值:
    33 63 48 42 34 1
  10. 将每个值加上 63:
    96 126 111 105 97 64
  11. 将每个值转换为其 ASCII 对应值:
    `~oia@

下表显示了一些编码点的示例,其中将编码显示为相对于原来的点的一系列偏移。

示例

点:(38.5, -120.2)、(40.7, -120.95)、(43.252, -126.453)



纬度 经度 E5 纬度 E5 经度 纬度变化 经度变化 编码纬度 编码经度 编码点
38.5 -120.2 3850000 -12020000 +3850000 -12020000 _p~iF ~ps|U _p~iF~ps|U
40.7 -120.95 4070000 -12095000 +220000 -75000 _ulL nnqC _ulLnnqC
43.252 -126.453 4325200 -12645300 +255200 -550300 _mqN vxq`@ _mqNvxq`@

编码折线:_p~iF~ps|U_ulLnnqC_mqNvxq`@

编码级别

编码折线还会存储指定绘制折线时的精度的信息。该信息允许地图忽略不需要该精度的缩放级别的绘制段。编码折线中的每个点都会在一个 levels 字符串中存储此信息,该字符串会与编码点一起进行编码。

请注意:虽然此编码“级别”与缩放级别相关联,但这两者并不直接相对应。更确切地说,numLevels 参数会将现有的缩放级别(当前为 18)划分为多组缩放级别。例如,假设numLevels 值为 4,则缩放级别将会分为以下几个级别组:

编码折线级别 缩放级别
级别 0 缩放级别 0-5
级别 1 缩放级别 6-10
级别 2 缩放级别 11-14
级别 3 缩放级别 15-18

在本例中,编码级别值 3 可确保点在所有缩放级别下都能显示出来,而级别 0 将忽略超出缩放级别 5 的指定点。折线的端点通常应设为最大的编码级别,以确保端点在所有缩放级别下都能显示出来,并且能够正确绘制折线。

为进行优化,zoomFactor 参数应反映出 numLevels 中所指定不同缩放级别组之间的近似放大率。例如,假设每个缩放级别的放大率为两倍,并且每组中有大约 4 个缩放级别,则此值应设为 16。

这些级别值采用 Base64 编码为无符号的整数。请注意,由于级别值通常较小,因此它们不应超过 5 位界限;这会使得级别编码非常简单:只需将值加上 63 即可。不过,下面的编码过程假设您要转换为二进制值,然后再转换回来;当 API 版本中的级别值发生更改时,您的代码应执行此转换过程。

下面说明了为无符号值进行编码的步骤:

  1. 取初始无符号值:
    174
  2. 将十进制值转换为二进制值:
    10101110
  3. 将该二进制值分为 5 位一组的块(从右侧开始):
    101 01110
  4. 将这些 5 位一组的块倒序放置:
    01110 101
  5. 如果后面还有一个位块,则将每个值与 0x20 进行“或”操作 (OR):
    101110 00101
  6. 将每个值转换为十进制值:
    46 5
  7. 将每个值加上 63:
    109 68
  8. 将每个值转换为其 ASCII 对应值:
    mD
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值