經緯度相關計算公式

一、

1、計算兩點之間球面距離

matlab版

function [dist] = computeDistanceLatLon(lon1,lat1,lon2,lat2)
	pi = 3.14159265358979324;
	Rc = 6378137.0;
	Rj = 6356725.0;
	DEG2RAD = pi / 180.0;
	r_lat_1 = lat1 * DEG2RAD;
	r_lng_1 = lon1 * DEG2RAD;
	r_lat_2 = lat2 * DEG2RAD;
	r_lng_2 = lon2 * DEG2RAD;
	Ec = Rj + (Rc - Rj) * (90.0 - lat1) / 90.0;
	Ed = Ec * cos(r_lat_1);
	dx = (r_lng_2 - r_lng_1) * Ed;
	dy = (r_lat_2 - r_lat_1) * Ec;
	dist = sqrt(dx * dx + dy * dy);
end

pyhton 版

import math
def computeDistanceLatLon(lon1,lat1,lon2,lat2):
	pi = 3.14159265358979324
	Rc = 6378137.0
	Rj = 6356725.0
	DEG2RAD = pi / 180.0
	r_lat_1 = lat1 * DEG2RAD
	r_lng_1 = lon1 * DEG2RAD
	r_lat_2 = lat2 * DEG2RAD
	r_lng_2 = lon2 * DEG2RAD
	Ec = Rj + (Rc - Rj) * (90.0 - lat1) / 90.0
	Ed = Ec * math.cos(r_lat_1)
	dx = (r_lng_2 - r_lng_1) * Ed
	dy = (r_lat_2 - r_lat_1) * Ec
	return math.sqrt(dx * dx + dy * dy)

C++版

void calculate_dist_m(vector<double> &dist, double lon_a, double lat_a, double lon_b, double lat_b) {
        if ((int)dist.size() != 3) {
            dist.resize(3);
        }

        double lng1, lat1, lng2, lat2;
        lng1 = lon_a;
        lng2 = lon_b;
        lat1 = lat_a;
        lat2 = lat_b;
        const double Rc = 6378137.0;
        const double Rj = 6356725.0;
        const double DEG2RAD = M_PI / 180.0;

        double r_lat_1 = lat1 * DEG2RAD;
        double r_lng_1 = lng1 * DEG2RAD;
        double r_lat_2 = lat2 * DEG2RAD;
        double r_lng_2 = lng2 * DEG2RAD;

        double Ec = Rj + (Rc - Rj) * (90.0 - lat1) / 90.0;
        double Ed = Ec * cos(r_lat_1);
        dist[0] = ((r_lng_2 - r_lng_1) * Ed);
        dist[1] = ((r_lat_2 - r_lat_1) * Ec);

        dist[2] = sqrt(dist[0] * dist[0] + dist[1] * dist[1]);
    }

經驗公式版

dist = 111120*((lon1-lon2)^2+(lat1-lat2)^2)^0.5

二、

經緯度座標轉換

1、WGS84-GCJ02互轉

import math
# GCJ座標與WGS座標互轉
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626
a = 6378245.0
ee = 0.00669342162296594323
def out_of_china(lng, lat):
	return not (lng > 73.66 and lng < 135.05 and lat > 3.86 and lat < 53.55)

def _transformlng(lng, lat):
	ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
			0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
	ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
			math.sin(2.0 * lng * pi)) * 2.0 / 3.0
	ret += (20.0 * math.sin(lng * pi) + 40.0 *
			math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
	ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
			math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
	return ret

def _transformlat(lng, lat):
	ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
			0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
	ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
			math.sin(2.0 * lng * pi)) * 2.0 / 3.0
	ret += (20.0 * math.sin(lat * pi) + 40.0 *
			math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
	ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
			math.sin(lat * pi / 30.0)) * 2.0 / 3.0
	return ret

def wgs84_to_gcj02(lng, lat):

	if out_of_china(lng, lat):
		return [lng, lat]
	dlat = _transformlat(lng - 105.0, lat - 35.0)
	dlng = _transformlng(lng - 105.0, lat - 35.0)
	radlat = lat / 180.0 * pi
	magic = math.sin(radlat)
	magic = 1 - ee * magic * magic
	sqrtmagic = math.sqrt(magic)
	dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
	dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
	mglat = lat + dlat
	mglng = lng + dlng
	return [mglng, mglat]

def gcj02_to_wgs84(lng, lat):
	if out_of_china(lng, lat):
		return [lng, lat]
	dlat = _transformlat(lng - 105.0, lat - 35.0)
	dlng = _transformlng(lng - 105.0, lat - 35.0)
	radlat = lat / 180.0 * pi
	magic = math.sin(radlat)
	magic = 1 - ee * magic * magic
	sqrtmagic = math.sqrt(magic)
	dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
	dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
	mglat = lat + dlat
	mglng = lng + dlng
	return [lng * 2 - mglng, lat * 2 - mglat]

C 版:

int outOfChina(double lat, double lon)
    {
        if (lon < 72.004 || lon > 137.8347)
            return 1;
        if (lat < 0.8293 || lat > 55.8271)
            return 1;
        return 0;
    }
double transformLat(double x, double y)
    {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(x > 0 ? x:-x);
        ret += (20.0 * sin(6.0 * x * pi) + 20.0 *sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }

double transformLon(double x, double y)
    {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(x > 0 ? x:-x);
        ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0;
        return ret;
    }

 Location_t transformFromWGSToGCJ(Location_t wgLoc)
    {
        Location_t mgLoc;
        if (outOfChina(wgLoc.lat, wgLoc.lng))
        {
            mgLoc = wgLoc;
            return mgLoc;
        }
        double dLat = transformLat(wgLoc.lng - 105.0, wgLoc.lat - 35.0);
        double dLon = transformLon(wgLoc.lng - 105.0, wgLoc.lat - 35.0);
        double radLat = wgLoc.lat / 180.0 * pi;
        double magic = sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi);
        mgLoc.lat = wgLoc.lat + dLat;
        mgLoc.lng = wgLoc.lng + dLon;

        return mgLoc;
    }

 Location_t transformFromGCJToWGS(Location_t gcLoc)
    {
        Location_t wgLoc = gcLoc;
        Location_t currGcLoc, dLoc;
        while (1) {
            currGcLoc = transformFromWGSToGCJ(wgLoc);
            dLoc.lat = gcLoc.lat - currGcLoc.lat;
            dLoc.lng = gcLoc.lng - currGcLoc.lng;
            if (fabs(dLoc.lat) < 1e-7 && fabs(dLoc.lng) < 1e-7) {  
                return wgLoc;
            }
            wgLoc.lat += dLoc.lat;
            wgLoc.lng += dLoc.lng;
        }

        return wgLoc;
    }

2、WGS84與墨卡託座標系轉換

 

 

部分更復雜的計算可以參考:

https://www.cnblogs.com/yangms/p/9946399.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章