简体   繁体   English

确定点是否在多边形中

[英]Identify if point is in the polygon

As per my requirement, I am drawing polygons on google map shown in the image below.(using maps v2)根据我的要求,我正在下图所示的谷歌地图上绘制多边形。(使用地图 v2)在此处输入图片说明

Now I need to show an alert when user enters that particular polygons.现在我需要在用户输入特定多边形时显示警报。

How to identify if my current location is with in the polygon.如何确定我的当前位置是否在多边形中。 (Need optimized way without draining battery) (需要优化的方式而不消耗电池)

Thanks in advance.提前致谢。

Just tried Ray Casting algorithm which identifies point in polygon.刚刚尝试了识别多边形中点的光线投射算法。 This works perfect.这工作完美。

Refer http://en.wikipedia.org/wiki/Point_in_polygon for thesis of Ray-Casting有关光线投射的论文,请参阅http://en.wikipedia.org/wiki/Point_in_polygon

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

I found ray-casting method unreliable but I ended up using the PolyUtil from google maps.我发现光线投射方法不可靠,但我最终使用了谷歌地图中的PolyUtil

You need the dependency compile 'com.google.maps.android:android-maps-utils:0.5'您需要依赖compile 'com.google.maps.android:android-maps-utils:0.5'

And then the method looks like this然后方法看起来像这样

PolyUtil.containsLocation(userLocation, polyPointsList, false);

EDIT编辑

This is the description of this method found in source code这是在源代码中找到的此方法的描述

Computes whether the given point lies inside the specified polygon.计算给定点是否位于指定多边形内。 The polygon is always considered closed, regardless of whether the last point equals the first or not.无论最后一个点是否等于第一个点,多边形始终被认为是封闭的。 Inside is defined as not containing the South Pole -- the South Pole is always outside.里面被定义为不包含南极——南极总是在外面。 The polygon is formed of great circle segments if geodesic is true, and of rhumb (loxodromic) segments otherwise.如果测地线为真,则多边形由大圆段组成,否则由菱形(loxodromic)段组成。

Refer this link参考这个链接

Polygon Touch detection Google Map API V2 多边形触摸检测 Google Map API V2

Its RayCasting algorithm, it may help you :)它的 RayCasting 算法,它可以帮助你:)

A brief description about the algorithm:关于算法的简要说明:

A horizontal line is drawn from your point to the right, if it intersects the sides of polygon at odd number of times then the point is inside the polygon else outside :)一条水平线从您的点向右绘制,如果它与多边形的边相交奇数次,则该点位于多边形内部,否则位于外部:)

These wiki links will give you complete idea:这些维基链接会给你完整的想法:

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

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

Here is the code in Dart, taken from: https://github.com/KohlsAdrian/google_maps_utils/blob/master/lib/poly_utils.dart这是 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;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM