wpf - C# GMap.Net calculate surface of polygon -


i searching way calculate surface under polygon.

the thing want accomplish user uses program, can create polygon mark out property. want know surface area can tell user how big property is.

unit m² or km² or hectare.

the points of polygon have latitude , longitude.

i using c# wpf , gmap.net. map in windowsformhost can use winforms thing gmap.net because provoides overlays etc.

i hope can me or show me post explained didn't found.

using 2d vector space approximation (local tangent space)

in section, can detail how come these formulas.

let's note points points of polygon (where points[0] == points[points.count - 1] close polygon).

the idea behind next methods split polygon triangles (the area sum of triangle areas). but, support polygon types simple decomposition (not star-shaped polygon), triangle contributions negative (we have "negative" area). triangles decomposition use : {(o, points[i], points[i + 1]} o origin of affine space.

the area of non-self-intersecting polygon (in euclidian geometry) given by:

in 2d:

float getarea(list<vector2> points) {     float area2 = 0;     (int numpoint = 0; numpoint < points.count - 1; numpoint++)     {         mypoint point = points[numpoint];         mypoint nextpoint = points[numpoint + 1];         area2 += point.x * nextpoint.y - point.y * nextpoint.x;     }     return area2 / 2f; } 

in 3d, given normal, unitary normal of polygon (which planar):

float getarea(list<vector3> points, vector3 normal) {     vector3 vector = vector3.zero;     (int numpoint = 0; numpoint < points.count - 1; numpoint++)     {         mypoint point = points[numpoint];         mypoint nextpoint = points[numpoint + 1];         vector += vector3.crossproduct(point, nextpoint);     }     return (1f / 2f) * math.abs(vector3.dotproduct(vector, normal)); } 

in previous code assumed have vector3 struct add, subtract, multiply, crossproduct , dotproduct operations.

in case, have lattitude , longitude. then, not in 2d euclidean space. spheric space computing area of polygon more complex. however, locally homeomorphic 2d vector space (using tangent space). then, if area try measure not wide (few kilometers), above formula should work.

now, have find normal of polygon. so, , reduce error (because approximating area), use normal @ centroid of polygon. centroid given by:

vector3 getcentroid(list<vector3> points) {     vector3 vector = vector3.zero;     vector3 normal = vector3.crossproduct(points[0], points[1]);  // gets normal of first triangle (it used know if contribution of triangle positive or negative)     normal = (1f / normal.length) * normal;  // makes vector unitary     float sumprojectedareas = 0;     (int numpoint = 0; numpoint < points.count - 1; numpoint++)     {         mypoint point = points[numpoint];         mypoint nextpoint = points[numpoint + 1];         float triangleprojectedarea = vector3.dotproduct(vector3.crossproduct(point, nextpoint), normal);         sumprojectedareas += triangleprojectedarea;         vector += triangleprojectedarea  * (point + nextpoint);     }     return (1f / (6f * sumprojectedareas)) * vector; } 

i've added new property vector3 : vector3.length

finally, convert latitude , longitude vector3:

vector3 geographiccoordinatestopoint(float latitude, float longitude) {     return earthradius * new vector3(math.cos(latitude) * math.cos(longitude), math.cos(latitude) * math.sin(longitude), math.sin(latitude)); } 

to sum up:

// converts latitude/longitude coordinates 3d coordinates list<vector3> pointsin3d = (from point in points                             select geographiccoordinatestopoint(point.latitude, point.longitude))                            .tolist();  // gets centroid (to have normal of vector space) vector3 centroid = getcentroid(pointsin3d );  // on sphere, normal @ given point colinear vector going center of sphere point. vector3 normal = (1f / centroid.length) * centroid;  // want unitary normal.  // area computed using: float area = getarea(pointsin3d, normal); 

the vector3 struct

public struct vector3 {     public static readonly vector3 0 = new vector3(0, 0, 0);      public readonly float x;     public readonly float y;     public readonly float z;      public float length { return math.sqrt(x * x + y * y + z * z); }      public vector3(float x, float y, float z)     {          x = x;          y = y;          z = z;     }      public static vector3 operator +(vector3 vector1, vector3 vector2)     {         return new vector3(vector1.x + vector2.x, vector1.y + vector2.y, vector1.z + vector2.z);     }     public static vector3 operator -(vector3 vector1, vector3 vector2)     {         return new vector3(vector1.x - vector2.x, vector1.y - vector2.y, vector1.z - vector2.z);     }     public static vector3 operator *(float scalar, vector3 vector)     {         return new vector3(scalar * vector.x, scalar * vector.y, scalar * vector.z);     }      public static float dotproduct(vector3 vector1, vector3 vector2)     {         return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;     }     public static vector3 crossproduct(vector3 vector1, vector3 vector2)     {         return return new vector3(vector1.y * vector2.z - vector1.z * vector2.y,                                   vector1.z * vector2.x - vector1.x * vector2.z,                                   vector1.x * vector2.y - vector1.y * vector2.x);     } } 

Comments

Popular posts from this blog

html5 - What is breaking my page when printing? -

c# - must be a non-abstract type with a public parameterless constructor in redis -

ajax - PHP/JSON Login script (Twitter style) not setting sessions -