can we initialCameraPosition in GoogleMap - Flutter - google-maps

how can we setup initial camera positions in googleMap i.e. instead of hard code lat/lang (below code)
GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(30.666, 76.8127),
zoom: 15
),
onMapCreated: _onMapCreated,
myLocationEnabled: true,
mapType: MapType.hybrid,
compassEnabled: true,
trackCameraPosition: true,
)
I just want my current location lat/lang instead of hard coded values

Use location package.
Here is an example.
var currentLocation = LocationData;
var location = new Location();
// Platform messages may fail, so we use a try/catch PlatformException.
try {
currentLocation = await location.getLocation();
} on PlatformException catch (e) {
if (e.code == 'PERMISSION_DENIED') {
error = 'Permission denied';
}
currentLocation = null;
}
And then
var location = new Location(); location.onLocationChanged().listen((LocationData currentLocation) {
print(currentLocation.latitude);
print(currentLocation.longitude);
})

Related

Flutter - Google Maps, More than one different custom marker Image at the same time?

I am using Flutter and the Google Maps API.
I have managed to have a custom marker that is displayed when the map opens.
Is there a way to have multiple different custom markers Images at the same time on the same map?
I can't find a way to do that.
Any ideas or links are welcomed :)
class Neighborhood extends StatefulWidget {
const Neighborhood({Key key}) : super(key: key);
#override
_NeighborhoodState createState() => _NeighborhoodState();
}
class _NeighborhoodState extends State<Neighborhood> {
Location _location = Location();
GoogleMapController _controller;
List<Marker> allMarkers = [];
PageController _pageController;
int prevPage;
int bottomSelectedIndex = 0;
//initialising the custom pinIcon
BitmapDescriptor pinIcon;
#override
void initState() {
super.initState();
//calling the the function that will await the pinIcon and have it ready with initState();
setCustomMapPin();
_pageController = PageController(initialPage: 1, viewportFraction: 0.8)
..addListener(_onScroll);
}
void _onScroll() {...
_myPlacesList(index) {...
Then I created the Google Map
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(40.505757, 22.846576),
zoom: 12.0,
),
onMapCreated: mapCreated,
myLocationEnabled: true,
myLocationButtonEnabled: true,
mapToolbarEnabled: false,
markers: Set.from(allMarkers),
),
),
}
void setCustomMapPin() async {
pinIcon = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(devicePixelRatio: 2.5), 'assets/images/iconMap.png');
}
void mapCreated(controller) {
setState(() {
_controller = controller;
_location.getLocation();
//Adding markers to the screen.Calling the markers from different file.
myPlaces.forEach((e) {
allMarkers.add(Marker(
markerId: MarkerId(e.name),
draggable: false,
icon: pinIcon,
infoWindow: InfoWindow(
title: e.name,
snippet: e.address,
),
position: e.locationCoords,
onTap: () {
_pageController.animateToPage(myPlaces.indexOf(e),
duration: Duration(milliseconds: 300), curve: Curves.ease);
},
));
});
});
}
//moves the camera to pin location
void moveCamera() {...
}
You can do it with something like this
_markers.add(Marker(
consumeTapEvents: true,
position: _center,
infoWindow: InfoWindow(
title: 'New Marker',
snippet: '',
),
icon: markerImage, //you custom marker, instance of BitmapDescriptor
)
and than you instantiate the map with:
GoogleMap(
onMapCreated: (GoogleMapController controller) {
mapController = controller;
},
myLocationEnabled: locationEnable,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 10.0,
),
mapType: MapType.normal,
markers: _markers,
)
var markerImage = await BitmapDescriptor.fromAssetImage(
ImageConfiguration(size: Size(96, 96)),
'assets/image/marker_image.png');

Flutter: How to place the mylocation button on Google Maps at different positions?

