Files
AndroidAisMap/class_diagram_mermaid.md
T
2025-10-07 09:34:26 +03:00

24 KiB

Диаграмма классов AIS Map Application (Обновленная архитектура)

classDiagram
    %% Основные Activity и UI компоненты
    class MainActivity {
        -AppCoordinator appCoordinator
        -MapController mapController
        -CompassController compassController
        -UIRenderingCoordinator uiCoordinator
        -MapView mapView
        -SettingsManager settingsManager
        -CompassView compassView
        -CoordinatesDockWidget coordinatesWidget
        +onCreate()
        +onResume()
        +onPause()
        +onDestroy()
    }

    class AisTargetsActivity {
        -AisTargetsAdapter adapter
        -List~AISVessel~ aisVessels
        +onCreate()
        +updateAISList()
    }

    class SettingsActivity {
        -SettingsManager settingsManager
        +onCreate()
        +saveSettings()
    }

    %% Главный координатор приложения (новая архитектура)
    class AppCoordinator {
        -Context context
        -NMEAController nmeaController
        -NetworkController networkController
        -DataController dataController
        -NotificationController notificationController
        -CompassController compassController
        -MapController mapController
        -Vessel ownVessel
        -List~AISVessel~ aisVessels
        -Map~String, VesselPathController~ aisPathControllers
        -SettingsManager settingsManager
        -VesselPathController pathController
        -UIDataChangeNotifier uiDataNotifier
        -Handler uiHandler
        -AppCoordinatorListener listener
        +initializeControllers()
        +startServices()
        +stopServices()
        +onVesselUpdated()
        +onAISVesselUpdated()
        +onDOPUpdated()
        +onDataReceived()
        +onNotificationShown()
        +onCompassChanged()
    }

    %% Специализированные контроллеры (новая архитектура)
    class NMEAController {
        -Context context
        -NMEAParser nmeaParser
        -AndroidNMEAListener androidNmeaListener
        -GPSLocationListener gpsLocationListener
        -ExecutorService executor
        -NMEAControllerListener listener
        +startAndroidNMEAListener()
        +stopAndroidNMEAListener()
        +startGPSLocationListener()
        +stopGPSLocationListener()
        +parseNMEAData()
        +onVesselUpdated()
        +onAISVesselUpdated()
        +onDOPUpdated()
    }

    class NetworkController {
        -Context context
        -UDPListener udpListener
        -ExecutorService executor
        -int udpPort
        -boolean isUDPEnabled
        -boolean isUDPNMEAEnabled
        -NetworkControllerListener listener
        +setUDPEnabled()
        +startUDPListener()
        +stopUDPListener()
        +onDataReceived()
        +onUDPError()
    }

    class DataController {
        -Context context
        -Repository repository
        -SettingsManager settingsManager
        -ExecutorService executor
        -Handler dbCleanupHandler
        -Runnable dbCleanupRunnable
        -DataControllerListener listener
        +restoreDataAsync()
        +saveVesselData()
        +saveAISData()
        +performDatabaseCleanup()
        +onDataRestored()
        +onDataSaved()
        +onDataCleaned()
    }

    class NotificationController {
        -Context context
        -NotificationService notificationService
        -NotificationControllerListener listener
        +notifyNewAISTarget()
        +notifySafetyMessage()
        +notifyGPSStatus()
        +onNotificationShown()
        +onNotificationError()
    }

    class CompassController {
        -Context context
        -CompassSensor compassSensor
        -Handler uiHandler
        -CompassControllerListener listener
        +startCompass()
        +stopCompass()
        +isCompassAvailable()
        +isCompassActive()
        +getCompassStatus()
        +onCompassChanged()
        +onCompassError()
    }

    %% Контроллеры
    class MapController {
        -Context context
        -MapInterface currentMapInterface
        -MapView mapView
        -org.maplibre.android.maps.MapView mapLibreView
        -List~MapInterfaceChangeListener~ listeners
        +addMapInterfaceChangeListener()
        +removeMapInterfaceChangeListener()
        +switchToYandexMaps()
        +switchToMapLibre()
        +getCurrentMapInterface()
    }

    class NMEAParser {
        -Vessel ownVessel
        -List~AISVessel~ aisVessels
        -NMEAParserListener listener
        -GPSLocationListener gpsLocationListener
        -Map~String, Map~Integer, String~~ aisFragments
        -boolean hybridMode
        +parseNMEA()
        +setHybridMode()
        +setGPSLocationListener()
    }

    class UDPListener {
        -int port
        -DatagramSocket socket
        -ExecutorService executor
        -AtomicBoolean isRunning
        -UDPListenerCallback callback
        +start()
        +stop()
        +setCallback()
    }

    class AndroidNMEAListener {
        -LocationManager locationManager
        -NMEAMessageCallback callback
        -boolean isListening
        +startListening()
        +stopListening()
        +setCallback()
    }

    class GPSLocationListener {
        -Context context
        -LocationManager locationManager
        -LocationCallback callback
        -boolean isListening
        -int satelliteCount
        -int activeSatellites
        -double pdop
        -double hdop
        -double vdop
        +startListening()
        +stopListening()
        +setCallback()
    }

    class VesselPathController {
        -Context context
        -SettingsManager settingsManager
        -SharedPreferences prefs
        -String vesselId
        -Handler uiHandler
        -List~VesselPathPoint~ pathPoints
        -VesselPathPoint lastPoint
        +addPathPoint()
        +getPathPoints()
        +clearPath()
        +savePath()
        +loadPath()
    }

    %% Интерфейсы карт
    class MapInterface {
        <<interface>>
        +initialize()
        +cleanup()
        +addOwnVesselMarker()
        +updateOwnVesselPosition()
        +addAISVesselMarker()
        +updateAISVesselPosition()
        +removeAISVesselMarker()
        +clearAISVesselMarkers()
        +centerOnPosition()
        +setZoom()
        +getZoom()
        +setBearing()
        +getBearing()
        +addLayer()
        +removeLayer()
        +setMarkerClickListener()
        +clearVesselPath()
        +showCursor()
        +hideCursor()
        +updateCursorCoordinates()
        +updateCursorFromMapCenter()
        +setAisVesselInfo()
        +clearAisVesselInfo()
    }

    class MapInterfaceChangeListener {
        <<interface>>
        +onMapInterfaceChanged()
    }

    class MarkerClickListener {
        <<interface>>
        +onOwnVesselClick()
        +onAISVesselClick()
    }

    %% Реализации карт
    class YandexMapImpl {
        -Context context
        -MapView mapView
        -MapObjectCollection mapObjects
        -MarkerClickListener markerClickListener
        -YandexMarkerManager markerManager
        -CursorOverlay cursorOverlay
        -Vessel ownVessel
        +initialize()
        +cleanup()
        +addOwnVesselMarker()
        +updateOwnVesselPosition()
        +addAISVesselMarker()
        +updateAISVesselPosition()
        +removeAISVesselMarker()
        +clearAISVesselMarkers()
        +centerOnPosition()
        +setZoom()
        +getZoom()
        +setBearing()
        +getBearing()
    }

    class MapLibreMapImpl {
        -Context context
        -MapView mapView
        -MapLibreMap mapLibreMap
        -MarkerClickListener markerClickListener
        -CursorOverlay cursorOverlay
        -Vessel ownVessel
        -Map~String, AISVessel~ aisVessels
        +initialize()
        +cleanup()
        +addOwnVesselMarker()
        +updateOwnVesselPosition()
        +addAISVesselMarker()
        +updateAISVesselPosition()
        +removeAISVesselMarker()
        +clearAISVesselMarkers()
        +centerOnPosition()
        +setZoom()
        +getZoom()
        +setBearing()
        +getBearing()
    }

    %% Менеджеры маркеров
    class YandexMarkerManager {
        -MapObjectCollection mapObjects
        -Map~String, YandexMarkerWrapper~ ownVesselMarkers
        -Map~String, YandexMarkerWrapper~ aisVesselMarkers
        +addOwnVesselMarker()
        +updateOwnVesselMarker()
        +addAISVesselMarker()
        +updateAISVesselMarker()
        +removeAISVesselMarker()
        +clearAllMarkers()
    }

    class MarkerManager {
        -MapLibreMap mapLibreMap
        -Map~String, MarkerWrapper~ ownVesselMarkers
        -Map~String, MarkerWrapper~ aisVesselMarkers
        +addOwnVesselMarker()
        +updateOwnVesselMarker()
        +addAISVesselMarker()
        +updateAISVesselMarker()
        +removeAISVesselMarker()
        +clearAllMarkers()
    }

    %% Модели данных
    class Vessel {
        -double latitude
        -double longitude
        -double course
        -double speed
        -double heading
        -double magneticCompass
        -int signalStrength
        -LocalDateTime lastUpdate
        -String vesselName
        -String mmsi
        -String callSign
        -double altitude
        -int satellites
        -int activeSatellites
        -double pdop
        -double hdop
        -double vdop
        -float accuracy
        -long fixTime
        -String fixQuality
        +updatePosition()
        +updateGPSQuality()
        +getGPSQualityPercentage()
        +getGPSQualityDescription()
    }

    class AISVessel {
        -String mmsi
        -String vesselName
        -String callSign
        -int imo
        -String vesselType
        -double latitude
        -double longitude
        -double course
        -double speed
        -double heading
        -double rateOfTurn
        -double length
        -double width
        -double draft
        -String destination
        -LocalDateTime eta
        -LocalDateTime lastUpdate
        -int signalStrength
        -boolean isActive
        -String navigationalStatus
        -String lastSafetyMessage
        -boolean positionAccuracy
        -String vesselClass
        -String vendorId
        -boolean selected
        +updatePosition()
        +isDataStale()
        +shouldBeRemoved()
        +getMinutesSinceLastUpdate()
    }

    class VesselPathPoint {
        -double latitude
        -double longitude
        -double course
        -double speed
        -long timestamp
        +VesselPathPoint()
        +toJSON()
        +fromJSON()
    }

    %% База данных и репозиторий
    class AppDatabase {
        <<abstract>>
        +aisVesselDao() AISVesselDao
        +vesselDao() VesselDao
        +getInstance() AppDatabase
    }

    class Repository {
        -AISVesselDao aisVesselDao
        -VesselDao vesselDao
        -ExecutorService ioExecutor
        +upsertAIS()
        +deleteStaleAIS()
        +getAllAISSync()
        +observeAllAIS()
        +getAISByMmsiSync()
        +upsertOwnVessel()
        +getLatestOwnVesselSync()
        +getLatestOwnVesselAsync()
    }

    class AISVesselDao {
        <<interface>>
        +upsert()
        +deleteStale()
        +getAll()
        +observeAll()
        +getByMmsi()
    }

    class VesselDao {
        <<interface>>
        +upsert()
        +getLatest()
    }

    class AISVesselEntity {
        -String mmsi
        -String vesselName
        -String callSign
        -int imo
        -String vesselType
        -double latitude
        -double longitude
        -double course
        -double speed
        -double heading
        -double rateOfTurn
        -double length
        -double width
        -double draft
        -String destination
        -long etaEpochMs
        -long lastUpdateEpochMs
        -int signalStrength
        -boolean isActive
        -String navigationalStatus
        -String lastSafetyMessage
        -boolean positionAccuracy
        -String vesselClass
        -String vendorId
    }

    class VesselEntity {
        -double latitude
        -double longitude
        -double course
        -double speed
        -double heading
        -double magneticCompass
        -int signalStrength
        -long lastUpdateEpochMs
        -String vesselName
        -String mmsi
        -String callSign
        -double altitude
        -int satellites
        -int activeSatellites
        -double pdop
        -double hdop
        -double vdop
        -float accuracy
        -long fixTime
        -String fixQuality
    }

    %% UI компоненты
    class UIRenderingCoordinator {
        -MapInterface mapInterface
        -Handler uiHandler
        -Vessel pendingVesselUpdate
        -Map~String, AISVessel~ pendingAISUpdates
        -Set~String~ pendingAISRemovals
        -Runnable vesselUpdateRunnable
        -Runnable aisUpdateRunnable
        -Runnable pathUpdateRunnable
        -boolean vesselUpdatePending
        -boolean aisUpdatePending
        -boolean pathUpdatePending
        +requestVesselUpdate()
        +requestAISUpdate()
        +requestAISRemoval()
        +flushPendingOperations()
        +cleanup()
    }

    class UIDataChangeNotifier {
        <<interface>>
        +onVesselPositionChanged()
        +onGPSQualityChanged()
        +onAISVesselChanged()
        +onAISVesselRemoved()
        +onVesselPathChanged()
        +onRequestCenterMap()
        +onCompassUpdate()
    }

    class CompassView {
        -float azimuth
        -Paint compassPaint
        -Paint needlePaint
        -Paint textPaint
        -List~AISVessel~ nearbyVessels
        +setAzimuth()
        +setNearbyVessels()
        +onDraw()
    }

    class CompassSensor {
        -SensorManager sensorManager
        -Sensor magnetometer
        -Sensor accelerometer
        -CompassCallback callback
        -float[] lastAccelerometer
        -float[] lastMagnetometer
        -boolean lastAccelerometerSet
        -boolean lastMagnetometerSet
        -float[] rotationMatrix
        -float[] orientation
        +startListening()
        +stopListening()
        +setCallback()
    }

    class CoordinatesDockWidget {
        -TextView latitudeText
        -TextView longitudeText
        -TextView accuracyText
        -TextView satellitesText
        -TextView qualityText
        +updateCoordinates()
        +updateGPSQuality()
    }

    class CursorOverlay {
        -ViewGroup parentView
        -TextView coordinatesText
        -TextView vesselInfoText
        -boolean isVisible
        +show()
        +hide()
        +updateCoordinates()
        +setVesselInfo()
        +clearVesselInfo()
    }

    %% Сервисы
    class NotificationService {
        -Context context
        -SettingsManager settingsManager
        -Vibrator vibrator
        -ToneGenerator toneGenerator
        -boolean isInitialized
        +showSafetyAlert()
        +showNewVesselNotification()
        +clearNotifications()
        +setVibrationEnabled()
        +setSoundEnabled()
    }

    class AISForegroundService {
        -Context context
        -AppController appController
        -NotificationManager notificationManager
        -boolean isRunning
        +startForeground()
        +stopForeground()
        +onStartCommand()
        +onDestroy()
    }

    %% Утилиты
    class SettingsManager {
        -Context context
        -SharedPreferences prefs
        +getUDPPort()
        +setUDPPort()
        +isUDPEnabled()
        +setUDPEnabled()
        +isAndroidNMEAEnabled()
        +setAndroidNMEAEnabled()
        +isUDPNMEAEnabled()
        +setUDPNMEAEnabled()
        +getDataMode()
        +setDataMode()
        +getDataStaleWarningMinutes()
        +setDataStaleWarningMinutes()
        +getDataStaleRemoveMinutes()
        +setDataStaleRemoveMinutes()
        +isPathTrackingEnabled()
        +setPathTrackingEnabled()
        +getPathColor()
        +setPathColor()
        +getPredictionColor()
        +setPredictionColor()
        +getPathWidth()
        +setPathWidth()
        +getPredictionWidth()
        +setPredictionWidth()
        +getPathMaxPoints()
        +setPathMaxPoints()
        +getPredictionHorizonSec()
        +setPredictionHorizonSec()
        +isVibrationEnabled()
        +setVibrationEnabled()
        +isSoundEnabled()
        +setSoundEnabled()
        +isKeepScreenOnEnabled()
        +setKeepScreenOnEnabled()
        +isCursorEnabled()
        +setCursorEnabled()
    }

    class GeoUtils {
        <<utility>>
        +calculateDistance()
        +calculateBearing()
        +isValidCoordinate()
        +formatCoordinate()
        +convertToDecimalDegrees()
    }

    class LogSender {
        <<utility>>
        +sendLog()
        +sendError()
        +sendWarning()
        +sendInfo()
    }

    class MIDToCountry {
        <<utility>>
        +getCountryByMID()
        +getCountryName()
        +isValidMID()
    }

    class NavigationUtils {
        <<utility>>
        +calculateCourse()
        +calculateSpeed()
        +calculateETA()
        +isCollisionRisk()
    }

    %% Связи между классами (новая архитектура)
    MainActivity --> AppCoordinator : uses
    MainActivity --> MapController : uses
    MainActivity --> CompassController : uses
    MainActivity --> UIRenderingCoordinator : uses
    MainActivity --> CompassView : uses
    MainActivity --> CoordinatesDockWidget : uses

    AppCoordinator --> NMEAController : coordinates
    AppCoordinator --> NetworkController : coordinates
    AppCoordinator --> DataController : coordinates
    AppCoordinator --> NotificationController : coordinates
    AppCoordinator --> CompassController : coordinates
    AppCoordinator --> MapController : coordinates
    AppCoordinator --> VesselPathController : uses
    AppCoordinator --> SettingsManager : uses
    AppCoordinator --> UIRenderingCoordinator : uses

    NMEAController --> NMEAParser : uses
    NMEAController --> AndroidNMEAListener : uses
    NMEAController --> GPSLocationListener : uses

    NetworkController --> UDPListener : uses

    DataController --> Repository : uses
    DataController --> SettingsManager : uses

    NotificationController --> NotificationService : uses

    CompassController --> CompassSensor : uses

    MapController --> MapInterface : manages
    MapController --> YandexMapImpl : creates
    MapController --> MapLibreMapImpl : creates
    MapController --> MapInterfaceChangeListener : notifies

    YandexMapImpl ..|> MapInterface : implements
    MapLibreMapImpl ..|> MapInterface : implements
    AppController ..|> MapInterfaceChangeListener : implements
    AppController ..|> MarkerClickListener : implements

    YandexMapImpl --> YandexMarkerManager : uses
    MapLibreMapImpl --> MarkerManager : uses

    Repository --> AppDatabase : uses
    Repository --> AISVesselDao : uses
    Repository --> VesselDao : uses

    AppDatabase --> AISVesselEntity : contains
    AppDatabase --> VesselEntity : contains

    UIRenderingCoordinator ..|> UIDataChangeNotifier : implements
    UIRenderingCoordinator ..|> MapInterfaceChangeListener : implements

    NMEAParser --> Vessel : creates/updates
    NMEAParser --> AISVessel : creates/updates
    NMEAParser --> GPSLocationListener : uses

    VesselPathController --> VesselPathPoint : manages
    VesselPathController --> SettingsManager : uses

    NotificationService --> SettingsManager : uses

    CompassSensor --> CompassView : updates
    CompassView --> AISVessel : displays

    %% Интерфейсы и их реализации (новая архитектура)
    AppCoordinator ..|> NMEAControllerListener : implements
    AppCoordinator ..|> NetworkControllerListener : implements
    AppCoordinator ..|> DataControllerListener : implements
    AppCoordinator ..|> NotificationControllerListener : implements
    AppCoordinator ..|> CompassControllerListener : implements
    AppCoordinator ..|> MarkerClickListener : implements
    AppCoordinator ..|> MapInterfaceChangeListener : implements

    NMEAController ..|> NMEAParserListener : implements
    NMEAController ..|> NMEAMessageCallback : implements

    NetworkController ..|> UDPListenerCallback : implements

    CompassController ..|> CompassListener : implements

    NMEAParser ..|> NMEAParserListener : implements
    UDPListener ..|> UDPListenerCallback : implements
    AndroidNMEAListener ..|> NMEAMessageCallback : implements
    GPSLocationListener ..|> LocationCallback : implements
    CompassSensor ..|> CompassListener : implements

