# Диаграмма классов AIS Map Application (PlantUML) ```plantuml @startuml AIS_Map_Architecture !theme plain skinparam classAttributeIconSize 0 skinparam classFontSize 10 skinparam packageFontSize 12 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() + onCreateOptionsMenu() + onOptionsItemSelected() } class AisTargetsActivity { - AisTargetsAdapter adapter - List 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 aisVessels - Map 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 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 aisVessels - NMEAParserListener listener - GPSLocationListener gpsLocationListener - Map> 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 pathPoints - VesselPathPoint lastPoint + addPathPoint() + getPathPoints() : List + 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 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 ownVesselMarkers - Map aisVesselMarkers + addOwnVesselMarker() + updateOwnVesselMarker() + addAISVesselMarker() + updateAISVesselMarker() + removeAISVesselMarker() + clearAllMarkers() } class MarkerManager { - MapLibreMap mapLibreMap - Map ownVesselMarkers - Map 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 + observeAllAIS() : LiveData> + getAISByMmsiSync() : AISVesselEntity + upsertOwnVessel() + getLatestOwnVesselSync() : VesselEntity + getLatestOwnVesselAsync() } interface AISVesselDao { + upsert() + deleteStale() + getAll() : List + observeAll() : LiveData> + 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 pendingAISUpdates - Set 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 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` - Утилиты помечены как `<>` - Четкое разделение по функциональным областям Эта диаграмма более компактна и лучше подходит для презентаций и документации. Вы можете использовать её в PlantUML редакторах или онлайн сервисах для генерации изображений.