Files
feature-next-arch/lib/features/home/presentation/widgets/map/test_amap_page.dart

179 lines
5.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
import 'CoordTransform/coord_transform.dart';
class AmapFlutterMapPage extends StatefulWidget {
const AmapFlutterMapPage({super.key});
@override
State<AmapFlutterMapPage> createState() => _AmapFlutterMapPageState();
}
class _AmapFlutterMapPageState extends State<AmapFlutterMapPage> {
final MapController _mapController = MapController();
static const String amapKey = "bbb1f0f20eed6bf679eddf2625630aba";
LatLng _currentCenter = const LatLng(39.908823, 116.397470);
bool _isLoading = true;
// 新增:标记页面是否已销毁,防止异步操作访问已释放的控制器
bool _isDisposed = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_checkAndGetLocation();
});
}
// 新增:页面销毁时标记状态
@override
void dispose() {
_isDisposed = true; // 先标记销毁状态
// _mapController.dispose(); // 再销毁控制器
super.dispose();
}
Future<void> _checkAndGetLocation() async {
var status = await Permission.location.status;
if (status.isDenied) {
status = await Permission.location.request();
if (status.isDenied) {
if (!_isDisposed) { // 防护:页面没销毁才弹提示
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(AppLocalizations.of(context).translate('route_planning.location_permission_denied'))),
);
setState(() { _isLoading = false; });
}
return;
}
}
if (status.isPermanentlyDenied) {
if (!_isDisposed) { // 防护:页面没销毁才弹提示
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(context).translate('route_planning.location_permanently_denied')),
action: SnackBarAction(label: AppLocalizations.of(context).translate('route_planning.go_to_settings'), onPressed: openAppSettings),
),
);
setState(() { _isLoading = false; });
}
return;
}
await _getCurrentLocation();
}
Future<void> _getCurrentLocation() async {
if (_isDisposed) return;
setState(() { _isLoading = true; });
print('📍 开始定位...');
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
if (!_isDisposed) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(AppLocalizations.of(context).translate('route_planning.location_service_disabled'))),
);
setState(() { _isLoading = false; });
}
return;
}
try {
final position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.bestForNavigation,
forceAndroidLocationManager: true,
timeLimit: const Duration(seconds: 8),
);
if (_isDisposed) return;
// ⭐⭐⭐ 关键修复点:WGS84 → GCJ02 ⭐⭐⭐
final gcjPoint = CoordTransform.wgs84ToGcj02(
position.latitude,
position.longitude,
);
setState(() {
_currentCenter = gcjPoint;
_isLoading = false;
});
if (!_isDisposed) {
_mapController.move(gcjPoint, 15.0);
}
print('✅ 定位成功(GCJ02): ${gcjPoint.latitude}, ${gcjPoint.longitude}');
} catch (e) {
if (!_isDisposed) {
setState(() { _isLoading = false; });
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('${AppLocalizations.of(context).translate('route_planning.location_failed')}: $e'),
action: SnackBarAction(
label: AppLocalizations.of(context).translate('route_planning.retry'),
onPressed: _checkAndGetLocation,
),
),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context).translate('route_planning.title')),
actions: [
IconButton(
icon: const Icon(Icons.my_location),
onPressed: _checkAndGetLocation,
tooltip: AppLocalizations.of(context).translate('route_planning.my_location'),
),
],
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: FlutterMap(
mapController: _mapController,
options: MapOptions(
center: _currentCenter,
zoom: 15.0,
minZoom: 3.0,
maxZoom: 18.0,
interactiveFlags: InteractiveFlag.all,
),
children: [
TileLayer(
urlTemplate:
"https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}&key=$amapKey",
subdomains: const ['1', '2', '3', '4'],
tileProvider: NetworkTileProvider(),
),
MarkerLayer(
markers: [
Marker(
point: _currentCenter,
width: 40,
height: 40,
child: const Icon(Icons.location_on, color: Colors.red, size: 40),
),
],
),
],
),
);
}
}