Как ArcGIS вычисляет расстояние между двумя точками с неэквидистантной проекцией?

10

Это дополнительный вопрос к моему предыдущему: Можете ли вы предложить несколько хорошо написанных вводных текстов о проекциях системы координат?


Давайте предположим, что я работаю с картографической проекцией CH1903, которая, насколько я знаю, является конформной, но не эквидистантной. Смысл, углы (форма) были сохранены, но не области, расстояния или масштаб. (По крайней мере , они не были сохранены в точности ). Все идет нормально.

Мне интересно, какие вычисления выполняет ArcGIS, когда я хочу вычислить расстояние между двумя точками. В ArcObjects я мог бы использовать IProximityOperatorинтерфейс следующим образом:

IPoint a = ...,
       b = ...;

double distance = ((IProximityOperator)a).ReturnDistance(b);

Вопрос: Когда я работаю с системой отсчета, которая не точно сохраняет расстояния, что будет делать ArcGIS, когда я запросю у нее расстояние между двумя точками (как показано выше)?

  • Делает ли он просто некоторые пифагорейские вычисления (a 2 + b 2 = c 2 ), чтобы получить расстояние, а это означает, что возвращаемое расстояние будет настолько точным, насколько позволяет проекция?

  • Или он сделает что-то более сложное, например, некоторую форму повторного проецирования, чтобы получить более точное расстояние?

( Тот же вопрос, но в более общем плане: после того, как эти геометрии спроецированы, выполняет ли ArcGIS все вычисления просто в евклидовом пространстве или же проекция используемой карты все еще влияет на вычисления расстояний, углов, площадей и т. Д.?)

stakx
источник
2
Пожалуйста, создайте новый вопрос вместо изменения оригинала. В противном случае вы подрываете все механизмы на этом сайте: что означают рейтинги, когда два или более вопроса находятся в игре в одной ветке? Что бы значило пометить один ответ как правильный? И т.д.
whuber
1
@whuber: Хотя все, что было написано в этой теме, по-прежнему относится к теме WRT, в которой задан первоначальный вопрос, я согласен с тем, что сейчас действительно задаются два вопроса. Это слишком поздно, чтобы изменить это сейчас, но учту ваш совет в следующий раз.
stakx

Ответы:

10

Если вам нужен стабильный метод вычисления геодезических расстояний, я рекомендую оболочку Ричи Кармайкла для ESRI Projection Engine .

Обновление: я только что попробовал код Ричи с ArcGIS 10.0 на Vista64 и получил исключение после вызова LoadLibrary. Я рассмотрю это позже.

На данный момент, хотя, некоторые код в ответ на вопросы в комментариях к другому ответу.

Код сравнивает IProximityOperator для точек с пространственными привязками и без них. Затем он показывает, как использовать азимутальную равноудаленную проекцию (с первой точкой, являющейся точкой касания), чтобы найти расстояние большого круга.

private void Test()
{
    IPoint p1 = new PointClass();
    p1.PutCoords(-98.0, 28.0);

    IPoint p2 = new PointClass();
    p2.PutCoords(-78.0, 28.0);

    Debug.Print("Euclidian Distance {0}", EuclidianDistance(p1, p2));
    Debug.Print("Distance with no spatialref {0}", GetDistance(p1, p2));

    ISpatialReferenceFactory srf = new SpatialReferenceEnvironmentClass();
    IGeographicCoordinateSystem gcs =
    srf.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);

    p1.SpatialReference = gcs;
    p2.SpatialReference = gcs;

    Debug.Print("Distance with spatialref {0}", GetDistance(p1, p2));
    Debug.Print("Great Circle Distance {0}", GreatCircleDist(p1, p2));

}
private double GetDistance(IPoint p1, IPoint p2)
{
    return ((IProximityOperator)p1).ReturnDistance(p2);
}

private double EuclidianDistance(IPoint p1, IPoint p2)
{
    return Math.Sqrt(Math.Pow((p2.X - p1.X),2.0) + Math.Pow((p2.Y - p1.Y), 2.0));
}

private double GreatCircleDist(IPoint p1, IPoint p2)
{
    ISpatialReferenceFactory srf = new SpatialReferenceEnvironmentClass();
    IProjectedCoordinateSystem pcs =
    srf.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_WGS1984N_PoleAziEqui);
    pcs.set_CentralMeridian(true, p1.X);
    ((IProjectedCoordinateSystem2)pcs).LatitudeOfOrigin = p1.Y;
    p1.SpatialReference = pcs.GeographicCoordinateSystem;
    p1.Project(pcs);
    p2.SpatialReference = pcs.GeographicCoordinateSystem;
    p2.Project(pcs);
    return EuclidianDistance(p1, p2);
}

Вот вывод:

Euclidian Distance 20
Distance with no spatialref 20
Distance with spatialref 20
Great Circle Distance 1965015.61318737

Я думаю, что было бы интересно проверить это на dll движка проекции (pe.dll). Будет публиковать результаты, если я когда-нибудь получу код Ричи на работу.

