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

如何获取CarPlay CPPointOfInterestTemplate地图屏幕的经纬度范围?

在CarPlay的CPPointOfInterestTemplate中获取地图可视区域的经纬度范围

要实现地图滚动/位置变化时获取屏幕的经纬度范围,你需要利用CPMapTemplateDelegate的代理方法监听地图区域变化,具体步骤如下:

一、修改原生Swift代码(FCPPointOfInterestTemplate.swift)

  1. 让FCPPointOfInterestTemplate类遵守CPMapTemplateDelegate协议,并将模板的代理设置为自身
  2. 实现区域变化的代理方法,提取可视区域的经纬度范围,再通过MethodChannel传递给Flutter端

修改后的代码如下:

//
//  FCPPointOfInterestTemplate.swift
//  flutter_carplay
//
//  Created by Olaf Schneider on 15.02.22.
//

import CarPlay
import Flutter

@available(iOS 14.0, *)
class FCPPointOfInterestTemplate: NSObject, CPMapTemplateDelegate {
    private(set) var _super: CPPointOfInterestTemplate?
    private(set) var elementId: String
    private var title: String
    private var poi: [FCPPointOfInterest]

    init(obj: [String: Any]) {
        self.elementId = obj["_elementId"] as! String
        self.title = obj["title"] as! String
        self.poi = (obj["poi"] as! [[String: Any]]).map {
            FCPPointOfInterest(obj: $0)
        }
        super.init()
    }

    var get: CPPointOfInterestTemplate {
        var pois: [CPPointOfInterest] = []

        for p in poi {
            pois.append(p.get)
        }

        let pointOfInterestTemplate = CPPointOfInterestTemplate.init(
            title: self.title, pointsOfInterest: pois, selectedIndex: NSNotFound)
        // 设置代理,监听地图区域变化
        pointOfInterestTemplate.delegate = self
        self._super = pointOfInterestTemplate
        return pointOfInterestTemplate
    }

    // 监听地图可视区域变化的代理方法
    func mapTemplate(_ mapTemplate: CPMapTemplate, didChangeVisibleRegion visibleRegion: CPMapRegion) {
        // 提取可视区域的东北、西南角坐标
        let northEast = visibleRegion.northEast
        let southWest = visibleRegion.southWest
        
        // 封装成可传递给Flutter的数据
        let regionData = [
            "northEastLat": northEast.latitude,
            "northEastLng": northEast.longitude,
            "southWestLat": southWest.latitude,
            "southWestLng": southWest.longitude,
            "elementId": self.elementId
        ]
        
        // 通过MethodChannel将数据发送到Flutter端
        let channel = FlutterMethodChannel(name: "flutter_carplay/map_region", binaryMessenger: FlutterGetAppController.shared?.binaryMessenger ?? FlutterBinaryMessengerImpl())
        channel.invokeMethod("onRegionChanged", arguments: regionData)
    }
}

@available(iOS 14.0, *)
extension FCPPointOfInterestTemplate: FCPRootTemplate {}

二、Flutter端接收区域变化回调

在Flutter代码中,通过MethodChannel监听原生发送的区域变化事件,进而请求对应范围内的充电桩:

import 'package:flutter/services.dart';

class CarPlayMapHandler {
  final MethodChannel _channel = const MethodChannel('flutter_carplay/map_region');

  void initRegionListener() {
    _channel.setMethodCallHandler((MethodCall call) async {
      if (call.method == 'onRegionChanged') {
        final Map<String, dynamic> args = call.arguments as Map<String, dynamic>;
        // 获取可视区域的经纬度范围
        final double neLat = args['northEastLat'];
        final double neLng = args['northEastLng'];
        final double swLat = args['southWestLat'];
        final double swLng = args['southWestLng'];
        final String elementId = args['elementId'];

        // 根据范围请求充电桩数据
        await _fetchChargingStations(neLat, neLng, swLat, swLng);
      }
    });
  }

  Future<void> _fetchChargingStations(double neLat, double neLng, double swLat, double swLng) async {
    // 这里实现你的充电桩接口请求逻辑
    // 例如:根据东北、西南角坐标构造范围查询条件
  }
}

关键说明

  • CPMapTemplateDelegate的mapTemplate:didChangeVisibleRegion:方法会在地图滚动、缩放、位置更新时触发,完全满足需求
  • 传递的elementId可用于区分不同的模板实例(如有多个)
  • 确保MethodChannel的名称在原生和Flutter端完全一致,否则会导致通信失败

内容的提问来源于stack exchange,提问作者Ragul PR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:40:58