import 'dart:core'; import 'package:latlong2/latlong.dart'; import 'package:flutter/material.dart'; class Measurement { int measurementID; DateTime timeMeasured; Sensor sensor; String bodyOfWater; LatLng center; List <SubDiv> subDivs; Measurement({ required this.measurementID, required this.timeMeasured, required this.sensor, required this.bodyOfWater, required this.center, required this.subDivs, }); factory Measurement.fromJson(Map<String, dynamic> json) { if (json == null) { throw const FormatException('Error parsing Measurement: JSON data is null'); } try { return Measurement( measurementID: json['MeasurementID'] ?? 0, timeMeasured: json['TimeMeasured'] != null ? DateTime.parse(json['TimeMeasured']) : DateTime(0), sensor:json['Sensor'] != null ? Sensor.fromJson(json['Sensor']) : Sensor.empty(), bodyOfWater: json['BodyOfWater'] != null ? json['BodyOfWater'].toString() : 'nil', center: LatLng( json['CenterLat'] != null ? json['CenterLat'].toDouble() : 0.0, json['CenterLon'] != null ? json['CenterLon'].toDouble() : 0.0, ), subDivs: (json['Subdivisions'] as List<dynamic>).map((data) => SubDiv.fromJson(data)).toList(), ); } catch (e) { throw FormatException('Error parsing Measurement: $e'); } } } class SubDiv { String sub_div_id; int groupID; double minThickness; double avgThickness; LatLng center; double accuracy; Color color; List<IceStats> iceStats; SubDiv({ required this.sub_div_id, required this.groupID, required this.minThickness, required this.avgThickness, required this.center, required this.accuracy, required this.color, required this.iceStats, }); factory SubDiv.fromJson(Map<String, dynamic> json) { try { return SubDiv( sub_div_id: json['SubdivID'].toString(), groupID: json['GroupID'] ?? 0, minThickness: json['MinThickness'] ?? 0, avgThickness: json['AvgThickness'] ?? 0, center: json['CenLatitude'] != null && json['CenLongitude'] != null ? LatLng(json['CenLatitude'], json['CenLongitude']) : LatLng(0.0, 0.0), accuracy: json['Accuracy'] ?? 0.0, // Set grey as default color color: json['Color'] != null ? Color(json['Color']) : Colors.grey, iceStats: (json['IceStats'] as List<dynamic>?) ?.map((data) => IceStats.fromJson(data)) .toList() ?? [], ); } catch (e) { throw FormatException('Error parsing SubDiv: $e'); } } } class IceStats { DateTime dateTime; double slushIce; double blackIce; double totalIce; double snowDepth; double totalSnow; double cloudCover; double temperature; IceStats({ required this.dateTime, required this.slushIce, required this.blackIce, required this.totalIce, required this.snowDepth, required this.totalSnow, required this.cloudCover, required this.temperature, }); factory IceStats.fromJson(Map<String, dynamic>? json) { try { if (json == null) { // Return empty json return IceStats( dateTime: DateTime.now(), slushIce: 0.0, blackIce: 0.0, totalIce: 0.0, snowDepth: 0.0, totalSnow: 0.0, cloudCover: 0.0, temperature: 0.0, ); } return IceStats( dateTime: DateTime.parse(json['Date']), slushIce: json['Slush ice (m)'] != null ? json['Slush ice (m)'].toDouble() : 0.0, blackIce: json['Black ice (m)'] != null ? json['Black ice (m)'].toDouble() : 0.0, totalIce: json['Total ice (m)'] != null ? json['Total ice (m)'].toDouble() : 0.0, snowDepth: json['Snow depth (m)'] != null ? json['Snow depth (m)'].toDouble() : 0.0, totalSnow: json['Total snow (m)'] != null ? json['Total snow (m)'].toDouble() : 0.0, cloudCover: json['Cloud cover'] != null ? json['Cloud cover'].toDouble() : 0.0, temperature: json['Temperature (t)'] != null ? json['Temperature (t)'].toDouble() : 0.0, ); } catch (e) { throw FormatException('Error parsing IceStats: $e'); } } } class Sensor { int sensorID; String sensorType; bool active; Sensor({ required this.sensorID, required this.sensorType, required this.active, }); Sensor.empty() : sensorID = 0, sensorType = '', active = false; factory Sensor.fromJson(Map<String, dynamic> json) { try { return Sensor( sensorID: json['SensorID'] ?? 0, sensorType: json['SensorType'] ?? 'nil', active: json['Active'] ?? true, ); } catch (e) { throw FormatException('Error parsing Sensor: $e'); } } }