Adding makers from csv with coordinates
M-Exal opened this issue · 7 comments
Hey, I am developping an app for the university. I want to add some markers according to a readed csv.
Here is the code:
Future<void> loadCSV() async {
if(isControllerInitialized)
{
final String csv = await rootBundle.loadString('assets/locations.csv');
final List<List<dynamic>> csvList = const CsvToListConverter().convert(csv);
setState(() {
locations = csvList;
});
addMarkers();
}
}
void addMarkers()
{
if(isControllerInitialized){
if (locations != null && locations!.isNotEmpty)
{
for (var innerList in locations)
{
for(int i = 0; i+1 < innerList.length; i+=2)
{
double currLatitude = double.parse(innerList[i].toString());
double currLongitude = double.parse(innerList[i+1].toString());
controllerMap.addMarker(
GeoPoint(latitude: currLatitude, longitude: currLongitude),
markerIcon: const MarkerIcon(
icon: Icon(
Icons.location_on_sharp,
color: Colors.blue,
size: 48,
)
)
);
}
}
}
}
}
It does not work because of this:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: LateInitializationError: Field '_osmBaseController@497117859' has not been initialized.
#0 BaseMapController._osmBaseController (package:flutter_osm_interface/src/map_controller/base_map_controller.dart)
#1 BaseMapController.osmBaseController (package:flutter_osm_interface/src/map_controller/base_map_controller.dart:21:47)
#2 MapController.addMarker (package:flutter_osm_plugin/src/controller/map_controller.dart:505:11)
#3 _MyHomePageState.addMarkers (package:mobile_app_dev/main.dart:145:27)
#4 _MyHomePageState.loadCSV (package:mobile_app_dev/main.dart:130:7)
<asynchronous suspension>
I really do not understand why I have this error. Am I trying something impossible with the plugin ?
Edit: the behavior of my list of location is ok, I correctly read the csv.
you need to add marker after the map initialisation
can you provide the all code where you read and shown the map ?
First of all, thanks for fast answer @liodali .
Here is the beginning of the code:
class _MyHomePageState extends State<MyHomePage> {
late StreamSubscription<Position> _positionStreamSubscription;
Position? _currentPosition;
late MapController controllerMap;
bool isControllerInitialized = false;
List<List<dynamic>> locations = [];
@override
void initState() {
super.initState();
controllerMap = MapController.withPosition(
initPosition: GeoPoint(
latitude: 48.866667,
longitude: 2.333333,
),
);
isControllerInitialized = true;
_getCurrentLocation();
loadCSV();
}
And here you have how I render the map:
child: Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: OSMFlutter(
controller: controllerMap,
osmOption: OSMOption(
userTrackingOption: UserTrackingOption(
enableTracking: true,
unFollowUser: false,
),
zoomOption: ZoomOption(
initZoom: 8,
minZoomLevel: 3,
maxZoomLevel: 19,
stepZoom: 1.0,
),
userLocationMarker: UserLocationMaker(
personMarker: MarkerIcon(
icon: Icon(
Icons.location_on_sharp,
color: Colors.red,
size: 48,
),
),
directionArrowMarker: MarkerIcon(
icon: Icon(
Icons.double_arrow,
size: 48,
),
),
),
)
),
),
As you can see on the attached picture, the blue markers are not rendered.
use our OSMMixinObserver
to get notified that our map is read like this in you state class
because the controller initialisation internally
class _MyHomePageState extends State<MyHomePage> with OSMMixinObserver {
/// your initialisation
@override
void initState() {
super.initState();
controllerMap = MapController.withPosition(
initPosition: GeoPoint(
latitude: 48.866667,
longitude: 2.333333,
),
);
isControllerInitialized = true;
controllerMap.addObserver(this);
}
@override
Future<void> mapIsReady(bool isReady) async {
if (isReady) {
_getCurrentLocation();
loadCSV();
}
}
/// your other staff like build method or you can use also `onSingleTap`
Note I dont want to bother you with internal detail but we're using native sdk that force to do inner controller that why you get the error if you load csv and the map still not initialized
we can improve how you load the csv as well
because if those markers are related like station or bus or taxis you can use static position api
where you can add list of markers that share the same icon in just one API
Okay, that is working perfectly.
In terms of csv, it’s a document that requires specific points that I don’t think are referenced in an API. (if I understood your comment on that)
I mean if those points have the same icon you dont need to create them separately
you can use our staticPoints APIs
as well you can put this code :
final String csv = await rootBundle.loadString('assets/locations.csv');
final List<List<dynamic>> csvList = const CsvToListConverter().convert(csv);
in compute
Ohh okay, great.
Thanks !