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

Flutter Google Map点击区域判断异常:内外圈提示一致问题

问题解决思路及代码修复

你的核心问题是判断逻辑错误:你误用了当前位置的经纬度做对比,而非地图点击事件返回的点击位置。需要通过计算点击点到圆心的球面距离,再和圆圈半径做比较来实现判断。

1. 实现经纬度两点距离计算方法

先写一个标准的Haversine公式工具方法,用来计算两点间的实际地面距离(单位:米):

import 'dart:math';

double calculateDistance(LatLng start, LatLng end) {
  const double earthRadius = 6371000; // 地球半径,单位米
  double dLat = _degreesToRadians(end.latitude - start.latitude);
  double dLng = _degreesToRadians(end.longitude - start.longitude);

  double a = sin(dLat / 2) * sin(dLat / 2) +
      cos(_degreesToRadians(start.latitude)) *
          cos(_degreesToRadians(end.latitude)) *
          sin(dLng / 2) *
          sin(dLng / 2);
  double c = 2 * atan2(sqrt(a), sqrt(1 - a));
  return earthRadius * c;
}

double _degreesToRadians(double degrees) {
  return degrees * pi / 180;
}

2. 修复地图点击事件的判断逻辑

在GoogleMap组件的onTap回调里,用点击位置和圆心计算距离,再触发对应提示:

GoogleMap(
  // 保留你原有的其他配置(地图类型、初始相机位置等)
  markers: Set.from(_list),
  circles: circles,
  onTap: (LatLng tappedPosition) {
    // 取出圆圈的圆心和半径
    LatLng circleCenter = LatLng(25.00057631014206, 55.297173890099394);
    double circleRadius = 700;

    // 计算点击点到圆心的距离
    double distance = calculateDistance(circleCenter, tappedPosition);

    // 根据距离判断并显示提示
    if (distance <= circleRadius) {
      // 用SnackBar或fluttertoast插件都可以,这里以SnackBar为例
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("您在区域内")),
      );
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("您已超出区域")),
      );
    }
  },
)

关键注意事项

  • 别搞混当前位置和点击位置:你的需求是判断点击的点是否在圈内,必须用onTap返回的tappedPosition来计算,不是用户的实时定位坐标。
  • 必须用球面距离公式:经纬度是球面坐标,不能直接用线性差值计算距离,否则误差会大到完全失效。

内容的提问来源于stack exchange,提问作者govind d

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 11:00:55