Files
flutterApp/lib/features/home/presentation/widgets/map/dji_tile_layer.dart
2026-03-10 15:06:28 +08:00

105 lines
3.3 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:convert';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:flutter/services.dart' show rootBundle;
// 🔥 1. 定义场站模型(核心)
class DJIStation {
/// 场站标识(对应瓦片目录名:assets/tiles/[name])
final String name;
/// 场站显示名称(用于UI展示,如"一号场站")
final String displayName;
const DJIStation({required this.name, required this.displayName});
}
/// 大疆高清瓦片图层组件(适配 flutter_map v6.x)
class DJITileLayer extends StatefulWidget {
/// 场站名称(对应 tiles/[stationName] 目录)
final String stationName;
/// 地图控制器(用于加载中心点后移动地图)
final MapController mapController;
const DJITileLayer({super.key, required this.stationName, required this.mapController});
@override
State<DJITileLayer> createState() => _DJITileLayerState();
}
class _DJITileLayerState extends State<DJITileLayer> {
/// 场站中心点(从 parm/center.json 读取)
LatLng? _stationCenter;
/// 瓦片缩放级别范围
final double _minZoom = 16;
final double _maxZoom = 23;
@override
void initState() {
super.initState();
_loadStationCenter();
}
@override
void didUpdateWidget(covariant DJITileLayer oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.stationName != widget.stationName) {
_loadStationCenter();
}
}
/// 从 assets/tiles/[stationName]/parm/center.json 读取中心点
Future<void> _loadStationCenter() async {
try {
debugPrint("xsdscdvc");
final String configPath = 'assets/tiles/${widget.stationName}/parm/center.json';
debugPrint(configPath);
final jsonString = await rootBundle.loadString('assets/tiles/liaoning/parm/center.json');
debugPrint("$jsonString,jsonString");
final Map<String, dynamic> centerJson = json.decode(jsonString);
debugPrint("$centerJson,centerJson");
final double lng = centerJson['lng'] ?? centerJson['lon'];
final double lat = centerJson['lat'];
final LatLng newCenter = LatLng(lat, lng);
setState(() => _stationCenter = newCenter);
widget.mapController.move(newCenter, 19);
} catch (e) {
debugPrint('加载${widget.stationName}中心点失败:$e');
setState(() => _stationCenter = const LatLng(32.040644, 120.805718));
}
}
@override
Widget build(BuildContext context) {
final String tileUrlTemplate = 'assets/tiles/${widget.stationName}/{z}/{x}/{y}.png';
return TileLayer(
urlTemplate: tileUrlTemplate,
tileProvider: AssetTileProvider(), // 修复:直接使用类实例
tms: true,
minZoom: _minZoom,
maxZoom: _maxZoom,
);
}
}
/// 修复:适配 v6.x 的 AssetTileProvider(移除过时的 TileLayerOptions)
class AssetTileProvider extends TileProvider {
@override
ImageProvider<Object> getImage(TileCoordinates coords, TileLayer options) {
// 修复:v6.x 中使用 TileCoordinates 替代 Coords,TileLayer 替代 TileLayerOptions
final String path = options.urlTemplate!
.replaceAll('{z}', coords.z.toString())
.replaceAll('{x}', coords.x.toString())
.replaceAll('{y}', coords.y.toString());
debugPrint('加载大疆瓦片:$path');
return AssetImage(path);
}
}