简述
GeoHash本质上是空间索引的一种方式,其基本原理是将地球理解为一个二维平面,将平面递归分解成更小的子块,每个子块在一定经纬度范围内拥有相同的编码。以GeoHash方式建立空间索引,可以提高对空间poi数据进行经纬度检索的效率。
代码
/**
* <pre>
* GeoHash的工具类。
* 可以支持返回geohash
* geohash长度 Lat位数 Lng位数 Lat误差 Lng误差 km误差
* 1 2 3 ±23 ±23 ±2500
* 2 5 5 ± 2.8 ±5.6 ±630
* 3 7 8 ± 0.70 ± 0.7 ±78
* 4 10 10 ± 0.087 ± 0.18 ±20
* 5 12 13 ± 0.022 ± 0.022 ±2.4
* 6 15 15 ± 0.0027 ± 0.0055 ±0.61
* 7 17 18 ±0.00068 ±0.00068 ±0.076
* 8 20 20 ±0.000086 ±0.000172 ±0.01911
* 9 22 23 ±0.000021 ±0.000021 ±0.00478
* 10 25 25 ±0.00000268 ±0.00000536 ±0.0005971
* 11 27 28 ±0.00000067 ±0.00000067 ±0.0001492
* 12 30 30 ±0.00000008 ±0.00000017 ±0.0000186
* @author Terry
*/
public class GeoHashUtils {
/**
* 用户哈希匹配
*/
public static final int HASH_LEN = 7;
/**
* 用于距离匹配
*/
public static final int POI_MATCH_LEN = 7;
/**
* 返回一个geohash数值。
*
* @param lat
* @param lng
* @return
*/
public static String getGeoHash(double lat, double lng, int hashLen) {
GeoHash hash = GeoHash.withCharacterPrecision(lat, lng, hashLen);
return hash.toBase32();
}
/**
* 返回一个geohash数值。
*
* @param lat
* @param lng
* @return
*/
public static String getGeoHash(double lat, double lng) {
GeoHash hash = GeoHash.withCharacterPrecision(lat, lng, HASH_LEN);
return hash.toBase32();
}
/**
* 返回附近的9个geohash数值。
*
* @param lat
* @param lng
* @return
*/
public static String[] getNearbyHash(double lat, double lng, int hashLen) {
String[] hashs = new String[9];
GeoHash hash = GeoHash.withCharacterPrecision(lat, lng, hashLen);
hashs[0] = hash.toBase32();
GeoHash[] ghs = hash.getAdjacent();
for (int i = 0; i < 8; i++) {
hashs[i + 1] = ghs[i].toBase32();
}
return hashs;
}
/**
* 返回附近的9个geohash数值。
*
* @param lat
* @param lng
* @return
*/
public static String[] getNearbyHash(double lat, double lng) {
return getNearbyHash(lat, lng, HASH_LEN);
}
/**
* 获得两点间距离。
*
* @param lat1
* @param lng1
* @param lat2
* @param lng2
* @return
*/
public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
return VincentyGeodesy.distanceInMeters(new WGS84Point(lat1, lng1), new WGS84Point(lat2, lng2));
}
}
pom.xml需要引入的包
<dependency>
<groupId>ch.hsr</groupId>
<artifactId>geohash</artifactId>
<version>1.3.0</version>
</dependency>
总结
本人是做酒店项目的,其中有个很烦人的问题,就是如果正确映射供应商到我们本身的酒店。如果人工处理,则需要耗费大量的人力资源;如果匹配错误,则会造成很大的损失。所以我设计了一套方案,通过计算分数来确定自动映射还是手工映射。以上代码是一部分,是为了获取距离N米之内的酒店,然后再根据getDistance
方法计算距离,根据距离计算分数。具体想了解GeoHash的同学可以自行谷歌,为啥要获取GeoHash附近九个点都有解释。
评论区