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

Flutter Google Map:如何检测用户是否处于Marker矩形区域内

Flutter Google Maps 考勤应用:位置区域判断实现

首先得明确:Google Maps的Marker本身只是一个单点,没有自带的矩形区域。你需要为每个考勤点的Marker手动定义对应的矩形边界,常见两种方式:

  • 以Marker经纬度为中心,设置固定偏移量(比如南北/东西各偏移0.001度,大概对应100米左右,可根据实际精度需求调整)
  • 预先在后台或本地配置里存储每个考勤点的矩形四个顶点坐标(左上、右上、左下、右下)

获取用户当前位置

用Flutter常用的geolocator包来获取实时位置:

  1. 先在pubspec.yaml添加依赖:
dependencies:
  geolocator: ^10.1.0
  1. 编写工具方法请求权限并获取位置:
import 'package:geolocator/geolocator.dart';

Future<Position?> getCurrentLocation() async {
  bool serviceEnabled;
  LocationPermission permission;

  // 检查位置服务是否开启
  serviceEnabled = await Geolocator.isLocationServiceEnabled();
  if (!serviceEnabled) {
    // 可弹窗提示用户开启位置服务
    return null;
  }

  // 处理位置权限
  permission = await Geolocator.checkPermission();
  if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) {
      return null;
    }
  }

  if (permission == LocationPermission.deniedForever) {
    // 永久拒绝权限时,引导用户前往设置页开启
    return null;
  }

  // 获取高精度位置
  return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
}

判断用户是否在矩形区域内

方式1:基于中心偏移的矩形

假设你的考勤Marker中心坐标是LatLng(39.9042, 116.4074),偏移量设为0.001,矩形边界为中心坐标加减偏移量的范围,判断逻辑如下:

bool isWithinRect(LatLng userLoc, LatLng markerCenter, double offset) {
  bool latInRange = userLoc.latitude >= markerCenter.latitude - offset &&
      userLoc.latitude <= markerCenter.latitude + offset;
  bool lngInRange = userLoc.longitude >= markerCenter.longitude - offset &&
      userLoc.longitude <= markerCenter.longitude + offset;
  return latInRange && lngInRange;
}

方式2:预先定义四个顶点的矩形

如果矩形是不规则形状或提前配置好四个顶点,可使用点在多边形内的判断逻辑(矩形属于特殊多边形):

bool isPointInPolygon(LatLng point, List<LatLng> polygon) {
  int intersections = 0;
  int n = polygon.length;

  for (int i = 0; i < n; i++) {
    int j = (i + 1) % n;
    LatLng p1 = polygon[i];
    LatLng p2 = polygon[j];

    if (((p1.latitude > point.latitude) != (p2.latitude > point.latitude)) &&
        (point.longitude < (p2.longitude - p1.longitude) * (point.latitude - p1.latitude) / (p2.latitude - p1.latitude) + p1.longitude)) {
      intersections++;
    }
  }

  return intersections % 2 == 1;
}

// 调用示例:
// List<LatLng> rectCorners = [
//   LatLng(39.9052, 116.4064), // 左上
//   LatLng(39.9052, 116.4084), // 右上
//   LatLng(39.9032, 116.4084), // 右下
//   LatLng(39.9032, 116.4064), // 左下
// ];
// bool isInside = isPointInPolygon(userLoc, rectCorners);

整合到考勤逻辑中

在Google Maps的onMapCreated回调或位置更新事件里,调用上述方法完成判断:

// 假设考勤Marker的中心坐标
LatLng attendanceMarkerCenter = LatLng(39.9042, 116.4074);
// 偏移量,根据实际需求调整
double attendanceOffset = 0.001;

// 获取用户位置后执行判断
Position? userPos = await getCurrentLocation();
if (userPos != null) {
  LatLng userLatLng = LatLng(userPos.latitude, userPos.longitude);
  bool canCheckIn = isWithinRect(userLatLng, attendanceMarkerCenter, attendanceOffset);
  if (canCheckIn) {
    // 执行打卡逻辑
    print("可以打卡");
  } else {
    // 提示用户到达指定区域
    print("请到达考勤指定区域");
  }
}

内容的提问来源于stack exchange,提问作者Said Hussain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:10:29