GeoHash解析请参考这里:

http://www.open-open.com/lib/view/open1417940079964.html

java实现GeoHash,代码已注释。

import java.util.BitSet;
import java.util.HashMap; /**
* 地理知识补充: Latitude(纬度)[-90, 90],Longitude(经度)[-180, 180]
*
* @author FengKang 2014-10-03
*
*/
public class Geohash {
private static int numbits = 6 * 5; // 最大划分次数,也是生成二进制位的最大长度 final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; // decode时进行解码之用
final static HashMap<Character, Integer> lookup = new HashMap<>();
static {
int i = 0;
for (char ch : digits) {
lookup.put(ch, i++);
}
} /**
* 在[floor, ceil]区间内对lat进行编码 区间的划分次数为numbits次
*
* @param lat
* -待编码经/纬度
* @param floor
* @param ceil
* @return 二进制编码
*/
private BitSet getBits(double lat, double floor, double ceil) {
BitSet buffer = new BitSet(numbits);
for (int i = 0; i < numbits; ++i) {
double mid = (floor + ceil) / 2;
if (lat >= mid) {
buffer.set(i);
floor = mid;
} else {
ceil = mid;
}
} return buffer;
} /**
* 将long型i的二进制位中,每5位映射为一个digits[]中的编码
* 这里的实现方法是参照Long.java中toString的实现
*
* @param i
* @return
*/
private static String base32(long i) {
char[] buf = new char[65]; // buf[0]备用,若为负数则存储'-'
int charPos = 64;
boolean negative = (i < 0);
if (!negative) {
i = -i;
} while (i < -32) {
buf[charPos--] = digits[(int) (-(i % 32))];
i /= 32;
} buf[charPos] = digits[(int) (-i)]; if (negative) {
buf[--charPos] = '-';
} return new String(buf, charPos, (65 - charPos));
} public String encode(double lat, double lon) {
BitSet latbits = getBits(lat, -90, 90);
BitSet lonbits = getBits(lon, -180, 180); /* ! 先经度后纬度交错组合编码 */
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < numbits; ++i) {
buffer.append((lonbits.get(i)) ? '1' : '0');
buffer.append((latbits.get(i)) ? '1' : '0');
} System.out.println(buffer.toString());
// 将2进制字符串转换为10进制long型
return base32(Long.parseLong(buffer.toString(), 2));
} /**
* 根据bs对区间[floor, ceil]进行划分
* 0表示位于区间[floor, (floor + ceil)/2]
* 1表示位于区间[(floor + ceil)/2, ceil]
*
* @param bs
* 二进制序列
* @param floor
* 初始区间边界[floor, ceil]
* @param ceil
* @return 区间边界,最接近bs序列的区间边界
*/
private double decode(BitSet bs, double floor, double ceil) {
double mid = 0;
for (int i = 0; i < bs.length(); ++i) {
mid = (floor + ceil) / 2;
if (bs.get(i)) {
floor = mid; // 右区间
} else {
ceil = mid; // 左区间
}
} return mid;
} public double[] decode(String geohash) {
StringBuilder buffer = new StringBuilder();
for (char ch : geohash.toCharArray()) {
int i = lookup.get(ch) + 32; // 保证转换后的二进制字符串为5位
// +32转换为1#####,然后从下标为1处进行截取,即#####
buffer.append(Integer.toString(i, 2).substring(1));
}
// System.out.println(buffer); BitSet lonset = new BitSet();
BitSet latSet = new BitSet(); // even bits
int j = 0;
for (int i = 0; i < numbits * 2; i += 2) {
boolean isSet = false;
if (i < buffer.length()) {
isSet = (buffer.charAt(i) == '1');
} lonset.set(j++, isSet);
} // odd bits
j = 0;
for (int i = 1; i < numbits * 2; i += 2) {
boolean isSet = false; if (i < buffer.length()) {
isSet = (buffer.charAt(i) == '1');
} latSet.set(j++, isSet);
} double lon = decode(lonset, -180, 180);
double lat = decode(latSet, -90, 90); return new double[] { lat, lon };
} public static void main(String[] args) throws Exception {
Geohash geoHash = new Geohash();
String encodes = geoHash.encode(45, 125);
System.out.println(encodes); double[] decodes = geoHash.decode(encodes);
System.out.println(decodes[0]);
System.out.println(decodes[1]); /**
* 输出结果 111100101000000010101000000010101000000010101000000010101000
* yb0bh2n0p058 45.0 124.9999999254942
*/
}
}

注:代码非本人所写,本人仅仅添加一些注释!

