You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中使用apple_maps_flutter从ScreenCoordinate获取LatLng的方法

解决Apple Maps Flutter插件屏幕坐标转经纬度及手绘多边形实现思路

apple_maps_flutter确实没有提供类似Google Maps的getLatLng(ScreenCoordinate)方法,但可以通过以下两种方案实现手绘多边形的需求:

方案一:基于地图可见区域的计算(无原生依赖)

如果你的场景不需要支持地图旋转、倾斜,这种方法足够简单:

  • 用LayoutBuilder获取地图组件的实际宽高,同时监听地图的onCameraMove事件,每次相机移动时记录当前的visibleRegion(包含东北、西南两个角的经纬度)。
  • 监听用户触摸事件(用GestureDetector的onPanStart/onPanUpdate/onPanEnd),获取触摸点相对于地图组件的坐标(Offset)。
  • 通过比例计算转换经纬度:
    // 假设已获取:
    // visibleRegion: MapVisibleRegion
    // mapSize: Size (地图组件的宽高)
    // touchOffset: Offset (触摸点相对于地图左上角的偏移)
    
    double longitude = visibleRegion.southwest.longitude + 
        (touchOffset.dx / mapSize.width) * (visibleRegion.northeast.longitude - visibleRegion.southwest.longitude);
    
    double latitude = visibleRegion.northeast.latitude - 
        (touchOffset.dy / mapSize.height) * (visibleRegion.northeast.latitude - visibleRegion.southwest.latitude);
    
    LatLng convertedLatLng = LatLng(latitude, longitude);
    
  • 注意:地图旋转或倾斜时,这种方法会有明显误差,仅适用于基础场景。

方案二:通过Platform Channel调用原生Apple Maps API(高精度)

Apple Maps的原生MKMapView提供了convert(_:toCoordinateFrom:)方法,可以精准转换屏幕坐标到经纬度,支持所有地图状态:

Flutter端代码

import 'package:flutter/services.dart';
import 'package:apple_maps_flutter/apple_maps_flutter.dart';

final MethodChannel _mapConvertChannel = MethodChannel('your.app.id/map_coordinate_convert');

Future<LatLng?> convertScreenToLatLng(Offset screenOffset) async {
  try {
    final Map<String, dynamic>? result = await _mapConvertChannel.invokeMapMethod(
      'screenToCoordinate',
      {'x': screenOffset.dx, 'y': screenOffset.dy},
    );
    if (result == null) return null;
    return LatLng(result['latitude'], result['longitude']);
  } on PlatformException catch (e) {
    print('坐标转换失败: ${e.message}');
    return null;
  }
}

iOS端Swift代码

在AppDelegate.swift或对应的FlutterViewController中实现:

import UIKit
import Flutter
import MapKit
import apple_maps_flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    
    // 注册MethodChannel
    let convertChannel = FlutterMethodChannel(name: "your.app.id/map_coordinate_convert", binaryMessenger: controller.binaryMessenger)
    
    convertChannel.setMethodCallHandler { [weak self] call, result in
      guard call.method == "screenToCoordinate",
            let args = call.arguments as? [String: Double],
            let x = args["x"], let y = args["y"],
            // 获取Apple Maps的原生MKMapView实例
            let mapView = self?.getAppleMapView(from: controller) else {
        result(FlutterError(code: "INVALID", message: "参数错误或地图实例未找到", details: nil))
        return
      }
      
      let point = CGPoint(x: x, y: y)
      let coordinate = mapView.convert(point, toCoordinateFrom: mapView)
      result(["latitude": coordinate.latitude, "longitude": coordinate.longitude])
    }
    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
  
  // 从Flutter视图中获取MKMapView
  private func getAppleMapView(from controller: FlutterViewController) -> MKMapView? {
    for subview in controller.view.subviews {
      if let mapView = subview as? MKMapView {
        return mapView
      }
      if subview is FlutterViewController, let nestedMap = getAppleMapView(from: subview as! FlutterViewController) {
        return nestedMap
      }
    }
    return nil
  }
}

手绘多边形的具体实现步骤

  1. 维护一个List<LatLng>用于存储多边形的顶点。
  2. 用GestureDetector包裹Apple Maps组件,监听触摸事件:
    • onPanStart:转换触摸点为经纬度,添加到顶点列表。
    • onPanUpdate:实时转换触摸点,更新顶点列表的最后一个点(或添加新点,根据绘制逻辑)。
    • onPanEnd:结束当前线段,准备添加下一个顶点(或闭合多边形)。
  3. 将顶点列表传入Apple Maps的Polygon组件,设置polygons: {Polygon(polygonId: PolygonId("handdrawn"), points: _polygonPoints)},实现实时渲染。

内容的提问来源于stack exchange,提问作者Amani Saaduddin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:42:38