Python计算球面上多边形的面积

时间:2015-08-13 09:12:30

标签: python math

我有一系列的点,正确的提升和赤纬值。 这些点对应于球体表面上多边形的顶点。

计算这些点所包围区域的最佳方法是什么?我认为用等面积投影转换点,然后在平面上进行典型的多边形面积计算将是一个合适的解决方案。

注意:我不能使用自定义python库。例如pyproj或shapely

示例代码(适用于纬度经度,需要进行哪些修改才能确保使用天空坐标?)

def reproject(latitude, longitude):
    """Returns the x & y coordinates in metres using a sinusoidal projection"""
    from math import pi, cos, radians
    earth_radius = 6371009
    lat_dist = pi * earth_radius / 180.0

    y = [lat * lat_dist for lat in latitude]
    x = [long * lat_dist * cos(radians(lat)) 
                for lat, long in zip(latitude, longitude)]
    return x, y

def area_of_polygon(x, y):
    """Calculates the area of an arbitrary polygon given its vertices"""
    area = 0.0
    for i in xrange(-1, len(x)-1):
        area += x[i] * (y[i+1] - y[i-1])
    return abs(area) / 2.0

dec = [-15.,89.,89.,-15.,-15.]    
ra = [105.,105.,285.,285.,105.]

x,y = reproject(dec, ra)
print area_of_polygon(x,y)

2 个答案:

答案 0 :(得分:2)

一种方法是根据格林定理执行线积分。请参见下面的实现,有关更多详细信息,请参见this question

def polygon_area(lats, lons, algorithm = 0, radius = 6378137):
    """
    Computes area of spherical polygon, assuming spherical Earth. 
    Returns result in ratio of the sphere's area if the radius is specified.
    Otherwise, in the units of provided radius.
    lats and lons are in degrees.
    """
    from numpy import arctan2, cos, sin, sqrt, pi, power, append, diff, deg2rad
    lats = np.deg2rad(lats)
    lons = np.deg2rad(lons)

    # Line integral based on Green's Theorem, assumes spherical Earth

    #close polygon
    if lats[0]!=lats[-1]:
        lats = append(lats, lats[0])
        lons = append(lons, lons[0])

    #colatitudes relative to (0,0)
    a = sin(lats/2)**2 + cos(lats)* sin(lons/2)**2
    colat = 2*arctan2( sqrt(a), sqrt(1-a) )

    #azimuths relative to (0,0)
    az = arctan2(cos(lats) * sin(lons), sin(lats)) % (2*pi)

    # Calculate diffs
    # daz = diff(az) % (2*pi)
    daz = diff(az)
    daz = (daz + pi) % (2 * pi) - pi

    deltas=diff(colat)/2
    colat=colat[0:-1]+deltas

    # Perform integral
    integrands = (1-cos(colat)) * daz

    # Integrate 
    area = abs(sum(integrands))/(4*pi)

    area = min(area,1-area)
    if radius is not None: #return in units of radius
        return area * 4*pi*radius**2
    else: #return in ratio of sphere total area
        return area

请找到更明确的版本(以及更多参考文献和待办事项...)here

答案 1 :(得分:0)

看起来我可以将ra和dec视为lat和long,以m ^ 2计算地球表面上的区域,并使用此值转换为以sq度为单位的区域。

如果我在下面提出的解决方案存在缺陷,请告诉我:

def reproject(latitude, longitude):
    """Returns the x & y coordinates in metres using a sinusoidal projection"""
    from math import pi, cos, radians
    earth_radius = 6371009
    lat_dist = pi * earth_radius / 180.0

    y = [lat * lat_dist for lat in latitude]
    x = [long * lat_dist * cos(radians(lat)) 
                for lat, long in zip(latitude, longitude)]
    return x, y

def area_of_polygon(x, y):
    """Calculates the area of an arbitrary polygon given its vertices"""
    area = 0.0
    for i in xrange(-1, len(x)-1):
        area += x[i] * (y[i+1] - y[i-1])
    return ((abs(area) / 2.0)/5.10100E14) * 41253

dec = [-15.,89.,89.,-15.,-15.]    
ra = [105.,105.,285.,285.,105.]

x,y = reproject(dec, ra)
print area_of_polygon(x,y)