neurix
neurix

Reputation: 4316

GeoDjango: Determine the area of a polygon

In my model I have a polygon field defined via

polygon = models.PolygonField(srid=4326, geography=True, null=True, blank=True)

When I want to determine the area of the polygon, I call

area_square_degrees = object.polygon.area

But how can I convert the result in square degrees into m2 with GeoDjango? This answer does not work, since area does not have a method sq_m. Is there any built-in conversion?

Upvotes: 5

Views: 5067

Answers (4)

Alexander
Alexander

Reputation: 1355

You need to transform your data to the correct spatial reference system.

area_square_local_units = object.polygon.transform(srid, clone=False).area

In the UK you might use the British National Grid SRID of 27700 which uses meters.

area_square_meters = object.polygon.transform(27700, clone=False).area

You may or may not want to clone the geometry depending on whether or not you need to do anything else with it in its untransformed state.

Docs are here https://docs.djangoproject.com/en/1.8/ref/contrib/gis/geos/

Upvotes: 7

Guillaume Lebreton
Guillaume Lebreton

Reputation: 2801

I have struggled a lot with this, since i could'nt find a clean solution. The trick is you have to use the postgis capabilities (and and thus its only working with postgis..):

from django.contrib.gis.db.models.functions import Area
loc_obj = Location.objects.annotate(area_=Area("poly")).get(pk=??)  
# put the primary key of the object

print(loc_obj.area_)  # distance object, result should be in meters, but you can change to the unit you want, e.g  .mi for miles etc..

The models.py:

class Location(models.Model):
    poly = gis_models.PolygonField(srid=4326, geography=True)

It's i think the best way to do it if you have to deal with geographic coordinates instead of projections. It does handle the curve calculation of the earth, and the result is precise even with big distance/area

Upvotes: 4

castledom04
castledom04

Reputation: 217

I needed an application to get the area of poligons around the globe and if I used an invalid country/region projection I got the error OGRException: OGR failure

I ended using an OpenLayers implementation using the 4326 projection (is the default projection) to avoid concerning about every country/region specific projection. Here is my code:

import math

def getCoordsM2(coordinates):
    d2r = 0.017453292519943295  # Degrees to radiant
    area = 0.0
    for coord in range(0, len(coordinates)):
        point_1 = coordinates[coord]
        point_2 = coordinates[(coord + 1) % len(coordinates)]
        area += ((point_2[0] - point_1[0]) * d2r) *\
            (2 + math.sin(point_1[1] * d2r) + math.sin(point_2[1] * d2r))
    area = area * 6378137.0 * 6378137.0 / 2.0
    return math.fabs(area)

def getGeometryM2(geometry):
    area = 0.0
    if geometry.num_coords > 2:
        # Outer ring
        area += getCoordsM2(geometry.coords[0])
        # Inner rings
        for counter, coordinates in enumerate(geometry.coords):
            if counter > 0:
                area -= getCoordsM2(coordinates)
    return area

Simply pass your geometry to getGeometryM2 function and you are done! I use this function in my GeoDjango model as a property. Hope it helps!

Upvotes: 2

Sri
Sri

Reputation: 711

If Its earths surface area that you are talking about, 1 square degree has 12,365.1613 square km. So multiple your square degree and multiply by 10^6 to convert to meters.

Upvotes: -4

Related Questions