Как нарисовать многоугольник, используя строковый массив latlng в карте Google - PullRequest
2 голосов
/ 14 апреля 2020

В моем приложении у меня есть recyclerview, который содержит imagview, и этот imageview содержит stati c изображение карты с использованием координат, которые я храню в sqlite. и когда я нажимаю на это изображение, я передаю эти координаты в формате строкового массива в другое действие карты, а затем, используя координаты этого строкового массива, снова рисуем тот же многоугольник, который сохраняется в карте Google. но я не понимаю, как это сделать.

Я попытался следующий код, но не работает:

это код моего класса адаптера, где я отображаю stati c карта в представлении изображения и затем с помощью намерения передать координаты активности карты

   String url ="https://maps.googleapis.com/maps/api/staticmap?";
    url+="&zoom=18";
    url+="&size=300x300";
    url+="&maptype=satellite";
    url+="&path=color:green|fillcolor:0xFFFF0033|"+ Coordinates;
    url+="&key=" + "AIzaSyCj80x6E****Lx_KFsHKlogV0";
    Picasso.get().load(url).into(holder.poly_image);

    holder.poly_image.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {


            Intent i = new Intent(mCtx, EditMapsActivity.class);
            i.putExtra("img", Poly_Coords);
            mCtx.startActivity(i);
        }
    });

это моя деятельность на карте, где я хочу нарисовать многоугольник, используя координаты:

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

    // Obtain the SupportMapFragment and get notified when the map is ready 
   to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) 
    getSupportFragmentManager().findFragmentById(R.id.mapView);
    mapFragment.getMapAsync(EditMapsActivity.this);
    Intent intent = getIntent();
    String staticPolyCoords = intent.getStringExtra("img");
    Log.d("Log", "Polygon Coords" + staticPolyCoords);

    String answer = staticPolyCoords;
    ArrayList<Location> arrayListLatLng = new ArrayList<>();
    answer = answer.replace("lat/lng: (" , "");
    answer = answer.replace(")" , "");
    answer = answer.replace("]","");
    answer = answer.replace("[","");
    String[] arrayLatLng = answer.split(",");
    Log.d("LOG_TAG", "Polygon Coordinates" +  arrayLatLng);

    for(int i = 0 ; i < arrayLatLng.length ; i++ ){

       LatLng Cooordinate_Point = new 
       LatLng((Double.parseDouble(arrayLatLng[i])), 
       Double.parseDouble(arrayLatLng[i+1]));
        Log.d("LOG_TAG", "Polygon Coordinates" +  Cooordinate_Point);
        latLngList.add(Cooordinate_Point);
    }

, затем на карте готовый метод ()

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

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        DrawPolygon(latLngList);

    }


  private void DrawPolygon(List<LatLng> latLngList) {

  /*  myMap.addPolygon(new PolygonOptions().strokeColor(Color.GREEN).fillColor(0x7F228B22).add(latLngList));*/

    Polygon polygon = myMap.addPolygon(new PolygonOptions()
            .clickable(true)
            .add(latLngList));
    // Store a data object with the polygon, used here to indicate an arbitrary type.
    polygon.setTag("alpha");
    polygon.setStrokeWidth(3);
    polygon.setStrokeColor(Color.GREEN);
    polygon.setFillColor(0x7F228B22);

}

Ответы [ 5 ]

3 голосов
/ 23 апреля 2020

Используйте этот код для преобразования:

    String answer = staticPolyCoords;
    answer = answer.replace("lat/lng:" , "");
    answer = answer.replace(")" , "]");
    answer = answer.replace("(" , "[");

    try {
        JSONArray jsonArray = new JSONArray(answer);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONArray latLong = jsonArray.getJSONArray(i);
            double lat = latLong.getDouble(0);
            double lon = latLong.getDouble(1);
            coordinates.add(new LatLng(lat, lon));
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

А затем в своем методе drawPolygon попробуйте это для каждого l oop:

 PolygonOptions poly = new PolygonOptions();
    for (LatLng latLng : coordinates) {
        //use the coordinates.
        poly.addAll(Collections.singleton(latLng));
    }


    Polygon polygon = myMap.addPolygon(poly);
   //add here your set methods

    myMap.moveCamera(CameraUpdateFactory.newLatLng(coordinates.get(3)));
    CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);
    myMap.animateCamera(zoom);
 }
1 голос
/ 21 апреля 2020

Если вы хотите загрузить свою карту в приложение карты Google, тогда вы можете go с приведенным ниже подходом:

