问题

一POI(Point of Interest)数据库每天都有增量的数据更新进来,对每个新增的poi必须进行dedup(去重)。即在已有库中查找是否有匹配的poi。

解决

找是否匹配的POI,当然不可能把所有的数据(几千万的点)全部取出来一一匹配。所以通用的做法是按距离进行过滤,只取当前点一定范围内的点。这是一个典型的空间索引的问题(Spatial index)。 空间索引有R-Tree, Grid Index, Quad-Tree 等。

其中最容易实现的是Grid Index。把给定区域划分固定大小的格子,每个格子一个编号。根据距离过滤如下实现:

  • 对给定目标点,计算目标格子编号
  • 根据距离计算周边格子的编号
  • 取出相应格子内的POI点

批处理的优化

我们每天需要处理的是一批数据。可以做的一个优化是对待处理的数据进行排序,让地理位置相近的点处在队列的相邻位置。这样做的好处是:

  • 数据库端的缓存可能会有好的命中率。前一个(几个)点的查询结果可能被后一个(后几个)用到
  • 查询端可以做一个本地的LRU cache,同样的增加命中率。

地理位置相邻是一个二维坐标,而处理队列的编号是一维。Hilbert Curve 就是一个很好的二维映射一维的曲线,维持了数据的局部性特征。

Hilbert 编号生成 java代码

public class Hilbert {static Logger logger = Logger.getLogger(Hilbert.class);public static boolean debug = logger.isDebugEnabled();static ImmutableMap<String, Pair[][]> hilbert_map = null;static {hilbert_map = ImmutableMap.of("a", new Pair[][] {{ new Pair(0, "d"), new Pair(1, "a") },{ new Pair(3, "b"), new Pair(2, "a") } }, "b", new Pair[][] {{ new Pair(2, "b"), new Pair(1, "b") },{ new Pair(3, "a"), new Pair(0, "c") } }, "c", new Pair[][] {{ new Pair(2, "c"), new Pair(3, "d") },{ new Pair(1, "c"), new Pair(0, "b") } }, "d", new Pair[][] {{ new Pair(0, "a"), new Pair(3, "c") },{ new Pair(1, "d"), new Pair(2, "d") } });}/*** Our x and y coordinates, then, should be normalized to a range of 0 to* 2order-1* * @param x* @param y* @param order*            An order 1 curve fills a 2x2 grid, an order 2 curve fills a*            4x4 grid, and so forth.* @return*/public static long xy2d(int x, int y, int order) {String current_square = "a";long position = 0;int quad_x = 0;int quad_y = 0;int quad_position = 0;for (int i = order - 1; i >= 0; i--) {position <<= 2;quad_x = (x & (1 << i)) > 0 ? 1 : 0;quad_y = (y & (1 << i)) > 0 ? 1 : 0;Pair p = hilbert_map.get(current_square)[quad_x][quad_y];quad_position = p.no;current_square = p.square;position |= quad_position;}return position;}static int SCALE_FACTOR = (int) 1e5;static int hibert_order = 1;static double max_length = 1.5;static {int Max = (int) (max_length * SCALE_FACTOR);int size = 1;while (size < Max) {size <<= 1;hibert_order++;}}static class Pair {int no = 0;String square;Pair(int no, String square) {this.no = no;this.square = square;}}
}
http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves

Hilbert 分布效果

简单的case
   
实际的case

2012-01-11更新
server 的数据排序比client更有效果,server端已经保证了地理位置相邻的点物理位置也相邻。

insert into us_ta_2 (select * from us_ta_1 order by node_index)

