generated from Grigo/AndroidTemplate
feat: новая архитектура UI и расширенная визуализация AIS
Архитектурные улучшения: - Внедрен UIRenderingCoordinator с централизованным throttling - Решены проблемы зависания UI через батчинг операций карты - Добавлен VesselPathController для отслеживания маршрутов - Реализован MapLibreMapImpl как альтернатива Яндекс.Картам Визуализация AIS: - Добавлены векторные иконки для всех типов судов - Разделение Class A/B судов с соответствующими иконками - Иконки навигационных статусов (anchor, moored, engine, sail) - Улучшенный CursorOverlay с информацией о судах Производительность: - Throttling UI обновлений (vessel: 500ms, AIS: 1s, paths: 2s) - Устранение утечек Handler объектов - Оптимизация GeoJSON операций в MapLibre
This commit is contained in:
@@ -10,7 +10,10 @@ import android.view.View;
|
||||
|
||||
import com.grigowashere.aismap.models.Vessel;
|
||||
import com.grigowashere.aismap.models.AISVessel;
|
||||
import com.grigowashere.aismap.view.CursorOverlay;
|
||||
import com.grigowashere.aismap.R;
|
||||
import com.yandex.mapkit.Animation;
|
||||
import android.view.ViewGroup;
|
||||
import com.yandex.mapkit.geometry.Point;
|
||||
import com.yandex.mapkit.map.CameraPosition;
|
||||
import com.yandex.mapkit.map.MapObjectCollection;
|
||||
@@ -38,9 +41,23 @@ public class YandexMapImpl implements MapInterface {
|
||||
private com.yandex.mapkit.map.InputListener inputListener;
|
||||
private float lastMapAzimuth = 0.0f;
|
||||
|
||||
// Курсор overlay
|
||||
private CursorOverlay cursorOverlay;
|
||||
private Vessel ownVessel;
|
||||
|
||||
public YandexMapImpl(Context context, MapView mapView) {
|
||||
this.context = context;
|
||||
this.mapView = mapView;
|
||||
this.cursorOverlay = new CursorOverlay(context);
|
||||
|
||||
// Добавляем overlay курсора в MapView
|
||||
if (mapView instanceof ViewGroup) {
|
||||
ViewGroup parent = (ViewGroup) mapView;
|
||||
// Проверяем, не добавлен ли уже курсор
|
||||
if (parent.findViewById(R.id.cursor_cross) == null) {
|
||||
parent.addView(cursorOverlay.getView());
|
||||
}
|
||||
}
|
||||
|
||||
// Получение коллекции объектов карты
|
||||
try {
|
||||
@@ -59,6 +76,9 @@ public class YandexMapImpl implements MapInterface {
|
||||
// Инициализируем слушатель поворота карты
|
||||
setupCameraListener();
|
||||
|
||||
// Инициализируем слушатель движения карты
|
||||
setupMapMovementListener();
|
||||
|
||||
// Инициализируем менеджер маркеров
|
||||
if (markerManager != null) {
|
||||
markerManager.initialize();
|
||||
@@ -88,6 +108,10 @@ public class YandexMapImpl implements MapInterface {
|
||||
|
||||
@Override
|
||||
public void addOwnVesselMarker(Vessel vessel) {
|
||||
this.ownVessel = vessel;
|
||||
if (cursorOverlay != null) {
|
||||
cursorOverlay.setOwnVessel(vessel);
|
||||
}
|
||||
if (markerManager != null) {
|
||||
markerManager.updateOwnVesselMarker(vessel);
|
||||
}
|
||||
@@ -95,6 +119,10 @@ public class YandexMapImpl implements MapInterface {
|
||||
|
||||
@Override
|
||||
public void updateOwnVesselPosition(Vessel vessel) {
|
||||
this.ownVessel = vessel;
|
||||
if (cursorOverlay != null) {
|
||||
cursorOverlay.setOwnVessel(vessel);
|
||||
}
|
||||
if (markerManager != null) {
|
||||
markerManager.updateOwnVesselMarker(vessel);
|
||||
}
|
||||
@@ -255,6 +283,21 @@ public class YandexMapImpl implements MapInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Очищает трекер пути собственного судна
|
||||
*/
|
||||
@Override
|
||||
public void clearVesselPath() {
|
||||
if (markerManager != null) {
|
||||
markerManager.clearVesselPath("own_vessel");
|
||||
}
|
||||
|
||||
// Также очищаем VesselPathController если он используется
|
||||
// (для MapLibre это делается в MapLibreMapImpl, для Yandex - здесь)
|
||||
// В YandexMapImpl VesselPathController не используется напрямую,
|
||||
// но если в будущем будет использоваться, нужно добавить очистку
|
||||
}
|
||||
|
||||
/**
|
||||
* Очищает все пути движения
|
||||
*/
|
||||
@@ -359,4 +402,63 @@ public class YandexMapImpl implements MapInterface {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCursor() {
|
||||
if (cursorOverlay != null) {
|
||||
cursorOverlay.showCursor();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideCursor() {
|
||||
if (cursorOverlay != null) {
|
||||
cursorOverlay.hideCursor();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCursorCoordinates(double latitude, double longitude) {
|
||||
if (cursorOverlay != null) {
|
||||
cursorOverlay.updateCursorCoordinates(latitude, longitude);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCursorFromMapCenter() {
|
||||
if (cursorOverlay != null && mapView != null) {
|
||||
// Получаем координаты центра карты
|
||||
com.yandex.mapkit.geometry.Point center = mapView.getMap().getCameraPosition().getTarget();
|
||||
cursorOverlay.updateCursorCoordinates(center.getLatitude(), center.getLongitude());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAisVesselInfo(com.grigowashere.aismap.models.AISVessel vessel) {
|
||||
if (cursorOverlay != null) {
|
||||
cursorOverlay.setAisVesselInfo(vessel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAisVesselInfo() {
|
||||
if (cursorOverlay != null) {
|
||||
cursorOverlay.clearAisVesselInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Настраивает слушатель движения карты для обновления курсора
|
||||
*/
|
||||
private void setupMapMovementListener() {
|
||||
if (mapView != null) {
|
||||
mapView.getMap().addCameraListener(new com.yandex.mapkit.map.CameraListener() {
|
||||
@Override
|
||||
public void onCameraPositionChanged(com.yandex.mapkit.map.Map map, com.yandex.mapkit.map.CameraPosition cameraPosition, com.yandex.mapkit.map.CameraUpdateReason cameraUpdateReason, boolean finished) {
|
||||
// Обновляем координаты курсора при движении карты
|
||||
updateCursorFromMapCenter();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user