GeoHash代码实现–java

package com.sd.leo.geohash;import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;public class GeoHash {public static final double MINLAT = -90;public static final double MAXLAT = 90;public static final double MINLNG = -180;public static final double MAXLNG = 180;private static int numbits = 20; //经纬度单独编码长度private static double minLat;private static double minLng;private 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'};//定义编码映射关系final static HashMap<Character, Integer> lookup = new HashMap<Character, Integer>();//初始化编码映射内容static {int i = 0;for (char c : digits) {lookup.put(c, i++);}}public GeoHash() {setMinLatLng();}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');//添加纬度的编码}String code = base32(Long.parseLong(buffer.toString(), 2));//Log.i("okunu", "encode  lat = " + lat + "  lng = " + lon + "  code = " + code);return code;}//根据经纬度和范围,获取对应的二进制private BitSet getBits(double lat, double floor, double ceiling) {BitSet buffer = new BitSet(numbits);//指定初始大小为numbitsfor (int i = 0; i < numbits; i++) {double mid = (floor + ceiling) / 2;//求二分法中间值//大于中心值记为trueif (lat >= mid) {buffer.set(i);//将指定索引处的位设置为 true。floor = mid;  //区间设置为(mid,ceiling)} else {ceiling = mid;//区间设置为(floor,mid)}}return buffer;}//将经纬度合并后的二进制进行指定的32位编码private String base32(long i) {char[] buf = new char[65];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));//从charPos开始,到65 - charPos开始解译,也就是从最后赋值的}private void setMinLatLng() {//计算经纬度的最小单元,最小的区间的中心值minLat = MAXLAT - MINLAT;for (int i = 0; i < numbits; i++) {minLat /= 2.0;}minLng = MAXLNG - MINLNG;for (int i = 0; i < numbits; i++) {minLng /= 2.0;}}//对编码后的字符串解码public double[] decode(String geohash) {StringBuilder buffer = new StringBuilder();for (char c : geohash.toCharArray()) {int i = lookup.get(c) + 32;//32的二进制为:100000,要让每位十进制数转为二进制时,都满五位,所以+32buffer.append(Integer.toString(i, 2).substring(1));//去掉最高位,减32,还原数字}BitSet lonset = new BitSet();BitSet latset = new BitSet();//偶数位,经度,从0开始,每次后移两位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);}//奇数位,纬度,从1开始,每次后移两位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};}//根据二进制和范围解码private double decode(BitSet bs, double floor, double ceiling) {double mid = 0;for (int i = 0; i < bs.length(); i++) {//区间中心值mid = (floor + ceiling) / 2;if (bs.get(i)) {floor = mid;} else {ceiling = mid;}}return mid;}//查询该经纬度的geoHash以及该geoHash附近的8个geoHash点public ArrayList<String> getArroundGeoHash(double lat, double lon) {//Log.i("okunu", "getArroundGeoHash  lat = " + lat + "  lng = " + lon);ArrayList<String> list = new ArrayList<>();double uplat = lat + minLat;double downLat = lat - minLat;double leftlng = lon - minLng;double rightLng = lon + minLng;String leftUp = encode(uplat, leftlng);list.add(leftUp);String leftMid = encode(lat, leftlng);list.add(leftMid);String leftDown = encode(downLat, leftlng);list.add(leftDown);String midUp = encode(uplat, lon);list.add(midUp);String midMid = encode(lat, lon);list.add(midMid);String midDown = encode(downLat, lon);list.add(midDown);String rightUp = encode(uplat, rightLng);list.add(rightUp);String rightMid = encode(lat, rightLng);list.add(rightMid);String rightDown = encode(downLat, rightLng);list.add(rightDown);//Log.i("okunu", "getArroundGeoHash list = " + list.toString());return list;}public static void main(String[] args) throws Exception {GeoHash geohash = new GeoHash();String  geoHashCode= geohash.encode(40.222012, 116.248283);System.out.println(geoHashCode);ArrayList<String> arroundGeoHash = geohash.getArroundGeoHash(40.222012, 116.248283);System.out.println(arroundGeoHash);//对geoHash点解码double[] geo = geohash.decode(geoHashCode);//geo[0]为纬度,geo[1]为经度System.out.println(geo[0] + " " + geo[1]);}
}

