Files
AndroidAisMap/class_diagram_plantuml_nographviz.md
T

23 KiB

Диаграмма классов AIS Map Application (PlantUML - Без Graphviz)

@startuml AIS_Map_Architecture_NoGraphviz

!define RECTANGLE class
skinparam classAttributeIconSize 0
skinparam classFontSize 8
skinparam packageFontSize 10
skinparam backgroundColor white
skinparam classBackgroundColor white
skinparam packageBackgroundColor lightblue
skinparam packageBorderColor black
skinparam classBorderColor black
skinparam interfaceBackgroundColor lightgreen
skinparam interfaceBorderColor black
skinparam arrowColor black
skinparam arrowThickness 1

package "Main Activity" {
    class MainActivity {
        - AppCoordinator appCoordinator
        - MenuBinder menuBinder
        - BottomSheetsBinder bottomSheetsBinder
        - PermissionsBinder permissionsBinder
        - MapController mapController
        - CompassController compassController
        - UIRenderingCoordinator uiCoordinator
        + 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
        - SettingsManager settingsManager
        + initializeControllers()
        + startServices()
        + stopServices()
        + onVesselUpdated()
        + onAISVesselUpdated()
        + onDOPUpdated()
        + onDataReceived()
        + onNotificationShown()
        + onCompassChanged()
    }
    
    class NMEAController {
        - Context context
        - NMEAParser nmeaParser
        - AndroidNMEAListener androidNmeaListener
        - GPSLocationListener gpsLocationListener
        - ExecutorService executor
        + startAndroidNMEAListener()
        + stopAndroidNMEAListener()
        + startGPSLocationListener()
        + stopGPSLocationListener()
        + parseNMEAData()
    }
    
    class NetworkController {
        - Context context
        - UDPListener udpListener
        - ExecutorService executor
        - int udpPort
        - boolean isUDPEnabled
        + setUDPEnabled()
        + startUDPListener()
        + stopUDPListener()
    }
    
    class DataController {
        - Context context
        - Repository repository
        - SettingsManager settingsManager
        - ExecutorService executor
        + restoreDataAsync()
        + saveVesselData()
        + saveAISData()
        + performDatabaseCleanup()
    }
    
    class NotificationController {
        - Context context
        - NotificationService notificationService
        + notifyNewAISTarget()
        + notifySafetyMessage()
        + notifyGPSStatus()
    }
    
    class CompassController {
        - Context context
        - CompassSensor compassSensor
        - Handler uiHandler
        + startCompass()
        + stopCompass()
        + isCompassAvailable() : boolean
        + isCompassActive() : boolean
        + getCompassStatus() : String
    }
    
    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
        + init()
        + initAIS()
        + showOwnVesselSheet()
        + showAISVesselSheet()
        + startAutoUpdate()
        + stopAutoUpdate()
    }
    
    class BottomSheetsManager {
        - Context context
        - AppCoordinator appCoordinator
        - BottomSheetDialog ownVesselBottomSheet
        - BottomSheetDialog aisVesselBottomSheet
        - View bottomSheetView
        - View aisBottomSheetView
        - AISVessel currentAISVessel
        + 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
    }
    
    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
    }
}

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
    }
}

' Основные связи
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

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

@enduml

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

🎯 Ключевые изменения для совместимости:

  1. Убрана зависимость от Graphviz - диаграмма использует только встроенные возможности PlantUML
  2. Упрощены настройки - оставлены только базовые skinparam параметры
  3. Оптимизированы размеры - уменьшены размеры шрифтов для лучшей читаемости
  4. Убраны сложные элементы - удалены некоторые методы для упрощения

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

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

Преимущества этой версии:

  1. Совместимость - работает без Graphviz
  2. Производительность - быстрее генерируется
  3. Портативность - работает в большинстве редакторов
  4. Читаемость - четкая структура и связи

🔧 Как использовать:

  1. Онлайн редакторы: PlantUML Online Server, PlantText
  2. IDE плагины: IntelliJ IDEA, VS Code, Eclipse
  3. Командная строка: PlantUML jar файл
  4. Документация: GitLab, GitHub поддерживают PlantUML

Эта версия должна работать без проблем и показывать всю архитектуру вашего AIS Map приложения!