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

如何在手机到达指定区域时设置Oracle APEX项目值?

问题解决:儿童竞速PWA的圈数计数失效问题

核心问题分析

  1. 定位精度与跳变特性:民用GPS定位本身存在3-5米的误差,且位置更新不是连续平滑的,直接用==判断当前经度与起点经度完全匹配,几乎不可能触发。
  2. 起点线模型错误:10米长的水平线并非绝对同一经度(地球是球面,短距离内经度差极小,但更合理的是将起点定义为地理区域,而非单一坐标值)。
  3. 数据类型错误:把经纬度存在DOM元素的innerHTML中会转为字符串,数值比较时容易出现精度丢失或类型不匹配问题。
  4. 无状态控制:如果停留在起点区域内,会重复触发圈数累加,导致计数错误。

解决方案代码

HTML部分

<label for="round_no">圈数:</label>
<input id="round_no" value="0">
<br><br>
<label for="starting_area_info">起点区域范围:</label>
<input id="starting_area_info" readonly>
<br><br>
<label for="current_location">当前位置:</label>
<input id="current_location" readonly>

JavaScript部分

// 存储起点区域边界和状态,避免重复计数
let startArea = {
  minLat: 0,
  maxLat: 0,
  minLng: 0,
  maxLng: 0,
  isInArea: false
};

// 初始化起点区域:基于初始位置计算10米范围的地理边界
navigator.geolocation.getCurrentPosition(function(position) {
  const coords = position.coords;
  // 10米对应的经纬度偏移近似值(纬度1度≈111km,经度1度≈111km*cos(纬度))
  const meterToLat = 10 / 111000;
  const meterToLng = 10 / (111000 * Math.cos(coords.latitude * Math.PI / 180));
  
  // 定义起点矩形区域,覆盖10米长的水平线范围
  startArea.minLat = coords.latitude - meterToLat / 2;
  startArea.maxLat = coords.latitude + meterToLat / 2;
  startArea.minLng = coords.longitude - meterToLng / 2;
  startArea.maxLng = coords.longitude + meterToLng / 2;
  
  // 显示起点区域信息
  document.getElementById("starting_area_info").value = 
    `纬度: ${startArea.minLat.toFixed(6)} ~ ${startArea.maxLat.toFixed(6)}, 经度: ${startArea.minLng.toFixed(6)} ~ ${startArea.maxLng.toFixed(6)}`;
  
  updateCurrentLocation(coords);
}, function(error) {
  alert(`定位初始化失败: ${error.message}`);
}, {
  enableHighAccuracy: true, // 启用高精度定位
  timeout: 5000,
  maximumAge: 0
});

// 监听位置变化,判断是否进入起点区域
navigator.geolocation.watchPosition(function(position) {
  const coords = position.coords;
  updateCurrentLocation(coords);
  
  // 判断当前是否在起点区域内
  const currentInArea = 
    coords.latitude >= startArea.minLat && coords.latitude <= startArea.maxLat &&
    coords.longitude >= startArea.minLng && coords.longitude <= startArea.maxLng;
  
  // 仅当从区域外进入区域内时,累加圈数
  if (currentInArea && !startArea.isInArea) {
    const roundInput = document.getElementById("round_no");
    roundInput.value = Number(roundInput.value) + 1;
    startArea.isInArea = true;
  } else if (!currentInArea) {
    startArea.isInArea = false; // 离开区域时重置状态
  }
}, function(error) {
  console.error(`定位更新失败: ${error.message}`);
}, {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 0,
  frequency: 1000 // 每秒更新一次位置
});

// 辅助函数:更新当前位置显示
function updateCurrentLocation(coords) {
  document.getElementById("current_location").value = 
    `纬度: ${coords.latitude.toFixed(6)}, 经度: ${coords.longitude.toFixed(6)}`;
}

关键优化点

  • 区域判断替代全等匹配:将起点定义为矩形地理区域,只要当前位置落在区域内即判定为回到起点。
  • 状态控制:通过isInArea标记避免在起点区域内重复累加圈数,仅触发一次进入动作。
  • 高精度定位配置:开启enableHighAccuracy参数,提升定位精度。
  • 数值化存储:直接用变量存储经纬度数值,避免DOM字符串转换带来的精度问题。
  • 错误处理:添加定位失败提示,增强应用稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:08:20