Более точный способ расчета площади растров

11

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

Джанлука Франческини
источник
@radouxju Похоже, вы предлагаете, чтобы руководство Bugayevskiy & Snyder, которое я цитирую, не было ни заслуживающим доверия, ни официальным. (Напротив, это и то и другое - особенно если учесть, что это стало результатом сотрудничества всемирно признанных властей в США и России!) Что является основой этого скептицизма? Что еще вы бы искали? Обратите внимание, что эти расчеты совершенно точны. Точность ограничена только точностью, с которой задаются эллипсоидальные параметры, и точностью ваших расчетов: более высокая точность невозможна.
whuber
@whuber Я не говорил, что твоя цитата не заслуживает доверия. Мой комментарий к награде был сделан ДО того, как вы ответили, и когда я последний раз заходил на сайт, было слишком рано присудить награду.
Radouxju
@radouxju Спасибо за ваше объяснение! Я не узнал о награде за несколько часов после того, как отправил ответ.
whuber

Ответы:

14

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

Формула упрощается, если разбить расчет на основные этапы.

Во-первых, расстояние между восточной и западной границами - меридианами l0 и l1 - является частью целого круга, равного q = (l1 - l0) / 360 (когда меридианы измеряются в градусах) или 1 = ( l1 - l0) / (2 * pi) (когда меридианы измеряются в радианах). Найдите площадь всего среза, расположенную между параллелями f0 и f1, и просто умножьте ее на q .

Во-вторых, мы будем использовать формулу для площади горизонтального среза эллипсоида, ограниченного экватором (при f0 = 0) и параллелью на широте f (= f1). Площадь среза между любыми двумя широтами f0 и f1 (лежащая в одном полушарии) будет разницей между большей и меньшей областью.

Наконец, при условии, что модель действительно является эллипсоидом (а не сферой), площадь такого среза между экватором и параллелью на широте f определяется как

area(f) = pi * b^2 * (log(zp/zm) / (2*e) + sin(f) / (zp*zm))

где aи b- длины большой и малой осей генерирующего эллипса соответственно,

e = sqrt(1 - (b/a)^2)

это его эксцентричность, и

zm = 1 - e*sin(f); zp = 1 + e*sin(f)

(Это намного проще, чем вычисление с геодезическими, которые в любом случае являются лишь приближением к параллелям. Обратите внимание на комментарий @cffk относительно способа вычисления log(zp/zm)таким образом, чтобы избежать потери точности в низких широтах.)

фигура

