计算两点间的距离(java、mysql),根据点计算热力图密度

计算两点间的距离(java、mysql),根据点计算热力图密度,第1张

计算两点间的距离(java、mysql),根据点计算热力图密度

1、根据经纬度计算两点的距离,设置半径,计算距离小于此半径的点数量
2、https://www.cnblogs.com/ycsfwhh/archive/2010/12/20/1911232.html 根据两点经纬度计算距离
3、mysql st_distance()函数
st_distance 计算的结果单位是度,需要乘111195(地球半径6371000*PI/180)是将值转化为米。

#坐标转化为小数显示 经纬度的转化:经纬度以度数表示,一般可直接以小数点表示,但亦可把度数的小数点分为角分(1角分等于六十分之一度),和秒(一秒等于六十分之一分)。
select ROUND((substring(longitude,1, INSTR(longitude, '°') - 1) + substring(longitude, INSTR(longitude, '°') + 1)/ 60),6) as a from hdyjs_fishing_ground_point

update hdyjs_fishing_ground_point
set longitude = ROUND((substring(longitude,1, INSTR(longitude, '°') - 1) + substring(longitude, INSTR(longitude, '°') + 1)/ 60),6)

update hdyjs_fishing_ground_point
set latitude = ROUND((substring(latitude,1, INSTR(latitude, '°') - 1) + substring(latitude, INSTR(latitude, '°') + 1)/ 60),6)

#计算两点间的数据
select a.`name`,b.`name`,(st_distance(point(a.longitude,a.latitude),point(b.longitude,b.latitude)) * 111195) as distance 
from hdyjs_fishing_ground_point a 
inner join hdyjs_fishing_ground_point b


需求:将点数据封装成mapbox需要的热力图格式返回。
数据格式中需要计算每个点单位范围内的密度,最后想到的思路是每个点都跟其他点计算距离,取半径范围内点的数量作为密度。

计算地图上两点间的距离

首先看一下大佬的基础理论:https://www.cnblogs.com/ycsfwhh/archive/2010/12/20/1911232.html
得到如下的计算公式

C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)cos(MLatB)
Distance = R
Arccos©*Pi/180

1、Java代码实现
public final class DistanceUtils {
 
    
    private static final double EARTH_RADIUS = 6378.137;
 
    
    public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        // 纬度
        double lat1 = Math.toRadians(latitude1);
        double lat2 = Math.toRadians(latitude2);
        // 经度
        double lng1 = Math.toRadians(longitude1);
        double lng2 = Math.toRadians(longitude2);
        // 纬度之差
        double a = lat1 - lat2;
        // 经度之差
        double b = lng1 - lng2;
        // 计算两点距离的公式
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
        // 弧长乘地球半径, 返回单位: 千米
        s =  s * EARTH_RADIUS;
        return s;
    }
 
    public static void main(String[] args) {
        double d = getDistance(116.308479, 39.983171, 116.353454, 39.996059);
        System.out.println(d);
    }
}
2、sql实现
SELECt
    *,
    ROUND(
        6378.138 * 2 * ASIN(
            SQRT(
                POW(
                    SIN(
                        (
                            40.0497810000 * PI() / 180 - lat * PI() / 180
                        ) / 2
                    ),
                    2
                ) + COS(40.0497810000 * PI() / 180) * COS(lat * PI() / 180) * POW(
                    SIN(
                        (
                            116.3424590000 * PI() / 180 - lon * PI() / 180
                        ) / 2
                    ),
                    2
                )
            )
        ) * 1000
    ) AS juli
FROM
    customer
ORDER BY
    juli ASC
3、mysql st_distance()函数

st_distance(point(a.longitude,a.latitude),point(b.longitude,b.latitude)) * 111195

最后选择方法3进行热力图计算

表自关联后与每个点匹配,#{dis}为传入半径

select name,mmsi,count(0) as count,lon,lat 
from (
  select a.`name`,a.mmsi,
  (st_distance(point(a.longitude,a.latitude),point(b.longitude,b.latitude)) * 111195) as distance,
  a.longitude as lon,a.latitude as lat
  from (select * from table where create_date = (select create_date from table GROUP BY create_date order by create_date desc limit 1)) a
  inner join (select * from table where create_date = (select create_date from table GROUP BY create_date order by create_date desc limit 1)) b
) c
where distance < #{dis}
group by mmsi;

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5695452.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存