mysql已知坐标及距离获取坐标_获取距离某坐标附近一定范围内的点的两种方式...

获取距离某坐标附近一定范围内的点的两种方式

场景:数据库中有一些点坐标,需要查找出距离当前位置2千米范围内的坐标

方式1:根据两个经纬度计算距离,Oracle/MySql计算地表两点之间的距离:

Oracle:

创建获取弧度的函数:

CREATE OR REPLACe FUNCTION RAD(d number) RETURN NUMBER

is

PI number :=3.141592625;

begin

return d* PI/180.0;

end ;

创建根据两个坐标计算距离的函数

CREATE OR REPLACE FUNCTION GetDistance(LngBegin number,

LatBegin number,

LngEnd number,

LatEnd number) RETURN NUMBER is

earth_padius number := 6378.137;

radLat1 number := rad(LngBegin);

radLat2 number := rad(LngEnd);

a number := radLat1 - radLat2;

b number := rad(LatBegin) - rad(LatEnd);

s number := 0;

begin

s := 2 *

Asin(Sqrt(power(sin(a / 2), 2) +

cos(radLat1) * cos(radLat2) * power(sin(b / 2), 2)));

s := s * earth_padius;

s := Round(s * 10000)/10;

return s;

end;

查询距离

SELECT

GetDistance(#{lon},#{lat},SHOP_LON,SHOP_LAT) AS Mdistance

FROM Shop

MySql:

查询距离sql:

SELECt

ROUND( 6378.138 * 2 * ASIN( SQRT( POW( SIN(( #{lat} * PI() / 180 - SHOP_LAT * PI() / 180) / 2 ),

2 ) + COS(#{lat} * PI() / 180) * COS(SHOP_LAT * PI() / 180) * POW( SIN( ( #{lon} * PI() / 180 - SHOP_LON * PI() / 180 ) / 2 ),

2 ) ) ) * 1000 ) AS Mdistance

FROM Shop

当然,也可将计算方法封装为函数

拿到距离后根据条件取值,因为是sql查询,若数据量大时,效率是一个问题

方式2:根据经纬度和距离计算出矩形范围,取范围内的值:

提供工具类如下:

public class GeoUtil

{

private static double EARTH_RADIUS = 6378.137;

public static double[] getRectangle(double lng, double lat, long distance)

{

float delta = 111000;

if (lng != 0 && lat != 0)

{

double lng1 = lng - distance / Math.abs(Math.cos(Math.toRadians(lat)) * delta);

double lng2 = lng + distance / Math.abs(Math.cos(Math.toRadians(lat)) * delta);

double lat1 = lat - (distance / delta);

double lat2 = lat + (distance / delta);

return new double[] {lng1, lat1, lng2, lat2};

}

else

{

double lng1 = lng - distance / delta;

double lng2 = lng + distance / delta;

double lat1 = lat - (distance / delta);

double lat2 = lat + (distance / delta);

return new double[] {lng1, lat1, lng2, lat2};

}

}

public static double getDistanceOfMeter(double lat1, double lng1, double lat2, double lng2)

{

double radLat1 = rad(lat1);

double radLat2 = rad(lat2);

double a = radLat1 - radLat2;

double b = rad(lng1) - rad(lng2);

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) / 10;

return s;

}

private static double rad(double d)

{

return d * Math.PI / 180.0;

}

}

这种方式得到的是一个范围,查询时无需计算根据大小即可取出范围内的点,但是就没有具体的距离值了。在数据量大时效率较高。同时比较符合app的某些业务场景,例如每次展示手机屏幕范围内的点(手机是方的)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值