经纬度距离等相关计算的不同语言实现

因为最近在研究一款基于位置的附近应用,所以需要用到经纬度距离计算做排名因素。

1.根据经纬度、半径计算距离 最大最小经纬度

public class LatLonUtil {
	private static final double PI = 3.14159265; // 圆周率
	private static final double EARTH_RADIUS = 6378137;
	private static final double RAD = Math.PI / 180.0;

	// @see
	// The circumference of the earth is 24,901 miles.
	// 24,901/360 = 69.17 miles / degree
	/**
	 * @param raidus
	 *            单位:米 return minLat,minLng,maxLat,maxLng
	 */
	public static double[] getAround(double lat, double lon, int raidus) {

		Double latitude = lat;
		Double longitude = lon;

		Double degree = (24901 * 1609) / 360.0;
		double raidusMile = raidus;

		Double dpmLat = 1 / degree;
		Double radiusLat = dpmLat * raidusMile;
		Double minLat = latitude - radiusLat;
		Double maxLat = latitude + radiusLat;

		Double mpdLng = degree * Math.cos(latitude * (PI / 180));
		Double dpmLng = 1 / mpdLng;
		Double radiusLng = dpmLng * raidusMile;
		Double minLng = longitude - radiusLng;
		Double maxLng = longitude + radiusLng;
		// System.out.println("["+minLat+","+minLng+","+maxLat+","+maxLng+"]");
		return new double[] { minLat, minLng, maxLat, maxLng };
	}

	/**
	 * 根据两点间经纬度坐标(double值),计算两点间距离,单位为米
	 * @param lng1
	 * @param lat1
	 * @param lng2
	 * @param lat2
	 * @return
	 */
	public static double getDistance(double lng1, double lat1, double lng2,
			double lat2) {
		double radLat1 = lat1 * RAD;
		double radLat2 = lat2 * RAD;
		double a = radLat1 - radLat2;
		double b = (lng1 - lng2) * RAD;
		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) / 10000;
		return s;
	}

	public static void main(String[] args) {
		Double lat1 = 34.264648;
		Double lon1 = 108.952736;

		int radius = 1000;
		// [34.25566276027792,108.94186385411045,34.27363323972208,108.96360814588955]
		getAround(lat1, lon1, radius);

		// 911717.0 34.264648,108.952736,39.904549,116.407288
		double dis = getDistance(108.952736, 34.264648, 116.407288, 39.904549);
		System.out.println(dis);
	}

}

2.两个经纬度点之间的距离

PHP:

<?php 
  define('EARTH_RADIUS', 6378.137);//地球半径,假设地球是规则的球体
  define('PI', 3.1415926);
    /**
     *  计算两组经纬度坐标 之间的距离
     *   params :lat1 纬度1; lng1 经度1; lat2 纬度2; lng2 经度2; len_type (1:m or 2:km);
     *   return m or km
     */
    function GetDistance($lat1, $lng1, $lat2, $lng2, $len_type = 1, $decimal = 2)
    {
       $radLat1 = $lat1 * PI ()/ 180.0;   //PI()圆周率
       $radLat2 = $lat2 * PI() / 180.0;
       $a = $radLat1 - $radLat2;
       $b = ($lng1 * PI() / 180.0) - ($lng2 * PI() / 180.0);
       $s = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
       $s = $s * EARTH_RADIUS;
       $s = round($s * 1000);
       if ($len_type --> 1)
       {
           $s /= 1000;
       }
   return round($s, $decimal);
}
echo GetDistance(38.0822841,114.4774532,38.0882967,114.4776678, 1);//输出距离/米
 

?> 

Java:

	/**
	 * 计算地球上任意两点(经纬度)距离
	 * 
	 * @param long1
	 *            第一点经度
	 * @param lat1
	 *            第一点纬度
	 * @param long2
	 *            第二点经度
	 * @param lat2
	 *            第二点纬度
	 * @return 返回距离 单位:米
	 */
	public static double Distance(double long1, double lat1, double long2,
			double lat2) {
		double a, b, R;
		R = 6378137; // 地球半径
		lat1 = lat1 * Math.PI / 180.0;
		lat2 = lat2 * Math.PI / 180.0;
		a = lat1 - lat2;
		b = (long1 - long2) * Math.PI / 180.0;
		double d;
		double sa2, sb2;
		sa2 = Math.sin(a / 2.0);
		sb2 = Math.sin(b / 2.0);
		d = 2
				* R
				* Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1)
						* Math.cos(lat2) * sb2 * sb2));
		return d;
	}

Sql Server:

CREATE FUNCTION [f_GetDistance]
( 
@GPSLng DECIMAL(12,6),
@GPSLat DECIMAL(12,6),
@Lng  DECIMAL(12,6),
@Lat DECIMAL(12,6)
)
RETURNS DECIMAL(12,4)
AS
BEGIN
   DECLARE @result DECIMAL(12,4)
   SELECT @result = 6378137.0*ACOS(SIN(@GPSLat/180*PI())*SIN(@Lat/180*PI())+COS(@GPSLat/180*PI())*COS(@Lat/180*PI())*COS((@GPSLng-@Lng)/180*PI()))
   RETURN @result
