Java implementation transforms Geohash into corresponding latitude and longitude coordinates

Source: Internet
Author: User

Reprint Please specify source: http://blog.csdn.net/xiaojimanman/article/details/50568428

Http://www.llwjy.com/blogdetail/fc484929cff1efac413ec2524680c5d7.html

Personal Blog Station has been online, the website www.llwjy.com ~ welcome you to vomit Groove ~

-------------------------------------------------------------------------------------------------

In the blog Java Implementation of spatial index coding (Geohash) describes what is geohash and how to convert coordinates to Geohash, this blog is introduced, how to convert Geohash to the corresponding regional center point coordinates.


The correspondence between BASE32

In the last implementation, the correspondence relation between numerical value and Base32 is introduced, and the corresponding relation is saved by array. Now we need to find a data structure that can quickly find the base32 character and the value correspondence so we can use map to save the relationship.

private static final char[] CHARS = {' 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 '};p rivate static Hashmap<character, Integer> ; charsmap;static {charsmap = new hashmap<character, integer> (); for (int i = 0; i < chars.length; i++) {Charsmap.pu T (Chars[i], i);}}


Convert a value to a binary string

When we get the number corresponding to each character, we need to convert the number to a binary string, We can directly invoke the Integer.tobinarystring method to implement, because we want to ensure that after the conversion of the binary if 5 bits, for less than 16, we need to fill in the front 0, in order to achieve this function, we have the number of unity plus 32, after the conversion into a binary string, and then the first bit of 1 removed.

Private String getbase32binarystring (int i) {if (I < 0 | | i >) {return null;} String str = integer.tobinarystring (i + +); return str.substring (1);}

Converting Geohash to binary string

The previous step is to convert the value to a five-bit binary string, and below we describe how to convert the Geohash string to the corresponding binary string. By the correspondence between the BASE32 characters and the numbers described above, we can know the corresponding numbers of each character, and then convert the number to the corresponding five-bit binary string, and we then stitch together these strings to form a complete binary string.

private string Getgeohashbinarystring (string geohash) {if (Geohash = = NULL | | "". Equals (Geohash)) {return null;} StringBuffer sb = new StringBuffer (); for (int i = 0; i < geohash.length (); i++) {char c = geohash.charat (i); if (Charsma P.containskey (c)) {String cStr = getbase32binarystring (Charsmap.get (c)); if (cStr! = null) {sb.append (CSTR);}}} return sb.tostring ();}


splitting a Geohash binary string into a latitude and longitude binary string

In the last blog, it was introduced that the Geohash binary string is composed of a binary string of latitude and longitude, with an odd number of latitudes and even longitude , so we only need to take the Geohash string apart.

StringBuffer lat = new StringBuffer (); StringBuffer LNG = new StringBuffer (); for (int i = 0; i < geohashbinarystr.length (); i++) {if (i% 2! = 0) {lat.append ( Geohashbinarystr.charat (i));} else {lng.append (Geohashbinarystr.charat (i));}}


Convert latitude and longitude binary to the latitude and longitude corresponding to the midpoint

Last blog Introduction How to convert a latitude and longitude to the corresponding binary, is to see the latitude and longitude in the corresponding region, here we also do you, if the binary string first bit is 1, then the latitude and longitude in the large area, if 0, then in the small area, and then we split the area, Then you can determine whether the second bit of the binary string is 1 or 0, and so on, and finally returns the value of the midpoint in the last region.

Private double Getgeohashmid (String binarystr, Double min, double max) {if (Binarystr = = NULL | | binarystr.length () < 1 ) {return (min + max)/2.0;} if (Binarystr.charat (0) = = ' 1 ') {return Getgeohashmid (binarystr.substring (1), (min + max)/2.0, max);} else {return getge Ohashmid (binarystr.substring (1), Min, (min + max)/2.0);}}


test of running results


Full code