GeoHash解析及java实现的更多相关文章

  1. Xml解析之——Java/Android/Python

    Xml解析之——Java/Android/Python 一.Xml文件 test.xml <note> <to>George</to> <from>Jo ...

  2. 使用递归算法结合数据库解析成java树形结构

    使用递归算法结合数据库解析成java树形结构 1.准备表结构及对应的表数据a.表结构: create table TB_TREE ( CID NUMBER not null, CNAME VARCHA ...

  3. php解析处理java的btye字节;php解析处理java的ByteArrayOutputStream字节流/数据流

    php解析处理java的btye字节:php解析处理java的ByteArrayOutputStream字节流/数据流 一般java的字节流: 就是t public class Test { publ ...

  4. eclipse无法解析导入 java.util

    eclipse无法解析导入 java.util是因为jre配置错误. 1.点击需要导入jar的项目,右击项目属性(properties),进入到如下图界面: 2.选择Java Build Path选项 ...

  5. 【转】URL短地址压缩算法 微博短地址原理解析 (Java实现)

    转自: URL短地址压缩算法 微博短地址原理解析 (Java实现) 最近,项目中需要用到短网址(ShortUrl)的算法,于是在网上搜索一番,发现有C#的算法,有.Net的算法,有PHP的算法,就是没 ...

  6. [源码解析] 当 Java Stream 遇见 Flink

    [源码解析] 当 Java Stream 遇见 Flink 目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java St ...

  7. GeoHash核心原理解析及java代码实现(转)

    原文链接:http://blog.jobbole.com/80633/ 引子 机机是个好动又好学的孩子,平日里就喜欢拿着手机地图点点按按来查询一些好玩的东西.某一天机机到北海公园游玩,肚肚饿了,于是乎 ...

  8. stl文件格式解析代码--java版

    代码是参考three.js中的stlLoader.js写的. 需要注意的地方,java中byte取值-128~127 package test_stl.test_entry; import java. ...

  9. 逗号分割符--字段中含逗号等情况的解析方法Java实现

    最近在处理文本字符串时,没一行数据都是按照逗号分割的,每个字段值一般情况是带有双引号的,但是有的字段值里面还包含逗号,甚至有的字段就没有双引号,这个分割起来就有点麻烦了 下面说一下我解决方法,如果谁有 ...

随机推荐

  1. 一本通1633【例 3】Sumdiv

    1633:[例 3]Sumdiv 时间限制: 1000 ms         内存限制: 524288 KB [题目描述] 原题来自:Romania OI 2002 求 ABAB 的所有约数之和 mo ...

  2. BZOJ2440 中山市选2011完全平方数(容斥原理+莫比乌斯函数)

    如果能够知道不大于n的合法数有多少个,显然就可以二分答案了. 考虑怎么求这个.容易想到容斥,即枚举完全平方数.我们知道莫比乌斯函数就是此种容斥系数.筛出来就可以了. 注意二分时会爆int. #incl ...

  3. P3254 圆桌问题

    题目链接 非常简单的一道网络流题 我们发现每个单位的人要坐到不同餐桌上,那也就是说每张餐桌上不能有同一单位的人.这样的话,我们对于每个单位向每张餐桌连一条边权为1的边,表示同一餐桌不得有相同单位的人. ...

  4. 【BZOJ1434】[ZJOI2009]染色游戏(博弈论)

    [BZOJ1434][ZJOI2009]染色游戏(博弈论) 题面 BZOJ 洛谷 题解 翻硬币的游戏我似乎原来在博客里面提到过,对于这类问题,当前局面的\(SG\)函数就是所有反面朝上的硬币单一存在时 ...

  5. 【BZOJ5138】[Usaco2017 Dec]Push a Box(强连通分量)

    [BZOJ5138][Usaco2017 Dec]Push a Box(强连通分量) 题面 BZOJ 洛谷 题解 这题是今天看到萝卜在做然后他一眼秒了,我太菜了不会做,所以就来做做. 首先看完题目,是 ...

  6. 【JLOI 2012】时间流逝(期望,树上高斯消元)

    题目链接 这是一道传统的期望题,可是有一些套路值得我去掌握. 我们用$s$来表示一种状态,就是当前拥有的能量圈,是一个正整数拆分的形式. 用$f_{s}$表示如果遇到果冻鱼后丢掉了最小的能量圈后的状态 ...

  7. [整理]Error: [ngRepeat:dupes]的解决方法

    sdfsadf <div class="pageNum middle PT10"> <a href="javascript:void(0);" ...

  8. 用python处理文本,本地文件系统以及使用数据库的知识基础

    主要是想通过python之流的脚本语言来进行文件系统的遍历,处理文本以及使用简易数据库的操作. 本文基于陈皓的:<程序员技术练级攻略> 一.Python csv 对于电子表格和数据库导出文 ...

  9. 仿QQ聊天图文混排流程图【适用于XMPP】

      图文混排流程图.graffle4.8 KB   下面附上图片素材: 表情.zip692.5 KB     下面是字符串与图片的详细对应关系:                 "[呲牙]& ...

  10. Linux - 用户操作

    常用命令 users # 显示所有的登录用户 groups # 列出当前用户和他所属的组 who -q # 显示所有的登录用户 groupadd # 添加组 useradd user # 建立用户 p ...