Hilbert 曲线相关推荐

  1. hilbert曲线序编码matlab,Hilbert曲线扫描矩阵的生成算法及其MATLAB程序代码

    Hilbert曲线扫描矩阵的生成算法及其MATLAB程序代码 王笋,徐小双(华中科技大学控制科学与工程系,武汉 430074) 摘 要 Hilbert曲线是一种重要的图像处理工具,在图像处理,特别是图 ...

  2. Hilbert曲线简单介绍及生成算法

    Hilbert曲线 Hilbert曲线是一种填充曲线,相似的填充曲线还包含Z曲线.格雷码等其它方法.Hilbert曲线根据自身空间填充曲线的特性,能够线性地贯穿二维或者更高维度每一个离散单元.而且只穿 ...

  3. Hilbert曲线介绍以及代码实现

    空间填充曲线是指,一维曲线去包含整个二维甚至多维空间的一种函数曲线.而根据不同的排列规则,可以得到不同的空间填充曲线.     如Z-order曲线, 如图1(也就是geohash采取的曲线),Pea ...

  4. c语言希尔伯特曲线的算法分析,Hilbert曲线介绍以及代码实现

    空间填充曲线是指,一维曲线去包含整个二维甚至多维空间的一种函数曲线.而根据不同的排列规则,可以得到不同的空间填充曲线. 如Z-order曲线, 如图1(也就是geohash采取的曲线),Peano曲线 ...

  5. 希尔伯特曲线 java_Java中空间填充Hilbert曲线的递推算法

    我正在学习用 Java编写代码,我已经学习了java编程的递归部分.我理解了递归方法的基础知识,并且我正在尝试编写填充希尔伯特曲线(和Levy C曲线)的空间,到目前为止,一切都顺利进行,直到实际的递 ...

  6. java hilbert空间算法_Java中空间填充Hilbert曲线的递推算法

    我正在学习用 Java编写代码,我已经学习了java编程的递归部分.我理解了递归方法的基础知识,并且我正在尝试编写填充希尔伯特曲线(和Levy C曲线)的空间,到目前为止,一切都顺利进行,直到实际的递 ...

  7. [分形学] 基于 L 系统绘制 Hilbert (希尔伯特) 曲线

    德国数学家 David Hilbert 发现了这样一种可以填满整个单位正方形的分形曲线,称它为 Hilbert 曲线.具体的我就不多做介绍了,相关内容请自己搜索.这里只说程序. 程序执行后,按数字键 ...

  8. Analysis of the Clustering Properties of the Hilbert Space-Filling Curve 论文笔记

    摘要 已经针对各种应用提出了用于多维空间的线性映射的若干方案,诸如用于时空数据库的访问方法和图像压缩.在这些应用中,来自这种线性映射的最期望的属性之一是聚类,这意味着多维空间中的对象之间的局部性被保留 ...

  9. JUST技术:管理海量空间数据的利器-空间填充曲线

    现实世界中存在大量的多维空间数据,如加油站位置.河流走向等.为了高效存储和管理海量的空间数据,很多基于Key-Value存储的空间数据库,如开源的空间插件GeoMesa[1].京东城市自研的时空数据引 ...

最新文章

  1. 从 AlphaGo 到具有人类智慧的 AI 究竟有多远?François Chollet 有了一些新想法
  2. POJ2594 最小路径覆盖
  3. 学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践
  4. 学python需要记笔记吗_自学python需要做什么笔记
  5. 提升编程水平的靠谱方法
  6. 【数据结构与算法】之深入解析“分割回文串II”的求解思路与算法示例
  7. Vue-router路由基础总结(一)
  8. webpack的一些常用配置 (转)
  9. 3G应用上新闻联播 TD-SCDMA被内定?
  10. DBShop电子商务系统
  11. 生成对抗网络GAN损失函数loss的简单理解
  12. 不规则形状 前端_精度提升第一步:形状各异测区的像控点布设方案
  13. eval函数处理JSON数据需要加括号
  14. python爬取genek视频_【Python】爬虫(Xpath):批量爬取站长免费简历
  15. 基于Django+链家+Bootstrap真实数据的房源推荐/可视化系统
  16. delphi10 ftp文件名乱码问题
  17. 2021年中国茶叶电商发展现状及未来发展趋势分析[图]
  18. Linux 设备树 status 详解
  19. 每日总结-05-23
  20. <金屋藏书>app 技术支持

热门文章

  1. python qt 按钮_Python QtWidgets.QPushButton方法代码示例
  2. axure流程图模式_Axure基础教程:产品流程图的制作方法详解
  3. 单片机学习笔记9--常见的通信方式(基于百问网STM32F103系列教程)
  4. 【Binder 机制】AIDL 分析 ( 分析 AIDL 文件生成的 Java 源文件 | Binder | IBinder | Stub | Proxy )
  5. 采用GlodWave软件制作个性化铃声
  6. 利用CUDA流重叠计算和数据传输
  7. 宝塔服务器源代码修改记录,宝塔BT面板修改相关记录,所有插件免费用
  8. BT 面板控制命令 宝塔 Linux 常用命令收集整理
  9. 小米4c怎么添加语言怎么设置在哪,小米4c路由器设置教程
  10. Angularjs DataTable表格自动刷新