计算栅格面积的更准确方法


11

在日常工作中,经常有人要求我以30弧秒的分辨率计算地理投影中的全球栅格数据集的面积。这些数据集通常是“合并”操作的结果(一个典型的示例是与国家层相结合的植被类别)。为此,我们的单位创建了一个栅格数据集,其中地理投影中每个像素的面积为30弧秒。使用该面积网格,将执行zonalstat来汇总每个类别的面积。由于我不确定如何创建该区域网格,因此我一直想知道这种方法是否仅在等面积投影中重新投影栅格是否更准确(从简单的测试来看,这两种方法的结果是相似的)。是否有人遇到过类似情况?


@radouxju您似乎在暗示我引用的Bugayevskiy&Snyder手册既不可信也不官方。(相反,这两者都是-尤其是考虑到它是由美国和俄罗斯世界公认的当局合作造成的!)这种怀疑的基础是什么?您还会寻找什么?还要注意,这些计算是完全准确的。精度仅受给出椭圆形参数的精度以及计算精度的限制:不可能有更高的精度。
ub

@whuber我并不是在暗示您的引用不可信。在您回答之前,我对赏金的评论已经完成,而当我上次访问该网站时,授予赏金还为时过早。
radouxju 2014年

@radouxju谢谢您的解释!直到我发布答案几个小时后,我才意识到赏金。
whuber

Answers:


14

对于由平行线(纬度)和子午线(经度)界定的任何球形四边形的面积,都有一个相对简单的精确公式。可以使用椭圆(长轴a和短轴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))

其中ab分别是生成椭圆的长轴和短轴的长度,

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

(对于具有球形模型一个 = b,公式变为不定你必须采取限制为e -从上面,然后降低到标准式> 0 2 * pi * a^2 * sin(f)。)

根据这些公式,以赤道为基准的30'x 30'四边形的面积为3077.2300079129平方公里,而与杆(实际上只是一个三角形)接触的30'x 30'四边形的面积仅为13.6086152平方公里。

作为检验,适用于覆盖地球表面的720 x 360网格的所有单元的公式得出的总表面积为4 * pi *(6371.0071809)^ 2平方公里,表明地球的真实半径应为6371.0071809公里。这与Wikipedia值的不同之处仅在于最后一个有效数字(大约十分之一毫米)。(我认为Wikipedia的计算有点差劲:-)。

作为其他检查,我使用了这些公式的版本来复制列夫·M·布加耶夫斯基和约翰·P·斯奈德在《地图投影:参考手册》(Taylor和Francis,1995年)中的附录4和5 。附录4显示了最近的子午线和平行线的30'长段的弧长。抽查结果显示完全一致。然后,我以0.0005'(而不是0.5')的增量重新创建了表格,并根据这些弧长估算出的四边形面积在数值上进行了积分。椭球的总面积被精确地复制到八个以上的有效数字。附录5示出的值area(f)用于˚F = 0,1/2,1,...,90度,乘以1 /(2 * PI)。这些值被指定为最接近的平方公里。 肉眼检查0、45和90度附近的值显示出完美的一致性。


可以使用栅格代数来应用此精确公式,栅格代数以给出每个像元上限的纬度的网格和给出下限的纬度的网格开头。这些基本上都是y坐标网格。(在每种情况下,你可能想要创建sin(f),然后zmzp作为中间结果。)减去两个结果,采取的所述绝对值,并乘以分数q在第一步骤中获得的(等于0.5 / 360 = 1/720例如30英寸的单元格宽度)。这将是一个其值包含精确值的网格每个像元的面积(取决于网格自身的数值精度)。只需确保以正弦函数期望的形式表达纬度:许多栅格计算器会以度为单位给您提供坐标,但期望三角函数的弧度!


作为记录,这是 WGS 84椭球上从赤道到极点的30'x 30'单元的精确区域,间隔为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,同上,公式(2.1)。)

由于e ^ 2很小(对于地球的所有椭圆模型,约为1/150),并且z介于0和1之间,因此y也很小。因此,项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以内。


1
如果您的系统提供了atanh函数,那么您可以用2 * atanh(e * sin(f))替换log(zp / zm)来获得更准确的结果(较少的舍入)。
cffk 2014年

@cffk很好。我最初获得的公式是atanh,但将它们转换为对数,期望(a)大多数GIS用户不熟悉此功能,并且(b)许多用户将无法访问提供此功能的系统。尽管精度损失是一个潜在的问题,但对偏心率大小的快速检查显示,使用地球椭球时几乎没有损失-可能多了两个小数位。我提供了幂系列的一部分,以使读者可以根据需要获得最大的精度。
ub

3

radouxju问题的答案取决于投影到椭球体上的像素的形状。如果栅格的坐标系是经度和纬度,则像素为菱形线矩形,可以使用wuber的答案,或者更普遍地,您可以将公式用于边缘为菱形线的多边形。如果坐标系是大规模的保形投影(UTM,状态平面等),则通过测地线近似边缘并将其用于测地线多边形将更为准确。测地多边形可能是最适合常规使用的多边形,因为与菱形线多边形不同,测地多边形在极点附近表现良好。

我的库GeographicLib提供了测地线和横线多边形的公式的实现。测地线有多种语言版本。大黄线区域仅C ++。有一个在线版本(大地+恒向线),可在这里。这些计算的精度通常优于0.1平方米。

您必须判断可信/官方的...测地线公式来自测地线下方的区域(Danielsen,1989,需要订购)和测地线算法(Karney,2013,开放获取)。此处给出横线公式。


(+1)我赞成这篇文章,以获取其中的有用信息,即使它并未真正解决问题(或赏金),这两个问题都专门针对地理坐标系中的栅格。
ub

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])
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.