Расчетная площадь, заключенная в полигон на поверхности Земли

Скажем, у меня есть произвольный набор пар широты и долготы, представляющих точки на некоторой простой замкнутой кривой. В декартовом пространстве я мог легко вычислить площадь, заключенную такой кривой, используя теорему Грина. Каков аналогичный подход к вычислению площади на поверхности сферы? Я предполагаю, что я за то, что (хотя бы некоторое приближение) алгоритм функция Matlab areaint.

Ответ 1

Есть несколько способов сделать это.

1) Включить вклады от широтных полос. Здесь площадь каждой полосы будет (Rcos (A) (B1-B0)) (RdA), где A - широта, B1 и B0 - начальная и конечная долготы, а все углы находятся в радианах.

2) Разбейте поверхность на сферические треугольники и вычислите площадь с использованием теоремы Жирара и добавьте их вверх.

3) Как предложено здесь Джеймсом Шеком, в работе ГИС они используют проекцию, сохраняющую область, на плоское пространство и вычисляют площадь там.

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

Изменить - сравнение этих двух методов:

При первом осмотре может показаться, что сферический треугольный подход является самым легким, но, в общем, это не так. Проблема в том, что нужно не только разбивать область на треугольники, но и на сферические треугольники, т.е. Треугольники, стороны которых являются большими дугами окружности. Например, широтные границы не квалифицируются, поэтому эти границы необходимо разбить на края, которые лучше приближают большие дуги окружности. И это становится труднее делать для произвольных ребер, где большие круги требуют определенных комбинаций сферических углов. Рассмотрим, например, как разбить среднюю полосу вокруг сферы, скажем, всю область между лат 0 и 45deg в сферические треугольники.

В конце концов, если нужно сделать это правильно с похожими ошибками для каждого метода, метод 2 даст меньше треугольников, но их будет сложнее определить. Метод 1 дает больше полос, но их тривиально определить. Поэтому я предлагаю метод 1 как лучший подход.

Ответ 2

Я переписал функцию "isaint" MATLAB в java, которая имеет точно такой же результат. "isaint" вычисляет "suface на единицу", поэтому я умножил ответ на Земную поверхность (5.10072e14 кв. м).

private double area(ArrayList<Double> lats,ArrayList<Double> lons)
{       
    double sum=0;
    double prevcolat=0;
    double prevaz=0;
    double colat0=0;
    double az0=0;
    for (int i=0;i<lats.size();i++)
    {
        double colat=2*Math.atan2(Math.sqrt(Math.pow(Math.sin(lats.get(i)*Math.PI/180/2), 2)+ Math.cos(lats.get(i)*Math.PI/180)*Math.pow(Math.sin(lons.get(i)*Math.PI/180/2), 2)),Math.sqrt(1-  Math.pow(Math.sin(lats.get(i)*Math.PI/180/2), 2)- Math.cos(lats.get(i)*Math.PI/180)*Math.pow(Math.sin(lons.get(i)*Math.PI/180/2), 2)));
        double az=0;
        if (lats.get(i)>=90)
        {
            az=0;
        }
        else if (lats.get(i)<=-90)
        {
            az=Math.PI;
        }
        else
        {
            az=Math.atan2(Math.cos(lats.get(i)*Math.PI/180) * Math.sin(lons.get(i)*Math.PI/180),Math.sin(lats.get(i)*Math.PI/180))% (2*Math.PI);
        }
        if(i==0)
        {
             colat0=colat;
             az0=az;
        }           
        if(i>0 && i<lats.size())
        {
            sum=sum+(1-Math.cos(prevcolat  + (colat-prevcolat)/2))*Math.PI*((Math.abs(az-prevaz)/Math.PI)-2*Math.ceil(((Math.abs(az-prevaz)/Math.PI)-1)/2))* Math.signum(az-prevaz);
        }
        prevcolat=colat;
        prevaz=az;
    }
    sum=sum+(1-Math.cos(prevcolat  + (colat0-prevcolat)/2))*(az0-prevaz);
    return 5.10072E14* Math.min(Math.abs(sum)/4/Math.PI,1-Math.abs(sum)/4/Math.PI);
}

Ответ 3

Вы упоминаете "географию" в одном из своих тегов, поэтому я могу только предположить, что вы находитесь за областью многоугольника на поверхности геоида. Обычно это делается с использованием проецируемой системы координат, а не географической системы координат (т.е. Lon/lat). Если бы вы сделали это в lon/lat, я бы предположил, что возвращаемая единица измерения будет составлять процент от поверхности сферы.

Если вы хотите сделать это с помощью более "ГИС", вам нужно выбрать единицу измерения для своей области и найти соответствующую проекцию, которая сохраняет область (не все). Поскольку вы говорите о вычислении произвольного многоугольника, я бы использовал что-то вроде проекция Lambert Azimuthal Equal Area. Задайте начало/центр проекции как центр вашего многоугольника, проецируйте многоугольник в новую систему координат, затем вычислите область с помощью стандартных планарных методов.

Если вам нужно сделать много полигонов в географической области, вероятны другие прогнозы, которые будут работать (или будут достаточно близки). Например, UTM является отличным приближением, если все ваши многоугольники группируются вокруг одного меридиана.

Я не уверен, что какое-либо из этого имеет какое-либо отношение к тому, как работает функция Matlab.

Ответ 4

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

R^2 * ( A + B + C - \pi)

где R - радиус сферы, а A, B, а C - внутренние углы треугольника (в радианах). Величина в скобках известна как "сферический избыток".

Ваш n -сторонний многоугольник будет разбит на треугольники n-2. Суммируя по всем треугольникам, извлекая общий коэффициент R^2 и объединяя все \pi, область вашего многоугольника

R^2 * ( S - (n-2)\pi )

где S - это угловая сумма вашего многоугольника. Количество в круглых скобках снова является сферическим избытком многоугольника.

[edit] Это верно, является ли многоугольник выпуклым. Все, что имеет значение, состоит в том, что оно может быть разбито на треугольники.

Вы можете определить углы из бит векторной математики. Предположим, что у вас есть три вершины A, B, C и интересуются углом at B. Поэтому мы должны найти два касательных вектора (их величины не имеют значения) к сфере из точки B вдоль больших круговых отрезков (краев многоугольника). Пусть это работает для BA. Большой круг лежит в плоскости, определяемой OA и OB, где O - центр сферы, поэтому он должен быть перпендикулярен нормальному вектору OA x OB. Он также должен быть перпендикулярен к OB, так как он касателен. Поэтому такой вектор задается выражением OB x (OA x OB). Вы можете использовать правильное правило, чтобы убедиться, что оно находится в соответствующем направлении. Обратите также внимание на то, что это упрощается до OA * (OB.OB) - OB * (OB.OA) = OA * |OB| - OB * (OB.OA).

Затем вы можете использовать хороший оловянный продукт, чтобы найти угол между сторонами: BA'.BC' = |BA'|*|BC'|*cos(B), где BA' и BC' - касательные векторы от B вдоль сторон до A и C.

[отредактировано ясно, что это касательные векторы, а не буквальные между точками]