如何转换Hilbert Curve QuadTree和S2 Geometry CellId

时间:2016-07-26 06:46:38

标签: hilbert-curve

问题

假设我知道Hilbert Curve Face和Quadtree,例如4/032212303102122(第4面,第15级)。

或许我知道S2 Geometry CellId,例如9749618424903892992

如何从一个转换为另一个?

应用

(这是你需要为宠物小精灵GO Ingress 地图)做的事情

我正在尝试在JavaScript中执行此操作,并且存在用于操作64位整数(long.js)以及S2CellIds(s2-geometry.js)的库。

另外,我只是通过添加或减去基数四个数字来走hilbert曲线感觉相当不错(除了交叉面时,但这种情况很少发生,我会很好......暂时... 。),只是不确定如何使用64位内存来回。

1 个答案:

答案 0 :(得分:2)

事实证明,使用字符串比使用二进制文件更容易,更容易 - 因为这是JavaScript,其中long.js的位移将花费更多的时间,实际上更快!

代码示例:

来自s2-geometry-javascript

'use strict';

var Long = require('long');
var S2 = {};

S2.FACE_BITS = 3;
S2.MAX_LEVEL = 30;
S2.POS_BITS = (2 * S2.MAX_LEVEL) + 1;

S2.fromFacePosLevel = function (faceN, posS, levelN) {
  var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long');

  if (!levelN) {
    levelN = posS.length;
  }
  if (posS.length > levelN) {
    posS = posS.substr(0, levelN);
  }

  var posB = Long.fromString(posS, true, 4).toString(2);
  while (posB.length < (2 * levelN)) {
    posB = '0' + posB;
  }
  var bin = Long.fromString(faceN.toString(10), true, 10).toString(2);
  while (bin.length < S2.FACE_BITS) {
    bin = '0' + bin;
  }
  bin += posB;
  bin += '1';
  while (bin.length < (S2.FACE_BITS + S2.POS_BITS)) {
    bin += '0';
  }

  return Long.fromString(bin, true, 2).toString(10);
};

说明:

这是比特

的快速'n'脏故障

id encoding

注意+表示concat而不是添加

(padding + face bits) + (padding + position bits) + (lsb marker + padding)

// quadkey       4/032212303102210
// id (base 10)  9749618446378729472
// base 4        10    032212303102210                   1000000000000000
// base 2       100    001110100110110011010010100100    1000000000000000000000000000000

面部编码

  • “人类可读”表格基础10
  • 3位 - 即展开的6面立方体,基面10面代表0,1,2,3,4,5
  • 6和7未使用且无效
  • 3个二进制字符 - 即000,001,010,011,100,101
  • 110和111未使用且无效
  • 用'0'(即001)
  • 左边填充到3位

位置编码

  • “人类可读”表格是基础4(四键)
  • 61位
  • 60个数据位,1位用于lsb marker
  • 以0填充左侧填充到LEVEL(即8级为00322130)

级别编码

  • “人类可读”表格基础10
  • 希尔伯特曲线quadkey / quadtree字符串的长度是
  • 从二进制形式的最低有效位计算
  • lsb(最低有效位)标记为'1',位于右侧
  • 右边填充到MAX_LEVEL * 2(在lsb标记之后),带有前导'0'
    • (即第30级为“1”,第27级为“1000”)