generated from Grigo/AndroidTemplate
Added marker manager
Hoping to get a sick day
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Реализация карты для Яндекс.Карт
|
||||
* Использует новый менеджер маркеров для предотвращения финализации объектов
|
||||
*/
|
||||
public class YandexMapImpl implements MapInterface {
|
||||
|
||||
@@ -30,35 +31,22 @@ public class YandexMapImpl implements MapInterface {
|
||||
private MapObjectCollection mapObjects;
|
||||
private MarkerClickListener markerClickListener;
|
||||
|
||||
private Map<String, com.yandex.mapkit.map.PlacemarkMapObject> aisMarkers;
|
||||
private Map<String, AISVessel> aisVessels; // Храним ссылки на AISVessel объекты
|
||||
private com.yandex.mapkit.map.PlacemarkMapObject ownVesselMarker;
|
||||
private Vessel ownVessel; // Храним ссылку на наше судно
|
||||
|
||||
// Флаги для отслеживания состояния обработчиков
|
||||
private boolean ownVesselClickListenerSet = false;
|
||||
private Map<String, Boolean> aisVesselClickListenersSet = new HashMap<>();
|
||||
|
||||
// Флаги для предотвращения повторного добавления обработчиков
|
||||
private Map<String, Boolean> aisVesselClickListenersAdded = new HashMap<>();
|
||||
// Новый менеджер маркеров
|
||||
private YandexMarkerManager markerManager;
|
||||
|
||||
// Слушатель поворота карты
|
||||
private com.yandex.mapkit.map.InputListener inputListener;
|
||||
private float lastMapAzimuth = 0.0f;
|
||||
|
||||
// Отслеживание двойного клика для AIS судов
|
||||
private Map<String, Long> lastClickTime = new HashMap<>();
|
||||
private static final long DOUBLE_CLICK_DELAY = 300; // 300мс для двойного клика
|
||||
|
||||
public YandexMapImpl(Context context, MapView mapView) {
|
||||
this.context = context;
|
||||
this.mapView = mapView;
|
||||
this.aisMarkers = new HashMap<>();
|
||||
this.aisVessels = new HashMap<>();
|
||||
|
||||
// Получение коллекции объектов карты
|
||||
try {
|
||||
this.mapObjects = mapView.getMap().getMapObjects().addCollection();
|
||||
// Инициализируем менеджер маркеров
|
||||
this.markerManager = new YandexMarkerManager(context, mapObjects, mapView);
|
||||
} catch (Exception e) {
|
||||
// Ошибка создания коллекции объектов карты
|
||||
}
|
||||
@@ -68,10 +56,21 @@ public class YandexMapImpl implements MapInterface {
|
||||
public void initialize() {
|
||||
// Инициализируем слушатель поворота карты
|
||||
setupCameraListener();
|
||||
|
||||
// Инициализируем менеджер маркеров
|
||||
if (markerManager != null) {
|
||||
markerManager.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
// Очищаем менеджер маркеров
|
||||
if (markerManager != null) {
|
||||
markerManager.cleanup();
|
||||
}
|
||||
|
||||
// Удаляем слушатель ввода
|
||||
if (inputListener != null && mapView != null) {
|
||||
mapView.getMap().removeInputListener(inputListener);
|
||||
@@ -87,168 +86,44 @@ public class YandexMapImpl implements MapInterface {
|
||||
|
||||
@Override
|
||||
public void addOwnVesselMarker(Vessel vessel) {
|
||||
// Сохраняем ссылку на судно
|
||||
this.ownVessel = vessel;
|
||||
|
||||
// Проверяем валидность координат (исключаем только невалидные значения)
|
||||
if (Double.isNaN(vessel.getLatitude()) || Double.isNaN(vessel.getLongitude()) ||
|
||||
Double.isInfinite(vessel.getLatitude()) || Double.isInfinite(vessel.getLongitude())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ownVesselMarker != null) {
|
||||
mapObjects.remove(ownVesselMarker);
|
||||
}
|
||||
|
||||
Point point = new Point(vessel.getLatitude(), vessel.getLongitude());
|
||||
ownVesselMarker = mapObjects.addPlacemark(point);
|
||||
|
||||
if (ownVesselMarker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Используем готовую иконку стрелки с учетом курса (синий цвет для нашего судна)
|
||||
setMarkerIcon(ownVesselMarker, "target", vessel.getCourse(), android.graphics.Color.BLUE);
|
||||
|
||||
// Устанавливаем размер иконки
|
||||
com.yandex.mapkit.map.IconStyle iconStyle = new com.yandex.mapkit.map.IconStyle();
|
||||
iconStyle.setScale(1.0f); // Уменьшаем масштаб иконки
|
||||
ownVesselMarker.setIconStyle(iconStyle);
|
||||
|
||||
// Устанавливаем обработчик кликов только если он еще не установлен
|
||||
if (!ownVesselClickListenerSet) {
|
||||
ownVesselMarker.addTapListener((mapObject, point1) -> {
|
||||
if (markerClickListener != null && ownVessel != null) {
|
||||
markerClickListener.onOwnVesselClick(ownVessel);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
ownVesselClickListenerSet = true;
|
||||
if (markerManager != null) {
|
||||
markerManager.updateOwnVesselMarker(vessel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOwnVesselPosition(Vessel vessel) {
|
||||
// Обновляем ссылку на судно
|
||||
this.ownVessel = vessel;
|
||||
|
||||
// Проверяем валидность координат (исключаем только невалидные значения)
|
||||
if (Double.isNaN(vessel.getLatitude()) || Double.isNaN(vessel.getLongitude()) ||
|
||||
Double.isInfinite(vessel.getLatitude()) || Double.isInfinite(vessel.getLongitude())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ownVesselMarker == null) {
|
||||
// Создаем маркер нашего судна, если его еще нет
|
||||
addOwnVesselMarker(vessel);
|
||||
} else {
|
||||
// Всегда обновляем иконку с текущим курсом
|
||||
// Обновляем иконку с новым курсом (синий цвет для нашего судна)
|
||||
setMarkerIcon(ownVesselMarker, "target", vessel.getCourse(), android.graphics.Color.BLUE);
|
||||
|
||||
// Обновляем позицию маркера
|
||||
Point newPoint = new Point(vessel.getLatitude(), vessel.getLongitude());
|
||||
ownVesselMarker.setGeometry(newPoint);
|
||||
|
||||
// Обработчик клика уже установлен при создании маркера, не добавляем повторно
|
||||
if (markerManager != null) {
|
||||
markerManager.updateOwnVesselMarker(vessel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAISVesselMarker(AISVessel vessel) {
|
||||
// Проверяем валидность координат (исключаем только невалидные значения)
|
||||
if (Double.isNaN(vessel.getLatitude()) || Double.isNaN(vessel.getLongitude()) ||
|
||||
Double.isInfinite(vessel.getLatitude()) || Double.isInfinite(vessel.getLongitude())) {
|
||||
return;
|
||||
if (markerManager != null) {
|
||||
markerManager.updateAISVesselMarker(vessel);
|
||||
}
|
||||
|
||||
Point point = new Point(vessel.getLatitude(), vessel.getLongitude());
|
||||
com.yandex.mapkit.map.PlacemarkMapObject marker = mapObjects.addPlacemark(point);
|
||||
|
||||
if (marker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Сохраняем ссылку на судно
|
||||
aisVessels.put(vessel.getMmsi(), vessel);
|
||||
|
||||
// Используем готовую иконку стрелки для AIS судов с учетом курса и цвета
|
||||
int vesselColor = getVesselColor(vessel);
|
||||
setMarkerIcon(marker, "target", vessel.getCourse(), vesselColor, vessel.isSelected());
|
||||
|
||||
// Устанавливаем размер иконки
|
||||
com.yandex.mapkit.map.IconStyle iconStyle = new com.yandex.mapkit.map.IconStyle();
|
||||
iconStyle.setScale(1.0f); // Уменьшаем масштаб иконки
|
||||
marker.setIconStyle(iconStyle);
|
||||
|
||||
// Установка обработчика кликов только если он еще не установлен
|
||||
String mmsi = vessel.getMmsi();
|
||||
if (!aisVesselClickListenersAdded.containsKey(mmsi) || !aisVesselClickListenersAdded.get(mmsi)) {
|
||||
marker.addTapListener((mapObject, point1) -> {
|
||||
// Проверяем двойной клик
|
||||
long currentTime = System.currentTimeMillis();
|
||||
Long lastTime = lastClickTime.get(mmsi);
|
||||
|
||||
if (lastTime != null && (currentTime - lastTime) < DOUBLE_CLICK_DELAY) {
|
||||
// Двойной клик - вызываем BottomSheet
|
||||
if (markerClickListener != null) {
|
||||
markerClickListener.onAISVesselClick(vessel);
|
||||
}
|
||||
lastClickTime.remove(mmsi); // Сбрасываем для следующего двойного клика
|
||||
} else {
|
||||
// Одиночный клик - выделяем/снимаем выделение
|
||||
toggleVesselSelection(vessel);
|
||||
lastClickTime.put(mmsi, currentTime);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
aisVesselClickListenersAdded.put(mmsi, true);
|
||||
}
|
||||
|
||||
aisMarkers.put(vessel.getMmsi(), marker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAISVesselPosition(AISVessel vessel) {
|
||||
// Обновляем ссылку на судно
|
||||
aisVessels.put(vessel.getMmsi(), vessel);
|
||||
|
||||
com.yandex.mapkit.map.PlacemarkMapObject marker = aisMarkers.get(vessel.getMmsi());
|
||||
if (marker != null) {
|
||||
Point newPoint = new Point(vessel.getLatitude(), vessel.getLongitude());
|
||||
marker.setGeometry(newPoint);
|
||||
|
||||
// Всегда обновляем курс маркера
|
||||
int vesselColor = getVesselColor(vessel);
|
||||
setMarkerIcon(marker, "target", vessel.getCourse(), vesselColor, vessel.isSelected());
|
||||
|
||||
// Обработчик клика уже установлен при создании маркера, не добавляем повторно
|
||||
if (markerManager != null) {
|
||||
markerManager.updateAISVesselMarker(vessel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAISVesselMarker(String mmsi) {
|
||||
com.yandex.mapkit.map.PlacemarkMapObject marker = aisMarkers.remove(mmsi);
|
||||
if (marker != null) {
|
||||
mapObjects.remove(marker);
|
||||
if (markerManager != null) {
|
||||
markerManager.removeAISVesselMarker(mmsi);
|
||||
}
|
||||
// Удаляем ссылку на судно
|
||||
aisVessels.remove(mmsi);
|
||||
// Удаляем флаги обработчиков кликов
|
||||
aisVesselClickListenersSet.remove(mmsi);
|
||||
aisVesselClickListenersAdded.remove(mmsi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAISVesselMarkers() {
|
||||
for (com.yandex.mapkit.map.PlacemarkMapObject marker : aisMarkers.values()) {
|
||||
mapObjects.remove(marker);
|
||||
if (markerManager != null) {
|
||||
markerManager.clearAISVesselMarkers();
|
||||
}
|
||||
aisMarkers.clear();
|
||||
aisVessels.clear();
|
||||
aisVesselClickListenersSet.clear();
|
||||
aisVesselClickListenersAdded.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -286,159 +161,62 @@ public class YandexMapImpl implements MapInterface {
|
||||
public void setMarkerClickListener(MarkerClickListener listener) {
|
||||
this.markerClickListener = listener;
|
||||
|
||||
// Переустанавливаем обработчики кликов для всех существующих маркеров
|
||||
updateAllMarkerClickListeners();
|
||||
// Устанавливаем обработчик в менеджере маркеров
|
||||
if (markerManager != null) {
|
||||
markerManager.setMarkerClickListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет обработчики кликов для всех существующих маркеров
|
||||
* Этот метод переустанавливает обработчики для всех маркеров
|
||||
*/
|
||||
private void updateAllMarkerClickListeners() {
|
||||
// Обработчик для маркера нашего судна уже установлен при создании, не добавляем повторно
|
||||
|
||||
// Обработчики для AIS маркеров уже установлены при создании, не добавляем повторно
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание повернутой цветной иконки из ресурса
|
||||
*/
|
||||
private Bitmap createRotatedIconFromResource(int resourceId, double course, int color) {
|
||||
return createRotatedIconFromResource(resourceId, course, color, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание повернутой цветной иконки из ресурса с поддержкой выделения
|
||||
*/
|
||||
private Bitmap createRotatedIconFromResource(int resourceId, double course, int color, boolean isSelected) {
|
||||
try {
|
||||
// Получаем drawable из ресурса
|
||||
Drawable drawable = context.getResources().getDrawable(resourceId, null);
|
||||
if (drawable == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Применяем цвет к drawable
|
||||
if (color != 0) {
|
||||
drawable.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
// Получаем оригинальные размеры drawable
|
||||
int originalWidth = drawable.getIntrinsicWidth();
|
||||
int originalHeight = drawable.getIntrinsicHeight();
|
||||
|
||||
// Если размеры не определены, используем стандартные
|
||||
if (originalWidth <= 0) originalWidth = 32;
|
||||
if (originalHeight <= 0) originalHeight = 48;
|
||||
|
||||
// Масштабируем размеры (уменьшаем еще больше)
|
||||
float scale = 0.3f; // Уменьшаем в 3.3 раза
|
||||
int width = (int) (originalWidth * scale);
|
||||
int height = (int) (originalHeight * scale);
|
||||
|
||||
// Получаем азимут карты (поворот карты)
|
||||
float mapAzimuth = 0.0f;
|
||||
try {
|
||||
CameraPosition cameraPosition = mapView.getMap().getCameraPosition();
|
||||
mapAzimuth = cameraPosition.getAzimuth();
|
||||
} catch (Exception e) {
|
||||
// Не удалось получить азимут карты
|
||||
}
|
||||
|
||||
// Создаем bitmap минимального размера для уменьшения хитбокса
|
||||
int bitmapSize = Math.max(width, height) + 8; // Добавляем только небольшой отступ
|
||||
Bitmap bitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
// Поворачиваем маркер на курс судна с учетом поворота карты
|
||||
// Курс судна - это направление относительно севера
|
||||
// Азимут карты - это поворот карты относительно севера
|
||||
// Итоговый поворот = курс судна - азимут карты (чтобы маркер оставался относительно севера)
|
||||
float rotationAngle = (float) (course - mapAzimuth);
|
||||
|
||||
// Центрируем drawable в bitmap
|
||||
int centerX = bitmapSize / 2;
|
||||
int centerY = bitmapSize / 2;
|
||||
int left = centerX - width / 2;
|
||||
int top = centerY - height / 2;
|
||||
|
||||
// Устанавливаем границы для drawable
|
||||
drawable.setBounds(left, top, left + width, top + height);
|
||||
|
||||
// Поворачиваем canvas на курс
|
||||
canvas.save();
|
||||
canvas.rotate(rotationAngle, centerX, centerY);
|
||||
|
||||
// Рисуем drawable
|
||||
drawable.draw(canvas);
|
||||
|
||||
canvas.restore();
|
||||
|
||||
// Если судно выделено, добавляем рамку выделения
|
||||
if (isSelected) {
|
||||
// Получаем drawable для рамки выделения
|
||||
Drawable selectionDrawable = context.getResources().getDrawable(
|
||||
context.getResources().getIdentifier("chosentarget", "drawable", context.getPackageName()), null);
|
||||
|
||||
if (selectionDrawable != null) {
|
||||
// Масштабируем рамку выделения
|
||||
int selectionSize = Math.max(width, height) + 16; // Рамка немного больше
|
||||
int selectionLeft = centerX - selectionSize / 2;
|
||||
int selectionTop = centerY - selectionSize / 2;
|
||||
|
||||
selectionDrawable.setBounds(selectionLeft, selectionTop,
|
||||
selectionLeft + selectionSize, selectionTop + selectionSize);
|
||||
|
||||
// Рисуем рамку выделения
|
||||
selectionDrawable.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
public void refreshMarkerClickListeners() {
|
||||
if (markerManager != null) {
|
||||
markerManager.checkAndRestoreMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание иконки судна
|
||||
* Перерисовывает все маркеры с учетом текущего азимута карты
|
||||
* Вызывается при повороте карты
|
||||
*/
|
||||
private Bitmap createVesselIcon(int color, double course) {
|
||||
try {
|
||||
int size = 64; // Увеличиваем размер для лучшей видимости
|
||||
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setColor(color);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeWidth(3.0f);
|
||||
|
||||
// Рисуем треугольник-стрелку, направленную вверх (по умолчанию)
|
||||
android.graphics.Path path = new android.graphics.Path();
|
||||
path.moveTo(size / 2f, 0); // вершина
|
||||
path.lineTo(size * 0.1f, size * 0.8f); // левый нижний угол
|
||||
path.lineTo(size * 0.3f, size * 0.6f); // левая внутренняя точка
|
||||
path.lineTo(size * 0.3f, size * 0.9f); // левая нижняя точка
|
||||
path.lineTo(size * 0.7f, size * 0.9f); // правая нижняя точка
|
||||
path.lineTo(size * 0.7f, size * 0.6f); // правая внутренняя точка
|
||||
path.lineTo(size * 0.9f, size * 0.8f); // правый нижний угол
|
||||
path.close();
|
||||
|
||||
// Поворачиваем стрелку на курс (курс 0° = стрелка направлена вверх)
|
||||
// В морской навигации курс 0° = север, 90° = восток, 180° = юг, 270° = запад
|
||||
canvas.save();
|
||||
canvas.rotate((float) course, size / 2f, size / 2f);
|
||||
canvas.drawPath(path, paint);
|
||||
canvas.restore();
|
||||
|
||||
return bitmap;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
public void refreshAllMarkers() {
|
||||
if (markerManager != null) {
|
||||
markerManager.refreshAllMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет все маркеры при повороте карты
|
||||
* Вызывается из слушателя поворота карты
|
||||
*/
|
||||
public void onMapRotationChanged() {
|
||||
if (markerManager != null) {
|
||||
markerManager.refreshAllMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет и восстанавливает финализированные маркеры
|
||||
*/
|
||||
public void checkAndRestoreMarkers() {
|
||||
if (markerManager != null) {
|
||||
markerManager.checkAndRestoreMarkers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает количество активных маркеров
|
||||
*/
|
||||
public int getActiveMarkerCount() {
|
||||
if (markerManager != null) {
|
||||
return markerManager.getActiveMarkerCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Получение MapView для использования в layout
|
||||
*/
|
||||
@@ -446,79 +224,6 @@ public class YandexMapImpl implements MapInterface {
|
||||
return mapView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Принудительно пересоздает маркер нашего судна с иконкой
|
||||
*/
|
||||
public void recreateOwnVesselMarker(Vessel vessel) {
|
||||
if (ownVesselMarker != null) {
|
||||
mapObjects.remove(ownVesselMarker);
|
||||
ownVesselMarker = null;
|
||||
}
|
||||
addOwnVesselMarker(vessel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет обработчики кликов для всех маркеров
|
||||
* Вызывается после закрытия BottomSheet для восстановления функциональности
|
||||
*/
|
||||
public void refreshMarkerClickListeners() {
|
||||
updateAllMarkerClickListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает иконку для маркера с fallback
|
||||
*/
|
||||
private void setMarkerIcon(com.yandex.mapkit.map.PlacemarkMapObject marker, String iconName, double course) {
|
||||
setMarkerIcon(marker, iconName, course, 0); // По умолчанию без цвета
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает цветную иконку для маркера с fallback
|
||||
*/
|
||||
private void setMarkerIcon(com.yandex.mapkit.map.PlacemarkMapObject marker, String iconName, double course, int color) {
|
||||
setMarkerIcon(marker, iconName, course, color, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает цветную иконку для маркера с поддержкой выделения
|
||||
*/
|
||||
private void setMarkerIcon(com.yandex.mapkit.map.PlacemarkMapObject marker, String iconName, double course, int color, boolean isSelected) {
|
||||
try {
|
||||
// Сначала пробуем использовать ресурс с поворотом
|
||||
int iconResId = context.getResources().getIdentifier(iconName, "drawable", context.getPackageName());
|
||||
|
||||
if (iconResId != 0) {
|
||||
Bitmap rotatedBitmap = createRotatedIconFromResource(iconResId, course, color, isSelected);
|
||||
if (rotatedBitmap != null) {
|
||||
marker.setIcon(ImageProvider.fromBitmap(rotatedBitmap));
|
||||
return;
|
||||
} else {
|
||||
marker.setIcon(ImageProvider.fromResource(context, iconResId));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Если ресурс не найден, создаем программную иконку с учетом курса
|
||||
Bitmap iconBitmap = createVesselIcon(android.graphics.Color.BLUE, course);
|
||||
if (iconBitmap != null) {
|
||||
marker.setIcon(ImageProvider.fromBitmap(iconBitmap));
|
||||
} else {
|
||||
// Создаем простую иконку как fallback
|
||||
marker.setIcon(ImageProvider.fromResource(context, android.R.drawable.ic_menu_compass));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Создаем простую иконку как fallback
|
||||
marker.setIcon(ImageProvider.fromResource(context, android.R.drawable.ic_menu_compass));
|
||||
}
|
||||
|
||||
// После установки иконки проверяем, что обработчик клика все еще работает
|
||||
// Это может помочь с проблемами, когда установка иконки нарушает обработчики
|
||||
|
||||
// Обработчик клика для нашего судна уже установлен при создании маркера, не добавляем повторно
|
||||
|
||||
// Обработчики кликов уже установлены при создании маркеров, не добавляем повторно
|
||||
}
|
||||
|
||||
/**
|
||||
* Настройка слушателя поворота карты
|
||||
*/
|
||||
@@ -541,71 +246,29 @@ public class YandexMapImpl implements MapInterface {
|
||||
|
||||
// Включаем жесты поворота карты
|
||||
mapView.getMap().setRotateGesturesEnabled(true);
|
||||
|
||||
// Добавляем слушатель изменений камеры для обновления маркеров при повороте
|
||||
mapView.getMap().addCameraListener(new com.yandex.mapkit.map.CameraListener() {
|
||||
private long lastUpdateTime = 0;
|
||||
private static final long UPDATE_THROTTLE = 100; // 100мс между обновлениями
|
||||
|
||||
@Override
|
||||
public void onCameraPositionChanged(com.yandex.mapkit.map.Map map,
|
||||
com.yandex.mapkit.map.CameraPosition cameraPosition,
|
||||
com.yandex.mapkit.map.CameraUpdateReason reason,
|
||||
boolean finished) {
|
||||
|
||||
// Обновляем маркеры в реальном времени с throttling
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - lastUpdateTime >= UPDATE_THROTTLE) {
|
||||
onMapRotationChanged();
|
||||
lastUpdateTime = currentTime;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
// Ошибка установки слушателя
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Перерисовывает все маркеры с учетом текущего азимута карты
|
||||
* Вызывается при повороте карты
|
||||
*/
|
||||
public void refreshAllMarkers() {
|
||||
// Перерисовываем маркер нашего судна (синий цвет)
|
||||
if (ownVesselMarker != null && ownVessel != null) {
|
||||
setMarkerIcon(ownVesselMarker, "target", ownVessel.getCourse(), android.graphics.Color.BLUE);
|
||||
}
|
||||
|
||||
// Перерисовываем все AIS маркеры с их цветами
|
||||
for (Map.Entry<String, com.yandex.mapkit.map.PlacemarkMapObject> entry : aisMarkers.entrySet()) {
|
||||
String mmsi = entry.getKey();
|
||||
com.yandex.mapkit.map.PlacemarkMapObject marker = entry.getValue();
|
||||
AISVessel vessel = aisVessels.get(mmsi);
|
||||
|
||||
if (marker != null && vessel != null) {
|
||||
int vesselColor = getVesselColor(vessel);
|
||||
setMarkerIcon(marker, "target", vessel.getCourse(), vesselColor, vessel.isSelected());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Переключает выделение AIS судна
|
||||
*/
|
||||
private void toggleVesselSelection(AISVessel vessel) {
|
||||
vessel.setSelected(!vessel.isSelected());
|
||||
|
||||
// Обновляем иконку маркера с учетом состояния выделения
|
||||
com.yandex.mapkit.map.PlacemarkMapObject marker = aisMarkers.get(vessel.getMmsi());
|
||||
if (marker != null) {
|
||||
int vesselColor = getVesselColor(vessel);
|
||||
setMarkerIcon(marker, "target", vessel.getCourse(), vesselColor, vessel.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает цвет для AIS судна в зависимости от его статуса
|
||||
*/
|
||||
private int getVesselColor(AISVessel vessel) {
|
||||
// Можно настроить цвета в зависимости от параметров судна
|
||||
// Используем navigation status из AIS данных
|
||||
String navStatus = vessel.getNavigationalStatus();
|
||||
if (navStatus != null) {
|
||||
switch (navStatus.toLowerCase()) {
|
||||
case "under way using engine":
|
||||
case "under way":
|
||||
return android.graphics.Color.GREEN;
|
||||
case "at anchor":
|
||||
return android.graphics.Color.YELLOW;
|
||||
case "moored":
|
||||
return android.graphics.Color.BLUE;
|
||||
case "not under command":
|
||||
case "restricted manoeuvrability":
|
||||
return android.graphics.Color.RED;
|
||||
default:
|
||||
return android.graphics.Color.WHITE;
|
||||
}
|
||||
}
|
||||
return android.graphics.Color.WHITE; // По умолчанию белый
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user