Find nearby Dot Geohash algorithm and implementation (Java version)

Source: Internet
Author: User
Tags bitset cos pow sin stmt

Reference Documentation:

Http://blog.csdn.net/wangxiafghj/article/details/9014363geohash Algorithm principle and realization method
Http://blog.charlee.li/geohash-intro/geohash: Using strings to search for nearby locations
http://blog.sina.com.cn/s/blog_7c05385f0101eofb.html Find nearby points--geohash scenario discussion
http://www.wubiao.info/372 Find nearby xxx spherical distance and Geohash scheme discussion
Http://en.wikipedia.org/wiki/Haversine_formula haversine Formula spherical distance formula
http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe Spherical Distance formula code implementation
Http://developer.baidu.com/map/jsdemo.htm#a6_1 Spherical distance formula verification
http://www.wubiao.info/470 Mysql or Mongodb lbs fast Implementation Solution


Geohash has the following features:

First, Geohash uses a string to represent the longitude and latitude two coordinates. In some cases, you can't apply an index on two columns at the same time (for example, a version prior to MySQL 4, a data layer for Google APP engine, etc.), using Geohash to apply an index on only one column.

Second, Geohash represents not a point, but a rectangular area. For example, the code WX4G0EC19, which represents a rectangular region. Users can publish address codes to show that they are located near Beihai Park without exposing their precise coordinates, which helps protect privacy.

Third, the prefix of the encoding can represent a larger area. For example, WX4G0EC1, whose prefix wx4g0e represents a larger range including encoded WX4G0EC1. This feature can be used to search nearby locations. You can query all nearby locations by first calculating geohash (for example, WX4G0EC1) based on the user's current coordinates and then querying by its prefix (SELECT * from places WHERE geohash like ' wx4g0e% ').

Geohash is much more efficient than using latitude and longitude directly.

Geohash algorithm Implementation (Java version)

Package com. Disttest;import Java.util.bitset;import Java.util.hashmap;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 '};        Final static hashmap<character, integer> lookup = new Hashmap<character, integer> ();                static {int i = 0;        for (char c:digits) lookup.put (c, i++);                } public double[] decode (String geohash) {StringBuilder buffer = new StringBuilder ();                        for (char C:geohash.tochararray ()) {int i = Lookup.get (c) + 32;                Buffer.append (Integer.tostring (i, 2). SUBSTRING (1));           } 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);                }//China geographical coordinates: East longitude 73 ° to longitude 135 °, latitude 4° to latitude 53°double lon = decode (Lonset, 70, 140);                               Double lat = decode (latset, 0, 60);                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;                 The public String encode (double lat, double lon) {BitSet latbits = getBits (lat, 0, 60);                BitSet lonbits = getBits (lon, 70, 140);                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 ');        } return Base32 (Long.parselong (Buffer.tostring (), 2)); } Private BitSet GetBits (double lat, double floor, double ceiling) {BitSet buffer = new BitSet (numb ITS);                        for (int i = 0; i < numbits; i++) {Double mid = (floor + ceiling)/2;                                if (Lat >= mid) {buffer.set (i);                        Floor = mid;                        } else {ceiling = mid;        }} return buffer;                public static 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)); }}


Spherical distance formula:

