Kotlin GoogleMaps ClusterManager возвращает элементы кластера, размер которых меньше размера первоначально переданных ему элементов - PullRequest
0 голосов
/ 08 января 2020

Я использую ClusterManager для кластеризации потенциально тысяч маркеров. Кластеризация по умолчанию показывает такие значения, как 10+, 100+, 500+ и т. Д. c, и мне нужно было указать точное значение.

Поэтому я переопределил getClusterText(bucket: Int): String. При полном уменьшении масштаба один кластер, показанный на карте, будет отображать 3987, и все же я передал 4000 маркеров менеджеру кластера.

Затем я подумал, что это связано с кэшированием или чем-то еще, поэтому я увеличил масштаб, чтобы увидеть если бы все маркеры были там, где их ожидали. И вот, кажется, что, когда на одном и том же месте есть два или более маркеров (одинаковые lat и long), и одинаковые заголовок и фрагмент (я предполагаю), отображается только один из них, как если бы менеджер удалял то, что он думает, является дубликатами.

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

I во время передачи маркеров менеджеру кластера проверили, что они действительно имеют значение 4000. Но при уменьшении кластера только 4000-x

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

enter image description here

Как видите, кластеризация работает нормально. Однако, когда есть два одинаковых маркера, они не отображаются. Я проверил все подобные экземпляры (тот же lat, long и др. c), и менеджер просто отображает один элемент.

Я также пытался отрегулировать каждую переменную позиции ClusterItem, добавив очень маленькую случайную дробь к широте и долготе, а также отрегулировать заголовок и фрагмент, добавив случайную строку, но ничего не изменилось .

Что-то мне не хватает в ClusterManager или где-то еще?

Я не могу опубликовать код в данный момент

Обновление

Я проверил свой ответ json, и на этом месте действительно есть два элемента с одинаковыми данными / информацией (которые требуются и должны быть показаны). Все еще пытаюсь понять, почему они не объединяются в кластеры.

enter image description here

Ответы [ 2 ]

1 голос
/ 09 января 2020

Короче говоря:

Мой ClusterItem на самом деле является подклассом ArrayList<Double> (из-за структуры моего json). В результате clusterManager определенно игнорирует дубликаты. Как он определяет, что если два ArrayLists (для меня clisterItem), кажется, проверяет равенство содержимого , а не сами экземпляры. Так что если два ArrayLists (для меня ClusterItem) имеют одинаковое содержимое, то они одинаковы.

Long Story long:

Вот мое определение для clusterItem:

public final class CrimeQueryItem : ArrayList<Double>, ClusterItem{
    //pseudocode here!
    longitude: this[0]
    latitude: this[1]
    position: LatLng(latitude, longitude)
}

Со временем угадав, что два CrimeQueryItem совпадают, если массив, который они имеют , имеет одинаковое содержимое Я решил переопределить функцию equals:

override fun equals(other: Any?): Boolean {
    return this === other
}

Теперь это приводит к полной проверке равенства экземпляров вместо структурной проверки.

Теперь маркеры отображаются, как и ожидалось:

enter image description here

Теперь у меня больше нет расхождений в счетах:

enter image description here

Вывод: Я думаю, карта проверяет, если он уже добавил элемент, и если так, то пропускает его. В моем случае два маркера одинаковы, если они имеют одинаковое содержимое, поскольку они имеют тип ArrayList.

0 голосов
/ 08 января 2020

"Однако, когда есть два одинаковых маркера, он не отображает их. Я проверил все подобные экземпляры (один и тот же lat, long и т. Д. 1018 *), а менеджер просто отображает один элемент . "

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

Это может быть более сложный алгоритм - вам нужно определить количество маркеров с точно такой же позицией и чем разместить их, например, вокруг «центра» места. Или что-то в этом роде.

...