chore: add build artifacts, map assets, and routing data
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
class HazardModel {
|
||||
final String type; // 'accident', 'closure', 'bump', 'checkpoint', 'camera'
|
||||
final String title;
|
||||
final String description;
|
||||
final double latitude;
|
||||
final double longitude;
|
||||
final double altitude; // Altitude AMSL in meters (defaults to 0.0)
|
||||
final DateTime createdAt;
|
||||
|
||||
HazardModel({
|
||||
required this.type,
|
||||
required this.title,
|
||||
required this.description,
|
||||
required this.latitude,
|
||||
required this.longitude,
|
||||
this.altitude = 0.0,
|
||||
required this.createdAt,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'type': type,
|
||||
'title': title,
|
||||
'description': description,
|
||||
'latitude': latitude,
|
||||
'longitude': longitude,
|
||||
'altitude': altitude,
|
||||
'elevation_meters': altitude,
|
||||
'timestamp': createdAt.toIso8601String(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
class PlaceModel {
|
||||
final String id;
|
||||
final String name;
|
||||
final String category;
|
||||
final double latitude;
|
||||
final double longitude;
|
||||
final double elevationMeters; // GPS Altitude AMSL in meters (defaults to 0.0)
|
||||
final double? distanceKm;
|
||||
final String? address;
|
||||
|
||||
PlaceModel({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.category,
|
||||
required this.latitude,
|
||||
required this.longitude,
|
||||
this.elevationMeters = 0.0,
|
||||
this.distanceKm,
|
||||
this.address,
|
||||
});
|
||||
|
||||
factory PlaceModel.fromJson(Map<String, dynamic> json) {
|
||||
final rawElev = json['elevation_meters'] ?? json['elevation'] ?? json['altitude'] ?? 0.0;
|
||||
double elev = 0.0;
|
||||
if (rawElev is num) {
|
||||
elev = rawElev.toDouble();
|
||||
} else if (rawElev != null) {
|
||||
elev = double.tryParse(rawElev.toString()) ?? 0.0;
|
||||
}
|
||||
|
||||
return PlaceModel(
|
||||
id: json['id']?.toString() ?? '',
|
||||
name: json['name']?.toString() ?? '',
|
||||
category: json['category']?.toString() ?? 'other',
|
||||
latitude: double.tryParse(json['latitude']?.toString() ?? json['lat']?.toString() ?? '0') ?? 0.0,
|
||||
longitude: double.tryParse(json['longitude']?.toString() ?? json['lng']?.toString() ?? '0') ?? 0.0,
|
||||
elevationMeters: elev,
|
||||
distanceKm: json['distanceKm'] != null
|
||||
? (json['distanceKm'] as num).toDouble()
|
||||
: null,
|
||||
address: json['address']?.toString() ?? json['neighborhood']?.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'category': category,
|
||||
'latitude': latitude,
|
||||
'longitude': longitude,
|
||||
'elevation_meters': elevationMeters,
|
||||
'altitude': elevationMeters,
|
||||
if (address != null) 'address': address,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
|
||||
class RouteData {
|
||||
final List<LatLng> coordinates;
|
||||
final List<Map<String, dynamic>> steps;
|
||||
final double distanceM;
|
||||
final double durationS;
|
||||
final String points;
|
||||
final String routeName;
|
||||
final List<String> tags;
|
||||
final String? slopeWarning;
|
||||
final bool hasSteepSlope;
|
||||
final double maxInclinePercent;
|
||||
final double maxDeclinePercent;
|
||||
final double totalAscentMeters;
|
||||
final double totalDescentMeters;
|
||||
final double fuelLiters;
|
||||
final double fuelSavingsPercent;
|
||||
final int ecoScore;
|
||||
final bool isEcoFriendly;
|
||||
|
||||
RouteData({
|
||||
required this.coordinates,
|
||||
required this.steps,
|
||||
required this.distanceM,
|
||||
required this.durationS,
|
||||
required this.points,
|
||||
this.routeName = 'المسار المباشر الأسرع',
|
||||
this.tags = const [],
|
||||
this.slopeWarning,
|
||||
this.hasSteepSlope = false,
|
||||
this.maxInclinePercent = 0.0,
|
||||
this.maxDeclinePercent = 0.0,
|
||||
this.totalAscentMeters = 0.0,
|
||||
this.totalDescentMeters = 0.0,
|
||||
this.fuelLiters = 0.0,
|
||||
this.fuelSavingsPercent = 0.0,
|
||||
this.ecoScore = 0,
|
||||
this.isEcoFriendly = false,
|
||||
});
|
||||
|
||||
bool get isFastest => tags.contains('FASTEST');
|
||||
|
||||
String get formattedDistance {
|
||||
if (distanceM >= 1000) {
|
||||
return '${(distanceM / 1000).toStringAsFixed(1)} كم';
|
||||
}
|
||||
return '${distanceM.round()} م';
|
||||
}
|
||||
|
||||
String get formattedDuration {
|
||||
final int minutes = (durationS / 60).round();
|
||||
if (minutes >= 60) {
|
||||
final int hours = minutes ~/ 60;
|
||||
final int remainingMinutes = minutes % 60;
|
||||
return '$hours س $remainingMinutes د';
|
||||
}
|
||||
return '$minutes دقيقة';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user