Package com. Disttest;public class test{private static final double Earth_radius = 6371000;//Equatorial radius (unit m)/** * converted to radians (RAD) * */private St Atic Double rad (double D) {return d * math.pi/180.0;} /** * Based on the algorithm in the GoogleMap to obtain the distance between the two latitude and longitude, the accuracy of the calculation is similar to the accuracy of the Google map, the difference between 0.2 meters below * @param lon1 1th accuracy * @param lat1 1th latitude * @param lon2 2nd The accuracy of * @param lat3 2nd latitude * @return The distance returned, Unit m * */public static double getdistance (double lon1,double lat1,double lon2, Dou   ble lat2) {Double radLat1 = rad (LAT1);   Double radLat2 = rad (LAT2);   Double A = RADLAT1-RADLAT2;   Double b = rad (Lon1)-Rad (Lon2); Double s = 2 * Math.asin (MATH.SQRT (Math.pow (Math.sin (A/2), 2) +math.cos (RADLAT1) *math.cos (RADLAT2) *math.pow (Math.sin (   B/2), 2));   s = S * earth_radius;   s = Math.Round (S * 10000)/10000; return s;}        public static void Main (String []args) {double lon1=109.0145193757;      Double lat1=34.236080797698;      Double lon2=108.9644583556;      Double lat2=34.286439088548;      Double Dist;          String GeoCode;  Dist=test.getdistance (Lon1, LAT1, Lon2, LAT2);                  System.out.println ("Two points apart:" + dist + "M");      Geohash Geohash = new Geohash ();      Geocode=geohash.encode (LAT1, Lon1);           System.out.println ("Current Position code:" + GeoCode);      Geocode=geohash.encode (LAT2, Lon2);   System.out.println ("Distance Location Code:" + GeoCode); }//wqj7j37sfu03h2xb2q97/* Forever meet supermarket 108.8345750017734.256981052624wqj6us6cmkj5bbfj6qdgs6q08ubhhuq7*/}


Sorting of nearby Dot distances

Package com.  Disttest; Import Java.sql.drivermanager;import java.sql.resultset;import java.sql.sqlexception;import java.sql.Connection;  Import java.sql.Statement;        public class Sqltest {public static void main (string[] args) throws Exception {Connection conn = null;        String SQL;                String url = "Jdbc:mysql://132.97.**.**/test?"         + "User=***&password=****&useunicode=true&characterencoding=utf8";            try {class.forname ("com.mysql.jdbc.Driver");//dynamic load MySQL driver//System.out.println ("Load MySQL driver successfully");            A connection represents a database connection conn = drivermanager.getconnection (URL);            Statement contains many methods, such as executeupdate can be inserted, update and delete Statement stmt = Conn.createstatement ();            sql = "SELECT * from retailersinfotable limit 1,10";        ResultSet rs = stmt.executequery (sql);//ExecuteQuery Returns a collection of results, otherwise null value double lon1=109.0145193757;            Double lat1=34.236080797698;System.out.println ("Current position:");    int i=0;            string[][] array = new STRING[10][3];            while (Rs.next ()) {//remove geographic coordinates from database double lon2=double.parsedouble (rs.getstring ("longitude"));                        Double lat2=double.parsedouble (rs.getstring ("Latitude"));            Generates GEOHASH encoding Geohash Geohash = new Geohash () according to geographic coordinates;                        String Geocode=geohash.encode (LAT2, Lon2). substring (0, 9);                     Calculates the distance between two points int dist= (int) test.getdistance (Lon1, LAT1, Lon2, LAT2);    Array[i][0]=string.valueof (i);    Array[i][1]=geocode;            Array[i][2]=integer.tostring (Dist);                    i++;                System.out.println (lon2+ "---" +lat2+ "---" +geocode+ "---" +dist); } array=sqltest.getorder (array);        Two-dimensional array sorting sqltest.showarray (array);        Print array} catch (SQLException e) {System.out.println ("MySQL operation Error");    E.printstacktrace ();        } finally {conn.close (); }/* * Two-dimensional array sorting, compare array[][2] values, return two-dimensional array * */public static string[][] GetOrder (string[][] array) {for (int j = 0; J < Array.Length;  J + +) {for (int bb = 0; bb < array.length-1; bb++) {string[] ss;int a1=integer.valueof (array[bb][2]);  Convert to type int a2=integer.valueof (array[bb+1][2]), if (A1&GT;A2) {ss = Array[bb];array[bb] = array[bb + 1];ARRAY[BB + 1] = SS;}}}    return array;  }/* Print array */public static void Showarray (string[][] array) {for (int. a=0;a<array.length;a++) {for (int      j=0;j<array[0].length;j++) System.out.print (array[a][j]+ "");      System.out.println (); }    }}









Find nearby Dot Geohash algorithm and implementation (Java version)

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.