Calculate the distance between two points (java, mysql), and calculate the heat map density according to the point

Requirement: Encapsulate the point data into the heat map format required by mapbox and return it.
In the data format, it is necessary to calculate the density within the unit range of each point. The last idea is to calculate the distance between each point and other points, and take the number of points within the radius as the density.

Determine the idea:
1. Calculate the distance between two points according to the latitude and longitude, set the radius, and calculate the number of points whose distance is less than this radius.
2. Calculate the distance according to the latitude and longitude of two points.
3. Mysql st_distance() function

Calculate the distance between two points on the map

First look at the basic theory of the boss: https://www.cnblogs.com/ycsfwhh/archive/2010/12/20/1911232.html
Get the following calculation formula

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

1. Java code implementation
public final class DistanceUtils {
 
    /**
     * 地球半径,单位 km
     */
    private static final double EARTH_RADIUS = 6378.137;
 
    /**
     * 根据经纬度,计算两点间的距离
     *
     * @param longitude1 第一个点的经度
     * @param latitude1  第一个点的纬度
     * @param longitude2 第二个点的经度
     * @param latitude2  第二个点的纬度
     * @return 返回距离 单位千米
     */
    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 implementation
/*传入的参数为:纬度 40.0497810000 经度 116.3424590000 经度 ASC升序由近至远 DESC 降序 由远到近 */
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 () function

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

Finally, choose method 3 for heat map calculation

After the table is self-associated, it matches each point, #{dis} is the incoming radius

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;

Guess you like

Origin blog.csdn.net/qq_16253859/article/details/122288750