GeoHash代码实现--java相关推荐

  1. 二叉树的建立和遍历程序代码(Java,C)

    C语言 考虑到c语言的scanf("%c",&c)是输入后一个字符一个字符的取出这一特性,我们选择用createBiTree()方法接受输入的参数,然后直接建立.运用递归的 ...

  2. 死锁是什么?死锁产生的条件?如何避免死锁?以及死锁的示例代码(Java代码)

    文章目录 一.什么是死锁? 二.产生死锁的条件? 三.产生死锁的示例代码(java) 四.如何避免死锁? 一.什么是死锁? 下面图片参考 JavaGuide中的内容: 死锁的概念: 死锁:指的是相互两 ...

  3. 从Java代码到Java堆理解和优化您的应用程序的内存使用

    从Java代码到Java堆理解和优化您的应用程序的内存使用 简介: 本文将为您提供 Java? 代码内存使用情况的深入见解,包括将 int 值置入一个Integer 对象的内存开销.对象委托的成本和不 ...

  4. 编程笔试(解析及代码实现):国内各大银行(招商银行/浦发银行等)在线笔试常见题目(猴子吃桃/字符串逆序输出/一段话输出字的个数/单词大小转换等)及其代码实现(Java/Python/C#等)之详细攻略

    编程笔试(解析及代码实现):国内各大银行(招商银行/浦发银行等)在线笔试常见题目(猴子吃桃/字符串逆序输出/一段话输出字的个数/单词大小转换等)及其代码实现(Java/Python/C#等)之详细攻略 ...

  5. java 151建议_编写高质量代码改善java程序的151个建议——导航开篇

    前言 系列文章: 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,惨不忍睹是吧.确实,人和代码一样都在成长,都在变好当中.有时候只是实现功能的编程,长 ...

  6. 对于原生代码使用Java线程的优缺点

    对于原生的代码使用Java线程与原生的线程相比有一下的优点: 它是很容易建立的. 在原生代码不需要任何改变 它不需要明确的附加到这虚拟机,Java线程已经是Java平台的一部分.原生代码和Java代码 ...

  7. 编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议1~5)...

                 The reasonable man adapts himself to the world; The unreasonable one persists in trying ...

  8. java class文件 代码_java_基础——用代码编译.java文件+加载class文件

    java_基础--用代码编译.java文件+加载class文件 java_基础--用代码编译.java文件+加载class文件 [简单编译的流程] package com.zjm.www.test; ...

  9. Android代码抄袭Java曝猛料 新证据出现

    Oracle最初告Android代码里侵犯了他们旗下Java知识产权的时候,大多数不明真相的围观群众都是站在Google这一边的,毕竟Oracle蛮横不讲理惯了嘛. 但是,这次我们还真是当了不明真相的 ...

最新文章

  1. 他智商167,超过爱因斯坦,花17年炸遍美国高校,却因一疏漏被捕
  2. Nginx前端设置反向代理,后端Apache如何获取访客的真实IP,结合PHP。
  3. vscode设置eslint检验无效_大整理!JavaScript开发者的27个神奇VSCode工具
  4. intel x540-at2 openstack 下桥接故障
  5. bzoj3507: [Cqoi2014]通配符匹配
  6. [USACO14JAN]记录奥林比克
  7. 透明度百分比换算十六进制
  8. jdk 中英对照 百度网盘_Hadoop部署一jdk与MySQL
  9. 练习答案-分支与循环-超市买苹果练习-猜数字小游戏
  10. form和ajax同时提交吗,form表单提交与ajax消息传递
  11. python获取随机大小写字母_python获取随机大小写字母
  12. 解决办法:对BZ2_bzDecompressInit/BZ2_bzDecompress/BZ2_bzDecompressEnd未定义的引用
  13. AUFN Carplay盒子固件级视频及图文教程!
  14. tomcat修改端口号
  15. 产生式系统实验(AI实验一)
  16. 前端cookie 放到请求头_ajax请求头cookie问题
  17. ps钢笔抠图的的引用说明
  18. win10计算机维护,Win10系统打开或关闭自动维护功能的方法
  19. Translatium 19.2.1 中文版 优秀的在线翻译工具
  20. 算法笔记之回溯法(一)——溯洄从之,道阻且长;溯游从之,宛在水中央。

热门文章

  1. 艺术画笔见乾坤—Matplotlib
  2. js怎么实现对html代码加密解密,JS实现Base64加密解密
  3. Oracle学习笔记:使用replace、regexp_replace实现字符替换、姓名脱敏
  4. android源码大全 IOS游戏源代码打包下载 小游戏|视频教程 微信小程序源码带后台全套|公众号平台
  5. 计算机毕业设计Java医院预约挂号系统(系统+源码+mysql数据库+Lw文档)
  6. JAVAFX控件——TableView数据的导入和插入(数据库)
  7. 我奋斗了18年不是为了和你壹起喝咖啡
  8. 新品爆款打造流程与操作步骤--电商人必看
  9. P2p网站建设解决方案
  10. Ruby on Rails的核心特性是什么?