Implementing Geofence - C#
I need to implement Geofence in C#. Geofence area can be round, rectangle, polygon etc. Does anyone have 开发者_开发知识库Geofence implementation in C#?
I found Geo Fencing - point inside/outside polygon. But, it supports polygon only.
I have tested various implementations and this example worked properly for me:
Example
public static bool PolyContainsPoint(List<Point> points, Point p) {
bool inside = false;
// An imaginary closing segment is implied,
// so begin testing with that.
Point v1 = points[points.Count - 1];
foreach (Point v0 in points)
{
double d1 = (p.Y - v0.Y) * (v1.X - v0.X);
double d2 = (p.X - v0.X) * (v1.Y - v0.Y);
if (p.Y < v1.Y)
{
// V1 below ray
if (v0.Y <= p.Y)
{
// V0 on or above ray
// Perform intersection test
if (d1 > d2)
{
inside = !inside; // Toggle state
}
}
}
else if (p.Y < v0.Y)
{
// V1 is on or above ray, V0 is below ray
// Perform intersection test
if (d1 < d2)
{
inside = !inside; // Toggle state
}
}
v1 = v0; //Store previous endpoint as next startpoint
}
return inside;
}
Refer to my Implementation:
Polygon
Circle
Adding both C# implementation here
It worked for me!
//Location will hold the latitude and longitude.
public class Location
{
public double lat { get; set; }
public double lng { get; set; }
public Location(double lat, double lng)
{
this.lat = lat;
this.lng = lng;
}
}
//Implementation for the Polygon.
bool IsPointInPolygon(List<Location> poly, Location point)
{
int i, j;
bool c = false;
for (i = 0, j = poly.Count - 1; i < poly.Count; j = i++)
{
if ((((poly[i].lat <= point.lat) && (point.lat < poly[j].lat))
|| ((poly[j].lat <= point.lat) && (point.lat < poly[i].lat)))
&& (point.lng < (poly[j].lng - poly[i].lng) * (point.lat - poly[i].lat)
/ (poly[j].lat - poly[i].lat) + poly[i].lng))
{
c = !c;
}
}
return c;
}
//Geofencing for the Circle.
//GetDistance will return total Kilometers
//p1 is the Center lat,long and p2 is the current location lat,long
//radius in meters
public bool IsPointInCircle(Location p1,Location p2,double radius)
{
return GetDistance(p1,p2)>radius*0.001?false:true;
}
public double GetDistance(Location pos1, Location pos2)
{
double e = pos1.lat * (Math.PI / 180);
double f = pos1.lng * (Math.PI / 180);
double g = pos2.lat * (Math.PI / 180);
double h = pos2.lng * (Math.PI / 180);
double i =
(Math.Cos(e) * Math.Cos(g) * Math.Cos(f) * Math.Cos(h)
+ Math.Cos(e) * Math.Sin(f) * Math.Cos(g) * Math.Sin(h)
+ Math.Sin(e) * Math.Sin(g));
double j = Math.Acos(i);
return (6371 * j);
}
精彩评论