mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
152 lines
4.4 KiB
Dart
152 lines
4.4 KiB
Dart
import 'dart:math' as math;
|
|
|
|
import 'package:flutter_map/flutter_map.dart';
|
|
import 'package:latlong2/latlong.dart';
|
|
|
|
import '../utils/custom_map_id.dart';
|
|
|
|
class CustomMapConfig {
|
|
final String filePath;
|
|
final String displayName;
|
|
final String mapId;
|
|
final int imageWidth;
|
|
final int imageHeight;
|
|
final double? metersPerPixel;
|
|
final LatLng? calibrationPointA;
|
|
final LatLng? calibrationPointB;
|
|
|
|
const CustomMapConfig({
|
|
required this.filePath,
|
|
required this.displayName,
|
|
required this.mapId,
|
|
required this.imageWidth,
|
|
required this.imageHeight,
|
|
this.metersPerPixel,
|
|
this.calibrationPointA,
|
|
this.calibrationPointB,
|
|
});
|
|
|
|
bool get isCalibrated => metersPerPixel != null && metersPerPixel! > 0;
|
|
|
|
double get _displayScale {
|
|
final heightScale = imageHeight / 90.0;
|
|
final widthScale = imageWidth / 180.0;
|
|
return math.max(1.0, math.max(heightScale, widthScale));
|
|
}
|
|
|
|
double get _displayHeight => imageHeight / _displayScale;
|
|
|
|
double get _displayWidth => imageWidth / _displayScale;
|
|
|
|
LatLngBounds get bounds =>
|
|
LatLngBounds(const LatLng(0, 0), LatLng(_displayHeight, _displayWidth));
|
|
|
|
LatLngBounds get displayBounds =>
|
|
LatLngBounds(LatLng(_displayHeight, 0), LatLng(0, _displayWidth));
|
|
|
|
LatLng toDisplayPoint(LatLng point) {
|
|
return LatLng(
|
|
_displayHeight - (point.latitude / _displayScale),
|
|
point.longitude / _displayScale,
|
|
);
|
|
}
|
|
|
|
LatLng fromDisplayPoint(LatLng point) {
|
|
return LatLng(
|
|
(_displayHeight - point.latitude) * _displayScale,
|
|
point.longitude * _displayScale,
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'filePath': filePath,
|
|
'displayName': displayName,
|
|
'mapId': mapId,
|
|
'imageWidth': imageWidth,
|
|
'imageHeight': imageHeight,
|
|
'metersPerPixel': metersPerPixel,
|
|
'calibrationPointA': calibrationPointA != null
|
|
? {
|
|
'lat': calibrationPointA!.latitude,
|
|
'lon': calibrationPointA!.longitude,
|
|
}
|
|
: null,
|
|
'calibrationPointB': calibrationPointB != null
|
|
? {
|
|
'lat': calibrationPointB!.latitude,
|
|
'lon': calibrationPointB!.longitude,
|
|
}
|
|
: null,
|
|
};
|
|
}
|
|
|
|
CustomMapConfig copyWith({
|
|
String? filePath,
|
|
String? displayName,
|
|
String? mapId,
|
|
int? imageWidth,
|
|
int? imageHeight,
|
|
double? metersPerPixel,
|
|
bool clearMetersPerPixel = false,
|
|
LatLng? calibrationPointA,
|
|
bool clearCalibrationPointA = false,
|
|
LatLng? calibrationPointB,
|
|
bool clearCalibrationPointB = false,
|
|
}) {
|
|
return CustomMapConfig(
|
|
filePath: filePath ?? this.filePath,
|
|
displayName: displayName ?? this.displayName,
|
|
mapId: normalizeCustomMapId(mapId) ?? this.mapId,
|
|
imageWidth: imageWidth ?? this.imageWidth,
|
|
imageHeight: imageHeight ?? this.imageHeight,
|
|
metersPerPixel: clearMetersPerPixel
|
|
? null
|
|
: (metersPerPixel ?? this.metersPerPixel),
|
|
calibrationPointA: clearCalibrationPointA
|
|
? null
|
|
: (calibrationPointA ?? this.calibrationPointA),
|
|
calibrationPointB: clearCalibrationPointB
|
|
? null
|
|
: (calibrationPointB ?? this.calibrationPointB),
|
|
);
|
|
}
|
|
|
|
static CustomMapConfig? fromJson(Map<String, dynamic>? json) {
|
|
if (json == null) return null;
|
|
|
|
final filePath = json['filePath'];
|
|
final displayName = json['displayName'];
|
|
final mapId = json['mapId'];
|
|
final imageWidth = json['imageWidth'];
|
|
final imageHeight = json['imageHeight'];
|
|
if (filePath is! String ||
|
|
displayName is! String ||
|
|
mapId is! String ||
|
|
imageWidth is! int ||
|
|
imageHeight is! int) {
|
|
return null;
|
|
}
|
|
|
|
LatLng? parsePoint(dynamic raw) {
|
|
if (raw is! Map<String, dynamic>) return null;
|
|
final lat = raw['lat'];
|
|
final lon = raw['lon'];
|
|
if (lat is! num || lon is! num) return null;
|
|
return LatLng(lat.toDouble(), lon.toDouble());
|
|
}
|
|
|
|
final metersPerPixel = json['metersPerPixel'];
|
|
return CustomMapConfig(
|
|
filePath: filePath,
|
|
displayName: displayName,
|
|
mapId: normalizeCustomMapId(mapId) ?? mapId,
|
|
imageWidth: imageWidth,
|
|
imageHeight: imageHeight,
|
|
metersPerPixel: metersPerPixel is num ? metersPerPixel.toDouble() : null,
|
|
calibrationPointA: parsePoint(json['calibrationPointA']),
|
|
calibrationPointB: parsePoint(json['calibrationPointB']),
|
|
);
|
|
}
|
|
}
|