Flutter Google Map:如何检测用户是否处于Marker矩形区域内
Flutter Google Maps 考勤应用:位置区域判断实现
首先得明确:Google Maps的Marker本身只是一个单点,没有自带的矩形区域。你需要为每个考勤点的Marker手动定义对应的矩形边界,常见两种方式:
- 以Marker经纬度为中心,设置固定偏移量(比如南北/东西各偏移0.001度,大概对应100米左右,可根据实际精度需求调整)
- 预先在后台或本地配置里存储每个考勤点的矩形四个顶点坐标(左上、右上、左下、右下)
获取用户当前位置
用Flutter常用的geolocator包来获取实时位置:
- 先在
pubspec.yaml添加依赖:
dependencies: geolocator: ^10.1.0
- 编写工具方法请求权限并获取位置:
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
相关产品推荐
相关产品推荐

