Android: как расположить Latlog в android google, чтобы он образовывал прямоугольник многоугольника? - PullRequest
0 голосов
/ 21 апреля 2020

у меня 4 LatLng. Для создания многоугольника прямоугольника они должны быть в списке по часовой стрелке или против часовой стрелки, поэтому, когда я добавлю эти LatLng в addPolygon(new LatLng) на карте Google, он создаст форму прямоугольника. Но в моем случае они могут быть по часовой стрелке или против часовой стрелки или в другой форме. Один пример -> 1-й LatLng, затем 3-й LatLng, затем 2-й LatLng и 4-й LatLng. В этом случае он не будет создавать прямоугольник многоугольника на карте Google. Поэтому я должен расположить его по часовой стрелке или против часовой стрелки, чтобы форма фигуры была прямоугольной. Когда я помещаю этот список LatLng в addPolygon() на карте Google.

Предположим:

val rectOptions = PolygonOptions()
        .add(
            LatLng(37.35, -122.0),
            LatLng(37.45, -122.0),
            LatLng(37.45, -122.2),
            LatLng(37.35, -122.2)
        )

Если я поставлю rectOptions в AddPolygon() в mMap.addPolygon(rectOptions), это создаст прямоугольную angular фигуру на карте Google. В моем случае:

val rectOptions = PolygonOptions()
        .add(
            LatLng(37.45, -122.0),
            LatLng(37.45, -122.2),
            LatLng(37.35, -122.0),
            LatLng(37.35, -122.2)
        )

Это не создаст прямоугольную angular форму. Поэтому я должен расположить эти LatLng так, чтобы они образовывали прямоугольную angular форму.

1 Ответ

0 голосов
/ 21 апреля 2020

Как правило, ваша задача Конструкция выпуклой оболочки и может быть решена одним из алгоритмов выпуклой оболочки , например, как Алгоритм упаковки подарков (он же Джарвис) в это реализация .

Обратите внимание, что большинство реализаций алгоритмов выпуклой оболочки предназначены для плоских (x,y) координат точек, а не для LatLng координат местоположения, поэтому проще всего преобразовать LatLng в плоские (x,y) точки с Projection.toScreenLocation() и затем, после применения алгоритма выпуклой оболочки, преобразовать его обратно в LatLng с помощью Projection.fromScreenLocation() метода.

Также помните, что Projection объект будет возвращать действительные значения только после того, как карта прошла процесс макета (то есть он имеет действительные width и height набор), и вы можете получить его в OnCameraIdleListener или использовать подход, описанный andr в этот ответ .

Таким образом, полный исходный код демо может быть таким:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mGoogleMap;
    private SupportMapFragment mMapSupportedFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMapSupportedFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_fragment);
        mMapSupportedFragment.getMapAsync(MainActivity.this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;

        mGoogleMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
            @Override
            public void onCameraIdle() {
                ArrayList<LatLng> sourcePoints = new ArrayList<>();
                sourcePoints.add(new LatLng(37.35, -122.0));
                sourcePoints.add(new LatLng(37.45, -122.2));
                sourcePoints.add(new LatLng(37.40, -122.1));
                sourcePoints.add(new LatLng(37.35, -122.2));
                sourcePoints.add(new LatLng(37.45, -122.0));

                Projection projection = mGoogleMap.getProjection();
                ArrayList<Point> screenPoints = new ArrayList<>(sourcePoints.size());
                for (LatLng location : sourcePoints) {
                    Point p = projection.toScreenLocation(location);
                    screenPoints.add(p);
                }

                ArrayList<Point> convexHullPoints = convexHull(screenPoints);
                ArrayList<LatLng> convexHullLocationPoints = new ArrayList(convexHullPoints.size());
                for (Point screenPoint : convexHullPoints) {
                    LatLng location = projection.fromScreenLocation(screenPoint);
                    convexHullLocationPoints.add(location);
                }

                PolygonOptions polygonOptions = new PolygonOptions();
                for (LatLng latLng : convexHullLocationPoints) {
                    polygonOptions.add(latLng);
                }

                mGoogleMap.clear();
                Polygon polygon = mGoogleMap.addPolygon(polygonOptions.strokeColor(Color.argb(255, 49, 101, 187)).fillColor(Color.argb(100, 49, 101, 187)));
            }
        });
    }

    private boolean CCW(Point p, Point q, Point r) {
        return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y) > 0;
    }

    public ArrayList<Point> convexHull(ArrayList<Point> points)
    {
        int n = points.size();
        if (n <= 3) return points;

        ArrayList<Integer> next = new ArrayList<>();

        // find the leftmost point
        int leftMost = 0;
        for (int i = 1; i < n; i++)
            if (points.get(i).x < points.get(leftMost).x)
                leftMost = i;
        int p = leftMost, q;
        next.add(p);

        // iterate till p becomes leftMost
        do {
            q = (p + 1) % n;
            for (int i = 0; i < n; i++)
                if (CCW(points.get(p), points.get(i), points.get(q)))
                    q = i;
            next.add(q);
            p = q;
        } while (p != leftMost);

        ArrayList<Point> convexHullPoints = new ArrayList();
        for (int i = 0; i < next.size() - 1; i++) {
            int ix = next.get(i);
            convexHullPoints.add(points.get(ix));
        }

        return convexHullPoints;
    }
}

Также вы можете найти более простой алгоритм, если вам нужно «сортировать» точки только по прямоугольникам (например, вам нужно проверить, какие 3 точки образуют прямой угол и добавить их от первого к третьему, а затем добавить четвертую точку и т. д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...