多边形触摸检测谷歌地图API V2 [英] Polygon Touch detection Google Map API V2

查看:134
本文介绍了多边形触摸检测谷歌地图API V2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出如何最好地做到这一点,我有一个多边形画有地图。因为它似乎并不仿佛谷歌地图API V2具有触摸检测上的多边形。我不知道是否是可以检测触摸点是否在多边形里面?如果是的话怎么样,我的主要目标是勾勒出一个国家在地图上,当用户点击该状态,它会显示自定义视图中的更多细节。截至目前,我能捕捉到 MapOnClick 地图,但是当用户点击 Polygon的内部我要的 polygon.getID()设置吐司。我是个新手,所以我道歉,如果我不太清楚。

  googleMap.setOnMapClickListener(新OnMapClickListener()
    {
        公共无效onMapClick(经纬度点)
        {
        布尔checkPoly =真;

        Toast.makeText(MainActivity.this的位置是区外,Toast.LENGTH_LONG).show();
        }
     });
     }
     }
   赶上(例外五){
         Log.e(APP,失败,E);
     }
 

确定这是我的半工作至今

 私人布尔rayCastIntersect(经纬度自来水,经纬度Verta酒店,经纬度vertB){

    双ΔY= vertA.latitude;
    双增= vertB.latitude;
    双AX = vertA.longitude;
    双BX = vertB.longitude;
    双PY = tap.latitude;
    双的pX = tap.longitude;
     如果(AY>通过){
            AX = vertB.longitude;
            一条Y = vertB.latitude;
            BX = vertA.longitude;
            BX = vertA.latitude;
        }
    的System.out.println(一条Y:+一条Y +AX+ AX);
    的System.out.println(通过+ BY +BX+ BX);

     如果(PX℃,)的pX + = 360;
        如果(AX< 0)AX + = 360;
        如果(BX℃,)BX + = 360;

        如果(PY = = ||一条Y PY ==通过)PY + = 0.00000001;
        如果((PY>由|| PY< AY)||(PX> Math.max(AX,BX)))返回false;
        如果(PX< Math.min(AX,BX))

            返回true;
//}

    双M =(AX!= BX)? ((BY  -  AY)/(BX  -  AX)):AX;
    蜜蜂双=(AX!= PX)? ((PY  -  AY)/(PX  -  AX)):AX;
    双X =(PY  - 蜜蜂)/平方米;

    返回X>的pX;
}
 

}

这是我遇到的问题是,触摸真实的每个多边形的左边,直到它到达一个又一个。有什么毛病我的算法,将导致此问题?任何帮助将是AP preciated。

解决方案

你正在试图解决的问题是点多边形测试。

为了帮助可视光线投射的概念:

绘制多边形上的一张纸。然后,开始在任何随机点,画一条直线到页面的右侧。如果您的线路相交的多边形的次数为奇数,这意味着你的出发点是在多边形内部。


那么,你怎么做,在code?

您的多边形是由顶点的列表:的ArrayList<的GeoPoint>顶点。你需要看看每个线段个别,看看你的相交它

 私人布尔isPointInPolygon(GeoPoint对象自来水,ArrayList的<的GeoPoint>顶点){
    INT intersectCount = 0;
    对于(INT J = 0; J< vertices.size() -  1; J ++){
        如果(rayCastIntersect(自来水,vertices.get(J),vertices.get(J + 1))){
            intersectCount ++;
        }
    }

    返回(intersectCount%2)== 1); //奇=里面,即使=之外;
}

私人布尔rayCastIntersect(GeoPoint对象自来水,GeoPoint对象Verta酒店,GeoPoint对象vertB){

    双ΔY= vertA.getLatitude();
    双增= vertB.getLatitude();
    双AX = vertA.getLongitude();
    双BX = vertB.getLongitude();
    双PY = tap.getLatitude();
    双重的pX = tap.getLongitude();

    如果((AY> PY&安培;&功放;通过> PY)||(AY< PY&安培;&放大器;以< PY)||(AX<分辩率和放大器;&安培; BX< PX)){
        返回false; // a和b不能同时为高于或低于pt.y,和一个或b必须pt.x的东
    }

    双M =(AY-BY)/(AX-BX); //兴起了跑
    蜜蜂双=(-aX)* M +一条Y; // y = mx + b中
    双X =(PY  - 蜜蜂)/平方米; //代数是整洁!

    返回X>的pX;
}
 

I'm trying to figure out how best to do this, I have a map with one Polygon drawn on it. Since it doesn't seem as though the Google Maps API V2 has a touch detection on a Polygon. I was wonder if it is possible to detect whether the touch point is inside the Polygon? If so then how, my main goal is to outline a state on a map and when the user taps that state it will show more details inside a custom view. As of now I am able to capture the MapOnClick of the map but when the user taps inside the Polygon I want the polygon.getID() set on the Toast. I am a newbie so I apologize if I am not clear enough.

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

Ok this is what I have semi-working so far

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

}

The issue that I am having is the touch is true to the left of each polygon until it reaches another one. What's wrong with my algorithm that would cause this issue? Any help would be appreciated.

解决方案

The problem you're trying to solve is the Point in Polygon test.

To help visualize the concept of Ray Casting:

Draw a Polygon on a piece of paper. Then, starting at any random point, draw a straight line to the right of the page. If your line intersected with your polygon an odd number of times, this means your starting point was inside the Polygon.


So, how do you do that in code?

Your polygon is comprised of a list of vertices: ArrayList<Geopoint> vertices. You need to look at each Line Segment individually, and see if your Ray intersects it

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

这篇关于多边形触摸检测谷歌地图API V2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