地图查询与截图

TencentMapController 提供了一系列查询方法,用于获取地图可见区域、坐标转换、截图等。

本文档介绍地图查询相关的 API 及其使用方法。




可见区域查询

final bounds = await controller.getVisibleRegion();
print('西南角: ${bounds.southwest.latitude}, ${bounds.southwest.longitude}');
print('东北角: ${bounds.northeast.latitude}, ${bounds.northeast.longitude}');

返回当前地图视口对应的 LatLngBounds,包含 southwest(西南角)和 northeast(东北角)两个 LatLng


坐标转换

屏幕坐标 → 经纬度

final latLng = await controller.getLatLng(ScreenCoordinate(x: 200, y: 400));
print('经纬度: ${latLng.latitude}, ${latLng.longitude}');
参数 类型 说明
screenCoordinate ScreenCoordinate 屏幕坐标(逻辑像素)

返回值:LatLng

经纬度 → 屏幕坐标

final point = await controller.getScreenCoordinate(
  const LatLng(39.9087, 116.3975),
);
print('屏幕坐标: ${point.x}, ${point.y}');

返回值:ScreenCoordinate(逻辑像素)。


批量坐标转换

批量经纬度 → 屏幕坐标

final points = await controller.getScreenCoordinates([
  const LatLng(39.9087, 116.3975),
  const LatLng(39.9100, 116.4000),
  const LatLng(39.9200, 116.4100),
]);
for (final p in points) {
  print('屏幕坐标: ${p.x}, ${p.y}');
}

批量屏幕坐标 → 经纬度

final latLngs = await controller.getLatLngs([
  const ScreenCoordinate(x: 100, y: 200),
  const ScreenCoordinate(x: 300, y: 400),
]);
for (final ll in latLngs) {
  print('经纬度: ${ll.latitude}, ${ll.longitude}');
}

注意:批量接口比循环调用单个接口效率更高,因为减少了 MethodChannel 的通信次数。当需要转换 10 个以上坐标时,强烈建议使用批量接口。


截图

final pngBytes = await controller.takeSnapshot();
// pngBytes 为 Uint8List 格式的 PNG 图片数据
// 可用于保存到文件或显示在 Image Widget 中
final image = Image.memory(pngBytes);

返回值:Uint8List?(PNG 格式,截屏失败时返回 null

注意:截图包含地图瓦片和所有覆盖物(Marker、Polyline 等),但不包含 Flutter Widget 层的 UI 元素。


清除缓存

await TencentMapInitializer.clearCache();

清除地图瓦片缓存。适用于地图样式更新后强制刷新的场景。

注意:此方法必须在任何 TencentMap Widget 创建之前调用。清除缓存后地图会重新下载瓦片,会短暂出现空白。


完整示例

class MapQueryPage extends StatefulWidget {
  const MapQueryPage({super.key});
  @override
  State<MapQueryPage> createState() => _MapQueryPageState();
}

class _MapQueryPageState extends State<MapQueryPage> {
  TencentMapController? _controller;
  String _info = '';

  void _queryVisibleRegion() async {
    final bounds = await _controller!.getVisibleRegion();
    setState(() {
      _info = '可见区域: SW(${bounds.southwest.latitude.toStringAsFixed(4)}, '
          '${bounds.southwest.longitude.toStringAsFixed(4)}) '
          'NE(${bounds.northeast.latitude.toStringAsFixed(4)}, '
          '${bounds.northeast.longitude.toStringAsFixed(4)})';
    });
  }

  void _takeSnapshot() async {
    final bytes = await _controller!.takeSnapshot();
    // 显示截图预览
    showDialog(
      context: context,
      builder: (_) => AlertDialog(
        content: Image.memory(bytes),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          TencentMap(
            initialCameraPosition: const CameraPosition(
              target: LatLng(39.9087, 116.3975),
              zoom: 12,
            ),
            onMapCreated: (c) => _controller = c,
          ),
          Positioned(
            top: 16,
            left: 16,
            child: Container(
              padding: const EdgeInsets.all(8),
              color: Colors.white,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(_info),
                  ElevatedButton(
                    onPressed: _queryVisibleRegion,
                    child: const Text('查询可见区域'),
                  ),
                  ElevatedButton(
                    onPressed: _takeSnapshot,
                    child: const Text('截图'),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}
本页内容