расстояние между двумя точками земли, в GPS координатах стандарта WGS84

domino

Новичок
расстояние между двумя точками земли, в GPS координатах стандарта WGS84

PHP:
define('COORDINATES_FORMAT', 'WGS84');
define('MAJOR_AXIS', 6378137.0); //meters
define('MINOR_AXIS', 6356752.3142); //meters
define('MAJOR_AXIS_POW_2', pow(MAJOR_AXIS, 2)); //meters
define('MINOR_AXIS_POW_2', pow(MINOR_AXIS, 2)); //meters

/*
$gps_1['lat'] - latitude (широта)
$gps_1['lon'] - longitude (долгота)
$gps_1['point_elevation'] (высота точки) // == 0 if this is sea. but must be defined!

*/

//get arrays with gps coordinates, returns earth terrestrial distance between 2 points
function get_distance_between_2_points($gps_1, $gps_2, $decart=false)
{
	if(!$decart)
	{
		$true_angle_1 = get_true_angle($gps_1);
		$true_angle_2 = get_true_angle($gps_2);
		
		$point_radius_1 = get_point_radius($gps_1, $true_angle_1);
		$point_radius_2 = get_point_radius($gps_2, $true_angle_2);
		
		$earth_point_1_x = $point_radius_1 * cos(deg2rad($true_angle_1));
		$earth_point_1_y = $point_radius_1 * sin(deg2rad($true_angle_1));
		
		$earth_point_2_x = $point_radius_2 * cos(deg2rad($true_angle_2));
		$earth_point_2_y = $point_radius_2 * sin(deg2rad($true_angle_2));
		
		$x = get_distance_between_2_points(array('lat'=>$earth_point_1_x, 'lon'=>$earth_point_1_y), array('lat'=>$earth_point_2_x, 'lon'=>$earth_point_2_y), true);
		$y = pi() *  (  ($earth_point_1_x + $earth_point_2_x) / 360 ) * ( $gps_1['lon'] - $gps_2['lon'] );

		return sqrt( pow($x,2) + pow($y,2) );
	}
	else
	{
		return sqrt(pow(($gps_1['lat'] - $gps_2['lat']), 2) + pow(($gps_1['lon'] - $gps_2['lon']), 2));
	}
}

//returns degree's decimal measure, getting degree, minute and second
function get_decimal_degree($deg=0, $min=0, $sec=0)
{
	return ($deg<0) ? (-1*(abs($deg) + (abs($min)/60) + (abs($sec)/3600))) : (abs($deg) + (abs($min)/60) + (abs($sec)/3600));
}

// get point, returns true angle
function get_true_angle($gps)
{
	return atan(	(  (MINOR_AXIS_POW_2 / MAJOR_AXIS_POW_2) * tan(deg2rad( $gps['lat']))    )  ) * 180/pi(); 
}

//get point and true angle, returns radius of small circle (radius between meridians) 
function get_point_radius($gps, $true_angle)
{
	return (1 / sqrt((pow(cos(deg2rad($true_angle)), 2) / MAJOR_AXIS_POW_2) + (pow(sin(deg2rad($true_angle)), 2) / MINOR_AXIS_POW_2))) + $gps['point_elevation']; 
}



function check_lat($lat)
{
	if($lat>=0 && $lat<=90)
	{
		return 'north';
	}
	else
	if($lat>=-90 && $lat<=0)
	{
		return 'south';
	}

	return false;
}

function check_lon($lon)
{
	if($lon>=0 && $lon<=180)
	{
		return 'east';
	}
	else
	if($lon>=-180 && $lon<=0)
	{
		return 'west';
	}

	return false;

}
 
  • Like
Реакции: AmdY

domino

Новичок
что и? берите пользуйтесь кому надо. это не от фонаря. это из реальной морской навигационной задачи для PHP (слежение за кораблями с GPS и гуглмапс). если у кого-то есть желание считать всю математику с нуля - ради бога.
 

leadaxe

Новичок
Огромная благодарность. Проверил все четко работает. Сильно помогло и сэкономило время
 

