Hilbert 曲线
来源:互联网 发布:好玩角色扮演网游知乎 编辑:程序博客网 时间:2024/04/29 01:09
问题
一POI(Point of Interest)数据库每天都有增量的数据更新进来,对每个新增的poi必须进行dedup(去重)。即在已有库中查找是否有匹配的poi。
解决
找是否匹配的POI,当然不可能把所有的数据(几千万的点)全部取出来一一匹配。所以通用的做法是按距离进行过滤,只取当前点一定范围内的点。这是一个典型的空间索引的问题(Spatial index)。空间索引有R-Tree, Grid Index, Quad-Tree 等。
其中最容易实现的是Grid Index。把给定区域划分固定大小的格子,每个格子一个编号。根据距离过滤如下实现:
其中最容易实现的是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 曲线
- Hilbert 曲线
- Hilbert曲线-学习
- Hilbert曲线代码和思路
- hilbert曲线用于空间索引
- 递归算法(2) Hilbert-Peano曲线
- Hilbert曲线简介及生成算法
- Hilbert曲线介绍以及代码实现
- LS文法生成Hilbert-Peano曲线
- Hilbert曲线简介及生成算法
- Hilbert曲线简介及生成算法
- LS文法构图算法(3) Hilbert-Peano曲线
- Hilbert 空间填充曲线的产生式规则
- 用Python写的hilbert曲线生成代码
- GeoHadoop 之 Hilbert 空间填充曲线 Java 实现(一)
- GeoHadoop 之 Hilbert 空间填充曲线 Java 实现(二)
- 使用java绘制希尔伯特曲线(hilbert curve)
- Hilbert排序
- 引用传递和值传递的区别
- 使用SharedPreferences进行数据存储
- libavi - parse and demux AVI
- 程序员需要具备的基本技能
- Ext自定义事件
- Hilbert 曲线
- apache mina 2.x 菜鸟入门
- C++中实现Singleton的正确方法
- NYOJ 453 小珂的烦恼
- html5&CSS实现后台管理页面
- V4L2 简介
- LINUX 服务器遭到SYN FLOOD攻击
- XMPP——(1)大作业MyMeeting实现
- Windows X64上强制用x86模式运行c#程序