geohash java,GeoHash的简单使用例子

以前开发一个项目有这样一个需求,货主找附件的车,原来是通过使经纬度进行匹配的,

因为经纬度是2个字段,所以匹配起来性能比较低,有一个geohash算法可以将二维的经纬度匹配

转为一维的匹配,降低查询效率.详细了解请参见相关博文

背景

网上百度的geohash java版的代码发现计算并不准确

于是去maven库查询了一下发现有对应的jar包,而且写的比较详细。

对应pom文件

ch.hsr

geohash

1.0.10

简单使用例子import ch.hsr.geohash.GeoHash;

import com.lin.jedisFactory.JedisPoolUtil;

import redis.clients.jedis.Jedis;

import java.util.Set;

/**

* Created by Kevin on 2015/2/4.

*/

public class GeoHashTest {

public static void main(String[] args) {

/*假设货主的纬经度,南开区*/

double lat1 = 39.145609;

double lon1 = 117.154471;

/*假设司机1的纬经度,和平区*/

double lat2 = 39.122661;

double lon2 = 117.220299;

/*假设司机2的纬经度东丽*/

double lat3 = 39.093657;

double lon3 = 117.320047;

GeoHash geoHash1 = GeoHash.withCharacterPrecision(lat1,lon1,12);

GeoHash geoHash2 = GeoHash.withCharacterPrecision(lat2,lon2,12);

GeoHash geoHash3 = GeoHash.withCharacterPrecision(lat3,lon3,12);

System.out.println("南开区:"+geoHash1.toBase32());

System.out.println("和平区:"+geoHash2.toBase32());

System.out.println("东丽区:"+geoHash3.toBase32());

double distance1 = getDistance(lat1, lon1, lat2, lon2);

double distance2 = getDistance(lat1, lon1, lat3, lon3);

System.out.println("南开-和平 距离:" + distance1);

System.out.println("南开-东丽 距离:" + distance2);

String prefix = geoHash1.toBase32().substring(0,4);

System.out.println(prefix);

Jedis jedis = JedisPoolUtil.getJedis();

jedis.sadd(geoHash2.toBase32().substring(0,4), "siji1");

jedis.sadd(geoHash3.toBase32().substring(0,4), "siji2");

Set ret = jedis.smembers(prefix);

JedisPoolUtil.release(jedis);

System.out.println(ret);

}

/**

* @param lat1 起始地纬度

* @param lon1 起始地经度

* @param lat2 目的地纬度

* @param lon2 目的地经度

* @return

*/

public static double getDistance(double lat1, double lon1, double lat2, double lon2) {

if (Math.abs(lat1) > 90 || Math.abs(lon1) > 180

|| Math.abs(lat2) > 90 || Math.abs(lon2) > 180) {

throw new IllegalArgumentException("The supplied coordinates are out of range.");

}

int R = 6378137;

double latRad1 = Math.toRadians(lat1);

double lonRad1 = Math.toRadians(lon1);

double latRad2 = Math.toRadians(lat2);

double lonRad2 = Math.toRadians(lon2);

//结果

double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin((latRad1 - latRad2) / 2), 2)

+ Math.cos(latRad1) * Math.cos(latRad2) * Math.pow(Math.sin((lonRad1 - lonRad2) / 2), 2)))*R;

distance = Math.round(distance * 10000)/10000;

return Math.round(distance);

}

}

这里面给的GeoHash的构造方法时protected的,所以实例化不出来的,获取一个对象的方法对应的给了2种。

一个是withBitPrecision,里面的numberOfBits参数不好给,就是算出的那个二进制位数。

另一个是withCharacterPrecision,里面的numberOfCharacters就是给的字符串位数,最多12位,如果要取wwgqmsvc51ze对应的前四位,可以传值为4,我们用这个比较好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值