From 4d7fbddcf7d026fb5aa3734e2aa44d836fa698da Mon Sep 17 00:00:00 2001 From: Sara <sarasdj@stud.ntnu.no> Date: Thu, 29 Feb 2024 13:07:19 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20working=20Mj=C3=B8sa=20choropleth=20map!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/lib/pages/default_page.dart | 9 ++- .../pages/marker_handler/get_relation.dart | 36 ++++++++++++ app/lib/pages/widgets/cloropleth_map.dart | 55 +++---------------- app/lib/pages/widgets/map_widget.dart | 5 +- 4 files changed, 54 insertions(+), 51 deletions(-) create mode 100644 app/lib/pages/marker_handler/get_relation.dart diff --git a/app/lib/pages/default_page.dart b/app/lib/pages/default_page.dart index 29ad2d91..4be907bd 100644 --- a/app/lib/pages/default_page.dart +++ b/app/lib/pages/default_page.dart @@ -4,6 +4,8 @@ import 'widgets/map_widget.dart'; import 'marker_handler/marker_data.dart'; import 'consts.dart'; import 'marker_handler/get_markers.dart'; +import 'marker_handler/get_relation.dart'; +import 'dart:typed_data'; class DefaultPage extends StatefulWidget { const DefaultPage({super.key}); @@ -17,14 +19,17 @@ class _DefaultPageState extends State<DefaultPage> { bool showBar = false; List<Measurement> markerList = []; + Uint8List relation = Uint8List(0); // Call fetchMarkerTemplate and await its result before setting the state Future<void> loadMarkerList() async { try { List<Measurement> fetchedMarkers = await fetchMarkerData(); + Uint8List fetchedRelation = await fetchRelation(); - setState(() { + setState(() { // Initialise markers and relations markerList = fetchedMarkers; + relation = fetchedRelation; }); } catch (e) { showDialog( @@ -95,7 +100,7 @@ class _DefaultPageState extends State<DefaultPage> { ), body: ListView( children: [ // Add main widget - MapContainerWidget(markerList: markerList), + MapContainerWidget(markerList: markerList, relation: relation), ], ), ), diff --git a/app/lib/pages/marker_handler/get_relation.dart b/app/lib/pages/marker_handler/get_relation.dart new file mode 100644 index 00000000..9b306a54 --- /dev/null +++ b/app/lib/pages/marker_handler/get_relation.dart @@ -0,0 +1,36 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import '../consts.dart'; +import 'dart:typed_data'; + + +/// Fetch relation data from server +Future<Uint8List> fetchRelation() async { + try { + // Custom HTTP client + HttpClient client = HttpClient() + ..badCertificateCallback = // NB: temporary disable SSL certificate validation + (X509Certificate cert, String host, int port) => true; + + // Execute request to to get_relation endpoint + var request = await client.getUrl(Uri.parse('${serverURI}get_relation')); + var response = await request.close(); // Close response body at end of function + + // Parse body to JSON if request is ok + if (response.statusCode == 200) { + var responseBody = await response.transform(utf8.decoder).join(); + + if (responseBody.isNotEmpty) { + return Uint8List.fromList(utf8.encode(responseBody)); + } else { + throw Exception('Response body is empty'); + } + } else { + throw Exception('Failed to fetch relation data: Status code ${response.statusCode}'); + } + } catch (e) { + throw Exception('Failed to fetch relation data: ${e.toString()}'); + } +} + diff --git a/app/lib/pages/widgets/cloropleth_map.dart b/app/lib/pages/widgets/cloropleth_map.dart index 35e3c5bf..fd0e9bfc 100644 --- a/app/lib/pages/widgets/cloropleth_map.dart +++ b/app/lib/pages/widgets/cloropleth_map.dart @@ -3,8 +3,7 @@ import 'package:app/pages/consts.dart'; import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_maps/maps.dart'; import '../consts.dart'; -import 'dart:convert'; -import 'dart:io'; +import 'dart:typed_data'; /// A class containing thickness for each subdivision of the map. class IceThicknessModel { @@ -18,7 +17,9 @@ class IceThicknessModel { /// The map data is fetched from the server, and the map is rendered /// using the Syncfusion Flutter Maps library. class ChoroplethMap extends StatefulWidget { - const ChoroplethMap({Key? key,}) : super(key: key); + const ChoroplethMap({Key? key, required this.relation}) : super(key: key); + + final Uint8List relation; @override _ChoroplethMapState createState() => _ChoroplethMapState(); @@ -27,66 +28,24 @@ class ChoroplethMap extends StatefulWidget { class _ChoroplethMapState extends State<ChoroplethMap> { late MapShapeSource mapShapeSource; List<IceThicknessModel> iceThicknessList = <IceThicknessModel>[]; - Uint8List? relation; @override void initState() { super.initState(); - fetchRelation(); // Fetch relation data from server } @override Widget build(BuildContext context) { - return relation != null - ? SfMaps( + return SfMaps( layers: [ MapShapeLayer( source: MapShapeSource.memory( - relation!, + widget.relation, shapeDataField: 'name', ), color: Colors.orange, ), ], - ) : const Center(child: CircularProgressIndicator()); - } - - // Fetch relation data from server - Future<void> fetchRelation() async { - try { - // Custom HTTP client - HttpClient client = HttpClient() - ..badCertificateCallback = // NB: temporary disable SSL certificate validation - (X509Certificate cert, String host, int port) => true; - - // Execute request to to get_relation endpoint - var request = await client.getUrl(Uri.parse('${serverURI}get_relation')); - var response = await request.close(); // Close response body at end of function - - // Parse body to JSON if request is ok - if (response.statusCode == 200) { - var responseBody = await response.transform(utf8.decoder).join(); - - if (responseBody.isNotEmpty) { - var jsonData = json.decode(responseBody); - - if (jsonData != null) { - print("JSON data NOT NULL"); - // Convert JSON string to Uint8List - setState(() { - relation = Uint8List.fromList(utf8.encode(jsonData)); - }); // Update UI - } else { - throw Exception('Failed to parse response body'); - } - } else { - throw Exception('Response body is empty'); - } - } else { - throw Exception('Failed to fetch relation data: Status code ${response.statusCode}'); - } - } catch (e) { - throw Exception('Failed to fetch relation data: ${e.toString()}'); - } + ); } } diff --git a/app/lib/pages/widgets/map_widget.dart b/app/lib/pages/widgets/map_widget.dart index 41bbbd69..d353e034 100644 --- a/app/lib/pages/widgets/map_widget.dart +++ b/app/lib/pages/widgets/map_widget.dart @@ -6,14 +6,17 @@ import 'stat_charts.dart'; import 'sat_layer.dart'; import 'package:flutter_map/flutter_map.dart'; import 'cloropleth_map.dart'; +import 'dart:typed_data'; /// MapContainerWidget is the main widget that contains the map with all /// its layers, polygons and markers. class MapContainerWidget extends StatefulWidget { final List<Measurement> markerList; + final Uint8List relation; const MapContainerWidget({Key? key, required this.markerList, + required this.relation, }) : super(key: key); @override @@ -59,7 +62,7 @@ class _MapContainerWidgetState extends State<MapContainerWidget> { SizedBox( width: screenWidth * boxWidth, height: screenWidth * boxHeight, - child: ChoroplethMap(), + child: ChoroplethMap(relation: widget.relation), /*FlutterMap( options: MapOptions( center: mapCenter, -- GitLab