Files
AndroidAisMap/class_diagram_plantuml.md
T

26 KiB

Диаграмма классов AIS Map Application (PlantUML)

@startuml AIS_Map_Architecture

!define RECTANGLE class
skinparam classAttributeIconSize 0
skinparam classFontSize 9
skinparam packageFontSize 11
skinparam backgroundColor white
skinparam classBackgroundColor white
skinparam packageBackgroundColor lightblue
skinparam packageBorderColor black
skinparam classBorderColor black
skinparam interfaceBackgroundColor lightgreen
skinparam interfaceBorderColor black

package "Main Activity" {
    class MainActivity {
        - AppCoordinator appCoordinator
        - MenuBinder menuBinder
        - BottomSheetsBinder bottomSheetsBinder
        - PermissionsBinder permissionsBinder
        - MapController mapController
        - CompassController compassController
        - UIRenderingCoordinator uiCoordinator
        - MapView mapView
        - SettingsManager settingsManager
        - CompassView compassView
        - CoordinatesDockWidget coordinatesWidget
        - BottomSheetsManager bottomSheetsManager
        + onCreate()
        + onResume()
        + onPause()
        + onDestroy()
    }
    
    class AisTargetsActivity {
        - AisTargetsAdapter adapter
        - List<AISVessel> aisVessels
        + onCreate()
        + updateAISList()
    }
    
    class SettingsActivity {
        - SettingsManager settingsManager
        + onCreate()
        + saveSettings()
    }
}

package "Controllers Factory" {
    interface ControllersFactory {
        + createAppCoordinator() : AppCoordinator
    }
    
    class DefaultControllersFactory {
        + createAppCoordinator() : AppCoordinator
    }
}

package "Core Controllers" {
    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()
        + isAndroidNMEAEnabled() : boolean
        + isUDPEnabled() : boolean
    }
    
    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() : boolean
        + isCompassActive() : boolean
        + getCompassStatus() : String
        + onCompassChanged()
        + onCompassError()
    }
    
    class MapController {
        - Context context
        - MapInterface currentMapInterface
        - MapView mapView
        - MapLibreMapView mapLibreView
        - List<MapInterfaceChangeListener> listeners
        + addMapInterfaceChangeListener()
        + removeMapInterfaceChangeListener()
        + switchToYandexMaps()
        + switchToMapLibre()
        + getCurrentMapInterface() : MapInterface
    }
}

package "UI Binders" {
    class MenuBinder {
        - AppCoordinator appCoordinator
        - SettingsManager settingsManager
        - MenuActions actions
        + onCreateOptionsMenu()
        + onPrepareOptionsMenu()
        + onOptionsItemSelected()
    }
    
    class BottomSheetsBinder {
        - Context context
        - BottomSheetDialog ownVesselBottomSheet
        - BottomSheetDialog aisVesselBottomSheet
        - View ownBottomSheetView
        - View aisBottomSheetView
        - AISVessel currentAISVessel
        - Handler updateHandler
        - Runnable updateRunnable
        + init()
        + initAIS()
        + showOwnVesselSheet()
        + showAISVesselSheet()
        + startAutoUpdate()
        + stopAutoUpdate()
    }
    
    class BottomSheetsManager {
        - Context context
        - AppCoordinator appCoordinator
        - BottomSheetDialog ownVesselBottomSheet
        - BottomSheetDialog aisVesselBottomSheet
        - View bottomSheetView
        - View aisBottomSheetView
        - AISVessel currentAISVessel
        - Handler timeUpdateHandler
        - Handler bottomSheetUpdateHandler
        + init()
        + showOwnVesselSheet()
        + showAISVesselSheet()
        + updateOwnVesselUI()
        + updateAISBottomSheetUI()
        + stopAutoUpdate()
    }
    
    class PermissionsBinder {
        - Activity activity
        + ensurePermission() : boolean
        + handleOnRequestPermissionsResult() : boolean
    }
}

package "Data Processing" {
    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() : boolean
        + stopListening()
        + setCallback()
    }
    
    class GPSLocationListener {
        - Context context
        - LocationManager locationManager
        - LocationCallback callback
        - boolean isListening
        - int satelliteCount
        - int activeSatellites
        - double pdop
        - double hdop
        - double vdop
        + startListening() : boolean
        + stopListening()
        + setCallback()
    }
    
    class VesselPathController {
        - Context context
        - SettingsManager settingsManager
        - SharedPreferences prefs
        - String vesselId
        - Handler uiHandler
        - List<VesselPathPoint> pathPoints
        - VesselPathPoint lastPoint
        + addPathPoint()
        + getPathPoints() : List<VesselPathPoint>
        + clearPath()
        + savePath()
        + loadPath()
    }
}

package "Maps" {
    interface MapInterface {
        + initialize()
        + cleanup()
        + addOwnVesselMarker()
        + updateOwnVesselPosition()
        + addAISVesselMarker()
        + updateAISVesselPosition()
        + removeAISVesselMarker()
        + clearAISVesselMarkers()
        + centerOnPosition()
        + setZoom()
        + getZoom() : float
        + setBearing()
        + getBearing() : float
        + addLayer()
        + removeLayer()
        + setMarkerClickListener()
        + clearVesselPath()
        + showCursor()
        + hideCursor()
        + updateCursorCoordinates()
        + updateCursorFromMapCenter()
        + setAisVesselInfo()
        + clearAisVesselInfo()
    }
    
    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() : float
        + setBearing()
        + getBearing() : float
    }
    
    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() : float
        + setBearing()
        + getBearing() : float
    }
    
    class MapForgeImpl {
        - Context context
        - MapView mapView
        - MarkerClickListener markerClickListener
        - CursorOverlay cursorOverlay
        - Vessel ownVessel
        + initialize()
        + cleanup()
        + addOwnVesselMarker()
        + updateOwnVesselPosition()
        + addAISVesselMarker()
        + updateAISVesselPosition()
        + removeAISVesselMarker()
        + clearAISVesselMarkers()
        + centerOnPosition()
        + setZoom()
        + getZoom() : float
        + setBearing()
        + getBearing() : float
    }
    
    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()
    }
}

package "Data Models" {
    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() : int
        + getGPSQualityDescription() : String
    }
    
    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() : boolean
        + shouldBeRemoved() : boolean
        + getMinutesSinceLastUpdate() : long
    }
    
    class VesselPathPoint {
        - double latitude
        - double longitude
        - double course
        - double speed
        - long timestamp
        + VesselPathPoint()
        + toJSON() : String
        + fromJSON()
    }
}

package "Database" {
    abstract class AppDatabase {
        + aisVesselDao() : AISVesselDao
        + vesselDao() : VesselDao
        + getInstance() : AppDatabase
    }
    
    class Repository {
        - AISVesselDao aisVesselDao
        - VesselDao vesselDao
        - ExecutorService ioExecutor
        + upsertAIS()
        + deleteStaleAIS()
        + getAllAISSync() : List<AISVesselEntity>
        + observeAllAIS() : LiveData<List<AISVesselEntity>>
        + getAISByMmsiSync() : AISVesselEntity
        + upsertOwnVessel()
        + getLatestOwnVesselSync() : VesselEntity
        + getLatestOwnVesselAsync()
    }
    
    interface AISVesselDao {
        + upsert()
        + deleteStale()
        + getAll() : List<AISVesselEntity>
        + observeAll() : LiveData<List<AISVesselEntity>>
        + getByMmsi() : AISVesselEntity
    }
    
    interface VesselDao {
        + upsert()
        + getLatest() : VesselEntity
    }
    
    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
    }
}

package "UI Components" {
    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()
    }
    
    interface UIDataChangeNotifier {
        + 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
        - CompassListener 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()
    }
}

package "Services" {
    class NotificationService {
        - Context context
        - SettingsManager settingsManager
        - Vibrator vibrator
        - ToneGenerator toneGenerator
        - boolean isInitialized
        + showSafetyAlert()
        + showNewVesselNotification()
        + clearNotifications()
        + setVibrationEnabled()
        + setSoundEnabled()
    }
    
    class AISForegroundService {
        - Context context
        - AppCoordinator appCoordinator
        - NotificationManager notificationManager
        - boolean isRunning
        + startForeground()
        + stopForeground()
        + onStartCommand()
        + onDestroy()
    }
}

