Откуда берется радиус Земли по умолчанию в ST_Distance_Sphere?


15

MySQL говорит в документах для ST_Distance_Sphere

В расчетах используется сферическая земля и настраиваемый радиус. Необязательный аргумент радиуса должен быть указан в метрах. Если опущен, радиус по умолчанию составляет 6 370 986 метров. Если аргумент radius присутствует, но не является положительным, возникает ER_WRONG_ARGUMENTSошибка.

PostGIS говорит в документах ST_Distance_Sphere, (хотя документы уже не точны )

Использует сферическую землю и радиус 6370986 метров.

Откуда они взяли по умолчанию 6 370 986 метров? В WGS84 говорится, что радиус большой оси составляет 6 378 137,0 м. PostGIS, который сейчас использует средний радиус, по существу использует 6371008.

Глядя на код

#define WGS84_MAJOR_AXIS 6378137.0
#define WGS84_INVERSE_FLATTENING 298.257223563
#define WGS84_MINOR_AXIS (WGS84_MAJOR_AXIS - WGS84_MAJOR_AXIS / WGS84_INVERSE_FLATTENING)
#define WGS84_RADIUS ((2.0 * WGS84_MAJOR_AXIS + WGS84_MINOR_AXIS ) / 3.0)

это значит

-- SELECT 6378137.0 - 6378137.0 / 298.257223563;
WGS84_MINOR_AXIS = 6356752.314245179498
-- SELECT ( 2.0 * 6378137.0 + ( 6378137.0 - 6378137.0 / 298.257223563) ) / 3.0;
WGS84_RADIUS = 6371008.771415059833

Более новые версии гораздо менее эффективны, более сложны и используют Pro4j, но, похоже, делают то же самое.

Тем не менее, откуда приходит 6370986?


1
Он представляет средний радиус Земли, который должен быть (2*minorAxis+majorAxis)/3 ... хотя это значение для WGS84 все еще на несколько метров больше (6 371 008,771)
JGH

да, это вопрос, почему расхождение.
Эван Кэрролл

2
Какой-то разработчик искал это в сети? Источник postgis может пролить свет на это
Ian Turton

2
@IanTurton Большинство ошибок можно свести к тому, что «какой-то разработчик что-то сделал, и источник может пролить свет на это». Я намеревался сделать работу, полагая, что это было бы то, что нужно, если бы никто не знал историю. Смотрите ответ ниже.
Эван Кэрролл

1
Возможно, была опечатка, и они имели в виду 6370996 ... это очень близко к автономному радиусу Кларка 1866 года.
Mkennedy

Ответы:


21

Хорошо, это весело ! Я отследил это. В старой копии lwgeom/lwgeom_spheroid.cPostGIS 1.0.0rc4 вы можете увидеть это,

/*
 * This algorithm was taken from the geo_distance function of the 
 * earthdistance package contributed by Bruno Wolff III.
 * It was altered to accept GEOMETRY objects and return results in
 * meters.
 */
PG_FUNCTION_INFO_V1(LWGEOM_distance_sphere);
Datum LWGEOM_distance_sphere(PG_FUNCTION_ARGS)
{
        const double EARTH_RADIUS = 6370986.884258304;

Переходя к документам earthdistance, вы найдете это:

Обратите внимание, что в отличие от кубовой части модуля, модули здесь жестко привязаны: изменение earth()функции не повлияет на результаты этого оператора.

И этот аппаратный номер: EARTH_RADIUSможно увидеть здесь

/* Earth's radius is in statute miles. */
static const double EARTH_RADIUS = 3958.747716;

Так что вы можете сделать это просто.

EARTH_RADIUS * MILES_TO_METERS = EARTH_RADIUS_IN_METERS
 3958.747716 * 1609.344        = 6370986.884258304

И у тебя есть 6370986.884258304. Конечно, просто обрежьте это и сохраните, longпотому что почему бы и нет.

Таким образом, в сущности, радиус в MySQL был взят из задания отложенного копирования из PostGIS, которое преобразовало радиус в милях в метры из непонятной константы из случайного 20-летнего модуля PostgreSQL .

earth_distanceэто модуль, предшествующий PostGIS Брюса Момджяна. Настоящим я провозглашаю 6370986 постоянную Бомджяна: хорошее приближение Земли в метрах, чтобы удовлетворить MySQL. Хотя, возможно, ненадолго.


2
Но откуда взялась эта очень точная цифра 3958.747716? Ближайший я могу найти 3958,74795, что число американских обзорных миль в 6371 километров, но это все еще оставляет около 37 см неучтенных ,,,
hmakholm осталось Моника

1
@HenningMakholm продолжай сражаться в хорошей борьбе, не знаю. ;)
Эван Кэрролл

2
Очень хорошая находка!
Пол Рэмси
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.