Dwi*_*ill 12 java android coordinates point-in-polygon google-maps-android-api-2
我想弄清楚如何最好地做到这一点,我有一张地图上Polygon画了一张.因为Google Maps API V2似乎没有在Polygon上进行触摸检测.我很想知道是否可以检测触点是否在Polygon内?如果是这样,我的主要目标是在地图上勾画状态,当用户点击该状态时,它将在自定义视图中显示更多细节.到目前为止,我能够捕获MapOnClick地图,但是当用户点击内部时,Polygon我想要polygon.getID()设置在地图上Toast.我是新手,所以如果我不够清楚,我会道歉.
googleMap.setOnMapClickListener(new OnMapClickListener()
{
public void onMapClick(LatLng point)
{
boolean checkPoly = true;
Toast.makeText(MainActivity.this,"The Location is outside of the Area", Toast.LENGTH_LONG).show();
}
});
}
}
catch (Exception e) {
Log.e("APP","Failed", e);
}
Run Code Online (Sandbox Code Playgroud)
好的,这就是我到目前为止所做的半工作
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 > bY) {
aX = vertB.longitude;
aY = vertB.latitude;
bX = vertA.longitude;
bX = vertA.latitude;
}
System.out.println("aY: "+aY+" aX : "+aX);
System.out.println("bY: "+bY+" bX : "+bX);
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;
// }
double m = (aX != bX) ? ((bY - aY) / (bX - aX)) : aX;
double bee = (aX != pX) ? ((pY - aY) / (pX - aX)) : aX;
double x = (pY - bee) / m;
return x > pX;
}
Run Code Online (Sandbox Code Playgroud)
}
我遇到的问题是触摸在每个多边形的左边都是真的,直到到达另一个多边形.我的算法会导致这个问题出了什么问题?任何帮助,将不胜感激.
Mat*_*att 24
您要解决的问题是Point in Polygon测试.
为了帮助可视化光线投射的概念:
在一张纸上绘制多边形.然后,从任意随机点开始,在页面右侧画一条直线.如果您的线与多边形相交了奇数次,则表示您的起点位于多边形内.
那么,你如何在代码中做到这一点?
您的多边形由顶点列表组成: ArrayList<Geopoint> vertices.您需要Line Segment单独查看每个,并查看Ray它是否相交
private boolean isPointInPolygon(Geopoint tap, ArrayList<Geopoint> 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(Geopoint tap, Geopoint vertA, Geopoint vertB) {
double aY = vertA.getLatitude();
double bY = vertB.getLatitude();
double aX = vertA.getLongitude();
double bX = vertB.getLongitude();
double pY = tap.getLatitude();
double pX = tap.getLongitude();
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;
}
Run Code Online (Sandbox Code Playgroud)
use*_*495 15
Google地图支持库现在有一个静态方法可以为您检查:
PolyUtil.containsLocation(LatLng point, List<LatLng>polygon, boolean geodesic);
Run Code Online (Sandbox Code Playgroud)
尽管文档没有在指南中明确提及,但方法仍然存在
随着Google Play Services 8.4.0的发布,Maps API已经包含了对添加OnPolygonClickListener多边形的支持.这两个多边形,折线和覆盖支持类似的活动.
您只需要调用GoogleMap.setOnPolygonClickListener(OnPolygonClickListener listener)它来设置它,并相应地为其他侦听器(setOnPolylineClickListener,&c):
map.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
@Override
public void onPolygonClick(Polygon polygon) {
// Handle click ...
}
});
Run Code Online (Sandbox Code Playgroud)
虽然有点晚,但它很好地解决了这个用例.
| 归档时间: |
|
| 查看次数: |
13219 次 |
| 最近记录: |