def Polygon(self, polyline = False): """Return a PolygonArea object :param polyline: if True then the object describes a polyline instead of a polygon :return: a :class:`~geographiclib.polygonarea.PolygonArea` """ from geographiclib.polygonarea import PolygonArea return PolygonArea(self, polyline)
def __init__(self, poly): # Converti le polygone en liste de points points_lon_lat = list(poly.exterior.coords) points_lat_lon = [(point[1], point[0]) for point in points_lon_lat] # Converti le rectangle en liste de points rectangle = poly.minimum_rotated_rectangle rpoints_lon_lat = list(rectangle.exterior.coords) rpoints_lat_lon = [(point[1], point[0]) for point in rpoints_lon_lat] # Converti le polygone dans la bonne projection wgs84 = Geodesic.WGS84 geopoly = PolygonArea(wgs84) for point in points_lat_lon[0:-1]: geopoly.AddPoint(point[0], point[1]) geopoly_result = geopoly.Compute() # Converti le rectangle dans la bonne projection georectangle = PolygonArea(wgs84) for point in rpoints_lat_lon[0:-1]: georectangle.AddPoint(point[0], point[1]) georectangle_result = georectangle.Compute() # Calcule les dimensions du rectangle rdistance = [] for i in range(0, 4): rdistance.append( wgs84.Inverse(rpoints_lat_lon[i % 4][0], rpoints_lat_lon[i % 4][1], rpoints_lat_lon[(i + 1) % 4][0], rpoints_lat_lon[(i + 1) % 4][1])["s12"]) rdistance = [ abs((rdistance[0] + rdistance[2]) / 2.0), abs((rdistance[1] + rdistance[3]) / 2.0) ] # Données membres self.polygon = poly self.centroid = poly.centroid self.rectangle = poly.minimum_rotated_rectangle self.perimeter = abs(geopoly_result[1]) self.area = abs(geopoly_result[2]) self.rectangle_min = min(rdistance) self.rectangle_max = max(rdistance) self.rectangle_perimeter = abs(georectangle_result[1]) self.rectangle_area = abs(georectangle_result[2]) self.ratio = self.area / self.rectangle_area self.polygon_conversion = self.area / self.polygon.area self.rectangle_conversion = self.rectangle_area / self.rectangle.area self.nvertices = len(points_lon_lat) - 1 self.nedges = self.nvertices
def Area(self, points, polyline = False): """Compute the area of a geodesic polygon given by points, an array of dictionaries with entries lat and lon. Return a dictionary with entries number the number of verices perimeter the perimeter area the area (counter-clockwise traversal positive) There is no need to "close" the polygon. If polyline is set to True, then the points define a polyline instead of a polygon, the length is returned as the perimeter, and the area is not returned. """ from geographiclib.polygonarea import PolygonArea for p in points: Geodesic.CheckPosition(p['lat'], p['lon']) num, perimeter, area = PolygonArea.Area(self, points, polyline) result = {'number': num, 'perimeter': perimeter} if not polyline: result['area'] = area return result
class PlanimeterTest(unittest.TestCase): from geographiclib.polygonarea import PolygonArea polygon = PolygonArea(Geodesic.WGS84) polyline = PolygonArea(Geodesic.WGS84, True) def Planimeter(points): PlanimeterTest.polygon.Clear() for p in points: Geodesic.CheckPosition(p[0], p[1]) PlanimeterTest.polygon.AddPoint(p[0], p[1]) return PlanimeterTest.polygon.Compute(False, True) Planimeter = staticmethod(Planimeter) def PolyLength(points): PlanimeterTest.polyline.Clear() for p in points: Geodesic.CheckPosition(p[0], p[1]) PlanimeterTest.polyline.AddPoint(p[0], p[1]) return PlanimeterTest.polyline.Compute(False, True) PolyLength = staticmethod(PolyLength) def test_Planimeter0(self): # Check fix for pole-encircling bug found 2011-03-16 points = [[89, 0], [89, 90], [89, 180], [89, 270]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 631819.8745, delta = 1e-4) self.assertAlmostEqual(area, 24952305678.0, delta = 1) points = [[-89, 0], [-89, 90], [-89, 180], [-89, 270]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 631819.8745, delta = 1e-4) self.assertAlmostEqual(area, -24952305678.0, delta = 1) points = [[0, -1], [-1, 0], [0, 1], [1, 0]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 627598.2731, delta = 1e-4) self.assertAlmostEqual(area, 24619419146.0, delta = 1) points = [[90, 0], [0, 0], [0, 90]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 30022685, delta = 1) self.assertAlmostEqual(area, 63758202715511.0, delta = 1) num, perimeter, area = PlanimeterTest.PolyLength(points) self.assertAlmostEqual(perimeter, 20020719, delta = 1) self.assertTrue(Math.isnan(area)) def test_Planimeter5(self): # Check fix for Planimeter pole crossing bug found 2011-06-24 points = [[89, 0.1], [89, 90.1], [89, -179.9]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 539297, delta = 1) self.assertAlmostEqual(area, 12476152838.5, delta = 1) def test_Planimeter6(self): # Check fix for Planimeter lon12 rounding bug found 2012-12-03 points = [[9, -0.00000000000001], [9, 180], [9, 0]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 36026861, delta = 1) self.assertAlmostEqual(area, 0, delta = 1) points = [[9, 0.00000000000001], [9, 0], [9, 180]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 36026861, delta = 1) self.assertAlmostEqual(area, 0, delta = 1) points = [[9, 0.00000000000001], [9, 180], [9, 0]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 36026861, delta = 1) self.assertAlmostEqual(area, 0, delta = 1) points = [[9, -0.00000000000001], [9, 0], [9, 180]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 36026861, delta = 1) self.assertAlmostEqual(area, 0, delta = 1) def test_Planimeter12(self): # Area of arctic circle (not really -- adjunct to rhumb-area test) points = [[66.562222222, 0], [66.562222222, 180]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 10465729, delta = 1) self.assertAlmostEqual(area, 0, delta = 1) def test_Planimeter13(self): # Check encircling pole twice points = [[89,-360], [89,-240], [89,-120], [89,0], [89,120], [89,240]] num, perimeter, area = PlanimeterTest.Planimeter(points) self.assertAlmostEqual(perimeter, 1160741, delta = 1) self.assertAlmostEqual(area, 32415230256.0, delta = 1)