Android 地理围栏(多边形)

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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'

以上是关于Android 地理围栏(多边形)的主要内容,如果未能解决你的问题,请参考以下文章

地理围栏:如何识别对象(特征),使用 Oracle Spatial 重叠地理围栏边界?

如何检查给定坐标是不是属于多边形? (离线地理围栏)

地理围栏:使用 oracle 空间查找多边形内的要素数量(点/线/多边形)

地理围栏精度

定义地理围栏并查看点是不是在其内部/外部的算法

如何获得以米为单位的距离