发表于2013年10月16日


今天有很大进展,相对于前面的算法更靠谱了很多,思路不再单一。

我在找查最基本的概念,纬度、经度。

平均:
纬度1度 = 大约111km
纬度1分 = 大约1.85km
纬度1秒 = 大约30.9m

北京的经纬度是多少?我们很容易从地图上查出来是东经116度24分,北纬39度54分

geohash的算法(纬度,经度)

下面以(39.92324, 116.3906)为例,

  1. 得到纬度编码为 1011 1000 1100 0111 1001,
  2. 得到116.3906编码为 1101 0010 1100 0100 0100。
  3. 将经度和纬度的编码合并,奇数位是纬度,偶数位是经度,得到编码 11100 11101 00100 01111 00000 01101 01011 00001。
  4. 用0-9、b-z(去掉a, i, l, o)这32个字母进行base32编码,得到(39.92324, 116.3906)的编码为wx4g0ec1。

以geohash的python库为例,相关的geohash操作如下:

>>> import geohash
>>> geohash.encode(39.92324, 116.3906, 5)  # 编码,5表示编码长度'wx4g0'
>>> geohash.expand('wx4g0')                # 求wx4g0格子及周围8个格子的编码
['wx4ep', 'wx4g1', 'wx4er', 'wx4g2', 'wx4g3', 'wx4dz', 'wx4fb', 'wx4fc', 'wx4g0']

最后,我们来看看本文开头提出的两个问题:速度慢,缓存命中率低:
使用geohash查询附近地点,用的是字符串前缀匹配:SELECT * FROM place WHERE geohash LIKE ‘wx4g0%’;
而前缀匹配可以利用geohash列上的索引,因此查询速度不会太慢;
另外,即使用户坐标发生微小的变化,也能编码成相同的geohash,这就保证了每次执行相同的SQL语句,使得缓存命中率大大提高。

发表于2013年10月13日


添加laser项目,按照一维数组设计存储。在边界处理时碰到问题,思考方向可能不正确,明天继续。

发表于2013年10月12日


思考:

  1. 定义不同的存储过程,由程序根据不同需求不同调用;
    • 正方形范围粗略距离:
    • 圆形范围精准距离;
  2. 缩小搜索范围,表形式:
    • 根据地域划分;
    • 根据经纬度划分;

早上在路上想到的:

  1. 距离计算考虑水平高度问题;
  2. 预约概念定义:应包括与自身预约(提醒,安排)和与自身以外的预约;
  3. 地点性质预约:临近地点与指定地点;