确定点是否在多边形中

时间:2014-09-24 10:14:19

标签: android google-maps geolocation android-maps-v2 polygons

根据我的要求,我在谷歌地图上绘制多边形,如下图所示。(使用地图v2)enter image description here

现在我需要在用户输入特定多边形时显示警告。

如何识别我的当前位置是否在多边形中。 (需要优化的方式而不会耗尽电池)

提前致谢。

4 个答案:

答案 0 :(得分:25)

刚刚尝试了Ray Casting算法,该算法识别多边形中的点。这很完美。

请参阅http://en.wikipedia.org/wiki/Point_in_polygon了解Ray-Casting的论文

private boolean isPointInPolygon(LatLng tap, ArrayList<LatLng> vertices) {
        int intersectCount = 0;
        for (int j = 0; j < vertices.size() - 1; j++) {
            if (rayCastIntersect(tap, vertices.get(j), vertices.get(j + 1))) {
                intersectCount++;
            }
        }

        return ((intersectCount % 2) == 1); // odd = inside, even = outside;
    }

    private boolean rayCastIntersect(LatLng tap, LatLng vertA, LatLng vertB) {

        double aY = vertA.latitude;
        double bY = vertB.latitude;
        double aX = vertA.longitude;
        double bX = vertB.longitude;
        double pY = tap.latitude;
        double pX = tap.longitude;

        if ((aY > pY && bY > pY) || (aY < pY && bY < pY)
                || (aX < pX && bX < pX)) {
            return false; // a and b can't both be above or below pt.y, and a or
                            // b must be east of pt.x
        }

        double m = (aY - bY) / (aX - bX); // Rise over run
        double bee = (-aX) * m + aY; // y = mx + b
        double x = (pY - bee) / m; // algebra is neat!

        return x > pX;
    }

答案 1 :(得分:18)

我发现光线投射方法不可靠,但我最终使用谷歌地图中的PolyUtil

您需要依赖项compile 'com.google.maps.android:android-maps-utils:0.5'

然后该方法看起来像这样

PolyUtil.containsLocation(userLocation, polyPointsList, false);

修改

这是源代码

中找到的此方法的说明
  

计算给定点是否位于指定的多边形内。无论最后一个点是否等于第一个点,多边形始终被视为闭合。内部被定义为不包含南极 - 南极总是在外面。如果测地线为真,则多边形由大圆段形成,否则由多边形(loxodromic)段形成。

答案 2 :(得分:2)

参考此链接

Polygon Touch detection Google Map API V2

它的RayCasting算法,它可以帮助你:)

关于算法的简要说明:

从你的点到右边绘制一条水平线,如果它以奇数次与多边形的边相交,那么该点就在多边形内部,在外面:)

这些wiki链接将为您提供完整的想法:

http://en.wikipedia.org/wiki/Point_in_polygon

http://rosettacode.org/wiki/Ray-casting_algorithm

答案 3 :(得分:0)

这是 Dart 中的代码,取自: https://github.com/KohlsAdrian/google_maps_utils/blob/master/lib/poly_utils.dart

  /// Checks if [point] is inside [polygon]
  static bool containsLocationPoly(Point point, List<Point> polygon) {
    num ax = 0;
    num ay = 0;
    num bx = polygon[polygon.length - 1].x - point.x;
    num by = polygon[polygon.length - 1].y - point.y;
    int depth = 0;

    for (int i = 0; i < polygon.length; i++) {
      ax = bx;
      ay = by;
      bx = polygon[i].x - point.x;
      by = polygon[i].y - point.y;

      if (ay < 0 && by < 0) continue; // both "up" or both "down"
      if (ay > 0 && by > 0) continue; // both "up" or both "down"
      if (ax < 0 && bx < 0) continue; // both points on left

      num lx = ax - ay * (bx - ax) / (by - ay);

      if (lx == 0) return true; // point on edge
      if (lx > 0) depth++;
    }

    return (depth & 1) == 1;
  }