def _exs(n, points): # iterate over spherical edge excess a1, b1 = points[n - 1].to2ab() ta1 = tan_2(a1) for i in range(n): a2, b2 = points[i].to2ab() db, b2 = unrollPI(b1, b2, wrap=wrap) ta2, tdb = map1(tan_2, a2, db) yield atan2(tdb * (ta1 + ta2), 1 + ta1 * ta2) ta1, b1 = ta2, b2
def areaOf(points, radius=R_M, wrap=True): '''Calculate the area of a (spherical) polygon (with great circle arcs joining the points). @param points: The polygon points (L{LatLon}[]). @keyword radius: Optional, mean earth radius (C{meter}). @keyword wrap: Wrap and unroll longitudes (C{bool}). @return: Polygon area (C{meter}, same units as I{radius}, squared). @raise TypeError: Some I{points} are not L{LatLon}. @raise ValueError: Insufficient number of I{points}. @note: The area is based on Karney's U{'Area of a spherical polygon' <http://osgeo-org.1560.x6.nabble.com/Area-of-a-spherical-polygon-td3841625.html>}. @see: L{pygeodesy.areaOf}, L{sphericalNvector.areaOf} and L{ellipsoidalKarney.areaOf}. @example: >>> b = LatLon(45, 1), LatLon(45, 2), LatLon(46, 2), LatLon(46, 1) >>> areaOf(b) # 8666058750.718977 >>> c = LatLon(0, 0), LatLon(1, 0), LatLon(0, 1) >>> areaOf(c) # 6.18e9 ''' n, points = _Trll.points2(points, closed=True) # Area method due to Karney: for each edge of the polygon, # # tan(Δλ/2) · (tan(φ1/2) + tan(φ2/2)) # tan(E/2) = ------------------------------------ # 1 + tan(φ1/2) · tan(φ2/2) # # where E is the spherical excess of the trapezium obtained by # extending the edge to the equator-circle vector for each edge if iterNumpy2(points): def _exs(n, points): # iterate over spherical edge excess a1, b1 = points[n - 1].to2ab() ta1 = tan_2(a1) for i in range(n): a2, b2 = points[i].to2ab() db, b2 = unrollPI(b1, b2, wrap=wrap) ta2, tdb = map1(tan_2, a2, db) yield atan2(tdb * (ta1 + ta2), 1 + ta1 * ta2) ta1, b1 = ta2, b2 s = fsum(_exs(n, points)) * 2 else: a1, b1 = points[n - 1].to2ab() s, ta1 = [], tan_2(a1) for i in range(n): a2, b2 = points[i].to2ab() db, b2 = unrollPI(b1, b2, wrap=wrap) ta2, tdb = map1(tan_2, a2, db) s.append(atan2(tdb * (ta1 + ta2), 1 + ta1 * ta2)) ta1, b1 = ta2, b2 s = fsum(s) * 2 if isPoleEnclosedBy(points): s = abs(s) - PI2 return abs(s * radius**2)