12

先日、apoint(X,Y)がポリゴン内にあるかどうかを計算するクラスを Java で作成しました。(XYdouble、地理座標になるため)。

Java にはクラスがあることは知っていますが、andを使用Polygonする必要がありました。Path2DPoint2DPolygondouble

でポリゴンを作成したらPath2D、その方法を使用してcontainsPath2D持っていた)、問題は解決しました。

しかし今、私は Android にインポートしたいのですが、インポートするPath2D必要があるため、問題はここにあります:

import java.awt.geom.Path2D;
import java.awt.geom.Point2D;

Androidにはawtが存在しないため、使用できません。

Path2Dでは、 hadcontainsメソッドに似たクラスはありますか? または私は自分で計算する必要がありますか?

を使用してJavaで行った方法は次のPath2Dとおりです。

private void ConstructPolygon(Vector<Point2D> coodinates)
{       
    this.polygon.moveTo(coodinates.get(0).getX(), coodinates.get(0).getY());        

    //System.out.println(coodinates.get(0).getX() + "   " + coodinates.get(0).getY());
    //System.out.println("asda");

    for(int i = 1; i < this.num_points; i++)
    {
        //System.out.println(coodinates.get(i).getX() + "   " + coodinates.get(i).getY());
        this.polygon.lineTo(coodinates.get(i).getX(), coodinates.get(i).getY());
    }
    this.polygon.closePath();
}
public boolean InsideCity(Point2D punto)
{
    return this.polygon.contains(punto);                
}
4

4 に答える 4

36

これには、私の単純なライブラリを正確に使用できます: https://github.com/snatik/polygon-contains-point

ポリゴンを準備する:

Polygon polygon = Polygon.Builder()
    .addVertex(new Point(1, 3))
    .addVertex(new Point(2, 8))
    .addVertex(new Point(5, 4))
    .addVertex(new Point(5, 9))
    .addVertex(new Point(7, 5))
    .addVertex(new Point(6, 1))
    .addVertex(new Point(3, 1))
    .build();

ポイントがポリゴンの内側にあることを確認します。

Point point = new Point(4.5f, 7);
boolean contains = polygon.contains(point);

フロートタイプと穴を含むポリゴンで機能します:)

于 2013-04-04T16:46:02.047 に答える
26

Google マップの PolyUtil を使用できます。

import com.google.maps.android.PolyUtil;

boolean inside = PolyUtil.containsLocation(new LatLng(...), poly, true);
于 2016-07-09T09:03:30.640 に答える
7

これが私がAndroidで行った方法です。これは、この Java プログラム (レイ キャスティング アルゴリズム) に基づいてい ます。 -google-maps/46720#46720

    public boolean pointInPolygon(LatLng point, Polygon polygon) {
        // ray casting alogrithm http://rosettacode.org/wiki/Ray-casting_algorithm
        int crossings = 0;
        List<LatLng> path = polygon.getPoints();
        path.remove(path.size()-1); //remove the last point that is added automatically by getPoints()

        // for each edge
        for (int i=0; i < path.size(); i++) {
            LatLng a = path.get(i);
            int j = i + 1;
            //to close the last edge, you have to take the first point of your polygon
            if (j >= path.size()) {
                j = 0;
            }
            LatLng b = path.get(j);
            if (rayCrossesSegment(point, a, b)) {
                crossings++;
            }
        }

        // odd number of crossings?
        return (crossings % 2 == 1);
     }

    public boolean rayCrossesSegment(LatLng point, LatLng a,LatLng b) {
                // Ray Casting algorithm checks, for each segment, if the point is 1) to the left of the segment and 2) not above nor below the segment. If these two conditions are met, it returns true
                double px = point.longitude,
                py = point.latitude,
                ax = a.longitude,
                ay = a.latitude,
                bx = b.longitude,
                by = b.latitude;
            if (ay > by) {
                ax = b.longitude;
                ay = b.latitude;
                bx = a.longitude;
                by = a.latitude;
            }
            // alter longitude to cater for 180 degree crossings
            if (px < 0 || ax <0 || bx <0) { px += 360; ax+=360; bx+=360; }
            // if the point has the same latitude as a or b, increase slightly py
            if (py == ay || py == by) py += 0.00000001;


            // if the point is above, below or to the right of the segment, it returns false
            if ((py > by || py < ay) || (px > Math.max(ax, bx))){ 
                return false;
            }
            // if the point is not above, below or to the right and is to the left, return true
            else if (px < Math.min(ax, bx)){ 
                return true;
            }
            // if the two above conditions are not met, you have to compare the slope of segment [a,b] (the red one here) and segment [a,p] (the blue one here) to see if your point is to the left of segment [a,b] or not
            else {
                double red = (ax != bx) ? ((by - ay) / (bx - ax)) : Double.POSITIVE_INFINITY;
                double blue = (ax != px) ? ((py - ay) / (px - ax)) : Double.POSITIVE_INFINITY;
                return (blue >= red);
            }

     }
于 2014-09-14T12:54:31.603 に答える
5

申し訳ありません@sromku私は自分自身に尋ねました(私はこの種のものを使用したことがありません)

誰かが同じ質問をしている場合、それが私が解決した方法です

Builder poly2 = new Polygon.Builder();
    for(int i = 0; i< xpoints.length;i++){
        poly2.addVertex(new Point(xpoints[i],ypoints[i]));
    }
    Polygon polygon2 = poly2.build();
于 2013-04-10T16:23:23.643 に答える