Phương pháp 1: Tự viết công thức Haversine để tính khoảng cách
Bước 1: Lấy tọa độ vị trí hiện tại của người dùng bằng wx.getLocation:
get currentPosition() {
const that = this;
wx.getLocation({
success(res) {
that.setData({
currentLongitude: res.longitude,
currentLatitude: res.latitude
});
},
fail(err) {
console.error('Lấy vị trí thất bại:', err);
}
});
}
Bước 2: Sử dụng API địa chỉ ngược (geocoding) của Tencent Map để chuyển đổi địa chỉ đích thành tọa độ:
resolveAddress(address) {
const that = this;
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
data: {
key: 'YOUR_TENCENT_MAP_KEY',
address: address
},
method: 'GET',
success(res) {
if (res.data.status === 0 && res.data.result) {
const loc = res.data.result.location;
that.setData({
targetLatitude: loc.lat,
targetLongitude: loc.lng
});
}
}
});
}
Bước 3: Viết hàm tính khoảng cách dựa trên công thức Haversine:
calculateDistance(lat1, lng1, lat2, lng2) {
lat1 = Number(lat1); lng1 = Number(lng1);
lat2 = Number(lat2); lng2 = Number(lng2);
const R = 6378137; // Bán kính Trái Đất (mét)
const toRad = Math.PI / 180;
const dLat = (lat2 - lat1) * toRad;
const dLng = (lng2 - lng1) * toRad;
const radLat1 = lat1 * toRad;
const radLat2 = lat2 * toRad;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(radLat1) * Math.cos(radLat2) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c; // Khoảng cách tính bằng mét
}
Bước 4: Gọi hàm tính toán:
const distance = this.calculateDistance(
this.data.currentLatitude,
this.data.currentLongitude,
this.data.targetLatitude,
this.data.targetLongitude
);
Tuy nhiên, khi xử lý nhiều địa điểm cùng lúc, thứ tự phản hồi từ API geocoding có thể không ổn định, dẫn đến sai lệch dữ liệu. Để giải quyết điều này, nên sử dụng phương pháp dưới đây.
Phương pháp 2: Dùng SDK chính thức của Tencent Map
Bước 1: Cấp quyền lấy vị trí như ở Phương pháp 1.
Bước 2: Thêm file qqmap-wx-jssdk.min.js vào thư mục lib trong dự án.
Bước 3: Nhập và khởi tạo SDK trong trang JavaScript:
const QQMapWX = require('../../lib/js/qqmap-wx-jssdk.min.js');
let qqSdk;
onLoad() {
qqSdk = new QQMapWX({ key: 'YOUR_TENCENT_MAP_KEY' });
}
Bước 4: Kết hợp geocoding và tính khoảng cách qua SDK:
fetchAndCalculate(address) {
const that = this;
wx.request({
url: 'https://apis.map.qq.com/ws/geocoder/v1/',
data: {
key: 'YOUR_TENCENT_MAP_KEY',
address: address
},
success(res) {
if (res.data.status === 0) {
const loc = res.data.result.location;
qqSdk.calculateDistance({
mode: 'walking', // hoặc driving, transit
from: `${that.data.currentLatitude},${that.data.currentLongitude}`,
to: [`${loc.lat},${loc.lng}`],
success(result) {
const meters = result.result.elements[0].distance;
const km = (meters / 1000).toFixed(2);
that.setData({ displayDistance: `${km} km` });
},
fail(err) {
console.error('Tính khoảng cách thất bại:', err);
}
});
}
}
});
}
API calculateDistance hỗ trợ nhiều điểm đến cùng lúc và đảm bảo thứ tự kết quả khớp với danh sách đầu vào, rất phù hợp khi xử lý danh sách địa điểm. Ngoài ra, SDK cũng hỗ trợ các chế độ di chuyển như đi bộ, lái xe giúp kết quả chính xác hơn so với công thức hình học đơn thuần.
Lưu ý: API của Tencent Map có giới hạn số lượng yêu cầu mỗi ngày tùy theo loại key. Nên kiểm tra kỹ tài liệu và tối ưu việc gọi API để tránh vượt quá giới hạn.