Flutter实现点击按钮获取当前位置并在OpenStreetMap添加标记
实现Flutter地图点击按钮定位当前位置并添加红色标记
问题描述
我想在Flutter项目的按钮中添加功能:点击按钮时,OpenStreetMap显示我的当前位置并添加红色标记。现有代码如下:
现有页面代码
import 'package:geocoding/geocoding.dart'; // Package maps import 'package:geolocator/geolocator.dart'; // Package maps import 'package:flutter_map/flutter_map.dart'; // Package maps import 'package:latlong2/latlong.dart'; // Package maps class _AbsenPageState extends State<AbsenPage> { Position? _currentLocation; bool servicePermission = false; LocationPermission permission = LocationPermission.denied; String _currentAddress = ""; bool showSyncText = true; // 控制"点击图标同步"文本的显示 Future<Position> _getCurrentLocation() async { servicePermission = await Geolocator.isLocationServiceEnabled(); if (!servicePermission) { print("Service Disabled"); } permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); } return await Geolocator.getCurrentPosition(); } _getAddressFromCoordinates() async { try { List<Placemark> placemarks = await placemarkFromCoordinates( _currentLocation!.latitude, _currentLocation!.longitude, ); Placemark place = placemarks[0]; setState(() { _currentAddress = "${place.street}"; showSyncText = false; // 获取到地址后隐藏提示文本 }); } catch (e) { print(e); } } @override Widget build(BuildContext context) { return Scaffold( body: Stack( fit: StackFit.expand, children: [ FlutterMap( options: const MapOptions( center: LatLng(-7.238141, 112.734710), zoom: 18.0, ), children: [ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', subdomains: const ['a', 'b', 'c'], ), ], ),
现有按钮代码
ElevatedButton( onPressed: () async { _currentLocation = await _getCurrentLocation(); await _getAddressFromCoordinates(); print("$_currentAddress"); }, ),
解决方案
要实现点击按钮定位并添加红色标记的功能,需要做以下3处修改:
- 添加标记图层:在
FlutterMap的子组件中加入MarkerLayer,根据当前位置生成红色标记 - 动态切换地图中心:当获取到当前位置后,自动将地图中心定位到该位置
- 触发UI刷新:获取位置后调用
setState,让地图更新标记和中心坐标
修改后的关键代码
1. 更新FlutterMap组件
FlutterMap( options: MapOptions( // 有当前位置时用当前坐标作为中心,否则用默认值 center: _currentLocation != null ? LatLng(_currentLocation!.latitude, _currentLocation!.longitude) : const LatLng(-7.238141, 112.734710), zoom: 18.0, ), children: [ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', subdomains: const ['a', 'b', 'c'], ), // 只有获取到位置后才显示标记 if (_currentLocation != null) MarkerLayer( markers: [ Marker( width: 80.0, height: 80.0, point: LatLng(_currentLocation!.latitude, _currentLocation!.longitude), builder: (ctx) => const Icon( Icons.location_on, color: Colors.red, size: 40.0, ), ), ], ), ], ),
2. 更新按钮的onPressed方法
ElevatedButton( onPressed: () async { _currentLocation = await _getCurrentLocation(); await _getAddressFromCoordinates(); // 刷新UI,让地图更新中心和标记 setState(() {}); print("$_currentAddress"); }, ),
说明
- 点击按钮后,程序会先检查位置权限、获取当前位置,然后地图会自动跳转到你的位置并显示红色定位图标
- 如果需要自定义标记样式,可以修改
Marker的builder部分,比如替换成自定义图片或容器组件
内容的提问来源于stack exchange,提问作者Asa Marsal
相关产品推荐
相关产品推荐