dr-sm

Новичок
с помощью гуглмапс нельзя следить за коробляме если что.
это нарушение лицензионного соглашения.

omg wtf warez!!! :D
 
  • Like
Реакции: craz

dr-sm

Новичок
хотят денег, причем много очень (
10.9 use the Service or Content with any products, systems, or applications for or in connection with:
(a) real time navigation or route guidance, including but not limited to turn-by-turn route guidance that is synchronized to the position of a user's sensor-enabled device;
(b) any systems or functions for automatic or autonomous control of vehicle behavior; or
(c) dispatch, fleet management, business asset tracking, or similar enterprise applications (the Google Maps APIs can be used to track assets (such as cars, buses or other vehicles) as long as the tracking application is made available to the public without charge. For example, you may offer a free, public Maps API Implementation that displays real-time public transit or other transportation status information. If your Maps API Implementation is deployed internally or you are charging for use of your Maps API Implementation, please contact the Google Maps API Premier sales team for more information);
 

domino

Новичок
хотят денег, причем много очень (
и что? задача не противоречит лицензии п. 10.9 С. а под пункты A и B не подпадает. и вообще, проект работает уже 3 года и приносит столько бабла, что клиенту хватит оплатить любую лицензию. да и гонорары давно пропиты, так что нечего тут грабить мои корованы.

и, самое главное, стартпост никаким макаром не затрагивает гугл.
 

dr-sm

Новичок
да это шутка была, по мотивам разразившейся недавно в очередной раз "трагедии CURL".


кстати как твой алгоритм ведет себя на коротких дистанциях?
загнал вот реальный трек 10к точек, получилось:
Код:
Distance One: 346154.59991846
Distance Two: 347226.91607613
Delta: 1072.3161576724
первое - обычный haversine.
интересно, что точнее.
 

vanicx

Новичок
алгоритм считает кратчайшее расстояние, не по поверхности земли, а сквозь землю. Еще и с ошибками при переходе через нулевой меридиан :-(
 
Последнее редактирование:

vanicx

Новичок
спасибо!
чет даже не пробовал библиотеки искать, искал формулы :-(
 

fixxxer

К.О.
Партнер клуба
Как ты сюда попал, если искал формулы? :)

А вообще говоря, искать информацию, не специфичную для русскоговорящих, на русском языке - это вообще очень вредная привычка. ;)

По запросу "geographic distance formula" всё находится моментально.
 

domino

Новичок
Этому посту скоро 10 лет будет, зачем вообще его поднимать?

В 2017-м году на packagist есть всё. Вот за 5 секунд нашел https://packagist.org/packages/mjaschen/phpgeo
а земле 3млрд лет. и все еще крутится.

а по факту, в то время не было этих расчудесных библиотек. сами брали и считали. да и интересно было.
 

vanicx

Новичок
для тех кто найдет эту тему:
выше указанный алгоритм показывает странные результаты по меридиану
проверьте
$gps_1 = array('lat'=>-90, 'lon'=>0, 'point_elevation' => 0); $gps_2 = array('lat'=>90, 'lon'=>0, 'point_elevation' => 0);
result 12713 км
ответ вроде как должен быть порядка 20000 км
на малых "меж широтных" расстояниях результаты похожи на реальные, но стоит разойтись по широтам ошибка заметно увеличивается
P.S. если не прав прошу автора указать где, буду благодарен.
P.P.S. если в главную функцию первой строкой вставить
if ((($gps_1['lon']>0)&($gps_2['lon']<0)) || (($gps_1['lon']<0)&($gps_2['lon']>0))) { $gps_2['lon'] = (360-abs($gps_2['lon']))*($gps_1['lon']/abs($gps_1['lon'])); }
то будет показывать кратчайшее расстояние от точки до точки, иначе расстояние от 175 до -175 (как и от -175 до 175) , будет идти по большому кругу (350 градусов, а не как например мне бы хотелось 10)
 

craz

Нестандартное звание
я-то я-то зачем на это подписывался...
 
Сверху