Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The practice of spatial index in geographic se...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for halfrost halfrost
January 14, 2018

The practice of spatial index in geographic service

I share my practice 《Application of spatial index in geographic service》. The contents are as follows:
- How to understand n-dimensional space and n-dimensional space-time
- Efficient multi-dimensional spatial point indexing algorithm — Geohash and Google S2
- How to generate CellID in Google S2?
- The algorithm of finding LCA recent public ancestor on the quadtree in Google S2
- The magical of Bruyne sequence
- How to find the neighbors of Hilbert curve on the quadtree?
- How does Google S2 solve the problem of optimal solution in spatial coverage?

Article is in there: https://github.com/halfrost/Halfrost-Field#-go

Avatar for halfrost

halfrost

January 14, 2018
Tweet

More Decks by halfrost

Other Decks in Programming

Transcript

  1. F O R E W O R D N E

    X T S L I D E
  2. #01 GEOHASH S P AT I A L I N

    D E X N E X T S L I D E
  3. 4 5 % 4 5 % 4 5 % 4

    5 % 4 5 % 4 5 % GEOHASH (LEVEL-6) (31.1932993, 121.43960190000007) 纬 经
  4. GEOHASH (LEVEL-6) 101011000101110 L AT I T U D E

    纬 度 110101100101101 L O N G I T U D E 经 度 偶数位放经度,奇数位放纬度 (第 0 位为第⼀位) 111001100111100000110011110110
  5. CODE package geohash import ( "bytes" ) const ( BASE32

    = "0123456789bcdefghjkmnpqrstuvwxyz" MAX_LATITUDE float64 = 90 MIN_LATITUDE float64 = -90 MAX_LONGITUDE float64 = 180 MIN_LONGITUDE float64 = -180 ) var ( bits = []int{16, 8, 4, 2, 1} base32 = []byte(BASE32) ) type Box struct { MinLat, MaxLat float64 // 纬度 MinLng, MaxLng float64 // 经度 } func (this *Box) Width() float64 { return this.MaxLng - this.MinLng } func (this *Box) Height() float64 { return this.MaxLat - this.MinLat } // 输⼊值:纬度,经度,精度(geohash的⻓度) // 返回geohash, 以及该点所在的区域 func Encode(latitude, longitude float64, precision int) (string, *Box) { var geohash bytes.Buffer var minLat, maxLat float64 = MIN_LATITUDE, MAX_LATITUDE var minLng, maxLng float64 = MIN_LONGITUDE, MAX_LONGITUDE var mid float64 = 0 bit, ch, length, isEven := 0, 0, 0, true for length < precision { if isEven { if mid = (minLng + maxLng) / 2; mid < longitude { ch |= bits[bit] minLng = mid } else { maxLng = mid } } else { if mid = (minLat + maxLat) / 2; mid < latitude { ch |= bits[bit] minLat = mid } else { maxLat = mid } } isEven = !isEven if bit < 4 { bit++ } else { geohash.WriteByte(base32[ch]) length, bit, ch = length+1, 0, 0 } } b := &Box{ MinLat: minLat, MaxLat: maxLat, MinLng: minLng, MaxLng: maxLng, } return geohash.String(), b }
  6. SHARDING RULE 根据经纬度计算 Shard ID 及 Cell ID 若上⼀次在同⼀个 Cell,直接更新

    若上⼀次在不同 Cell,先删除上⼀ 个 Cell,再加⼊当前 Cell 的队列 中。 W R I T E ( U P D AT E L O C AT I O N ) 计算相交的 Shard 每个 Shard 做并⾏ Nearby 计算。 Geohash 只能先按照⼴度优先查 找相应的 Cell,过滤出 Cell 中符 合条件的点。 R E A D ( N E A R B Y S E A R C H )
  7. WHY why? 偶 数 位 放 经 度 , 奇

    数 位 放 纬 度 why? 理 论 基 础 why? 有 缺 点 么 ?
  8. #02 SPACE FILLING CURVE S P AT I A L

    F I L L I N G C U R V E N E X T S L I D E
  9. ANY QUESTIONS? T H A N K S F O

    R Y O U R AT T E N T I O N ! N E X T S L I D E
  10. #03 GOOGLE S2 S P AT I A L I

    N D E X N E X T S L I D E
  11. LAT / LNG x = r * sin θ *

    cos φ y = r * sin θ * sin φ z = r * cos θ
  12. FRACTAL 3 0 % 4 5 % 5 0 %

    f(x,y,z) -> g(face,u,v)
  13. PROGRAM 线性变换 u = 0.5 * ( u + 1)

    tan() 三⻆变换 u = 2 / pi * (atan(u) + pi / 4) = 2 * atan(u) / pi + 0.5 ⼆次变换 u >= 0,u = 0.5 * sqrt(1 + 3*u) u < 0,u = 1 - 0.5 * sqrt(1 - 3*u) 1 2 3
  14. N E X T S L I D E S(lat,lng)

    -> f(x,y,z) -> g(face,u,v) -> h(face,s,t) -> H(face,i,j) -> CellID GOOGLE S2
  15. GEOHASH VS GOOGLE S2 各种向量计算,⾯ 积计算,多边形覆 盖,距离问题,球 ⾯球体上的问题 ⼏ 何

    计 算 S2 还能解决多 边形覆盖的问题 多 边 形 覆 盖 S2 有30级,从 0.7cm² 到 85,000,000km² 。S2 的存 储只需要⼀个 uint64 即可 存下 突 变 性 Geohash 有12级,从5000km 到 3.7cm。中间每⼀ 级的变化⽐较⼤。有时候可能选择上⼀级会⼤很 多,选择下⼀级⼜会⼩⼀些。⽐如选择字符串⻓度 为4,它对应的 cell 宽度是39.1km,需求可能是 50km,那么选择字符串⻓度为5,对应的 cell 宽度 就变成了156km,瞬间⼜⼤了3倍了。Geohash 需 要 12 bytes 存储 L E V E L 精 细 度
  16. GOOGLE S2 1.涉及到⻆度,间隔,纬度经度点,单位⽮量等的表示,以及对这些 类型的各种操作。 2.单位球体上的⼏何形状,如球冠(“圆盘”),纬度 - 经度矩形,折 线和多边形。 3.⽀持点,折线和多边形的任意集合的强⼤的构造操作(例如联合) 和布尔谓词(例如,包含)。

    4.对点,折线和多边形的集合进⾏快速的内存索引。 5.针对测量距离和查找附近物体的算法。 6.⽤于捕捉和简化⼏何的稳健算法(该算法具有精度和拓扑保证)。 7.⽤于测试⼏何对象之间关系的有效且精确的数学谓词的集合。 8.⽀持空间索引,包括将区域近似为离散“S2单元”的集合。此功能可 以轻松构建⼤型分布式空间索引。