mysql和java获取经纬度的距离的两种方式

mysql和java获取经纬度的距离的两种方式

T713802819052   取车距离:40333   还车距离:15303      根据订单号vlookup关联一下,单位是 米

1.java与mysql的计算公式是一一对应的:

Haversine公式 标准公式:这是传统计算方法,兼容所有MySQL版本

SELECT ROUND(6378.138 * 2 * ASIN(
           SQRT(
               POW(SIN((目标纬度 * PI()/180 - latitude * PI()/180)/2), 2) +
               COS(目标纬度 * PI()/180) * COS(latitude * PI()/180) *
               POW(SIN((目标经度 * PI()/180 - longitude * PI()/180)/2), 2)
           )
       ) * 1000) AS distance

DEMO

SELECT ROUND(6378.137 * 2 * ASIN(
           SQRT(
               POW(SIN((39.852546 * PI()/180 - 39.755703 * PI()/180)/2), 2) +
               COS(39.852546 * PI()/180) * COS(39.755703 * PI()/180) *
               POW(SIN((116.45462 * PI()/180 - 116.142223 * PI()/180)/2), 2)
           )
       )) AS distance
计算结果:29

JAVA实现代码:

package com.example.core.mydemo.calc2;

import java.math.BigDecimal;

public class TestDistance {
    public static void main(String[] args) {
        String ss = String.valueOf(Math.round(calcDistance(116.142223,39.755703,116.45462,39.852546)));
        System.out.println(ss);
    }

    //计算方法
    /**
    * carLon            longitude    116.142223
    * carLat            latitude    39.755703
    * origionCarLon        目标经度    116.45462
    * originCarLat      目标纬度    39.852546
    **/
    public static double calcDistance(double carLon,double carLat,double origionCarLon,double originCarLat){
        return new BigDecimal(
                6378.137*2*Math.asin(Math.sqrt(Math.pow(Math.sin( (originCarLat*Math.PI/180-carLat*Math.PI/180)/2),2)
                        +Math.cos(originCarLat*Math.PI/180)*Math.cos(carLat*Math.PI/180)*
                        Math.pow(Math.sin( (origionCarLon*Math.PI/180-carLon*Math.PI/180)/2),2))))
                .doubleValue();
    }

}
计算结果:29

2.扩展其他的mysql函数
使用ST_DISTANCE_SPHERE函数 这是最推荐的方法,适用于MySQL 5.7及以上版本,直接返回以米为单位的距离

SELECT ST_DISTANCE_SPHERE(
           POINT(目标经度, 目标纬度),
           POINT(longitude, latitude)
       ) AS distance 

DEMO

       SELECT ST_DISTANCE_SPHERE(
           POINT(116.45462, 39.852546),
           POINT(116.142223, 39.755703)
       ) AS distance 
       
计算结果:28776.896048499308

使用ST_DISTANCE函数 适用于MySQL 5.6及以上版本,返回单位是度,需要转换为米

SELECT ST_DISTANCE(
           POINT(目标经度, 目标纬度),
           POINT(longitude, latitude)
       ) AS distance 

DEMO

SELECT ST_DISTANCE(
           POINT(116.45462, 39.852546),
           POINT(116.142223, 39.755703)
       ) AS distance 
       
计算结果:0.3270633765159325

度转米的基本公式‌:距离(米) = 度 × 111195
其中111195是地球平均半径6371000米乘以π再除以180得出的换算系数

DEMO

SELECT ST_DISTANCE(
           POINT(116.45462, 39.852546),
           POINT(116.142223, 39.755703)
       ) * 111195 AS distance 
       
计算结果:36367.81215168911       误差比较大

3.方法选择建议‌:
优先使用ST_DISTANCE_SPHERE函数,它计算最准确且性能最佳。对于旧版本MySQL,可选择Haversine公式或创建自定义函数来实现距离计算
精度差异‌:ST_DISTANCE_SPHERE采用球面计算,比平面转换更准确
对于新项目,强烈建议使用MySQL 5.7+的ST_DISTANCE_SPHERE函数,可避免单位转换带来的误差和复杂性

posted on 2025-10-30 18:09  oktokeep  阅读(17)  评论(1)    收藏  举报