package "Utils" {
    class SettingsManager {
        - Context context
        - SharedPreferences prefs
        + getUDPPort() : int
        + setUDPPort()
        + isUDPEnabled() : boolean
        + setUDPEnabled()
        + isAndroidNMEAEnabled() : boolean
        + setAndroidNMEAEnabled()
        + isUDPNMEAEnabled() : boolean
        + setUDPNMEAEnabled()
        + getDataMode() : String
        + setDataMode()
        + getDataStaleWarningMinutes() : int
        + setDataStaleWarningMinutes()
        + getDataStaleRemoveMinutes() : int
        + setDataStaleRemoveMinutes()
        + isPathTrackingEnabled() : boolean
        + setPathTrackingEnabled()
        + getPathColor() : int
        + setPathColor()
        + getPredictionColor() : int
        + setPredictionColor()
        + getPathWidth() : float
        + setPathWidth()
        + getPredictionWidth() : float
        + setPredictionWidth()
        + getPathMaxPoints() : int
        + setPathMaxPoints()
        + getPredictionHorizonSec() : int
        + setPredictionHorizonSec()
        + isVibrationEnabled() : boolean
        + setVibrationEnabled()
        + isSoundEnabled() : boolean
        + setSoundEnabled()
        + isKeepScreenOnEnabled() : boolean
        + setKeepScreenOnEnabled()
        + isCursorEnabled() : boolean
        + setCursorEnabled()
    }
    
    class GeoUtils {
        + calculateDistance() : double
        + calculateBearing() : double
        + isValidCoordinate() : boolean
        + formatCoordinate() : String
        + convertToDecimalDegrees() : double
    }
    
    class LogSender {
        + sendLog()
        + sendError()
        + sendWarning()
        + sendInfo()
    }
    
    class MIDToCountry {
        + getCountryByMID() : String
        + getCountryName() : String
        + isValidMID() : boolean
    }
    
    class NavigationUtils {
        + calculateCourse() : double
        + calculateSpeed() : double
        + calculateETA() : LocalDateTime
        + isCollisionRisk() : boolean
    }
}

' Relationships
MainActivity --> AppCoordinator : uses
MainActivity --> MenuBinder : uses
MainActivity --> BottomSheetsBinder : uses
MainActivity --> PermissionsBinder : uses
MainActivity --> MapController : uses
MainActivity --> CompassController : uses
MainActivity --> UIRenderingCoordinator : uses
MainActivity --> CompassView : uses
MainActivity --> CoordinatesDockWidget : uses
MainActivity --> BottomSheetsManager : uses

ControllersFactory <|.. DefaultControllersFactory : implements
MainActivity --> ControllersFactory : uses
DefaultControllersFactory --> AppCoordinator : creates

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

MenuBinder --> AppCoordinator : uses
MenuBinder --> SettingsManager : uses
BottomSheetsBinder --> Context : uses
BottomSheetsManager --> AppCoordinator : uses
PermissionsBinder --> Activity : uses

MapController --> MapInterface : manages
MapController --> YandexMapImpl : creates
MapController --> MapLibreMapImpl : creates
MapController --> MapForgeImpl : creates

YandexMapImpl ..|> MapInterface : implements
MapLibreMapImpl ..|> MapInterface : implements
MapForgeImpl ..|> MapInterface : 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

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

' Interface implementations
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

@enduml

Описание PlantUML диаграммы

🎯 Преимущества PlantUML:

  1. Компактность - более читаемая структура
  2. Группировка - логическое разделение по пакетам
  3. Цветовое кодирование - разные цвета для разных типов компонентов
  4. Автоматическое позиционирование - PlantUML сам расставляет элементы
  5. Экспорт - легко экспортировать в PNG, SVG, PDF

📦 Структура пакетов:

  • Main Activity - основные активности приложения
  • Controllers Factory - фабрика для создания контроллеров
  • Core Controllers - основные контроллеры системы
  • UI Binders - компоненты для управления UI
  • Data Processing - обработка данных и парсинг
  • Maps - система карт и маркеров
  • Data Models - модели данных
  • Database - слой базы данных
  • UI Components - UI компоненты
  • Services - сервисы приложения
  • Utils - утилиты и вспомогательные классы

🔗 Типы связей:

  • --> - использование/зависимость
  • ..|> - реализация интерфейса
  • <|.. - наследование
  • -- - ассоциация

🎨 Визуальные особенности:

  • Интерфейсы выделены специальным стилем
  • Абстрактные классы помечены как abstract
  • Утилиты помечены как <<utility>>
  • Четкое разделение по функциональным областям

Эта диаграмма более компактна и лучше подходит для презентаций и документации. Вы можете использовать её в PlantUML редакторах или онлайн сервисах для генерации изображений.