END
GO


JS:

function toRad(d) {  return d * Math.PI / 180; }

function calculateDistance(lngSrc, latSrc, lngDst, latDst) {
    EARTH_RADIUS = 6378137;
    //alert(lngSrc+" "+latSrc+" "+lngDst+" "+latDst)

    radLngSrc = toRad(lngSrc);
    radLngDst = toRad(lngDst);
    lngDiff = radLngSrc - radLngDst;
    radLatSrc = toRad(latSrc);
    radLatDst = toRad(latDst);
    latDiff = radLatSrc - radLatDst;
    s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(latDiff/2), 2) +
            Math.cos(radLatSrc) * Math.cos(radLatDst) * Math.pow(Math.sin(lngDiff/2),2)));
    s = s * EARTH_RADIUS;
    return Math.round(s);
}

function getDistanceText(distance) {
	distanceText = "";

	if (distance <= 100)
    {
        //53 0.053km 53m <100m
		distanceText = "<100m";
    }
	else if (distance < 1000)
    {
        //532 0.532km 532m
		distanceText = distance + "m";
    }
	else if (distance < 10000) {
        //1532 1.532km
        distance = distance/1000;
        distanceText = distance.toString().substr(0, distance.toString().indexOf('\.')+2)+"km";
	} else if (distance < 100000)
    {
        //11532 11.532km
        distance = distance/1000;
        distanceText = distance.toString().substr(0, distance.toString().indexOf('\.')+2)+"km";
    }
	else {
        //111532 111.532km >100km
		distanceText = ">100km";
	}
    return distanceText;
}

3.地图工具

package utils;

import java.text.DecimalFormat;

/**
 * 地图工具
 * @author lwg 2015-11-05
 *
 */
public class MapUtil {
	
	/**
	 * 返回**.**KM
	 * @param lon1 第一点经度
	 * @param lat1 第一点纬度
	 * @param lon2 第二点经度
	 * @param lat2 第二点纬度
	 * @return
	 */
	public static String getStrDistance(String lon1, String lat1, String lon2, String lat2) {
		return getStrDistance(MapUtil.Distance(lon1, lat1, lon2, lat2));
	}
	
	/**
	 * 返回**.**KM
	 * @param distance 距离
	 * @return
	 */
	public static String getStrDistance(double distance)  {
		if(distance<100){
			return "0.01KM";
		}
		DecimalFormat df=new DecimalFormat("#.##");
		return df.format(distance/1000d)+"KM";
	}
	
	/**
	 * 计算地球上任意两点(经纬度)距离
	 * @param coordinate1 第一点(经度lng,纬度lat)
	 * @param coordinate2 第二点(经度lng,纬度lat)
	 * @return
	 */
	public static double Distance(String coordinate1, String coordinate2) {
		String log_lat1[] = coordinate1.split(",");
		String gg_lon1 = log_lat1[0];
		String gg_lat1 = log_lat1[1];
		
		String log_lat2[] = coordinate2.split(",");
		String gg_lon2 = log_lat2[0];
		String gg_lat2 = log_lat2[1];
		return Distance(gg_lon1, gg_lat1, gg_lon2, gg_lat2);
	}
	
	/**
	 * 计算地球上任意两点(经纬度)距离
	 * @param lng1 第一点经度
	 * @param lat1 第一点纬度
	 * @param lng2 第二点经度
	 * @param lat2 第二点纬度
	 * @return
	 */
	public static double Distance(String lon1, String lat1, String lon2, String lat2) {
		return Distance(Double.parseDouble(lon1), Double.parseDouble(lat1), Double.parseDouble(lon2), Double.parseDouble(lat2));
	}
	
	/**
	 * 计算地球上任意两点(经纬度)距离
	 * 
	 * @param long1 第一点经度
	 * @param lat1 第一点纬度
	 * @param long2 第二点经度
	 * @param lat2 第二点纬度
	 * @return 返回距离 单位:米
	 */
	public static double Distance(double long1, double lat1, double long2, double lat2) {
		double a, b, R;
		R = 6378137; // 地球半径
		lat1 = lat1 * Math.PI / 180.0;
		lat2 = lat2 * Math.PI / 180.0;
		a = lat1 - lat2;
		b = (long1 - long2) * Math.PI / 180.0;
		double d;
		double sa2, sb2;
		sa2 = Math.sin(a / 2.0);
		sb2 = Math.sin(b / 2.0);
		d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));
		return d;
	}
	
	public static void main(String[] args) {
		System.out.println("正确:"+Distance("121.41128,31.170049", "121.411693,31.169045"));
		System.out.println("错误:"+Distance("31.170049,121.41128", "31.169045,121.411693"));
		System.out.println(getStrDistance(987654321));
	}
}
有些是借鉴PHP和Java的实现,之前我曾经写过Java版的不知道放哪个站点上发布了,现在重新发布一个多语言版的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值