String geoUri = "http://maps.google.com/maps?q=loc:" + latitude + "," + longitude + " (" + mTitle + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(geoUri));
context.startActivity(intent);

Или, если вы хотите загрузить ее в свое приложение, попробуйте MapActivity, где вам нужно чтобы сначала включить API Google Map, а затем ваши примененные координаты будут отображаться на карте

. Пожалуйста, проверьте ниже ссылку, это будет полезно для интеграции

https://developers.google.com/maps/documentation/android-sdk/start

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

Чтобы правильно нарисовать прямоугольник полигонов, попробуйте эту функцию сортировки:

fun sortConvexs(coordinates: MutableList<LatLng>): MutableList<LatLng> {

        val input = coordinates

        // Returns a positive value, if OAB makes a counter clockwise turn,negative for clockwise turn, and zero if the points are collinear.

        fun cross(P: LatLng, _A: LatLng, _B: LatLng): Double {
            val part1 = (_A.longitude - P.longitude) * (_B.latitude - P.latitude)
            val part2 = (_A.latitude - P.latitude) * (_B.longitude - P.longitude)
            return part1 - part2
        }

        // Sort points

        var points = input.sortedWith(
            Comparator<LatLng> { coordinate0, coordinate1 ->
                when {
                    (coordinate0.longitude == coordinate1.longitude) && (coordinate0.latitude < coordinate1.latitude) -> 1
                    (coordinate0.longitude < coordinate1.longitude) -> -1
                    else -> 0
                }
            }
        )

        // Build the lower hull

        var lower: MutableList<LatLng> = ArrayList<LatLng>()

        points.forEach { p ->

            while (lower.size >= 2 && cross(lower[lower.size - 2], lower[lower.size - 1], p) <= 0) {
                lower.removeAt(lower.size - 1)
            }

            lower.add(p)

        }

        // Build upper hull

        var upper: MutableList<LatLng> = ArrayList<LatLng>()

        points = points.asReversed()

        points.forEach { p ->
            while (upper.size >= 2 && cross(upper[upper.size - 2], upper[upper.size - 1], p) <= 0) {
                upper.removeAt(upper.size - 1)
            }

            upper.add(p)
        }

        // Last point of upper list is omitted because it is repeated at the beginning of the lower list.

        upper.removeAt(upper.size - 1)


        // Concatenation of the lower and upper hulls gives the total points.

        return (upper + lower).toMutableList()
    }


    fun getApproximateCenter(points: MutableList<LatLng>): LatLng {
        // Calc bounds first
        val boundsBuilder = LatLngBounds.builder()
        points.forEach {
            boundsBuilder.include(it)
        }
        val polygonBounds = boundsBuilder.build()

        val centerPoint = polygonBounds.center

        // Center point is inside the polygon, return it
        if (PolyUtil.containsLocation(centerPoint, points, true)) {
            return centerPoint
        }

        // Center point is out of bounds
        // Sample points at fixed percentages of the bounding box’s width East and West of the center point.
        val maxSearchSteps = 10
        var testPos: LatLng = centerPoint

        // Calculate NorthWest point so we can work out height of polygon NW->SE
        val northWest = LatLng(polygonBounds.northeast.latitude, polygonBounds.southwest.longitude)

        // Work out how tall and wide the bounds are and what our search
        // increment will be
        val boundsHeight = SphericalUtil.computeDistanceBetween(northWest, polygonBounds.southwest)
        val heightIncr = boundsHeight / maxSearchSteps

        val boundsWidth = SphericalUtil.computeDistanceBetween(northWest, polygonBounds.northeast)
        val widthIncr = boundsWidth / maxSearchSteps

        // Expand out from Centroid and find a point within polygon at
        // 0, 90, 180, 270 degrees
        for (n in 1..maxSearchSteps) {
            // Test point North of Centroid
            testPos = SphericalUtil.computeOffset(
                centerPoint,
                (heightIncr * n),
                0.0
            )
            if (PolyUtil.containsLocation(testPos, points, true)) {
                break
            }

            // Test point East of Centroid
            testPos = SphericalUtil.computeOffset(
                centerPoint,
                (widthIncr * n),
                90.0
            )
            if (PolyUtil.containsLocation(testPos, points, true)) {
                break
            }

            // Test point South of Centroid
            testPos = SphericalUtil.computeOffset(
                centerPoint,
                (heightIncr * n),
                180.0
            )
            if (PolyUtil.containsLocation(testPos, points, true)) {
                break
            }

            // Test point West of Centroid
            testPos = SphericalUtil.computeOffset(
                centerPoint,
                (widthIncr * n),
                270.0
            )
            if (PolyUtil.containsLocation(testPos, points, true)) {
                break
            }
        }

        return testPos
    }

