Java converts the GeoHash to the corresponding longitude and latitude coordinate instance code

  • 2020-04-01 04:37:32
  • OfStack

This article introduces the JAVA implementation of GeoHash into the corresponding longitude and latitude coordinates of the detailed code, to share for your reference, the specific content is as follows


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; 
  
 private int hashLength = 8; //Longitude and latitude to the geohash length
 private int latLength = 20; //Latitude is converted to binary length
 private int lngLength = 20; //Longitude converted to binary length
  
 private double minLat;//The unit size of latitude per lattice
 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'}; 
 private static HashMap<Character, Integer> CHARSMAP; 
  
 static { 
  CHARSMAP = new HashMap<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; 
 } 
  
  
 private void setMinLatLng() { 
  minLat = LocationBean.MAXLAT - LocationBean.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; 
  } 
 } 
  
  
 public List<String> getGeoHashBase32For9() { 
  double leftLat = location.getLat() - minLat; 
  double rightLat = location.getLat() + minLat; 
  double upLng = location.getLng() - minLng; 
  double downLng = location.getLng() + minLng; 
  List<String> base32For9 = new ArrayList<String>(); 
  //Three on the left, top to bottom
  String leftUp = getGeoHashBase32(leftLat, upLng); 
  if (!(leftUp == null || "".equals(leftUp))) { 
   base32For9.add(leftUp); 
  } 
  String leftMid = getGeoHashBase32(leftLat, location.getLng()); 
  if (!(leftMid == null || "".equals(leftMid))) { 
   base32For9.add(leftMid); 
  } 
  String leftDown = getGeoHashBase32(leftLat, downLng); 
  if (!(leftDown == null || "".equals(leftDown))) { 
   base32For9.add(leftDown); 
  } 
  //The middle three from top to bottom
  String midUp = getGeoHashBase32(location.getLat(), upLng); 
  if (!(midUp == null || "".equals(midUp))) { 
   base32For9.add(midUp); 
  } 
  String midMid = getGeoHashBase32(location.getLat(), location.getLng()); 
  if (!(midMid == null || "".equals(midMid))) { 
   base32For9.add(midMid); 
  } 
  String midDown = getGeoHashBase32(location.getLat(), downLng); 
  if (!(midDown == null || "".equals(midDown))) { 
   base32For9.add(midDown); 
  } 
  //Three from the top to the bottom
  String rightUp = getGeoHashBase32(rightLat, upLng); 
  if (!(rightUp == null || "".equals(rightUp))) { 
   base32For9.add(rightUp); 
  } 
  String rightMid = getGeoHashBase32(rightLat, location.getLng()); 
  if (!(rightMid == null || "".equals(rightMid))) { 
   base32For9.add(rightMid); 
  } 
  String rightDown = getGeoHashBase32(rightLat, downLng); 
  if (!(rightDown == null || "".equals(rightDown))) { 
   base32For9.add(rightDown); 
  } 
  return base32For9; 
 } 
 
  
 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; 
 } 
  
  
 public String getGeoHashBase32() { 
  return getGeoHashBase32(location.getLat(), location.getLng()); 
 } 
  
  
 private String getGeoHashBase32(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]; 
   for (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(); 
 } 
  
  
 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]; 
 } 
  
  
 private String getBase32BinaryString(int i) { 
  if (i < 0 || i > 31) { 
   return null; 
  } 
  String str = Integer.toBinaryString(i + 32); 
  return str.substring(1); 
 } 
  
  
 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 (CHARSMAP.containsKey(c)) { 
    String cStr = getBase32BinaryString(CHARSMAP.get(c)); 
    if (cStr != null) { 
     sb.append(cStr); 
    } 
   } 
  } 
  return sb.toString(); 
 } 
  
  
 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); 
  double lngValue = getGeoHashMid(lng.toString(), LocationBean.MINLNG, LocationBean.MAXLNG); 
  LocationBean location = new LocationBean(latValue, lngValue); 
  location.setGeoHash(geoHash); 
  return location; 
 } 
  
  
 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); 
  } 
 } 
  
  
 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); 
 } 
  
  
 private boolean[] merge(boolean[] 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; 
 } 
  
  
 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); 
  String 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)); 
 } 
 
} 

The above is the detailed content of this article, I hope to help you.


Related articles: