Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> HTML

Lấy vĩ độ, kinh độ từ địa chỉ bằng HTML5 Geolocation hoặc Google API

Để lấy tọa độ (latitude, longitude) từ địa chỉ hoặc vị trí hiện tại, có 2 hướng tiếp cận:

1. HTML5 Geolocation API - Vị trí hiện tại của USER

Chỉ lấy vị trí của người dùng (device), không geocode địa chỉ văn bản.

function getCurrentLocation() {
  return new Promise((resolve, reject) => {
    if (!navigator.geolocation) {
      reject(new Error('Trình duyệt không hỗ trợ Geolocation'));
      return;
    }
    
    navigator.geolocation.getCurrentPosition(
      position => resolve({
        lat: position.coords.latitude,
        lng: position.coords.longitude,
        accuracy: position.coords.accuracy
      }),
      error => reject(error),
      { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }
    );
  });
}

// Sử dụng
getCurrentLocation()
  .then(pos => console.log('Vị trí:', pos.lat, pos.lng))
  .catch(err => console.error('Lỗi:', err.message));

2. Google Maps Geocoding API - Địa chỉ → Tọa độ (Forward Geocoding)

Cần API Key (Google Cloud Console, enable Geocoding API, billing).

async function geocodeAddress(address, apiKey) {
  const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${apiKey}`;
  const response = await fetch(url);
  const data = await response.json();
  
  if (data.status === 'OK' && data.results.length > 0) {
    const loc = data.results[0].geometry.location;
    return { lat: loc.lat, lng: loc.lng, formatted: data.results[0].formatted_address };
  }
  throw new Error('Geocoding failed: ' + data.status);
}

// Sử dụng
geocodeAddress('1600 Amphitheatre Parkway, Mountain View, CA', 'YOUR_API_KEY')
  .then(loc => console.log(loc.lat, loc.lng))
  .catch(console.error);

3. Reverse Geocoding - Tọa độ → Địa chỉ

async function reverseGeocode(lat, lng, apiKey) {
  const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${apiKey}`;
  const response = await fetch(url);
  const data = await response.json();
  return data.results[0]?.formatted_address || 'Không tìm thấy';
}

4. Alternatives miễn phí (No API Key / Generous free tier)

Dịch vụFree TierĐặc điểm
Nominatim (OpenStreetMap)Unlimited (rate limit 1/s)Open source, self-hostable, policy: attribution required
LocationIQ10,000 req/dayDễ dùng, có SDK
OpenCage2,500 req/dayHỗ trợ forward/reverse, multilingual
Mapbox100,000 req/monthĐẹp, tích hợp map
// Nominatim example (free, no key)
async function nominatimGeocode(address) {
  const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(address)}`;
  const response = await fetch(url, { headers: { 'User-Agent': 'MyApp/1.0' } });
  const data = await response.json();
  if (data.length) return { lat: parseFloat(data[0].lat), lng: parseFloat(data[0].lon) };
  throw new Error('Not found');
}

So sánh

Tiêu chíHTML5 GeolocationGeocoding API
InputVị trí device (GPS/WiFi/IP)Địa chỉ văn bản / Tọa độ
OutputLat/Lng của userLat/Lng của địa chỉ / Địa chỉ của lat/lng
Yêu cầu HTTPSBắt buộcBắt buộc (Google)
Quyền userCần cho phép (prompt)Không cần (server-side)
Độ chính xácCao (GPS: ~10m)Tùy data (building level - city level)

Best Practice

  • Luôn handle error: permission denied, timeout, unavailable.
  • Cache kết quả geocoding (localStorage/IndexedDB) để giảm API call.
  • Debounce input tìm kiếm địa chỉ (300ms).
  • Respect rate limits & terms of service.