Как использовать setTag полилинии для сохранения пользовательских данных в Google Maps - PullRequest
0 голосов
/ 29 декабря 2018

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

Код для достижения полилинии

PolylineOptions lineOptions = new PolylineOptions().width(7).color(Color.BLACK).geodesic(true);

for (int i = 0; i < points.size(); i++) {
    LatLng latLng1 = new LatLng(Double.parseDouble(points.get(i).getmLatitude()), Double.parseDouble(points.get(i).getmLongitude()));
    lineOptions.add(latLng1);
}

if (mPolyline != null) {
    mPolyline.remove();
}

mPolyline = mMap.addPolyline(lineOptions);
mPolyline.setClickable(true);

for (int i = 0; i < points.size(); i++) {
//setting tags to be used on ployline click                   
mPolyline.setTag(points.get(i).getTime());
}

List<PatternItem> pattern = Arrays.asList(
        new Gap(15), new Dash(15), new Gap(15));
mPolyline.setPattern(pattern);
mPolyline.setJointType(JointType.ROUND);

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

mMap.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
    @Override
    public void onPolylineClick(Polyline polyline) {
        Toast.makeText(mContext, (String) polyline.getTag(), Toast.LENGTH_SHORT).show();
    }
});

Спасибо за помощь:)

РЕДАКТИРОВАТЬ

 mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
    @Override
    public void onMapClick(LatLng latLng) {
        boolean isOnRoute = PolyUtil.isLocationOnPath(latLng, lineOptions.getPoints(), false, 25);

        if (isOnRoute) {              
            for (LocationVo mCoordinates : points) {
              double distanceInMeters =  SphericalUtil.computeDistanceBetween(latLng, mCoordinates.getmLatLong());
                boolean isWithin50m = distanceInMeters < 50;
                if (isWithin50m) {
                    Toast.makeText(mContext, mCoordinates.getTime(), Toast.LENGTH_SHORT).show();
                    break;
                }
            }
        }
    }
});

Не все мои полилинии соответствуют условиям и не показывают тосты при клике

1 Ответ

0 голосов
/ 16 января 2019

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

Проблема, с которой вы столкнулись, заключается в вашем предположении, что вы всегда будете в пределах 50 метров от точки - это неверно, а также не то, что вы хотите, насколько я могу судить.По определению, если isOnRoute истинно, вы всегда хотите найти точку, поскольку по определению они нажали на ломаную линию;это делается (неэффективно) путем простого вычисления всех расстояний от точки щелчка до всех точек ломаной линии и определения кратчайшего расстояния (простой цикл с логикой min);затем используйте эту точку для вашего тоста.

Теперь, если вы действительно хотите ограничить то, что считается «успешным» кликом, где успешный клик - это и «на ломаной линии», и «около точки», тогда ваша проверка расстояния будет добавлена ​​ с использованием некоторого приемлемого значения - это будет фактически определять «коробку» вокруг каждой точки с размерами 50 метров (25 x 2) - независимо от того, какой будет ваша проверка расстояния.Обратите внимание, что это не то же самое, что просто проверка радиуса окружности вокруг каждой точки, если радиус желаемой окружности не эквивалентен допуску ломаной линии.

(Еще одна тривиальная точка - измерение микшированиясистемы, использующие false для геодезической, а затем для вычисления сферического расстояния - но это не должно быть проблемой для вашей реализации.) (Если будет полезно, я добавлю картинку позже.)

Сводка изменений: "проверьте, еслипользователь щелкает вдоль ломаной линии «И», чтобы определить ближайшую точку вдоль линии «И», отображать некоторые тосты за эту точку ».

Так что внесите эту модификацию после того, как isOnRoute истинно:

        LocationVo closestPoint = null;
        double minDist = -1;
        for (LocationVo mCoordinates : points) {
          double distanceInMeters =  SphericalUtil.computeDistanceBetween(latLng, mCoordinates.getmLatLong());
          if (minDist < 0 || distanceInMeters < minDist) {
             minDist = distanceInMeters;
             closestPoint = mCoordinates;
          }
        }
        if (closestPoint != null) {
            Toast.makeText(mContext, closestPoint.getTime(), Toast.LENGTH_SHORT).show();
        }

Чтобы реализовать рассмотренную выше «рамку» вокруг каждой точки, измените одно условие:

          if ((distanceInMeters < MAX_DISTANCE_FROM_POINT) && (minDist < 0 || distanceInMeters < minDist)) {

Обратите внимание, это означает, что в некоторых случаях вы не получите тост, даже если они щелкнули вдоль полилинии.

...