在Android中使用Google Maps API检查点是不是在多边形中

Posted

技术标签:

【中文标题】在Android中使用Google Maps API检查点是不是在多边形中【英文标题】:Check if point is in polygon with Google Maps API in Android在Android中使用Google Maps API检查点是否在多边形中 【发布时间】:2017-05-03 08:40:55 【问题描述】:

我正在使用 android 上的 Google Maps API 来创建拼图。此链接包含我用来绘制非洲国家的数据:World countries coordinates。

当用户点击地图时,会进行测试以检查它是否在正确的国家/地区。

点在正确的国家内:正确的国家是绿色的

指向另一个已知国家:当前国家以红色显示

下面的代码迭代非洲国家列表(一个国家可能包含多个多边形)以找到包含点击点的国家并将其与正确的国家进行比较。

mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() 
    @Override
    public void onMapClick(LatLng latLng) 

        if(isPointInPolygon(latLng,answerPolygon)) 
            // right answer
            Toast.makeText(MapsActivity.this, "point inside the right polygon", Toast.LENGTH_SHORT).show();
            Polygon p = mMap.addPolygon(new PolygonOptions().addAll(answerPolygon));
            p.setStrokeWidth(p.getStrokeWidth()/5);
            p.setFillColor(0x7F00FF00);
        
        else 
            // wrong answer
            // search current polygon
            // color current polygon in red
            if (colorPolygonInRed(latLng))
                Polygon p = mMap.addPolygon(new PolygonOptions().addAll(answerPolygon));
                p.setStrokeWidth(p.getStrokeWidth()/5);
                p.setFillColor(0x7F00FF00);
                Toast.makeText(MapsActivity.this, "point in known polygons", Toast.LENGTH_SHORT).show();
            
            else 
                Toast.makeText(MapsActivity.this, "point in unknown polygons", Toast.LENGTH_SHORT).show();
            
        
    
);

函数 isPointInPolygon() 仅适用于地图上的一个多边形,因为它基于几何(射线相交)。在我的情况下它不起作用。 例如,当我在乍得这个国家(this picture 中的蓝点)内单击时,埃及被染成红色(我的列表按字母顺序排序,因此埃及是单击点右侧的第一个验证射线相交条件)。

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

public boolean colorPolygonInRed(LatLng point)
    for (Country country:countryList)
        for (ArrayList<LatLng> polygon : country.getCoordinates())
            if(isPointInPolygon(point,polygon)) 
                Polygon p = mMap.addPolygon(new PolygonOptions().addAll(polygon));
                p.setStrokeWidth(p.getStrokeWidth()/5);
                p.setFillColor(0x7FE00808);
                return true;
            
        
    
    return false;

从我的列表中获取单击的多边形的正确方法是什么?

【问题讨论】:

【参考方案1】:

您可以使用Google Maps Android API Utility Library 中的PolyUtil.containsLocation 方法。来自the documentation:

public static boolean containsLocation(LatLng point, java.util.List 多边形, 布尔测地线)

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

【讨论】:

感谢@antonio 的回答!这正是我想要的。 如果多边形是闭合的,我会从这个方法中得到更好的结果。这意味着第一点和最后一点应该相同。您可以通过调用 var isClosed = PolyUtil.isClosedPolygon(polygon) if (!isClosed) polygon.add(polygon[0]) 检查多边形是否闭合 你能告诉我参数测地线是什么意思吗?我出真/假取决于什么? 如果geodesictrue,则多边形由great circle segments 组成,如果false 它由rhumb segments 组成(loxodromic)。【参考方案2】:

稍后响应,但对于将来的搜索,您还可以使用以下方法检查某个位置是否在当前可见地图区域内:

// Kotlin code
var location = LatLng(-27.6016488, -48.5137219)    
val isInside = mGoogleMap.projection.visibleRegion.latLngBounds.contains(location)

文档链接:contains (LatLng point)

【讨论】:

以上是关于在Android中使用Google Maps API检查点是不是在多边形中的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 gradle 导入 com.google.maps.android:android-maps-utils

在 Google Maps Android API v2 中使用新的 OnMyLocationChangeListener

在Android中使用Google Maps API检查点是不是在多边形中

是否可以在 Android 电视上使用 Google Maps Geolocation API?

在 Android Studio 中使用 Gradle 管理 Google Maps API 密钥

Android Google Maps:使用折线在多边形中切孔