Geo-fencing: taking an action when a lat/lng point enters or exits a geographi shape

Good, or common, uses of geo-fencing include: location tracking of objects and users, lifehacking, games (in the form of run-arounds, check-ins), and hyper-local ads and offers. Apps that are obvious employers of geo-fences include: foursquare (check-in reminders). The code below code calculates great-circle distances between the two points – that is, the shortest distance over the earth’s surface – using the ‘Haversine’ formula. If the distance between the two points is less than the radius, then it is within the circle. We can for sure provide sample code for polygons too.

Create fantastic map application using GoogleMapControl.DLL

###################################################################
## Is latitude/longitude point inside a circle
###################################################################
double GetDistance(double lat1, double lon1, double lat2, double lon2)
{
var R = 6371; // Radius of the earth in km
var dLat = ToRadians(lat2-lat1); // deg2rad below
var dLon = ToRadians(lon2-lon1);
var a =
Math.Sin(dLat/2) * Math.Sin(dLat/2) +
Math.Cos(ToRadians(lat1)) * Math.Cos(ToRadians(lat2)) *
Math.Sin(dLon/2) * Math.Sin(dLon/2);

var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1-a));
var d = R * c; // Distance in km
return d;
}

double ToRadians(double deg)
{
return deg * (Math.PI/180);
}

###################################################################
## Is latitude/longitude point inside a polygon
###################################################################

If the polygon is convex then one can consider the polygon as a ”path” from the first vertex. A point is on the interior of this polygons if it is always on the same side of all the line segments making up the path. Given a line segment between P0 (x0,y0) and P1 (x1,y1), another point P (x,y) has the following relationship to the line segment. Compute (y – y0) (x1 – x0) – (x – x0) (y1 – y0) if it is less than 0 then P is to the right of the line segment, if greater than 0 it is to the left, if equal to 0 then it lies on the line segment.

public static bool IsInPolygon(Point[] poly, Point point)
{
var coef = poly.Skip(1).Select((p, i) =>
(point.Y – poly[i].Y)*(p.X – poly[i].X)
– (point.X – poly[i].X) * (p.Y – poly[i].Y))
.ToList();

if (coef.Any(p => p == 0))
return true;

for (int i = 1; i < coef.Count(); i++) { if (coef[i] * coef[i - 1] < 0) return false; } return true; } Test it with simple rectangle like this:

Point[] pts = new Point[] { new Point { X = 1, Y = 1 },
new Point { X = 1, Y = 3 },
new Point { X = 3, Y = 3 },
new Point { X = 3, Y = 1 } };
IsInPolygon(pts, new Point { X = 2, Y = 2 }); ==> true
IsInPolygon(pts, new Point { X = 1, Y = 2 }); ==> true
IsInPolygon(pts, new Point { X = 0, Y = 2 }); ==> false