Обновление: как только я изменил код Richies для компиляции для x86, я запустил его. Интересно ... большое расстояние по кругу, которое он мне дал, составляет 1960273,80162999 - значительное отличие от того, которое было получено из азимутального равноудаленного метода, описанного выше.

Кирк Куйкендалл
источник
Причина расхождения, вероятно, заключается в том, что отрезок (в PCS), соединяющий точки, не является проецированной геодезической, которая будет криволинейной при проецировании. Соответственно вы получаете меньшее значение, чем вы должны. Проверка этой теории проста: возьмите простую геодезическую (такую ​​как экватор) и сравните два вычисления расстояния между двумя широко разделенными точками на геодезической. Одним из них является прямой расчет, как в вашем коде; другая разбивает геодезическую на сегменты, напрямую вычисляет длины сегментов и складывает их. Последнее должно быть более точным.
whuber
9

В ArcGIS 10 обратите внимание на IGeometryServer2, который теперь имеет GetDistanceGeodesic (геодезическое расстояние между двумя геометриями), GetLengthsGeodesic (возвращает геодезическую длину каждой полилинии) и DensifyGeodesic (уплотняет полилинию путем построения точек вдоль геодезических линий, соединяющих вершины 4: : GeodesicDensify) методы.

Как упоминалось в других ответах, ArcGIS по-прежнему использует в основном плоские вычисления.

Мелита Кеннеди


Некоторые комментарии к другим ответам (пока недостаточно комментариев для непосредственного комментирования!).

Азимутальная эквидистантная проекция Эсри поддерживает эллипсоиды. Код GreatCircleDist создает PCS, который использует GCS на основе эллипсоида / сфероида, поэтому расстояния от центра / исходной точки будут геодезическими, а не большими расстояниями по окружности. Это также может быть упрощено. Нам известны проекционные координаты первой точки, потому что это центр проекции: 0,0. Таким образом, только 2-й пункт должен быть спроецирован. Затем можно использовать упрощенную функцию EuclidianDistance.

Я проверил результаты по геодезическим функциям pe.dll, и они совпали. Похоже, что приложение Ричи использует сферу, поэтому оно возвращает большие расстояния / координаты окружности в своем тестовом приложении. Вот почему результаты не совпадают. Я не узнал значения радиуса; Я думаю, что мне нужно поговорить с ним об этом!

mkennedy
источник
2
Мелита - Рад видеть тебя здесь!
Кирк Куйкендалл
1
Я согласен, добро пожаловать на борт!
Мэтт Вилки
8

Точность любого ответа о ArcGIS может быть изменена в любое время - насколько нам известно, новые процедуры будут включены в следующий пакет обновления без предупреждения или документации. При этом в программном обеспечении ESRI долгое время использовались евклидовы вычисления ( например , формула Пифагора для расстояний) всякий раз, когда используются проекционные координаты. Часто в расчетах, подобных тем, что вы иллюстрируете, программное обеспечение даже не имеет доступа к информации о проекции, так что еще можно сделать?

Ваш вопрос сам по себе предполагает, что расчеты евклидова расстояния для эквидистантной проекции верны. Нет ничего более далекого от правды. Для одноточечной эквидистантной проекции евклидово расстояние до базовой точки гарантированно равно геодезическому расстоянию; для двухточечной равноудаленной проекции евклидово расстояние до любой базовой точки гарантированно равно геодезическому расстоянию. В обмен на эти гарантии метрическое искажение между всеми остальными парами точек обычно значительно увеличивается по сравнению с другими проекциями, которые можно выбрать.

Whuber
источник
@whuber: Спасибо, что ответили . Что касается первого абзаца: я подумал, что ArcGIS может увидеть, что используется проекция карты CH1903 (которая использует эллипсоид Бесселя 1841), а затем спроецировать точки обратно на этот эллипсоид через датум, а затем выполнить расчеты расстояния для эллипсоида. Из вашего ответа я понимаю, что ArcGIS не будет делать все это и останется в евклидовом XY-пространстве для проведения вычислений. (Как насчет другого программного обеспечения ГИС?) - 2-й абзац: Вы, конечно, правы, спасибо за разъяснение этого пункта.
Stakx
Скрытый механизм репроекции возможен, только если точечные объекты поддерживают ссылки на проекцию. Я не верю, что они делают.
whuber
@whuber: Достаточно ли (для более точных расчетов) знать эллипсоид, используемый для проекции? AFAIK, ArcGIS хранит ссылку на используемую проекцию с каждым классом объектов (слой данных).
Stakx
1
На самом деле IPoint, который является производным от IGeometry, имеет SpatialReference в качестве свойства. help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/… Однако я не думаю, что ReturnDistance использует его. Возможно, стоит проверить, изменилось ли это.
Кирк Кайкендалл
1
@stakx Я обновил свой ответ, включив в него код, показывающий, что настройка пространственной привязки не влияет на ReturnDistance.
Кирк Кайкендалл