Описание обновленной архитектуры

Основные компоненты:

  1. MainActivity - главная активность приложения, координирует UI компоненты
  2. AppCoordinator - главный координатор, управляет всеми специализированными контроллерами
  3. NMEAController - специализированный контроллер для обработки NMEA сообщений
  4. NetworkController - контроллер для сетевых операций (UDP)
  5. DataController - контроллер для операций с базой данных
  6. NotificationController - контроллер для управления уведомлениями
  7. CompassController - контроллер для управления магнитным компасом
  8. MapController - управляет переключением между различными реализациями карт
  9. UIRenderingCoordinator - координирует обновления UI с throttling
  10. VesselPathController - управляет путями судов

Новая архитектура - Разделение ответственности:

AppCoordinator (Главный координатор):

  • Координирует работу всех специализированных контроллеров
  • Управляет общим состоянием приложения
  • Обрабатывает события от контроллеров и передает их в UI

Специализированные контроллеры:

  • NMEAController - только парсинг и обработка NMEA данных
  • NetworkController - только сетевые операции (UDP слушание)
  • DataController - только операции с базой данных
  • NotificationController - только показ уведомлений
  • CompassController - только работа с магнитным компасом

Паттерны архитектуры:

  • Coordinator Pattern - AppCoordinator координирует работу контроллеров
  • Single Responsibility Principle - каждый контроллер отвечает за одну область
  • Strategy Pattern - для переключения между различными реализациями карт
  • Observer Pattern - для уведомлений об изменениях данных
  • Repository Pattern - для работы с данными
  • Command Pattern - для отложенного выполнения UI операций

Преимущества новой архитектуры:

  1. Разделение ответственности - каждый контроллер отвечает за свою область
  2. Лучшая тестируемость - контроллеры можно тестировать независимо
  3. Упрощенная поддержка - изменения в одной области не влияют на другие
  4. Масштабируемость - легко добавлять новые контроллеры
  5. Чистая архитектура - четкое разделение между слоями

Особенности:

  • Гибридный режим получения GPS данных (через Location API + NMEA)
  • Throttling UI обновлений для производительности
  • Поддержка множественных источников данных (UDP, Android NMEA, GPS)
  • Модульная архитектура с возможностью переключения карт
  • Система уведомлений с вибрацией и звуком
  • Централизованная координация через AppCoordinator