Andrea Lucchesi
Andrea Lucchesi

Reputation: 43

Polygon Area in Bing Maps

Hi I have a problem calculating the area of a polygon in Bing maps. I'm using this code to calculate area.

public static double PolygonArea(LocationCollection points, double resolution)
    {
        int n = points.Count;
        var partialSum = 0.0;
        var sum = 0.0;

        for (int i = 0; i < n - 1; i++)
        {
            partialSum = (points[i].Longitude * points[i + 1].Latitude) -
                (points[i + 1].Longitude * points[i].Latitude);
            sum += partialSum;
        }

        var area = 0.5 * sum / Math.Pow(resolution, 2);
        area = Math.Abs(area);
        return area;
    }

This is the resolution method

public static double Resolution(double latitude, double zoomLevel)
  {                
      double groundResolution = Math.Cos(latitude * Math.PI / 180) *
       2 * Math.PI * EARTH_RADIUS_METERS / (256 * Math.Pow(2, zoomLevel));

            return groundResolution;
   }

How can I trasform it in m^2?

EDIT1: I tried your answer but I noticed that area change if I change zoom level.

I try to explain my problem from another point of you. I have to make the porting of an iOS app that uses this algorithm to calculate area

-(long double)calcArea :(CLLocationCoordinate2D*) pastureCordinates :(long) count {
  long double area  = 0.0;
  long double scale = 0.0;

  for (int cnt = 1; cnt < count; cnt++) {
      area +=    (MKMapPointForCoordinate(pastureCordinates[cnt - 1]).x)
      * (MKMapPointForCoordinate(pastureCordinates[cnt]).y)
      - (MKMapPointForCoordinate(pastureCordinates[cnt]).x)
      * (MKMapPointForCoordinate(pastureCordinates[cnt - 1]).y);
  }

  area +=    (MKMapPointForCoordinate(pastureCordinates[count - 1]).x)
  * (MKMapPointForCoordinate(pastureCordinates[0]).y)
  - (MKMapPointForCoordinate(pastureCordinates[0]).x)
  * (MKMapPointForCoordinate(pastureCordinates[count - 1]).y);

  scale = MKMapPointsPerMeterAtLatitude(pastureCordinates[count -1].latitude);
  area  = (area / (long double)2) / pow(scale,2);

  area = fabsl(area);
  return area;

}

I used the functions found here: https://msdn.microsoft.com/en-us/library/bb259689.aspx to calculate the scale, the ground resolution but the results are different compared to the iOS solution.

Upvotes: 1

Views: 1546

Answers (2)

rbrundritt
rbrundritt

Reputation: 17954

Ok, I've played around with some code and put together a simple method that calculates the area fairly accurately without having to use really in-depth spatial mathematics.

private double CalculateArea(LocationCollection locs)
{
    double area = 0;
    for (var i = 0; i < locs.Count - 1; i++)
    {
        area += Math.Atan(
            Math.Tan(Math.PI / 180 * (locs[i + 1].Longitude - locs[i].Longitude) / 2) *
            Math.Sin(Math.PI / 180 * (locs[i + 1].Latitude + locs[i].Latitude) / 2) /
            Math.Cos(Math.PI / 180 * (locs[i + 1].Latitude - locs[i].Latitude) / 2));
    }

    if (area < 0)
    {
        area *= -1;
    }

    return area * 2 * Math.Pow(6378137.0, 2);
}

Testing this with various polygons and comparing them to the calculated area in SQL, I found that in the worse case the difference was about 0.673% when using a ridiculously large polygon. When testing against a polygon that was about 0.5 sq KM in size, the difference was about 0.06%. Note that this method returns an area in sq meters.

Upvotes: 3

rbrundritt
rbrundritt

Reputation: 17954

Calculating the area of a polygon on a map is very complicated as the world is a sphere and you are actually trying to calculate the area of a polygon stretched on the surface of a sphere. Since you are using WPF I'd suggest to make things easy and make use of the spatial library available in SQL server. All the spatial functionalities in SQL server are available as a dll which you can use in your WPF application. You can easily use this library to calculate the area of a polygon accurately and do a lot of other really powerful things as well. To start off with, if you have SQL instelled you can find the SQL Spatial Library (Microsoft.SqlServer.Types) located in the C:\Program Files (x86)\Microsoft SQL Server\110\Shared directory. If you don't have SQL Server installed, don't worry, you don't have to install it, this library is available as a Nuget package here: https://www.nuget.org/packages/Microsoft.SqlServer.Types

Take a look at this hands on lab for information using SQL spatial tools in .NET: http://view.officeapps.live.com/op/view.aspx?src=http%3A%2F%2Fecn.channel9.msdn.com%2Fo9%2Flearn%2FSQL2008R2TrainingKit%2FLabs%2FUsingSpatialDataInManagedCode%2FLab.docx

Once you have this library you can create an SQL Geography object from your polygon. Once this is done you can then use the STArea method to calculate the area of the polygon. There is a ton of other spatial methods available as well which you can use to create a really powerful mapping application.

Upvotes: 0

Related Questions