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

  • Автор темы Автор темы domino
  • Дата начала Дата начала

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
что и? берите пользуйтесь кому надо. это не от фонаря. это из реальной морской навигационной задачи для PHP (слежение за кораблями с GPS и гуглмапс). если у кого-то есть желание считать всю математику с нуля - ради бога.
 
Огромная благодарность. Проверил все четко работает. Сильно помогло и сэкономило время
 
с помощью гуглмапс нельзя следить за коробляме если что.
это нарушение лицензионного соглашения.

omg wtf warez!!! :D
 
  • Like
Реакции: craz
хотят денег, причем много очень (
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);
 
хотят денег, причем много очень (
и что? задача не противоречит лицензии п. 10.9 С. а под пункты A и B не подпадает. и вообще, проект работает уже 3 года и приносит столько бабла, что клиенту хватит оплатить любую лицензию. да и гонорары давно пропиты, так что нечего тут грабить мои корованы.

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


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

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

По запросу "geographic distance formula" всё находится моментально.
 
Этому посту скоро 10 лет будет, зачем вообще его поднимать?

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

а земле 3млрд лет. и все еще крутится.

а по факту, в то время не было этих расчудесных библиотек. сами брали и считали. да и интересно было.
 
для тех кто найдет эту тему:
выше указанный алгоритм показывает странные результаты по меридиану
проверьте
$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)
 
Сверху