前置知识: HTML5

地理位置定位

1 minIntermediate2026/6/14

Geolocation

1. Geolocation API

if ('geolocation' in navigator) {
  navigator.geolocation.getCurrentPosition(
    (position) => {
      console.log('纬度:', position.coords.latitude);
      console.log('经度:', position.coords.longitude);
      console.log('精度:', position.coords.accuracy);
    },
    (error) => {
      switch (error.code) {
        case error.PERMISSION_DENIED:
          console.error('用户拒绝');
          break;
        case error.POSITION_UNAVAILABLE:
          console.error('位置不可用');
          break;
        case error.TIMEOUT:
          console.error('请求超时');
          break;
      }
    },
    { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
  );
}

watchPosition

const watchId = navigator.geolocation.watchPosition(
  (pos) => console.log(`位置: ${pos.coords.latitude}, ${pos.coords.longitude}`),
  (err) => console.error(err),
  { enableHighAccuracy: true }
);
navigator.geolocation.clearWatch(watchId);

2. Haversine 距离计算

d=2rarcsin(sin2(φ2φ12)+cos(φ1)cos(φ2)sin2(λ2λ12))d = 2r \cdot \arcsin\left(\sqrt{\sin^2\left(\frac{\varphi_2 - \varphi_1}{2}\right) + \cos(\varphi_1) \cos(\varphi_2) \sin^2\left(\frac{\lambda_2 - \lambda_1}{2}\right)}\right)
function haversineDistance(lat1, lon1, lat2, lon2) {
  const R = 6371;
  const toRad = (deg) => (deg * Math.PI) / 180;
  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);
  const a =
    Math.sin(dLat / 2) ** 2 +
    Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2;
  return R * 2 * Math.asin(Math.sqrt(a));
}

3. 地理围栏

class Geofence {
  constructor(centerLat, centerLng, radiusMeters) {
    this.center = { lat: centerLat, lng: centerLng };
    this.radius = radiusMeters;
  }
  contains(lat, lng) {
    return haversineDistance(this.center.lat, this.center.lng, lat, lng) * 1000 <= this.radius;
  }
}