如何在 Flutter 中的 Google 地图上设置正确大小的标记?
How to set marker in correct size on Google Map in Flutter?
任何人都可以帮助我在 GoogleMap 上获得正确大小的标记,当我在地图上加载标记时,它变得非常大而且很难看。所以我必须手动以正确的宽度和高度裁剪标记图像。
但我需要它在代码中自动完成。我附上了输出的屏幕截图以及下面的代码。提前致谢。
这是我的代码
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class PlaceAutoComplete extends StatefulWidget {
const PlaceAutoComplete({Key? key}) : super(key: key);
@override
_PlaceAutoCompleteState createState() => _PlaceAutoCompleteState();
}
class _PlaceAutoCompleteState extends State<PlaceAutoComplete> {
//GPS permissions
bool servicestatus = false;
bool haspermission = false;
late LocationPermission permission;
GoogleMapController? _controller;
Circle? circle; //current location circle
Marker? marker; //pin marker on circle
//initial location object
static const CameraPosition initialLocation = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746);
@override
void initState() {
// TODO: implement initState
checkGps();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Google Places Auto Complete'),
centerTitle: true,
),
body: SafeArea(
child: Stack(
children: [
GoogleMap(
initialCameraPosition: initialLocation,
onMapCreated: (GoogleMapController controller) {
_controller = controller;
},
markers: Set.of((marker != null) ? [marker!] : []),
circles: Set.of((circle != null) ? [circle!] : []),
),
],
),
),
);
}
Future<Position> getCurrentLocationCoordinates() async {
Position currentLocationCoordinates = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
return currentLocationCoordinates;
}
void animateCurrentLocation() async {
Uint8List imageData = await getMarker();
var currentLocation = await getCurrentLocationCoordinates();
_controller!.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(currentLocation.latitude, currentLocation.longitude),
zoom: 15.0,
),),);
updateMarkerAndCircle(currentLocation, imageData);
}
checkGps() async {
servicestatus = await Geolocator.isLocationServiceEnabled();
if(servicestatus){
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
print('Location permissions are denied');
}else if(permission == LocationPermission.deniedForever){
print("'Location permissions are permanently denied");
}else{
haspermission = true;
}
}else{
haspermission = true;
}
if(haspermission){
setState(() {
//refresh the UI
});
animateCurrentLocation();
}
}else{
print("GPS Service is not enabled, turn on GPS location");
}
setState(() {
//refresh the UI
});
}
Future<Uint8List> getMarker() async {
ByteData byteData = await DefaultAssetBundle.of(context).load("assets/originicon.png");
return byteData.buffer.asUint8List();
}
void updateMarkerAndCircle(Position newLocalData, Uint8List imageData) {
LatLng latLng = LatLng(newLocalData.latitude , newLocalData.longitude );
setState(() {
marker = Marker(
markerId: MarkerId("home"), //marker ID is mandate to differentiate from the other markers
position: latLng,
rotation: newLocalData.heading ,
draggable: false,
zIndex: 2, //we want to place car image on above the circle
flat: true, // it will stick to map,even when u tilt the camera angle on map (basicaaly it will appear as it is stick on road)
anchor: Offset(0.5, 0.5), //it will make image to be center on the circle
icon: BitmapDescriptor.fromBytes(imageData), //image of car
);
circle = Circle(
circleId: CircleId("car"),
radius: newLocalData.accuracy ,
zIndex: 1, //we want to place circle below the car image
strokeColor: Colors.blue,
center: latLng,
fillColor: Colors.blue.withAlpha(70),
);
});
}
}
用这段代码替换你的方法 getMarker。
import 'dart:ui' as ui;
Future<Uint8List> getMarker(int width) async {
ByteData data = await rootBundle.load("assets/originicon.png");
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);
ui.FrameInfo fi = await codec.getNextFrame();
return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
}
任何人都可以帮助我在 GoogleMap 上获得正确大小的标记,当我在地图上加载标记时,它变得非常大而且很难看。所以我必须手动以正确的宽度和高度裁剪标记图像。
但我需要它在代码中自动完成。我附上了输出的屏幕截图以及下面的代码。提前致谢。
这是我的代码
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class PlaceAutoComplete extends StatefulWidget {
const PlaceAutoComplete({Key? key}) : super(key: key);
@override
_PlaceAutoCompleteState createState() => _PlaceAutoCompleteState();
}
class _PlaceAutoCompleteState extends State<PlaceAutoComplete> {
//GPS permissions
bool servicestatus = false;
bool haspermission = false;
late LocationPermission permission;
GoogleMapController? _controller;
Circle? circle; //current location circle
Marker? marker; //pin marker on circle
//initial location object
static const CameraPosition initialLocation = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746);
@override
void initState() {
// TODO: implement initState
checkGps();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Google Places Auto Complete'),
centerTitle: true,
),
body: SafeArea(
child: Stack(
children: [
GoogleMap(
initialCameraPosition: initialLocation,
onMapCreated: (GoogleMapController controller) {
_controller = controller;
},
markers: Set.of((marker != null) ? [marker!] : []),
circles: Set.of((circle != null) ? [circle!] : []),
),
],
),
),
);
}
Future<Position> getCurrentLocationCoordinates() async {
Position currentLocationCoordinates = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
return currentLocationCoordinates;
}
void animateCurrentLocation() async {
Uint8List imageData = await getMarker();
var currentLocation = await getCurrentLocationCoordinates();
_controller!.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(currentLocation.latitude, currentLocation.longitude),
zoom: 15.0,
),),);
updateMarkerAndCircle(currentLocation, imageData);
}
checkGps() async {
servicestatus = await Geolocator.isLocationServiceEnabled();
if(servicestatus){
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
print('Location permissions are denied');
}else if(permission == LocationPermission.deniedForever){
print("'Location permissions are permanently denied");
}else{
haspermission = true;
}
}else{
haspermission = true;
}
if(haspermission){
setState(() {
//refresh the UI
});
animateCurrentLocation();
}
}else{
print("GPS Service is not enabled, turn on GPS location");
}
setState(() {
//refresh the UI
});
}
Future<Uint8List> getMarker() async {
ByteData byteData = await DefaultAssetBundle.of(context).load("assets/originicon.png");
return byteData.buffer.asUint8List();
}
void updateMarkerAndCircle(Position newLocalData, Uint8List imageData) {
LatLng latLng = LatLng(newLocalData.latitude , newLocalData.longitude );
setState(() {
marker = Marker(
markerId: MarkerId("home"), //marker ID is mandate to differentiate from the other markers
position: latLng,
rotation: newLocalData.heading ,
draggable: false,
zIndex: 2, //we want to place car image on above the circle
flat: true, // it will stick to map,even when u tilt the camera angle on map (basicaaly it will appear as it is stick on road)
anchor: Offset(0.5, 0.5), //it will make image to be center on the circle
icon: BitmapDescriptor.fromBytes(imageData), //image of car
);
circle = Circle(
circleId: CircleId("car"),
radius: newLocalData.accuracy ,
zIndex: 1, //we want to place circle below the car image
strokeColor: Colors.blue,
center: latLng,
fillColor: Colors.blue.withAlpha(70),
);
});
}
}
用这段代码替换你的方法 getMarker。
import 'dart:ui' as ui;
Future<Uint8List> getMarker(int width) async {
ByteData data = await rootBundle.load("assets/originicon.png");
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width);
ui.FrameInfo fi = await codec.getNextFrame();
return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List();
}