Это работает для меня, основываясь на этом быстром ответе

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

Если я правильно понимаю ваш вопрос, вам нужно: сначала показать карту * stati c, затем, после нажатия, показать ту же карту stati c, но с несколькими полигонами на ней. Как и в случае с викториной, когда у первого (вопроса) Activity пользователя запрашивается правильное место объекта, а у второго (ответа) Activity отображается правильное место объекта.

Для этого вам необходимо:

1) привязать изображение карты c к геодезии c координат;

2) внедрить GoogleMap.addPolygon() метод рисования на нем полигона.

Обе эти задачи в общем-то не тривиальны, поэтому проще всего это сделать:

1) Если вы хотите получить быстрый правильный ответ, показанный во втором упражнении, запросите и получите от Stati c Map API в вашей первой Activity двух картах: первая - просто с изображением карты, а вторая - та же карта, но уже с полигонами. Первое изображение, которое вы показываете в этом упражнении, а второе Activity (которое вы показываете после щелчка), вы показываете второе изображение уже с полигонами. Или запросите второе изображение за секунду Activity, если хотите показать ответ только для нажатых карт. В Официальной документации вы можете найти, как получить статическое c изображение карты с полигоном на нем (взгляните на параметр path):

https://maps.googleapis.com/maps/api/staticmap ?size=400x400&center=40.653279,-73.959816&zoom=11 &path=fillcolor:0xAA000033%7Ccolor:0xFFFFFF00%7Cenc:}zswFtikbMjJzZ%7CRdPfZ}DxWvBjWpF~IvJnEvBrMvIvUpGtQpFhOQdKpz@bIx{A%7CPfYlvApz@bl@tcAdTpGpVwQtX}i@%7CGen@lCeAda@bjA%60q@v}@rfAbjA%7CEwBpbAd_@he@hDbu@uIzWcWtZoTdImTdIwu@tDaOXw_@fc@st@~VgQ%7C[uPzNtA%60LlEvHiYyLs^nPhCpG}SzCNwHpz@cEvXg@bWdG%60]lL~MdTmEnCwJ[iJhOae@nCm[%60Aq]qE_pAaNiyBuDurAuB}}Ay%60@%7CEKv_@?%7C[qGji@lAhYyH%60@Xiw@tBerAs@q]jHohAYkSmW?aNoaAbR}LnPqNtMtIbRyRuDef@eT_z@mW_Nm%7CB~j@zC~hAyUyJ_U{Z??cPvg@}s@sHsc@_z@cj@kp@YePoNyYyb@_iAyb@gBw^bOokArcA}GwJuzBre@i\tf@sZnd@oElb@hStW{]vv@??kz@~vAcj@zKa%60Atf@uQj_Aee@pU_UrcA &key=YOUR_API_KEY

Теперь карты Stati c URL-адреса API ограничены размером 8192 символа . Поэтому, если у вашего многоугольника много точек, вы должны использовать кодированный формат ломаной линии для точек многоугольника. Вы можете закодировать свой полигон с помощью PolyUtil.encode() метода Maps SDK для Android Utility Library .

2) (ИМХО лучше) используйте MapView/MapFragment Lite Mode Maps SDK для Android, который может обслуживать растровое изображение карты, предлагая ограниченную интерактивность для пользователя. В этом режиме поддерживаются полилинии, и вы можете сэкономить трафик c. В этом случае вы должны поместить MapView' or 'MapFragment в первом упражнении и MapView/MapFragment с теми же настройками (размер, положение камеры и т. Д. c.) Во втором упражнении, а когда пользователь нажимает на карту первого занятия, просто нарисуйте многоугольник карты второй и покажи это. Функциональность облегченного режима для фигур соответствует полному API :

GoogleMap map;
// ... get a map.
// Add a triangle in the Gulf of Guinea
Polygon polygon = map.addPolygon(new PolygonOptions()
     .add(new LatLng(0, 0), new LatLng(0, 5), new LatLng(3, 5), new LatLng(0, 0))
     .strokeColor(Color.RED)
 .fillColor(Color.BLUE));
0 голосов
/ 19 апреля 2020

Вызовите это из прослушивателя нажатия кнопки:

Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://www.google.com/maps/@?api=1&map_action=map&center=" + Coordinates));
mCtx.startActivity(i);

Источник: URL-адреса карт

...