area(f) это площадь непрозрачного среза от экватора до широты f (около 30 градусов северной широты на рисунке. X и Y - геоцентрические декартовы координатные оси, показанные для справки.

Для эллипсоида WGS 84 используйте постоянные значения

a = 6 378 137 meters,  b =  6 356 752.3142 meters,

влекущие за собой

e = 0.08181919084296

(Для сферической модели с a = b формула становится неопределенной. Вы должны взять предел при e -> 0 сверху, который затем сводится к стандартной формуле 2 * pi * a^2 * sin(f).)

Согласно этим формулам, четырехугольник 30 на 30 футов, основанный на экваторе, имеет площадь 3077.2300079129 квадратных километров, в то время как четырехугольник 30 на 30 футов, касающийся полюса (который на самом деле является просто треугольником), имеет площадь всего 13,6086152 кв. километров.

В качестве проверки формулы, применяемые ко всем ячейкам сетки 720 на 360, покрывающей земную поверхность, дают общую площадь поверхности 4 * пи * (6371.0071809) ^ 2 квадратных километра, указывая на то, что автономный радиус Земли должен составлять 6371.0071809 километров. Это отличается от значения в Википедии только последней значащей цифрой (около десятой доли миллиметра). (Я думаю, что расчеты Википедии немного неточны :-).

В качестве дополнительных проверок я использовал версии этих формул для воспроизведения Приложений 4 и 5 в Lev M. Bugayevskiy & John P. Snyder, Map Projection: A Reference Manual (Taylor & Francis, 1995). В Приложении 4 показаны длины дуг 30-метровых участков меридианов и параллелей, приведенные до ближайшего метра. Выборочная проверка результатов показала полное согласие. Затем я пересоздал таблицу с шагом 0,0005 ', а не с шагом 0,5', и численно интегрировал области четырехугольников, рассчитанные по этим длинам дуг. Общая площадь эллипсоида была точно воспроизведена с точностью до восьми значимых цифр. В Приложении 5 приведены значения area(f)для f = 0, 1/2, 1, ..., 90 градусов, умноженные на 1 / (2 * pi). Эти значения даны с точностью до квадратного километра. Визуальная проверка значений около 0, 45 и 90 градусов показала идеальное согласие.


Эта точная формула может быть применена с использованием растровой алгебры, начинающейся с сетки, задающей широты верхних пределов каждой ячейки, а другой - широты нижних пределов. Каждый из них, по сути, является сеткой с координатами y. (В каждом случае вы можете захотеть создать, sin(f)а затем zmи zpкак промежуточные результаты.) Вычтите два результата, возьмите их абсолютное значение и умножьте на долю q, полученную на первом шаге (равную 0,5 / 360 = 1/720 для 30 'ширины ячейки, например). Это будет сетка, значения которой содержат точныеобласти каждой ячейки (с точностью до собственной сетки). Просто не забудьте выразить широты в форме, ожидаемой функцией синуса: многие калькуляторы растров будут давать вам координаты в градусах, но ожидайте радианы для своих функций триггера!


Для справки, вот точные площади ячеек 30 на 30 на эллипсоиде WGS 84 от экватора до полюса с интервалами в 30 футов до 11 цифр (то же самое число, которое использовалось для минорного радиуса b ):

3077.2300079,3077.0019391,3076.5458145,3075.8616605,3074.9495164,3073.8094348,3072.4414813,3070.8457347,3069.0222870,3066.9712434,3064.6927222,3062.1868550,3059.4537865,3056.4936748,3053.3066912,3049.8930202,3046.2528597,3042.3864209,3038.2939285,3033.9756204,3029.4317480,3024.6625762,3019.6683833,3014.4494612,3009.0061153,3003.3386648,2997.4474422,2991.3327939,2984.9950800,2978.4346744,2971.6519646,2964.6473522,2957.4212526,2949.9740951,2942.3063230,2934.4183938,2926.3107788,2917.9839636,2909.4384482,2900.6747464,2891.6933866,2882.4949115,2873.0798782,2863.4488581,2853.6024374,2843.5412166,2833.2658109,2822.7768503,2812.0749792,2801.1608571,2790.0351582,2778.6985716,2767.1518013,2755.3955665,2743.4306011,2731.2576543,2718.8774905,2706.2908892,2693.4986451,2680.5015685,2667.3004848,2653.8962347,2640.2896746,2626.4816763,2612.4731271,2598.2649300,2583.8580035,2569.2532818,2554.4517149,2539.4542684,2524.2619238,2508.8756783,2493.2965451,2477.5255533,2461.5637477,2445.4121891,2429.0719545,2412.5441367,2395.8298444,2378.9302026,2361.8463521,2344.5794500,2327.1306692,2309.5011988,2291.6922441,2273.7050264,2255.5407830,2237.2007674,2218.6862492,2199.9985139,2181.1388633,2162.1086151,2142.9091030,2123.5416769,2104.0077025,2084.3085615,2064.4456516,2044.4203864,2024.2341953,2003.8885234,1983.3848318,1962.7245972,1941.9093120,1920.9404843,1899.8196375,1878.5483108,1857.1280585,1835.5604507,1813.8470724,1791.9895239,1769.9894206,1747.8483931,1725.5680867,1703.1501618,1680.5962932,1657.9081707,1635.0874985,1612.1359952,1589.0553936,1565.8474409,1542.5138984,1519.0565410,1495.4771578,1471.7775513,1447.9595378,1424.0249466,1399.9756206,1375.8134157,1351.5402005,1327.1578567,1302.6682785,1278.0733724,1253.3750574,1228.5752643,1203.6759360,1178.6790272,1153.5865040,1128.4003439,1103.1225355,1077.7550785,1052.2999830,1026.7592702,1001.1349711,975.42912705,949.64378940,923.78101904,897.84288636,871.83147097,845.74886152,819.59715539,793.37845851,767.09488512,740.74855748,714.34160569,687.87616739,661.35438752,634.77841811,608.15041795,581.47255240,554.74699308,527.97591765,501.16150951,474.30595754,447.41145586,420.48020351,393.51440422,366.51626611,339.48800143,312.43182627,285.34996030,258.24462644,231.11805066,203.97246162,176.81009042,149.63317034,122.44393648,95.244625564,68.037475592,40.824725575,13.608615243

Значения в квадратных километрах.


Если вы хотите приблизить эти области или просто лучше понять их поведение, формула сводится к степенному ряду, следуя этой схеме:

area(f) = 2 * pi * b^2 * z * (1 + (4/3)y + (6/5)y^2 + (8/7)y^3 + ...)

где

z = sin(f), y = (e*z)^2.

(Эквивалентная формула появляется в Bugayevskiy & Snyder, op. Cit. , Уравнение (2.1).)

Поскольку е ^ 2 очень мало (около 1/150 для всех эллипсоидальных моделей Земли) и z лежит в диапазоне от 0 до 1, у тоже мало. Таким образом, слагаемые y ^ 2, y ^ 3, ... быстро уменьшаются, добавляя точность еще на два десятичных знака к каждому члену. Если бы мы вообще игнорировали y , формула была бы таковой для сферы сферы радиуса b . Остальные термины можно понимать как поправку на экваториальную выпуклость Земли.


редактировать

Некоторые вопросы были подняты относительно того, как вычисление геодезического расстояния области сравнивается с этими точными формулами. Метод геодезического расстояния аппроксимирует каждый четырехугольник геодезическими, а не параллелями, которые соединяют его углы по горизонтали, и применяет евклидову формулу для трапеции. Для небольших четырехугольников, таких как 30-дюймовые, этот показатель слегка смещен и имеет относительную точность от 6 до 10 частей на миллион. Вот график ошибки для WGS 84 (или любого другого разумного земного эллипсоида, в этом отношении):

фигура 2

Таким образом, если (1) у вас есть легкий доступ к вычислениям геодезических расстояний и (2) может допустить ошибку на уровне ppm, вы можете рассмотреть возможность использования этих геодезических вычислений и умножения их результатов на 1.00000791 для исправления смещения. Для еще двух десятичных знаков точности вычтите pi / 2 * cos (2f) / 10 ^ 6 из поправочного коэффициента: результат будет с точностью до 0,04 ppm.

Whuber
источник
1
Если ваша система предоставляет функцию atanh, то вы можете немного более точные результаты (с меньшим округлением), заменив log (zp / zm) на 2 * atanh (e * sin (f)).
cffk
@cffk Это хороший момент. Изначально я получил формулы в терминах atanh, но преобразовал их в логарифмы, ожидая, что (a) большинство пользователей ГИС будут незнакомы с этой функцией и (b) многие пользователи не будут иметь доступа к системам, в которых она предусмотрена. Хотя потеря точности является потенциальной проблемой, быстрая проверка величины эксцентриситета показывает, что при работе с земными эллипсоидами теряется немного - возможно, чуть больше двух знаков после запятой. Я предоставил ряды отчасти, чтобы позволить читателям достичь максимально возможной точности, если они пожелают.
whuber
3

Ответ на вопрос Радукью зависит от формы пикселя при проецировании на эллипсоид. Если система координат растра - это долгота и широта, тогда пиксель - это прямоугольник прямой линии, и можно использовать ответ whuber, или, в более общем смысле, вы можете использовать формулу для многоугольника, ребра которого являются линиями прямой линии. Если система координат представляет собой крупномасштабную конформную проекцию (UTM, плоскость состояния и т. Д.), Было бы более точным приближать края по геодезическим и использовать формулу для геодезического многоугольника. Геодезические многоугольники, вероятно, лучше всего подходят для общего использования, поскольку, в отличие от многоугольников прямой линии, они «хорошо ведут себя» вблизи полюсов.

Реализации формул для полигонов геодезической и прямой линии предоставлены моей библиотекой GeographicLib . Геодезическая зона доступна на нескольких языках; область прямой линии - только C ++. Там в онлайн - версия (геодезическая + локсодромия) доступна здесь . Точность этих расчетов обычно лучше, чем 0,1 кв.

Вам придется судить о достоверности / официальности ... Геодезические формулы получены в области под геодезической (Danielsen, 1989, требуется подписка) и в алгоритмах для геодезических (Karney, 2013, открытый доступ). Формулы прямой линии приведены здесь .

cffk
источник
(+1) Я одобряю этот пост за полезную информацию в нем, хотя он на самом деле не затрагивает вопрос (или награду), оба из которых конкретно касаются растров в географических системах координат.
whuber
1

Я столкнулся с этим вопросом, пытаясь определить формулу для площади пикселя WGS84. В то время как ответ @ whuber содержит эту информацию, все еще была некоторая работа, чтобы получить формулу для площади пикселя квадратного градуса на данной широте. Я включил функцию Python, которую я написал ниже, которая абстрагирует это в один вызов. Хотя он не дает прямого ответа на вопрос автора об области ВСЕГО растра (хотя можно было бы суммировать площади всех пикселей), я думаю, что это все еще полезная информация для тех, кто может искать аналогичные вычисления.

def area_of_pixel(pixel_size, center_lat):
    """Calculate m^2 area of a wgs84 square pixel.

    Adapted from: /gis//a/127327/2397

    Parameters:
        pixel_size (float): length of side of pixel in degrees.
        center_lat (float): latitude of the center of the pixel. Note this
            value +/- half the `pixel-size` must not exceed 90/-90 degrees
            latitude or an invalid area will be calculated.

    Returns:
        Area of square pixel of side length `pixel_size` centered at
        `center_lat` in m^2.

    """
    a = 6378137  # meters
    b = 6356752.3142  # meters
    e = math.sqrt(1 - (b/a)**2)
    area_list = []
    for f in [center_lat+pixel_size/2, center_lat-pixel_size/2]:
        zm = 1 - e*math.sin(math.radians(f))
        zp = 1 + e*math.sin(math.radians(f))
        area_list.append(
            math.pi * b**2 * (
                math.log(zp/zm) / (2*e) +
                math.sin(math.radians(f)) / (zp*zm)))
    return pixel_size / 360. * (area_list[0] - area_list[1])
Богатый
источник