PolyUtil.containsLocation无法按预期工作。

7
我做了一个简单的测试:
LatLng city = new LatLng(53.121896, 18.010110);

List<LatLng> pts = new ArrayList<>();
pts.add(new LatLng(53.520790, 17.404158));
pts.add(new LatLng(53.450445, 19.209022));
pts.add(new LatLng(52.659365, 17.656366));
pts.add(new LatLng(52.525305, 19.303601));

LatLngBounds bounds = new LatLngBounds(pts.get(2), pts.get(1));

boolean contains1 = PolyUtil.containsLocation(city.latitude, city.longitude, pts, true);
System.out.println("contains1: " + contains1);

boolean contains2 = bounds.contains(city);
System.out.println("contains2: " + contains2);

这是它的工作原理:
  1. 我创建了一个特定的点(city),我想测试它是否在多边形内部,
  2. 我声明一个由4个点和2个边界点(东北和西南)组成的多边形。
输出结果是:
contains1: false
contains2: true

为什么PolyUtil.containsLocation返回false?我错过了什么?这是一件简单的事情,您可以在Google Maps上测试这些点。

PolyUtil是由Google提供的android maps utils类:'com.google.maps.android:android-maps-utils:0.5'

1个回答

23

您应该按照正确的顺序定义多边形的顶点。让我们通过截图来解释,因为图片胜过千言万语。当前,您对多边形有以下顶点:

enter image description here

如果您尝试为示例数组列表绘制多边形,您将看到以下多边形:

enter image description here

正如您所看到的那样,城市确实在多边形外面,而PolyUtil给出了正确的结果。与此同时,您正确地使用西南和东北顶点定义了边界,因此该城市在边界内。要修复此问题,您应交换示例中的3号和4号点。

LatLng city = new LatLng(53.121896, 18.010110);

List<LatLng> pts = new ArrayList<>();
pts.add(new LatLng(53.520790, 17.404158));
pts.add(new LatLng(53.450445, 19.209022));
pts.add(new LatLng(52.525305, 19.303601));
pts.add(new LatLng(52.659365, 17.656366));

bounds = new LatLngBounds(pts.get(3), pts.get(1));

boolean contains1 = PolyUtil.containsLocation(city.latitude, city.longitude, pts, true);
System.out.println("contains1: " + contains1);

boolean contains2 = bounds.contains(city);
System.out.println("contains2: " + contains2);

您可以在https://github.com/xomena-so/so44523611找到我用来创建截图的示例项目。

希望这能帮助到您!


哇!讲解得非常好!其实我在stackoverflow上找到了不同的解决方案,那是维基百科上的一种算法改写成Java语言。但这个解决方案更为简洁和清晰,所以下次我一定会使用它! - Makalele
如果我们从KML文件中获取了点,并且数量超过30个,那么我们如何知道哪些点需要交换以设置顶点的顺序? - Fazal Hussain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接