侧边栏壁纸
博主头像
Terry

『LESSON 5』

  • 累计撰写 90 篇文章
  • 累计创建 21 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Java工具类之GeoHash生成器

Terry
2020-07-25 / 0 评论 / 0 点赞 / 454 阅读 / 2,739 字 / 正在检测是否收录...

简述

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附近九个点都有解释。

0

评论区