I'm using Google Maps and by default the myLocation button shows up on the topRight corner. I want it at the bottom right corner.
I can't seem to have any property inside GoogleMap widget
GoogleMap(
myLocationEnabled: true,
myLocationButtonEnabled: true,
initialCameraPosition: CameraPosition(
target: _currentLocation,
zoom: 11.0,
),
onMapCreated: _onMapCreated,
),
Try using FloationgButton
GoogleMap(
mapType: MapType.hybrid,
initialCameraPosition: _kGooglePlex,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
myLocationEnabled: true,
),
floatingActionButton: FloatingActionButton.extended(
onPressed: _currentLocation,
label: Text('My Location'),
icon: Icon(Icons.location_on),
),
);
}
also set with the current location
void _currentLocation() async {
final GoogleMapController controller = await _controller.future;
LocationData currentLocation;
var location = new Location();
try {
currentLocation = await location.getLocation();
} on Exception {
currentLocation = null;
}
controller.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(
bearing: 0,
target: LatLng(currentLocation.latitude, currentLocation.longitude),
zoom: 17.0,
),
));
}

Flutter Google Maps Polyline - The argument type 'LatLng' can't be assigned to the parameter type 'List<LatLng>'

I am using Google Maps within my Flutter project. I am trying to parse two JSON files in my assets so that I can use their latitudes and longitudes in a Polyline and markers. The markers work fine but now I am adding another future to my Future builder for the polylines and I receive the following error:
The argument type LatLng can't be assigned to the parameter type List<LatLng>.
Future _future;
Future _futuree;
Future<String> loadString() async => await rootBundle.loadString('assets/busStops/stops_${widget.selectStation}.json');
List<Marker> allMarkers = [];
GoogleMapController _controller;
#override
void initState() {
// TODO: implement initState
super.initState();
//future 1
_future = loadString();
//future 2
_futuree = loadMyCoord();
}
Future<String> loadMyCoord() async {
var x = await rootBundle
.loadString('assets/route/coords_Centurion.json');
return x;
}
#override
Widget build(BuildContext context) {
createMarker(context);
return Scaffold(
appBar: AppBar(
title: Text("Bus Routes"),
centerTitle: true,
backgroundColor: Color.fromRGBO(59, 62, 64, 1),
actions: <Widget>[
FlatButton(
textColor: Colors.white,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => busStationList()),
);
},
child: Icon(Icons.add),
),
],
),
body: Stack(children: [
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: FutureBuilder(
// Futures
future: Future.wait(
[
//[0]
_future,
//[1]
_futuree,
]
),
builder: (
context,
AsyncSnapshot<List<dynamic>> snapshot,
) {
// Check hasData once for all futures.
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
List<dynamic> parsedJson = jsonDecode(snapshot.data[0]);
allMarkers = parsedJson.map((element) {
return Marker(
icon: customIcon,
markerId: MarkerId(element["Latitude"].toString()),
position: LatLng(element['Latitude'] ?? 0.0,
element['Longitude'] ?? 0.0));
}).toList();
List<dynamic> parseJson = jsonDecode(snapshot.data[1]);
List<Polyline> allPolylinesByPosition = [];
parseJson.forEach((element){
List<dynamic> coords = element["coords"];
coords.forEach((i) {
double lat = double.tryParse(i["latitude"]);
double lng = double.tryParse(i["longitude"]);
allPolylinesByPosition.add(Polyline(
polylineId: PolylineId('lines'),
points: points: LatLng(lat ?? 0.0, lng ?? 0.0);
visible: true,
color: Colors.red
));
}
);
});
return GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(-26.1711459, 27.9002758), zoom: 9.0),
markers: Set.from(allMarkers),
onMapCreated: mapCreated,
polylines: Set.from(allPolylinesByPosition),
);
},
),
),
]),
);
}
void mapCreated(controller) {
setState(() {
_controller = controller;
});
}
Few things to note, points parameter of Polyline only accepts list of LatLng (List<LatLng>) and not LatLng.
This line should be changed in your code. Try adding a list of LatLng instead of passing a single LatLng instance in the points parameter.
points: LatLng(lat ?? 0.0, lng ?? 0.0);
Polyline.dart
class Polyline {
const Polyline({
#required this.polylineId,
this.consumeTapEvents = false,
this.color = Colors.black,
this.endCap = Cap.buttCap,
this.geodesic = false,
this.jointType = JointType.mitered,
this.points = const <LatLng>[],
this.patterns = const <PatternItem>[],
this.startCap = Cap.buttCap,
this.visible = true,
this.width = 10,
this.zIndex = 0,
this.onTap,
});
Hi I have now done the following , and pulling data but it is not showing on the map
List<dynamic> parseJson = jsonDecode(snapshot.data[1]);
Set<Polyline> allPolylinesByPosition = {};
parseJson.forEach((element) {
List<dynamic> coords = element["coords"];
coords.forEach((i) {
List<LatLng> latlng = [
LatLng( double.tryParse(i["latitude"]) ?? 0.0 ,double.tryParse(i["longitude"]) ?? 0.0)
];
allPolylinesByPosition.add(Polyline(
polylineId: PolylineId((_lastMapPosition.toString())),
points:latlng,
visible: true,
width: 4,
color: Colors.red
));
print(PolylineId);
}
);
});
return GoogleMap(
initialCameraPosition: CameraPosition(
target: LatLng(-26.1711459, 27.9002758), zoom: 2.0),
markers: Set.from(allMarkers),
onMapCreated: mapCreated,
polylines: allPolylinesByPosition,
);
},
),
'''

Flutter - Google Maps doesn´t wait to Location

I´m trying to show a map with current location. For do this i used Location and Google Map plugins (last version).
I have a code similar to:
var lng, lat;
#override
initState() {
super.initState();
loading = true;
getLocation();
}
Future getLocation() async {
final location = Location();
var currentLocation = await location.getLocation();
setState(() {
lat = currentLocation.latitude;
lng = currentLocation.longitude;
loading=false;
});
}
loading==false ? GoogleMap(
mapType: MapType.hybrid,
myLocationButtonEnabled: true,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: LatLng(lat, lng),
zoom: 15.0,
)):null,
When we go the view with map a error appear around 1s (then view load properly) with this error in the console
I/flutter (15567): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════ I/flutter
(15567): The following assertion was thrown building
HomePageScreen(dirty, dependencies: I/flutter (15567):
[_LocalizationsScope-[GlobalKey#78c30], MediaQuery], state:
_HomePageScreen#9c9d2): I/flutter (15567): 'package:google_maps_flutter/src/location.dart': Failed assertion:
line 17 pos 16: 'latitude != I/flutter (15567): null': is not true.
I debug it and the error is relative simple: The Location plugin load latitude and longitude slow , Google Maps plugin load more fast. So we have a error.
The question is: How can i force Google map to wait location and longitude from Location plugin?
Show an empty Container() or any loading indicator while your lat and lng is null.
lat == null || lng == null
? Container()
: GoogleMap(
mapType: MapType.hybrid,
myLocationButtonEnabled: true,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: LatLng(lat, lng),
zoom: 15.0,
),
);
you can display a loader until you get your location,
var lng, lat;
#override
initState() {
super.initState();
loading = true;
getLocation();
}
Future getLocation() async {
final location = Location();
var currentLocation = await location.getLocation();
setState(() {
lat = currentLocation.latitude;
lng = currentLocation.longitude;
loading=false;
});
}
loading==false ? GoogleMap(
mapType: MapType.hybrid,
myLocationButtonEnabled: true,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: LatLng(lat, lng),
zoom: 15.0,
)):CircularProgressIndicator(),
You can also try this, and get rid of the empty Container.
GoogleMap(
mapType: MapType.hybrid,
myLocationButtonEnabled: true,
myLocationEnabled: true,
initialCameraPosition: CameraPosition(
target: LatLng(lat ?? 0, lng ?? 0), // so if lat, lng is null, we use 0 as placeholder.
zoom: 15.0,
),
)

Iterate markers Google Flutter maps

I´m trying to iterate markers in new google flutter map.
I retrieve the array of the coordinates with a web service, then i iterate the elements and get the index that have latitude and longitude.
for (int i = 0; i < list.length; i++) {
mapController.addMarker(MarkerOptions(position: list[0].values.elementAt(i)))));
}
And the map options.
GoogleMapController mapController;
GoogleMap(
onMapCreated: (GoogleMapController mapController) {
mapController = mapController;
},
options: GoogleMapOptions(
mapType: MapType.satellite,
myLocationEnabled :true,
cameraPosition: CameraPosition(
target: LatLng(40.347022, -3.750381), zoom: 5.0),
),
),
I suppose that mapController should take the coordinates that i put in the for loop, but doesn't work. The console return
The method 'addMarker' was called on null.
So the question is, how can i add multiple markers dynamically using google flutter map package?
Also i tried this simple code and works, so the error is occurred when adding markers.
GoogleMapController mapController;
GoogleMap(
onMapCreated: (GoogleMapController mapController) {
mapController = mapController;
mapController.addMarker(MarkerOptions(
position:LatLng(40.347022, -3.750381),
infoWindowText: InfoWindowText("Title", "Content"),
//icon:
));
mapController.addMarker(MarkerOptions(
position:LatLng(43.321871, -3.006887),
infoWindowText: InfoWindowText("Title", "Content"),
//icon:
));
},
options: GoogleMapOptions(
mapType: MapType.satellite,
myLocationEnabled :true,
cameraPosition: CameraPosition(
target: LatLng(40.347022, -3.750381), zoom: 5.0),
),
),
UPDATE 2
I found this example code. This is exactly that i want but i can´t repeat this code, return this error
https://github.com/gerryhigh/Flutter-Google-Maps-Demo/blob/master/lib/venues.dart
NoSuchMethodError: The getter 'className' was called on null.
I call an instance of Google maps in the main build function.Like this:
return GoogleMap(
onMapCreated: _onMapCreated,
options: GoogleMapOptions(
cameraPosition: CameraPosition(
target: _center1,
zoom: 11.0,
),
),
);
Inside the "_onMapCreated" function is where I have the iterator:
widget.model.allItems.forEach((item) {
//print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
print(item.lat);
var newItem = LatLng(double.parse(item.lat), double.parse(item.lon));
mapController.addMarker(
MarkerOptions(
icon: BitmapDescriptor.fromAsset(assetName),
position: newItem,
),
);
});
This is working for me.
In the first example GoogleMapController paramater and your local variable have the same name, so basically, local variable becomes shadowed and you're assigning function parameter value to itself. Renaming one of these two should resolve the issue.
void populateOrder(Item item) async {
if (item != null) {
for (int i = 0; i < item.feature.length; i++) {
var position = item.feature[i];
if (position != null) {
try {
if (double.parse(position.latitude) != null &&
double.parse(position.longitude) != null) {
mapController.clearMarkers().then((value){
mapController.addMarker(
MarkerOptions(
position: LatLng(double.parse(position.latitude),
double.parse(position.longitude)),
infoWindowText: InfoWindowText(position.schet, ""),
icon: BitmapDescriptor.defaultMarker,
),
);
});
}
} catch (e) {
print(e);
}
}
}
}
}
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
populateOrder(itemize);
Future.delayed(Duration(seconds: 6));
}
The library was updated: this is how I was able to show multiple markers on the map.
Completer<GoogleMapController> _controller = Completer();
// initial camera position
CameraPosition _cameraPos;
// A map of markers
Map<MarkerId, Marker> markers = <MarkerId, Marker>{};
// function to generate random ids
int generateIds() {
var rng = new Random();
var randomInt;
randomInt = rng.nextInt(100);
print(rng.nextInt(100));
return randomInt;
}
//call this function in initstate
// I'm getting a json Object with locations from an
// external api
buildMarkers() {
for (var i = 0; i < gridItem.locations.length; i++) {
var markerIdVal = generateIds();
final MarkerId markerId = MarkerId(markerIdVal.toString());
final Marker marker = Marker(
markerId: markerId,
position: LatLng(
gridItem.locations[i].latitude,
gridItem.locations[i].longitude,
),
infoWindow: InfoWindow(title: gridItem.locations[i].place, snippet: gridItem.locations[i].region),
);
// you could do setState here when adding the markers to the Map
markers[markerId] = marker;
}
print("Length:: + ${markers.length}");
}
// your Googlemaps Widget somewhere in your widget tree
GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _cameraPos,
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>[Factory<OneSequenceGestureRecognizer>(()=>ScaleGestureRecognizer())].toSet(),
markers: Set<Marker>.of(markers.values),
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);}),