generated from Grigo/AndroidTemplate
Daily checkup
This commit is contained in:
@@ -196,60 +196,63 @@ public class BottomSheetsManager {
|
||||
|
||||
if (tvTitle != null) {
|
||||
String name = vessel.getVesselName() != null && !vessel.getVesselName().isEmpty() ? vessel.getVesselName() : "AIS СУДНО";
|
||||
// Флаг страны по MMSI оставляем — это единственный визуальный
|
||||
// маркер, который тут реально несёт смысл. Остальные эмодзи в
|
||||
// карточке цели убраны, чтобы текст не выглядел как чат.
|
||||
String flag = getFlagEmojiForMMSI(vessel.getMmsi());
|
||||
tvTitle.setText((flag != null ? flag + " " : "") + "🚢 " + name);
|
||||
tvTitle.setText((flag != null ? flag + " " : "") + name);
|
||||
}
|
||||
if (tvMmsi != null) tvMmsi.setText("🆔 MMSI: " + (vessel.getMmsi() != null ? vessel.getMmsi() : "--"));
|
||||
if (tvCallsign != null) tvCallsign.setText("📻 Позывной: " + (vessel.getCallSign() != null ? vessel.getCallSign() : "--"));
|
||||
if (tvImo != null) tvImo.setText("🏷️ IMO: " + (vessel.getImo() > 0 ? String.valueOf(vessel.getImo()) : "--"));
|
||||
if (tvType != null) tvType.setText("🚢 Тип: " + (vessel.getVesselType() != null ? vessel.getVesselType() : "--"));
|
||||
if (tvMmsi != null) tvMmsi.setText("MMSI: " + (vessel.getMmsi() != null ? vessel.getMmsi() : "--"));
|
||||
if (tvCallsign != null) tvCallsign.setText("Позывной: " + (vessel.getCallSign() != null ? vessel.getCallSign() : "--"));
|
||||
if (tvImo != null) tvImo.setText("IMO: " + (vessel.getImo() > 0 ? String.valueOf(vessel.getImo()) : "--"));
|
||||
if (tvType != null) tvType.setText("Тип: " + (vessel.getVesselType() != null ? vessel.getVesselType() : "--"));
|
||||
|
||||
if (tvPosition != null) {
|
||||
if (vessel.getLatitude() != 0 && vessel.getLongitude() != 0) {
|
||||
tvPosition.setText(String.format("📍 Координаты: %.6f, %.6f", vessel.getLatitude(), vessel.getLongitude()));
|
||||
tvPosition.setText(String.format("Координаты: %.6f, %.6f", vessel.getLatitude(), vessel.getLongitude()));
|
||||
} else {
|
||||
tvPosition.setText("📍 Координаты: --");
|
||||
tvPosition.setText("Координаты: --");
|
||||
}
|
||||
}
|
||||
if (tvCourse != null) tvCourse.setText(vessel.getCourse() > 0 ? String.format("🧭 COG: %.1f°", vessel.getCourse()) : "🧭 COG: --°");
|
||||
if (tvRot != null) tvRot.setText(vessel.getRateOfTurn() != 0 ? String.format("🔄 ROT: %.1f°/мин", vessel.getRateOfTurn()) : "🔄 ROT: --°/мин");
|
||||
if (tvHeading != null) tvHeading.setText(vessel.getHeading() > 0 ? String.format("🧭 HDG: %.1f°", vessel.getHeading()) : "🧭 HDG: --°");
|
||||
if (tvSpeed != null) tvSpeed.setText(vessel.getSpeed() > 0 ? String.format("⚡ Скорость: %.1f узлов", vessel.getSpeed()) : "⚡ Скорость: -- узлов");
|
||||
if (tvDimensions != null) tvDimensions.setText((vessel.getLength() > 0 && vessel.getWidth() > 0) ? String.format("📏 Размеры: %.1f x %.1f м", vessel.getLength(), vessel.getWidth()) : "📏 Размеры: --");
|
||||
if (tvDraft != null) tvDraft.setText(vessel.getDraft() > 0 ? String.format("🌊 Осадка: %.1f м", vessel.getDraft()) : "🌊 Осадка: -- м");
|
||||
if (tvDestination != null) tvDestination.setText("🎯 Назначение: " + (vessel.getDestination() != null ? vessel.getDestination() : "--"));
|
||||
if (tvEta != null) tvEta.setText(vessel.getEta() != null ? String.format("⏰ ETA: %s", vessel.getEta().format(java.time.format.DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"))) : "⏰ ETA: --");
|
||||
if (tvNavStatus != null) tvNavStatus.setText("🚦 Статус: " + (vessel.getNavigationalStatus() != null ? vessel.getNavigationalStatus() : "--"));
|
||||
if (tvClass != null) tvClass.setText("📋 Класс: " + (vessel.getVesselClass() != null ? vessel.getVesselClass() : "--"));
|
||||
if (tvCourse != null) tvCourse.setText(vessel.getCourse() > 0 ? String.format("COG: %.1f°", vessel.getCourse()) : "COG: --°");
|
||||
if (tvRot != null) tvRot.setText(vessel.getRateOfTurn() != 0 ? String.format("ROT: %.1f°/мин", vessel.getRateOfTurn()) : "ROT: --°/мин");
|
||||
if (tvHeading != null) tvHeading.setText(vessel.getHeading() > 0 ? String.format("HDG: %.1f°", vessel.getHeading()) : "HDG: --°");
|
||||
if (tvSpeed != null) tvSpeed.setText(vessel.getSpeed() > 0 ? String.format("Скорость: %.1f узлов", vessel.getSpeed()) : "Скорость: -- узлов");
|
||||
if (tvDimensions != null) tvDimensions.setText((vessel.getLength() > 0 && vessel.getWidth() > 0) ? String.format("Размеры: %.1f x %.1f м", vessel.getLength(), vessel.getWidth()) : "Размеры: --");
|
||||
if (tvDraft != null) tvDraft.setText(vessel.getDraft() > 0 ? String.format("Осадка: %.1f м", vessel.getDraft()) : "Осадка: -- м");
|
||||
if (tvDestination != null) tvDestination.setText("Назначение: " + (vessel.getDestination() != null ? vessel.getDestination() : "--"));
|
||||
if (tvEta != null) tvEta.setText(vessel.getEta() != null ? String.format("ETA: %s", vessel.getEta().format(java.time.format.DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"))) : "ETA: --");
|
||||
if (tvNavStatus != null) tvNavStatus.setText("Статус: " + (vessel.getNavigationalStatus() != null ? vessel.getNavigationalStatus() : "--"));
|
||||
if (tvClass != null) tvClass.setText("Класс: " + (vessel.getVesselClass() != null ? vessel.getVesselClass() : "--"));
|
||||
if (tvSignal != null) {
|
||||
if (vessel.getSignalStrength() > 0) {
|
||||
tvSignal.setText(String.format("📶 Сигнал: %d", vessel.getSignalStrength()));
|
||||
tvSignal.setText(String.format("Сигнал: %d", vessel.getSignalStrength()));
|
||||
} else {
|
||||
tvSignal.setText(vessel.isPositionAccuracy() ? "📶 Точность: высокая" : "📶 Точность: низкая");
|
||||
tvSignal.setText(vessel.isPositionAccuracy() ? "Точность: высокая" : "Точность: низкая");
|
||||
}
|
||||
}
|
||||
if (tvLastUpdate != null) tvLastUpdate.setText(vessel.getLastUpdate() != null ? String.format("🕐 Обновлено: %s", vessel.getLastUpdate().format(java.time.format.DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"))) : "🕐 Обновлено: --");
|
||||
if (tvLastUpdate != null) tvLastUpdate.setText(vessel.getLastUpdate() != null ? String.format("Обновлено: %s", vessel.getLastUpdate().format(java.time.format.DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"))) : "Обновлено: --");
|
||||
|
||||
if (tvDistance != null || tvBearing != null) {
|
||||
Vessel ourVessel = appCoordinator.getOwnVessel();
|
||||
if (ourVessel != null && ourVessel.getLatitude() != 0 && ourVessel.getLongitude() != 0 && vessel.getLatitude() != 0 && vessel.getLongitude() != 0) {
|
||||
double distance = com.grigowashere.aismap.utils.NavigationUtils.calculateDistance(ourVessel.getLatitude(), ourVessel.getLongitude(), vessel.getLatitude(), vessel.getLongitude());
|
||||
if (tvDistance != null) tvDistance.setText("📏 Расстояние: " + com.grigowashere.aismap.utils.NavigationUtils.formatDistance(distance));
|
||||
if (tvDistance != null) tvDistance.setText("Расстояние: " + com.grigowashere.aismap.utils.NavigationUtils.formatDistance(distance));
|
||||
double bearing = com.grigowashere.aismap.utils.NavigationUtils.calculateBearing(ourVessel.getLatitude(), ourVessel.getLongitude(), vessel.getLatitude(), vessel.getLongitude());
|
||||
double relativeBearing = com.grigowashere.aismap.utils.NavigationUtils.calculateRelativeBearing(ourVessel.getCourse(), bearing);
|
||||
if (tvBearing != null) tvBearing.setText("🧭 Пеленг: " + com.grigowashere.aismap.utils.NavigationUtils.formatRelativeBearing(relativeBearing));
|
||||
if (tvBearing != null) tvBearing.setText("Пеленг: " + com.grigowashere.aismap.utils.NavigationUtils.formatRelativeBearing(relativeBearing));
|
||||
} else {
|
||||
if (tvDistance != null) tvDistance.setText("📏 Расстояние: --");
|
||||
if (tvBearing != null) tvBearing.setText("🧭 Пеленг: --");
|
||||
if (tvDistance != null) tvDistance.setText("Расстояние: --");
|
||||
if (tvBearing != null) tvBearing.setText("Пеленг: --");
|
||||
}
|
||||
}
|
||||
|
||||
if (tvTimeAgo != null) {
|
||||
if (vessel.getLastUpdate() != null) {
|
||||
long secondsAgo = java.time.Duration.between(vessel.getLastUpdate(), java.time.LocalDateTime.now()).getSeconds();
|
||||
tvTimeAgo.setText("⏱️ Время назад: " + formatTimeAgo(secondsAgo));
|
||||
tvTimeAgo.setText("Время назад: " + formatTimeAgo(secondsAgo));
|
||||
} else {
|
||||
tvTimeAgo.setText("⏱️ Время назад: --");
|
||||
tvTimeAgo.setText("Время назад: --");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +290,7 @@ public class BottomSheetsManager {
|
||||
TextView tvTimeAgo = aisBottomSheetView.findViewById(R.id.bottom_sheet_ais_time_ago);
|
||||
if (tvTimeAgo != null && currentAISVessel.getLastUpdate() != null) {
|
||||
long secondsAgo = java.time.Duration.between(currentAISVessel.getLastUpdate(), java.time.LocalDateTime.now()).getSeconds();
|
||||
tvTimeAgo.setText("⏱️ Время назад: " + formatTimeAgo(secondsAgo));
|
||||
tvTimeAgo.setText("Время назад: " + formatTimeAgo(secondsAgo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,10 +4,17 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.grigowashere.aismap.R;
|
||||
import com.grigowashere.aismap.maps.MapInterface;
|
||||
import com.grigowashere.aismap.maps.MapInterfaceChangeListener;
|
||||
import com.grigowashere.aismap.maps.MapLibreMapImpl;
|
||||
import com.grigowashere.aismap.maps.YandexMapImpl;
|
||||
import com.grigowashere.aismap.models.Vessel;
|
||||
import com.grigowashere.aismap.models.AISVessel;
|
||||
import com.grigowashere.aismap.utils.GeoUtils;
|
||||
import com.grigowashere.aismap.utils.SettingsManager;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.ArrayList;
|
||||
@@ -32,6 +39,8 @@ public class UIRenderingCoordinator implements UIDataChangeNotifier, MapInterfac
|
||||
|
||||
private MapInterface mapInterface;
|
||||
private Handler uiHandler;
|
||||
private SettingsManager settingsManager;
|
||||
private android.content.Context appContext;
|
||||
|
||||
// Pending операции для батчинга
|
||||
private Vessel pendingVesselUpdate;
|
||||
@@ -55,6 +64,16 @@ public class UIRenderingCoordinator implements UIDataChangeNotifier, MapInterfac
|
||||
setupThrottling();
|
||||
Log.i(TAG, "UIRenderingCoordinator инициализирован");
|
||||
}
|
||||
|
||||
/**
|
||||
* Передаёт {@link SettingsManager}, чтобы координатор смог отрисовать
|
||||
* кольца дальности вокруг собственного судна и halo предупреждения у
|
||||
* целей. Если не вызвать — отрисовка колец не выполняется.
|
||||
*/
|
||||
public void setSettingsManager(android.content.Context context, SettingsManager sm) {
|
||||
this.appContext = context != null ? context.getApplicationContext() : null;
|
||||
this.settingsManager = sm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Настройка throttling механизмов
|
||||
@@ -137,6 +156,7 @@ public class UIRenderingCoordinator implements UIDataChangeNotifier, MapInterfac
|
||||
try {
|
||||
Log.d(TAG, "Выполняем vessel update: " + pendingVesselUpdate.getLatitude() + "," + pendingVesselUpdate.getLongitude());
|
||||
mapInterface.updateOwnVesselPosition(pendingVesselUpdate);
|
||||
applyRangeRingsAround(pendingVesselUpdate);
|
||||
Log.d(TAG, "Vessel update выполнен успешно");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Ошибка vessel update: " + e.getMessage(), e);
|
||||
@@ -144,6 +164,57 @@ public class UIRenderingCoordinator implements UIDataChangeNotifier, MapInterfac
|
||||
|
||||
pendingVesselUpdate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Перерисовывает 3 кольца дальности (опасность/предупреждение/фильтр)
|
||||
* вокруг собственного судна и сообщает картам параметры warning-зоны для
|
||||
* подсветки целей. Если кольца отключены в настройках или координаты
|
||||
* невалидны — кольца очищаются.
|
||||
*/
|
||||
private void applyRangeRingsAround(Vessel vessel) {
|
||||
if (mapInterface == null) return;
|
||||
if (settingsManager == null || appContext == null) return;
|
||||
try {
|
||||
double lat = vessel != null ? vessel.getLatitude() : Double.NaN;
|
||||
double lon = vessel != null ? vessel.getLongitude() : Double.NaN;
|
||||
boolean ringsOn = settingsManager.isRangeRingsEnabled()
|
||||
&& GeoUtils.isValidCoordinates(lat, lon);
|
||||
if (!ringsOn) {
|
||||
mapInterface.clearOwnShipRangeRings();
|
||||
if (mapInterface instanceof MapLibreMapImpl) {
|
||||
((MapLibreMapImpl) mapInterface).setWarningZoneParams(lat, lon, 0.0);
|
||||
} else if (mapInterface instanceof YandexMapImpl) {
|
||||
((YandexMapImpl) mapInterface).setWarningZoneParams(lat, lon, 0.0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
double danger = settingsManager.getDangerRadiusMeters();
|
||||
double warning = settingsManager.getWarningRadiusMeters();
|
||||
double filter = settingsManager.getFilterRadiusMeters();
|
||||
int dangerStroke = ContextCompat.getColor(appContext, R.color.range_ring_danger_stroke);
|
||||
int dangerFill = ContextCompat.getColor(appContext, R.color.range_ring_danger_fill);
|
||||
int warningStroke = ContextCompat.getColor(appContext, R.color.range_ring_warning_stroke);
|
||||
int warningFill = ContextCompat.getColor(appContext, R.color.range_ring_warning_fill);
|
||||
int filterStroke = ContextCompat.getColor(appContext, R.color.range_ring_filter_stroke);
|
||||
int filterFill = ContextCompat.getColor(appContext, R.color.range_ring_filter_fill);
|
||||
double[] radii = new double[] { danger, warning, filter };
|
||||
int[] strokes = new int[] { dangerStroke, warningStroke, filterStroke };
|
||||
int[] fills = new int[] { dangerFill, warningFill, filterFill };
|
||||
boolean[] visible = new boolean[] {
|
||||
danger > 0.0,
|
||||
warning > 0.0,
|
||||
filter > 0.0 && settingsManager.isRangeFilterEnabled()
|
||||
};
|
||||
mapInterface.setOwnShipRangeRings(lat, lon, radii, strokes, fills, visible);
|
||||
if (mapInterface instanceof MapLibreMapImpl) {
|
||||
((MapLibreMapImpl) mapInterface).setWarningZoneParams(lat, lon, warning);
|
||||
} else if (mapInterface instanceof YandexMapImpl) {
|
||||
((YandexMapImpl) mapInterface).setWarningZoneParams(lat, lon, warning);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.w(TAG, "applyRangeRingsAround: " + t.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполнение обновлений AIS судов
|
||||
|
||||
Reference in New Issue
Block a user