【问题标题】:Android Geofencing (Polygon)Android 地理围栏(多边形)
【发布时间】:2013-08-31 10:20:56
【问题描述】:

如何从多个地理位置(经纬度值)创建多边形地理围栏。此外,如何跟踪用户是进入这个地理围栏区域还是在 android 上退出这个区域。

【问题讨论】:

    标签: android geolocation geofencing


    【解决方案1】:

    地理围栏只是一组构成多边形的纬度/经度点。获得纬度/经度点列表后,您可以使用点内多边形检查来查看某个位置是否在多边形内。

    这是我在自己的项目中使用的代码,用于对非常大的凹多边形(20K+ 顶点)执行多边形点检查:

    public class PolygonTest
    {
        class LatLng
        {
            double Latitude;
            double Longitude;
    
            LatLng(double lat, double lon)
            {
                Latitude = lat;
                Longitude = lon;
            }
        }
    
        bool PointIsInRegion(double x, double y, LatLng[] thePath)
        {
            int crossings = 0;
    
            LatLng point = new LatLng (x, y);
            int count = thePath.length;
            // for each edge
            for (var i=0; i < count; i++) 
            {
                var a = thePath [i];
                var j = i + 1;
                if (j >= count) 
                {
                    j = 0;
                }
                var b = thePath [j];
                if (RayCrossesSegment(point, a, b)) 
                {
                    crossings++;
                }
            }
            // odd number of crossings?
            return (crossings % 2 == 1);
        }
    
        bool RayCrossesSegment(LatLng point, LatLng a, LatLng b)
        {
            var px = point.Longitude;
            var py = point.Latitude;
            var ax = a.Longitude;
            var ay = a.Latitude;
            var bx = b.Longitude;
            var by = b.Latitude;
            if (ay > by)
            {
                ax = b.Longitude;
                ay = b.Latitude;
                bx = a.Longitude;
                by = a.Latitude;
            }
                // alter longitude to cater for 180 degree crossings
            if (px < 0) { px += 360; };
            if (ax < 0) { ax += 360; };
            if (bx < 0) { bx += 360; };
    
            if (py == ay || py == by) py += 0.00000001;
            if ((py > by || py < ay) || (px > Math.max(ax, bx))) return false;
            if (px < Math.min(ax, bx)) return true;
    
            var red = (ax != bx) ? ((by - ay) / (bx - ax)) : float.MAX_VALUE;
            var blue = (ax != px) ? ((py - ay) / (px - ax)) : float.MAX_VALUE;
            return (blue >= red);
        }
    }
    

    就程序流程而言,您需要后台服务进行位置更新,然后针对您的纬度/经度多边形数据执行此检查,以查看该位置是否在内部。

    【讨论】:

    • 地理围栏也可以是凹壳。我写了一个地理围栏 PHP 类。
    • 啊,我写错了不是吗?感谢您强调这一点。
    • 这是纯金恕我直言。它是否有任何实际限制、缺点或不准确之处?另外,这个算法有名字吗?
    【解决方案2】:

    如果人们仍在寻找多边形地理围栏检查,您可以使用 GoogleMaps.Util.PolyUtil containsLocation 方法完成此操作。

    【讨论】:

    • 实现 'com.google.maps.android:android-maps-utils:0.5'
    猜你喜欢
    • 2015-10-29
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    相关资源
    最近更新 更多