yandexmobile / yandexmapkit-android

Yandex Map Kit for Android
160 stars 65 forks source link

Клик по произвольному объекту наследнику OverlayItem #299

Closed pdapnz closed 6 years ago

pdapnz commented 6 years ago

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

TrackOverlayItem(GeoPoint geoPoint, Drawable drawable) {
    super(geoPoint, drawable);
}

И выход судя по всему только один - переопределять onSingleTapUp. Правильно ли я понимаю мне необходимо экранные координаты преобразовать в geo-координаты и дальше по своему алгоритму искать линии которые попали "под палец"?

@Override
public boolean onSingleTapUp(float x, float y) {
    //получаем реальный координаты
    getMapController().getGeoPoint(new ScreenPoint(x, y))
    //перебираем все объекты, ищем те, которые попали под тап
    return true;
}

Или есть более простой способ?

P.S. Более того пользователь может тапнуть на несколько "наложившихся" друг на друга линий, и в идеале нужно определить все на которые он попал, а не самую верхнюю =/

pdapnz commented 6 years ago

В итоге так и сделал. TrackOverlayItem хранит ссылку на список точек каждого трека трека. При тапе переводим экранные координаты в географические и ищем перебором по всем точкам треков. Способ позволяет найти все треки которые попали под тап.

public class TracksOverlay extends Overlay {

   ..........

   @Override
    public boolean onSingleTapUp(float x, float y) {

        if (isVisible()) {

            if (mListener != null) {
                List<OverlayItem> items = findOverlayItems(x, y);
                if (items.size() == 1) {
                    mListener.onClick(items.get(0));
                    return true;
                } else if (items.size() > 1) {
                    mItemsListener.onClick(items);
                    return true;
                }
            }
        }

        return false;
    }

    @NonNull
    private List<OverlayItem> findOverlayItems(float x, float y) {
        // задаем дельту от центра тапа
        GeoPoint maxPoint = getMapController().getGeoPoint(new ScreenPoint(x + DELTA_PX, y - DELTA_PX));
        GeoPoint minPoint = getMapController().getGeoPoint(new ScreenPoint(x - DELTA_PX, y + DELTA_PX));

        for (TrackOverlayItem item : mTrackOverlayItemList) {
            // и ищем перебором по всем своим координатам внутри этой области
        }
        return findedItems;
    }

   ..........