Подтвердить что ты не робот

Сенсорное обнаружение на полилинии в Google Maps API Android v2

Я хочу реализовать touchListener на полилинии, отображаемой с помощью API Google Maps V2 Android.

Уровень масштабирования: CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(lat_Lng, 5);

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

boolean onpoly = false;
            for (Polyline polyline : mPolylines) {
                for (LatLng polyCoords : polyline.getPoints()) {
                    float[] results = new float[1];

                    Location.distanceBetween(points.latitude, points.longitude, polyCoords.latitude, polyCoords.longitude, results);

                    if (results[0] < 100 ) {
                        onpoly = true;

                        Marker mark = map.addMarker(new MarkerOptions().position(points).title("AddEvent")

                        .snippet("" + addressaddexpense).icon(BitmapDescriptorFactory.fromResource(R.drawable.addicon)));

                        UtilsClass.dropPinEffect(mark);
                    }// end if..
                } // end for loop
            }// end for loop

            if (onpoly == true) {
                Toast.makeText(getActivity(), "Poly line detected", Toast.LENGTH_SHORT).show();
            }// end if

Это сработало, но не совсем. он не обнаружит событие касания, если я не увеличиваю масштаб, иногда заставляя меня коснуться карты более чем 5 раз перед масштабированием для достижения обнаружения.

Затем я изменил вышеупомянутое условие if от if (results[0] < 100 ) до if (results[0] < 150 * (22 - map.getCameraPosition().zoom)), а функциональность улучшилась, но все равно не работает все время.

Примечание. Я хочу обнаружить касание полилинии при любом уровне масштабирования.

4b9b3361

Ответ 1

попробуйте это

    final List<LatLng> latLngList; // Extract polyline coordinates and put them on this list
    private GoogleMap map;

for(int i = 0; i < latLngList.size(); i++){
                MarkerOptions mar = new MarkerOptions();
                    mar.position(new LatLng(latLngList.get(i).latitude, latLngList.get(i).longitude)).icon(BitmapDescriptorFactory.fromResource(R.drawable.trasparent_image)); //this image should be very small in size and transparent
                    map.addMarker(mar);
            }

            map.setOnMarkerClickListener(new OnMarkerClickListener() {

                @Override
                public boolean onMarkerClick(Marker arg0) {
                    for(int i = 0; i < latLngList.size(); i++){
                    if(latLngList.get(i).latitude == arg0.getPosition().latitude && latLngList.get(i).longitude == arg0.getPosition().longitude){
                        Toast.makeText(MainActivity.this, "PolyLineClick ", Toast.LENGTH_SHORT).show();
                        break;
                    }
                }
                    return false;
                }
            });

Ответ 2

До тех пор, пока не будут заданы вопросы в моих комментариях, я подумал, что попытаюсь сделать их избыточными, предложив использовать стороннюю библиотеку; android-maps-utils

Чтобы сделать то, что, я думаю, вы пытаетесь просто интегрировать в библиотеку и использовать следующую строку: PolyUtil.isLocationOnPath(point, polyline.getPoints(), isGeodesic, tolerance);

Для получения дополнительной информации вы также можете изучить этот поток, который кажется применимым.

Гудлак.

Ответ 3

Я думаю, что ваш подход правильный. Единственное, что не удается - это проверка расстояния. И это связано с тем, что сенсорный и уровень масштабирования:

Вы знаете, что при нажатии на экран точка экрана, передаваемая приложениям, является центром поверхности вашего пальца, который находится на связи с экраном. Это означает, что даже если кажется, что ваш палец точно соответствует значению PolyLine, его можно смещать с помощью нескольких пикселей...

Теперь настало время для уровня масштабирования, и в зависимости от его текущего значения расстояние между точкой, переданной приложению и PolyLine, может сильно различаться.

В результате предложение if выходит из строя, и вы должны нажимать несколько раз, пока некоторые из ваших кранов не будут достаточно близко к PolyLine. И, конечно, он становится лучше с более высоким уровнем масштабирования.

Вы должны включить уровень масштабирования, как это было сделано в отредактированном коде, но с некоторыми дополнительными функциями:
Проверьте" дельта ", что вы позволите ввести if, но на максимальный уровень масштабирования. Это должно быть небольшое значение. Затем вам нужно просто умножить его на текущий уровень масштабирования и рассчитать, как изменяется эта дельта. Используйте это зависимое от масштабирования значение в сравнении if.
Чтобы улучшить его, вы можете сделать более сложный расчет и получить эту дельта, начиная с расстояния до пикселя. Допустим, будет принят ответ, который при 50px или ниже будет PolyLine. Вычислите это расстояние в пикселях в метрах, снова на максимальном уровне масштабирования и используйте его, умноженное на текущий масштаб...
Чтобы еще больше увеличить его, вы можете получить это расстояние в пикселях, чтобы быть в зависимости от разрешения экрана и плотности.

Здесь вы можете найти, как вычислить пиксели экрана в метрах: fooobar.com/questions/415232/...

Ответ 4

Я реализовал аналогичную вещь следующим образом:

  • Преобразование всех местоположений в координаты экрана с помощью map.getProjection().toScreenLocation()
  • Используйте стандартную формулу расстояния для определения расстояния от точки к точке (или от точки к сегменту, если вы хотите также обнаруживать клики на сегментах линии), и если это расстояние меньше определенного порогового щелчка.

Ключевым моментом здесь является использование проекции карты для получения экранных координат. Таким образом, решение зависит от реального расстояния между пикселями на экране и не зависит от уровня масштабирования.