实施地理围栏 - C#

发布于 2024-10-22 22:28:00 字数 210 浏览 1 评论 0原文

我需要在 C# 中实现地理围栏。地理围栏区域可以是圆形、矩形、多边形等。有人用 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

离线来电— 2024-10-29 22:28:00

我已经测试了各种实现,这个示例对我来说工作正常:

示例

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; 
}

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; 
}
君勿笑 2024-10-29 22:28:00

请参阅我的实现:

多边形

Refer to my Implementation:

Polygon

Circle

假装不在乎 2024-10-29 22:28:00

在此添加 C# 实现
这对我有用!

//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);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文