Major architecture update

This commit is contained in:
2025-10-07 09:34:26 +03:00
parent 982e940b8d
commit a607133032
32 changed files with 6439 additions and 2061 deletions
+803
View File
@@ -0,0 +1,803 @@
# Диаграмма классов AIS Map Application (Обновленная архитектура)
```mermaid
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