Skip to content
Snippets Groups Projects
Commit c36010ae authored by Sara Savanovic Djordjevic's avatar Sara Savanovic Djordjevic
Browse files

update: json data parsing

parent 1d35e9ba
No related branches found
No related tags found
No related merge requests found
......@@ -17,24 +17,29 @@ class DefaultPage extends StatefulWidget {
class _DefaultPageState extends State<DefaultPage> {
late Timer _timer;
List<MarkerData> markerList = [];
List<MarkerTemplate> markerList = [];
// fetchMarkerData requests data from the update_map endpoint
Future<void> fetchMarkerData() async {
// fetchMarkerTemplate requests data from the update_map endpoint
Future<void> fetchMarkerTemplate() async {
try {
// Custom HTTP client
HttpClient client = HttpClient()
..badCertificateCallback = // NB: temporary disable SSL certificate validation
(X509Certificate cert, String host, int port) => true;
// Request makers from API and wait for response
var request = await client.getUrl(Uri.parse(serverURI+mapEndpoint));
var response = await request.close();
// Parse json response to list of MarkerData objects if request is ok
// Attempt to parse json if request is ok
if (response.statusCode == 200) {
var responseBody = await response.transform(utf8.decoder).join();
setState(() {
markerList = parseMarkerData(responseBody);
// Parse JSON string from response body
List<dynamic> jsonData = json.decode(responseBody);
// Convert response from type List<dynamic> to List<MarkerTemplate>
markerList = jsonData.map((data) => MarkerTemplate.fromJson(data)).toList();
});
} else {
print('Request failed with status: ${response.statusCode}');
......@@ -44,17 +49,17 @@ class _DefaultPageState extends State<DefaultPage> {
}
}
// Timer initializer
// State initializer
@override
void initState() {
super.initState();
// Call fetchMarkerData when the widget is first created
fetchMarkerData();
// Call fetchMarkerTemplate when the widget is first created
fetchMarkerTemplate();
// Schedule fetchMarkerData to run periodically based on fetchInterval const
// Schedule fetchMarkerTemplate to run periodically based on fetchInterval const
const Duration fiveMinutes = Duration(minutes: fetchInterval);
_timer = Timer.periodic(fiveMinutes, (timer) {
fetchMarkerData();
fetchMarkerTemplate();
});
}
......@@ -99,11 +104,11 @@ class _DefaultPageState extends State<DefaultPage> {
),
MarkerLayer(
// Dynamically allocate markers based on a list
markers: markerList.map((MarkerData markerData) {
markers: markerList.map((MarkerTemplate MarkerTemplate) {
return Marker(
width: markerData.size,
height: markerData.size,
point: markerData.location,
width: MarkerTemplate.size,
height: MarkerTemplate.size,
point: MarkerTemplate.location,
builder: (ctx) => GestureDetector(
onTap: () {
// NB: temporary print
......@@ -112,9 +117,9 @@ class _DefaultPageState extends State<DefaultPage> {
},
child: Image.asset(
'assets/icons/circle-red.png', // Path to your custom icon asset
color: markerData.color,
width: markerData.radius,
height: markerData.radius,
color: MarkerTemplate.color,
width: MarkerTemplate.size,
height: MarkerTemplate.size,
),
),
);
......
import 'package:flutter/material.dart';
import 'package:latlong2/latlong.dart';
import 'dart:convert';
// MarkerData holds data for the dynamically allocated markers
class MarkerData {
final LatLng location;
final double size;
final Color color;
final double radius;
// Sensor holds data about a single sensor
class Sensor {
int id;
String type;
bool active;
MarkerData({required this.location, required this.size, required this.color, required this.radius});
Sensor({required this.id, required this.type, required this.active});
factory Sensor.fromJson(Map<String, dynamic> json) {
return Sensor(
id: json['ID'],
type: json['type'],
active: json['active'],
);
}
}
// parseMarkerData parses jsonData into an object of type MakerData
List<MarkerData> parseMarkerData(String jsonString) {
final parsed = json.decode(jsonString);
return List<MarkerData>.from(parsed.map((data) => MarkerData(
location: LatLng(data['latitude'], data['longitude']),
size: data['size'].toDouble(),
color: parseColor(data['color']),
radius: data['radius'].toDouble(),
)));
// DateAndTime holds the date and time for a single measurement
class DateAndTime {
int year;
int month;
int day;
int hour;
int minute;
DateAndTime({
required this.year,
required this.month,
required this.day,
required this.hour,
required this.minute,
});
factory DateAndTime.fromJson(Map<String, dynamic> json) {
return DateAndTime(
year: json['year'],
month: json['month'],
day: json['day'],
hour: json['hour'],
minute: json['minute'],
);
}
}
// parseColor parses the color strings into Colors types
Color parseColor(String colorString) {
switch (colorString) {
case 'blue':
return Colors.blue;
case 'red':
return Colors.red;
case 'green':
return Colors.green;
default:
return Colors.black; // Default color if unrecognized
// Measurement holds data related to a singular measurement taken
// at a given time
class Measurement {
double longitude;
double latitude;
DateAndTime datetime;
Sensor sensor;
double precipitation;
double thickness;
double maxWeight;
double safetyLevel;
double accuracy;
Measurement({
required this.longitude,
required this.latitude,
required this.datetime,
required this.sensor,
required this.precipitation,
required this.thickness,
required this.maxWeight,
required this.safetyLevel,
required this.accuracy,
});
factory Measurement.fromJson(Map<String, dynamic> json) {
return Measurement(
longitude: json['longitude'],
latitude: json['latitude'],
datetime: DateAndTime.fromJson(json['datetime']),
sensor: Sensor.fromJson(json['sensor']),
precipitation: json['precipitation'],
thickness: json['thickness'],
maxWeight: json['max_weight'],
safetyLevel: json['safety_level'],
accuracy: json['accuracy'],
);
}
}
\ No newline at end of file
}
// MarkerTemplate holds all data required for rendering a marker
class MarkerTemplate {
Measurement geoData;
LatLng location;
double size;
Color color;
MarkerTemplate({
required this.geoData,
required this.location,
required this.size,
required this.color
});
factory MarkerTemplate.fromJson(Map<String, dynamic> json) {
// Parse from JSON string to type Color
Color parsedColor = parseColor(json['color']);
return MarkerTemplate(
geoData: Measurement.fromJson(json['geo_data']),
location: LatLng(json['latitude'], json['longitude']),
size: json['size'],
color: parsedColor,
);
}
// parseColor parses the color strings into Colors types
static Color parseColor(String colorString) {
switch (colorString) {
case 'yellow':
return Colors.yellow;
case 'red':
return Colors.red;
case 'green':
return Colors.green;
default:
return Colors.black; // Default color if unrecognized
}
}
}
No preview for this file type
No preview for this file type
......@@ -26,9 +26,9 @@ def get_markers():
precipitation=0.0, thickness=0.0, max_weight=0.0, safety_level=0.0, accuracy=4.0)
testData = [
MarkerTemplate(measurement1, 30.0-measurement1.accuracy, "Green"),
MarkerTemplate(measurement2, 10.0-measurement2.accuracy, "Red"),
MarkerTemplate(measurement3, 20.0-measurement3.accuracy, "Yellow"),
MarkerTemplate(measurement1, 30.0-measurement1.accuracy, "green"),
MarkerTemplate(measurement2, 10.0-measurement2.accuracy, "red"),
MarkerTemplate(measurement3, 20.0-measurement3.accuracy, "yellow"),
]
# NB: return test data as JSON
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment