generated from Grigo/AndroidTemplate
982e940b8d
Новые векторные иконки: - cog.xml: иконка шестеренки для настроек - compass.xml: иконка компаса для навигации - ownship.xml: иконка собственного судна - targetlist.xml: иконка списка целей с текстом 'LIST' Архитектурные изменения: - MainActivity.java: +99/- строк - обновление UI логики - AppController.java: +111/- строк - рефакторинг контроллера приложения - MapLibreMapImpl.java: +525/- строк - значительные улучшения карты - MapInterface.java: +10 строк - расширение интерфейса карты - CursorOverlay.java: +329/- строк - улучшение курсора и оверлеев - GeoUtils.java: +92 строк - новые гео-утилиты - NavigationUtils.java: +81/- строк - оптимизация навигации - VesselPathTracker.java: +18/- строк - улучшение трекинга судов - MapForgeImpl.java, YandexMapImpl.java: обновления карт UI изменения: - activity_main.xml: +65/- строк - обновление главного layout - cursor.xml: +16/- строк - улучшение курсора - targetlist.xml: +39 строк - обновление иконки списка целей Общий объем: +1087/-328 строк Подготовка к новой архитектуре UI и картографических компонентов
353 lines
9.3 KiB
Markdown
353 lines
9.3 KiB
Markdown
# Диаграмма классов AISMap
|
|
|
|
```mermaid
|
|
classDiagram
|
|
%% ========== MAIN ACTIVITY ==========
|
|
class MainActivity {
|
|
-AppController appController
|
|
-MapController mapController
|
|
-MapInterface mapInterface
|
|
-UIRenderingCoordinator uiCoordinator
|
|
-CompassView compassView
|
|
-CoordinatesDockWidget coordinatesWidget
|
|
-SettingsManager settingsManager
|
|
+onCreate()
|
|
+onStart()
|
|
+onStop()
|
|
+checkPermissions()
|
|
}
|
|
|
|
%% ========== CORE CONTROLLERS ==========
|
|
class AppController {
|
|
-Context context
|
|
-NMEAParser nmeaParser
|
|
-UDPListener udpListener
|
|
-AndroidNMEAListener androidNmeaListener
|
|
-GPSLocationListener gpsLocationListener
|
|
-MapInterface mapInterface
|
|
-Repository repository
|
|
-Vessel ownVessel
|
|
-Map~String,AISVessel~ activeVessels
|
|
-ExecutorService executor
|
|
+setMapInterface(MapInterface)
|
|
+startGPS()
|
|
+startUDP()
|
|
+getNearbyVessels()
|
|
+cleanup()
|
|
+Note: "Runtime State Manager"
|
|
}
|
|
|
|
class MapController {
|
|
-MapInterface mapInterface
|
|
-VesselPathController pathController
|
|
+initialize()
|
|
+updateVesselPosition()
|
|
+addAISVessel()
|
|
}
|
|
|
|
class VesselPathController {
|
|
-List~VesselPathPoint~ pathPoints
|
|
-int maxPathPoints
|
|
+addPathPoint(Vessel)
|
|
+getPath()
|
|
+clearPath()
|
|
}
|
|
|
|
%% ========== DATA MODELS ==========
|
|
class Vessel {
|
|
-double latitude
|
|
-double longitude
|
|
-double course
|
|
-double speed
|
|
-double heading
|
|
-int signalStrength
|
|
-LocalDateTime lastUpdate
|
|
-String vesselName
|
|
-String mmsi
|
|
-double altitude
|
|
-int satellites
|
|
-double pdop, hdop, vdop
|
|
+updatePosition()
|
|
+updateGPSQuality()
|
|
+getGPSQualityPercentage()
|
|
}
|
|
|
|
class AISVessel {
|
|
-String mmsi
|
|
-String vesselName
|
|
-String callSign
|
|
-int imo
|
|
-String vesselType
|
|
-double latitude, longitude
|
|
-double course, speed
|
|
-double heading, rateOfTurn
|
|
-double length, width, draft
|
|
-String destination
|
|
-LocalDateTime eta
|
|
-String navigationalStatus
|
|
+updatePosition()
|
|
+isDataStale()
|
|
+shouldBeRemoved()
|
|
}
|
|
|
|
class VesselPathPoint {
|
|
-double latitude
|
|
-double longitude
|
|
-LocalDateTime timestamp
|
|
-double course
|
|
-double speed
|
|
}
|
|
|
|
%% ========== MAP INTERFACES ==========
|
|
class MapInterface {
|
|
<<interface>>
|
|
+initialize()
|
|
+cleanup()
|
|
+addOwnVesselMarker(Vessel)
|
|
+updateOwnVesselPosition(Vessel)
|
|
+addAISVesselMarker(AISVessel)
|
|
+updateAISVesselPosition(AISVessel)
|
|
+removeAISVesselMarker(String)
|
|
+centerOnPosition(double, double)
|
|
+setMarkerClickListener(MarkerClickListener)
|
|
}
|
|
|
|
class YandexMapImpl {
|
|
-MapView mapView
|
|
-Map~String, PlacemarkMapObject~ aisMarkers
|
|
-PlacemarkMapObject ownVesselMarker
|
|
+initialize()
|
|
+addOwnVesselMarker()
|
|
+updateOwnVesselPosition()
|
|
}
|
|
|
|
class MapLibreMapImpl {
|
|
-MapView mapView
|
|
-GeoJsonSource source
|
|
-Map~String, JSONObject~ idToFeature
|
|
-Handler uiHandler
|
|
+initialize()
|
|
+refreshGeoJson()
|
|
+updateOwnVesselPosition()
|
|
}
|
|
|
|
class MapForgeImpl {
|
|
-MapView mapView
|
|
-List~Marker~ aisMarkers
|
|
-Marker ownVesselMarker
|
|
+initialize()
|
|
+addMarker()
|
|
+updateMarker()
|
|
}
|
|
|
|
%% ========== DATA PARSERS ==========
|
|
class NMEAParser {
|
|
-Vessel ownVessel
|
|
-List~AISVessel~ aisVessels
|
|
-NMEAParserListener listener
|
|
-GPSLocationListener gpsLocationListener
|
|
-boolean hybridMode
|
|
+parseNMEA(String)
|
|
+setHybridMode(boolean)
|
|
+parseGGA()
|
|
+parseRMC()
|
|
+parseAIS()
|
|
}
|
|
|
|
class UDPListener {
|
|
-int port
|
|
-DatagramSocket socket
|
|
-UDPListenerCallback callback
|
|
-boolean isListening
|
|
+startListening()
|
|
+stopListening()
|
|
+sendData()
|
|
}
|
|
|
|
class AndroidNMEAListener {
|
|
-LocationManager locationManager
|
|
-NMEAMessageCallback callback
|
|
+startListening()
|
|
+stopListening()
|
|
}
|
|
|
|
class GPSLocationListener {
|
|
-LocationManager locationManager
|
|
-LocationCallback callback
|
|
-Location lastLocation
|
|
+startLocationUpdates()
|
|
+stopLocationUpdates()
|
|
}
|
|
|
|
%% ========== UI COMPONENTS ==========
|
|
class CompassView {
|
|
-float targetAzimuth
|
|
-float currentAzimuth
|
|
-float magneticCompass
|
|
-List~AISVessel~ nearbyVessels
|
|
-Vessel ourVessel
|
|
+updateAzimuth(float)
|
|
+updateNearbyVessels()
|
|
+onDrawDock()
|
|
}
|
|
|
|
class CoordinatesDockWidget {
|
|
-Vessel vessel
|
|
-String coordinatesText
|
|
-String sogText
|
|
-String cogText
|
|
+updateVessel(Vessel)
|
|
+onDrawDock()
|
|
}
|
|
|
|
class BaseDockWidget {
|
|
<<abstract>>
|
|
-boolean isDockTop
|
|
-OnDockResizeListener resizeListener
|
|
+setDockPosition()
|
|
#onDrawDock()
|
|
#dp(int)
|
|
}
|
|
|
|
class CursorOverlay {
|
|
-TextView tvCursorLatitude
|
|
-TextView tvCursorLongitude
|
|
-TextView tvDistance
|
|
-Vessel ownVessel
|
|
-AISVessel currentAisVessel
|
|
+updateCursorPosition()
|
|
+updateAISVesselInfo()
|
|
}
|
|
|
|
%% ========== UTILITIES ==========
|
|
class SettingsManager {
|
|
-SharedPreferences prefs
|
|
+getUDPPort()
|
|
+isUDPEnabled()
|
|
+getDataMode()
|
|
+saveSettings()
|
|
}
|
|
|
|
class NavigationUtils {
|
|
<<utility>>
|
|
+calculateDistance()
|
|
+calculateBearing()
|
|
+formatCoordinates()
|
|
+formatSpeed()
|
|
}
|
|
|
|
class GeoUtils {
|
|
<<utility>>
|
|
+calculateDistance()
|
|
+calculateBearing()
|
|
+getVesselsInRadius()
|
|
+calculateCompassPosition()
|
|
+formatCoordinates()
|
|
+predictPosition()
|
|
+getNavigationStatusCode()
|
|
}
|
|
|
|
%% ========== DATA LAYER ==========
|
|
class Repository {
|
|
-AppDatabase database
|
|
-AISVesselDao aisDao
|
|
-VesselDao vesselDao
|
|
+saveVessel()
|
|
+saveAISVessel()
|
|
+getHistoricalVessels()
|
|
+cleanupOldData()
|
|
+getAISVessels()
|
|
+Note: "Persistent Data Manager"
|
|
}
|
|
|
|
class AppDatabase {
|
|
<<Room Database>>
|
|
+aisVesselDao()
|
|
+vesselDao()
|
|
}
|
|
|
|
%% ========== INTERFACES ==========
|
|
class NMEAParserListener {
|
|
<<interface>>
|
|
+onVesselUpdated(Vessel)
|
|
+onAISVesselUpdated(AISVessel)
|
|
+onParseError(String)
|
|
}
|
|
|
|
class UDPListenerCallback {
|
|
<<interface>>
|
|
+onDataReceived(String)
|
|
+onError(String)
|
|
}
|
|
|
|
class LocationCallback {
|
|
<<interface>>
|
|
+onLocationUpdated(Location)
|
|
+onLocationError(String)
|
|
}
|
|
|
|
class MarkerClickListener {
|
|
<<interface>>
|
|
+onOwnVesselClick(Vessel)
|
|
+onAISVesselClick(AISVessel)
|
|
}
|
|
|
|
%% ========== RELATIONSHIPS ==========
|
|
|
|
%% Main Activity relationships
|
|
MainActivity --> AppController : uses
|
|
MainActivity --> MapController : uses
|
|
MainActivity --> MapInterface : uses
|
|
MainActivity --> CompassView : contains
|
|
MainActivity --> CoordinatesDockWidget : contains
|
|
MainActivity --> SettingsManager : uses
|
|
|
|
%% AppController relationships
|
|
AppController --> NMEAParser : uses
|
|
AppController --> UDPListener : uses
|
|
AppController --> AndroidNMEAListener : uses
|
|
AppController --> GPSLocationListener : uses
|
|
AppController --> MapInterface : uses
|
|
AppController --> Vessel : manages
|
|
AppController --> AISVessel : manages
|
|
AppController ..|> NMEAParserListener : implements
|
|
AppController ..|> UDPListenerCallback : implements
|
|
AppController ..|> LocationCallback : implements
|
|
AppController ..|> MarkerClickListener : implements
|
|
|
|
%% Map implementations
|
|
MapInterface <|.. YandexMapImpl : implements
|
|
MapInterface <|.. MapLibreMapImpl : implements
|
|
MapInterface <|.. MapForgeImpl : implements
|
|
|
|
%% Parser relationships
|
|
NMEAParser --> NMEAParserListener : notifies
|
|
UDPListener --> UDPListenerCallback : notifies
|
|
GPSLocationListener --> LocationCallback : notifies
|
|
|
|
%% UI relationships
|
|
BaseDockWidget <|-- CompassView : extends
|
|
BaseDockWidget <|-- CoordinatesDockWidget : extends
|
|
CompassView --> Vessel : displays
|
|
CompassView --> AISVessel : displays
|
|
CoordinatesDockWidget --> Vessel : displays
|
|
|
|
%% Data relationships
|
|
MapController --> VesselPathController : uses
|
|
VesselPathController --> VesselPathPoint : manages
|
|
AppController --> Repository : uses for persistence
|
|
Repository --> AppDatabase : uses
|
|
Repository --> Vessel : stores
|
|
Repository --> AISVessel : stores
|
|
|
|
%% Utility relationships - CENTRALIZED
|
|
AppController --> GeoUtils : uses for calculations
|
|
CompassView --> GeoUtils : uses for positioning
|
|
CursorOverlay --> GeoUtils : uses for distance/bearing
|
|
MapController --> GeoUtils : uses for predictions
|
|
NavigationUtils ..> Vessel : formats
|
|
NavigationUtils ..> AISVessel : formats
|
|
GeoUtils ..> Vessel : calculates
|
|
GeoUtils ..> AISVessel : calculates
|
|
```
|