add benzin to gasview

This commit is contained in:
2026-09-25 21:17:36 +02:00
parent 9a4c5cd82a
commit 44fa19b89f
4 changed files with 143 additions and 78 deletions
+39 -9
View File
@@ -22,19 +22,49 @@ class GasstationsController extends GetxController {
Future<void> _loadStationInfosList() async { Future<void> _loadStationInfosList() async {
isLoading.value = true; isLoading.value = true;
var gelocationService = GeolocationService(); var geolocationService = GeolocationService();
var eControlService = EControlService(); var eControlService = EControlService();
// check if location is available
await gelocationService.getCurrentLocation(); await geolocationService.getCurrentLocation();
if (gelocationService.hasLocation) { if (geolocationService.hasLocation) {
var listResult = await eControlService.getEControlData( // Parallel Diesel und Benzin laden
gelocationService.latitude, final fuelData = await eControlService.getBothFuelData(
gelocationService.longitude, geolocationService.latitude,
'DIE', geolocationService.longitude,
); );
eControlData.value = listResult
List<EControlModel> dieselStations = (fuelData['DIE'] as List)
.map((json) => EControlModel.fromJson(json)) .map((json) => EControlModel.fromJson(json))
.toList(); .toList();
List<EControlModel> supStations = (fuelData['SUP'] as List)
.map((json) => EControlModel.fromJson(json))
.toList();
// Map zur Zusammenführung nach Tankstellen-ID
Map<int, EControlModel> combinedMap = {};
for (var station in dieselStations) {
if (station.id != null) {
combinedMap[station.id!] = station;
}
}
// Benzin-Preise in dieselben Tankstellen-Objekte mergen
for (var supStation in supStations) {
if (supStation.id != null) {
if (combinedMap.containsKey(supStation.id)) {
// Falls Tankstelle schon existiert, füge Benzin-Preis hinzu
final existingPrices = combinedMap[supStation.id!]!.prices ?? [];
final supPrices = supStation.prices ?? [];
combinedMap[supStation.id!]!.prices = [...existingPrices, ...supPrices];
} else {
combinedMap[supStation.id!] = supStation;
}
}
}
eControlData.value = combinedMap.values.toList();
} }
isLoading.value = false; isLoading.value = false;
update(); update();
+1 -1
View File
@@ -51,7 +51,7 @@ class GasstationsPage extends GetView<GasstationsController> {
strokeWidth: 3, strokeWidth: 3,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
Text( const Text(
'Lade Tankstellen...', 'Lade Tankstellen...',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
+16 -2
View File
@@ -7,11 +7,25 @@ class EControlService {
double longitude, double longitude,
String fuelType, String fuelType,
) async { ) async {
// REST Service... URL
String apiUrl = String apiUrl =
'https://api.e-control.at/sprit/1.0/search/gas-stations/by-address?latitude=$latitude&longitude=$longitude&fuelType=$fuelType&includeClosed=false'; 'https://api.e-control.at/sprit/1.0/search/gas-stations/by-address?latitude=$latitude&longitude=$longitude&fuelType=$fuelType&includeClosed=false';
var response = await http.get(Uri.parse(apiUrl)); var response = await http.get(Uri.parse(apiUrl));
print('${response.statusCode}'); if (response.statusCode == 200) {
return jsonDecode(response.body); return jsonDecode(response.body);
} }
return [];
}
/// Holt parallel Diesel ('DIE') und Super ('SUP') Daten
Future<Map<String, List<dynamic>>> getBothFuelData(
double latitude,
double longitude,
) async {
final results = await Future.wait([
getEControlData(latitude, longitude, 'DIE'),
getEControlData(latitude, longitude, 'SUP'),
]);
return {'DIE': results[0], 'SUP': results[1]};
}
} }
+80 -59
View File
@@ -23,14 +23,68 @@ class GasStationCard extends StatelessWidget {
} }
} }
// Hilfsmethode zur Erstellung eines einzelnen Preis-Badges
Widget _buildPriceBadge(Prices? priceInfo) {
if (priceInfo == null || priceInfo.amount == null) {
return const SizedBox.shrink();
}
final double price = priceInfo.amount!;
final String label = priceInfo.label ?? priceInfo.fuelType ?? '';
final Color badgeColor = _getPriceColor(price);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: badgeColor.withAlpha(35),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: badgeColor, width: 1.5),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.local_gas_station, color: badgeColor, size: 22),
const SizedBox(width: 6),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'€ ${price.toStringAsFixed(3)}',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: badgeColor,
),
),
if (label.isNotEmpty)
Text(
label,
style: TextStyle(
fontSize: 10,
color: Colors.grey[700],
fontWeight: FontWeight.w500,
),
),
],
),
],
),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final price = station.prices?.isNotEmpty == true // Suchen nach Diesel und Super/Benzin im Prices-Array
? station.prices!.first.amount final dieselPrice = station.prices?.firstWhere(
: null; (p) => p.fuelType == 'DIE' || (p.label?.toLowerCase().contains('diesel') ?? false),
final priceLabel = station.prices?.isNotEmpty == true orElse: () => station.prices?.isNotEmpty == true ? station.prices!.first : Prices(),
? station.prices!.first.label );
: '';
final supPrice = station.prices?.firstWhere(
(p) => p.fuelType == 'SUP' || (p.label?.toLowerCase().contains('benzin') ?? false) || (p.label?.toLowerCase().contains('super') ?? false),
orElse: () => Prices(),
);
return Card( return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
@@ -50,7 +104,7 @@ class GasStationCard extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Header Row with Position and Status // Header Row
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
@@ -113,7 +167,7 @@ class GasStationCard extends StatelessWidget {
Text( Text(
station.name ?? 'Unbekannte Tankstelle', station.name ?? 'Unbekannte Tankstelle',
style: const TextStyle( style: const TextStyle(
fontSize: 20, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.black87, color: Colors.black87,
), ),
@@ -134,7 +188,7 @@ class GasStationCard extends StatelessWidget {
'${station.location?.address ?? ''}, ' '${station.location?.address ?? ''}, '
'${station.location?.postalCode ?? ''} ' '${station.location?.postalCode ?? ''} '
'${station.location?.city ?? ''}', '${station.location?.city ?? ''}',
style: TextStyle(fontSize: 14, color: Colors.grey[700]), style: TextStyle(fontSize: 13, color: Colors.grey[700]),
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -143,80 +197,47 @@ class GasStationCard extends StatelessWidget {
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
// Price and Distance Row // Prices & Distance Row
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
// Price // Diesel & Benzin Preise nebeneinander
if (price != null) Expanded(
Container( child: Wrap(
padding: const EdgeInsets.symmetric( spacing: 8,
horizontal: 16, runSpacing: 8,
vertical: 10,
),
decoration: BoxDecoration(
color: _getPriceColor(price).withAlpha(50),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: _getPriceColor(price),
width: 2,
),
),
child: Row(
children: [ children: [
Icon( if (dieselPrice?.amount != null)
Icons.local_gas_station, _buildPriceBadge(dieselPrice),
color: _getPriceColor(price), if (supPrice?.amount != null)
size: 24, _buildPriceBadge(supPrice),
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'€ ${price.toStringAsFixed(3)}',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: _getPriceColor(price),
),
),
if (priceLabel?.isNotEmpty == true)
Text(
priceLabel!,
style: TextStyle(
fontSize: 10,
color: Colors.grey[600],
),
),
],
),
], ],
), ),
), ),
// Distance // Distance Badge
Container( Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 16, horizontal: 12,
vertical: 10, vertical: 8,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.blue[50], color: Colors.blue[50],
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon( Icon(
Icons.navigation, Icons.navigation,
color: Colors.blue[700], color: Colors.blue[700],
size: 20, size: 18,
), ),
const SizedBox(width: 8), const SizedBox(width: 6),
Text( Text(
_formatDistance(station.distance), _formatDistance(station.distance),
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 14,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.blue[700], color: Colors.blue[700],
), ),