There are few changes to Distanceutil and Locationbean, and there is no way to introduce their source code here.

 /** * @Description: Geohash to achieve the conversion of latitude and longitude * * Package com.lulei.geo; Import Java.util.arraylist;import java.util.arrays;import Java.util.hashmap;import Java.util.list;import  Com.lulei.geo.bean.locationbean;import Com.lulei.util.JsonUtil; public class Geohash {private Locationbean location;/** * 1 2500km;2 630km;3 78km;4 30km * 5 2.4km; 6 610m; 7 76m; 8 19m * /private int hashlength = 8; Latitude converted to Geohash length private int latlength = 20; Latitude conversion to binary length private int lnglength = 20; The longitude is converted to a binary length private double minlat;//the unit size of the latitude per cell private double minlng;//the unit size of each longitude private static final char[] CHARS = {' 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 '};p rivate static Hashmap<character, integer> charsmap;static {charsmap = new HASHMAP&L T Character, integer> (); for (int i = 0; i < chars.length; i++) {charsmap.put (chars[i], i);}} Public Geohash (double lat, double LNG) {location = new LocationbeaN (lat, LNG); Setminlatlng ();} public int gethashlength () {return hashlength;} /** * @Author: Lulei * @Description: Sets the smallest unit of latitude and longitude */private void setminlatlng () {Minlat = Locationbean.maxlat-locationbea n.minlat;for (int i = 0; i < latlength; i++) {Minlat/= 2.0;} MINLNG = locationbean.maxlng-locationbean.minlng;for (int i = 0; i < lnglength; i++) {minlng/= 2.0;}}  /** * @return * @Author: Lulei * @Description: Nine */public list<string> Getgeohashbase32for9 () with coordinates and surrounding points {double Leftlat = Location.getlat ()-Minlat;double Rightlat = Location.getlat () + minlat;double uplng = Location.getLng ()-MinL Ng;double downlng = location.getlng () + minlng; list<string> Base32for9 = new arraylist<string> ();//left Top to bottom 3 String leftup = GetGeoHashBase32 (Leftlat, UPLNG); if (!) ( Leftup = = NULL | | ". Equals (Leftup))) {Base32for9.add (leftup);} String Leftmid = getGeoHashBase32 (Leftlat, LOCATION.GETLNG ()); Leftmid = = NULL | | ". Equals (Leftmid))) {Base32for9.add (leftmid);} String Leftdown= GetGeoHashBase32 (Leftlat, DOWNLNG); Leftdown = = NULL | | ". Equals (Leftdown))) {Base32for9.add (leftdown);} Middle from top to bottom 3 string midup = GetGeoHashBase32 (Location.getlat (), UPLNG); Midup = = NULL | | ". Equals (Midup))) {Base32for9.add (midup);} String Midmid = getGeoHashBase32 (Location.getlat (), LOCATION.GETLNG ()); Midmid = = NULL | | ". Equals (Midmid))) {Base32for9.add (midmid);} String Middown = getGeoHashBase32 (Location.getlat (), DOWNLNG); Middown = = NULL | | ". Equals (Middown))) {Base32for9.add (middown);} Right from top to bottom 3 string rightup = GetGeoHashBase32 (Rightlat, UPLNG); Rightup = = NULL | | ". Equals (Rightup))) {Base32for9.add (rightup);} String Rightmid = getGeoHashBase32 (Rightlat, LOCATION.GETLNG ()); Rightmid = = NULL | | ". Equals (Rightmid))) {Base32for9.add (rightmid);} String Rightdown = getGeoHashBase32 (Rightlat, DOWNLNG); Rightdown = = NULL | | ". Equals (Rightdown))) {Base32for9.add (rightdown);} return BASE32FOR9;} /** * @param length * @return * @Author: Lulei * @DesCription: Set the latitude and longitude conversion to Geohash length */public boolean sethashlength (int length) {if (length < 1) {return false;}  Hashlength = Length;latlength = (length * 5)/2;if (length% 2 = = 0) {lnglength = Latlength;} else {lnglength = Latlength + 1;} SETMINLATLNG (); return true;} /** * @return * @Author: Lulei * @Description: Get base32 string for latitude and longitude */public string getGeoHashBase32 () {return getGeoHashBase3 2 (Location.getlat (), LOCATION.GETLNG ());} /** * @param lat * @param LNG * @return * @Author: Lulei * @Description: Get base32 string of latitude and longitude */private string getGeoHashBase3 2 (double lat, double LNG) {boolean[] Bools = getgeobinary (lat, LNG), if (bools = = null) {return null;} StringBuffer sb = new StringBuffer (); for (int i = 0; i < bools.length; i = i + 5) {boolean[] base32 = new BOOLEAN[5];FO R (Int j = 0; J < 5; J + +) {Base32[j] = bools[i + j];} Char cha = Getbase32char (base32); if (' = = cha) {return null;} Sb.append (CHA);} return sb.tostring ();} /** * @param base32 * @return * @Author: Lulei * @Description: Turn five-bit binary intoBase32 */private Char Getbase32char (boolean[] base32) {if (Base32 = = NULL | | Base32.length! = 5) {return ';} int num = 0;for (boolean bool:base32) {num <<= 1;if (bool) {num + = 1;}} Return chars[num% chars.length];} /** * @param i * @return * @Author: Lulei * @Description: Convert a number to a binary string */private string getbase32binarystring (int i) {if (I < 0 | | i > 31) {return null;} String str = integer.tobinarystring (i + +); return str.substring (1);} /** * @param geohash * @return * @Author: Lulei * @Description: Convert geohash to binary string */private string getgeohashbinarystring (String Geohash) {if (Geohash = = NULL | | "". Equals (Geohash)) {return null;} StringBuffer sb = new StringBuffer (); for (int i = 0; i < geohash.length (); i++) {char c = geohash.charat (i); if (Charsma P.containskey (c)) {String cStr = getbase32binarystring (Charsmap.get (c)); if (cStr! = null) {sb.append (CSTR);}}} return sb.tostring ();} /** * @param geohash * @return * @Author: Lulei * @Description: return geohash corresponding coordinates */public locatioNbean getLocation (String geohash) {string geohashbinarystr = getgeohashbinarystring (Geohash); if (geohashbinarystr = = NULL) {return null;} StringBuffer lat = new StringBuffer (); StringBuffer LNG = new StringBuffer (); for (int i = 0; i < geohashbinarystr.length (); i++) {if (i% 2! = 0) {lat.append ( Geohashbinarystr.charat (i));} else {lng.append (Geohashbinarystr.charat (i));}} Double latvalue = Getgeohashmid (lat.tostring (), Locationbean.minlat, Locationbean.maxlat);d ouble lngValue = Getgeohashmid (Lng.tostring (), LOCATIONBEAN.MINLNG, LOCATIONBEAN.MAXLNG); Locationbean location = new Locationbean (Latvalue, Lngvalue); Location.setgeohash (Geohash); return location;} /** * @param binarystr * @param min * @param max * @return * @Author: Lulei * @Description: Returns the binary corresponding middle value */private double Getgeohashmid (String binarystr, Double min, double max) {if (Binarystr = = NULL | | binarystr.length () < 1) {return (min + max)/2.0;} if (Binarystr.charat (0) = = ' 1 ') {return Getgeohashmid (binarystr.substring (1), (MIn + max)/2.0, max);} else {return Getgeohashmid (binarystr.substring (1), Min, (min + max)/2.0);}} /** * @param lat * @param LNG * @return * @Author: Lulei * @Description: Gets the coordinates of the GEO binary string */private boolean[] Getgeobinary ( Double lat, double LNG) {boolean[] Latarray = Gethasharray (lat, Locationbean.minlat, Locationbean.maxlat, latlength); boolean[] Lngarray = Gethasharray (LNG, LOCATIONBEAN.MINLNG, LOCATIONBEAN.MAXLNG, lnglength); return merge (LatArray, Lngarray);} /** * @param latarray * @param lngarray * @return * @Author: Lulei * @Description: Merge latitude and longitude binary */private boolean[] Merge (boo Lean[] Latarray, boolean[] lngarray) {if (Latarray = = NULL | | lngarray = NULL) {return null;} Boolean[] result = new Boolean[lngarray.length + latarray.length]; Arrays.fill (result, false); for (int i = 0; i < lngarray.length; i++) {result[2 * i] = lngarray[i];} for (int i = 0; i < latarray.length; i++) {result[2 * i + 1] = Latarray[i];} return result;} /** * @param value * @param min * @param max * @return *@Author: Lulei * @Description: Converts a number to a Geohash binary string */private boolean[] Gethasharray (double value, double min, double max, int length) {if (Value < min | | value > MAX) {return null;} if (length < 1) {return null;} Boolean[] result = new Boolean[length];for (int i = 0; i < length; i++) {Double mid = (min + max)/2.0;if (Value > MID) {Result[i] = True;min = Mid,} else {Result[i] = False;max = mid;}} return result;} public static void Main (string[] args) {//TODO auto-generated method stub Geohash g = new Geohash (40.221227, 116.24875); S Tring Geohash = G.getgeohashbase32 (); System.out.println (Geohash); Locationbean bean = g.getlocation (Geohash); System.out.println (Jsonutil.parsejson (bean)); System.out.println (New Geohash (Bean.getlat (), BEAN.GETLNG ()). GETGEOHASHBASE32 ()); System.out.println (Distanceutil.getdistance (Bean.getlat (), BEAN.GETLNG (), Bean.getlat ()-G.minlat, BEAN.GETLNG ()- G.MINLNG));}}

-------------------------------------------------------------------------------------------------
Small welfare
-------------------------------------------------------------------------------------------------
Individual at the Geek College, "Lucene case development" course has been launched, welcome everyone to spit Groove ~

First lesson: Lucene Overview

Lesson Two: Introduction to Lucene common functions

Lesson Three: web crawler

Lesson Four: Database connection pooling

Lesson Five: Collection of novel websites

Lesson Six: The operation of the novel website database

The seventh lesson: the realization of the novel Web site's distributed crawler

Java implementation transforms Geohash into corresponding latitude and longitude coordinates

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.