findme-miniprogram-frontend/utils/map-config.js

337 lines
8.4 KiB
JavaScript
Raw Permalink Normal View History

2025-12-27 17:16:03 +08:00
/**
* 地图配置文件
* 包含高德地图配置权限管理地图工具函数等
*/
const config = require('../config/config.js');
// 高德地图配置
const MAP_CONFIG = {
// 高德地图Key - 需要在高德开放平台申请
// 注意:下方为示例密钥,可能已过期或限制使用,请申请自己的密钥
amapKey: config.amapKey || '9207c12fec275ea84090280f693b88c6',
// 地图默认设置
defaults: {
latitude: 39.908823, // 北京天安门
longitude: 116.39747,
scale: 16,
minScale: 3,
maxScale: 22,
showLocation: true,
showScale: true,
showCompass: true,
enableOverlooking: false,
enableZoom: true,
enableScroll: true,
enableRotate: false,
enable3D: false
},
// 定位配置
location: {
type: 'gcj02', // 坐标系类型wgs84、gcj02
isHighAccuracy: true,
highAccuracyExpireTime: 4000,
timeout: 10000,
cacheTimeout: 60000 // 位置缓存时间
},
// 标记点配置
markers: {
// 当前用户标记 - 使用默认样式
currentUser: {
width: 30,
height: 30,
anchor: { x: 0.5, y: 1 }
},
// 好友标记 - 使用默认样式
friend: {
width: 25,
height: 25,
anchor: { x: 0.5, y: 1 }
},
// 陌生人标记 - 使用默认样式
stranger: {
width: 20,
height: 20,
anchor: { x: 0.5, y: 1 }
}
},
// 地图样式
style: {
normal: 'normal', // 普通地图
satellite: 'satellite', // 卫星地图
traffic: 'traffic' // 交通地图
}
};
// 权限配置
const PERMISSION_CONFIG = {
// 位置权限
location: {
scope: 'scope.userLocation',
name: '位置信息',
description: '用于获取您的位置信息,实现定位和附近功能'
},
// 其他权限
camera: {
scope: 'scope.camera',
name: '摄像头',
description: '用于拍照和扫码功能'
},
album: {
scope: 'scope.album',
name: '相册',
description: '用于选择图片功能'
}
};
/**
* 地图工具类
*/
class MapUtils {
/**
* 检查位置权限
*/
static checkLocationPermission() {
return new Promise((resolve, reject) => {
wx.getSetting({
success: (res) => {
if (res.authSetting['scope.userLocation'] === false) {
// 用户拒绝过位置权限
reject({
type: 'denied',
message: '位置权限被拒绝,请在设置中开启'
});
} else if (res.authSetting['scope.userLocation'] === true) {
// 用户已授权
resolve(true);
} else {
// 用户未授权,需要请求授权
resolve(false);
}
},
fail: (error) => {
console.error('获取权限设置失败:', error);
reject({
type: 'error',
message: '获取权限设置失败'
});
}
});
});
}
/**
* 请求位置权限
*/
static requestLocationPermission() {
return new Promise((resolve, reject) => {
wx.authorize({
scope: 'scope.userLocation',
success: () => {
resolve(true);
},
fail: (error) => {
console.warn('位置权限授权失败:', error);
// 引导用户去设置页面
wx.showModal({
title: '位置权限申请',
content: 'FindMe需要访问您的位置信息请在设置中开启位置权限',
confirmText: '去设置',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
wx.openSetting({
success: (settingRes) => {
if (settingRes.authSetting['scope.userLocation']) {
resolve(true);
} else {
reject({
type: 'denied',
message: '位置权限被拒绝'
});
}
},
fail: () => {
reject({
type: 'error',
message: '打开设置页面失败'
});
}
});
} else {
reject({
type: 'cancelled',
message: '用户取消授权'
});
}
}
});
}
});
});
}
/**
* 获取位置带权限检查
*/
static async getLocation(options = {}) {
try {
// 检查权限
const hasPermission = await this.checkLocationPermission();
if (!hasPermission) {
// 请求权限
await this.requestLocationPermission();
}
// 获取位置
return new Promise((resolve, reject) => {
const locationOptions = {
...MAP_CONFIG.location,
...options,
success: (res) => {
resolve({
latitude: res.latitude,
longitude: res.longitude,
accuracy: res.accuracy || 0,
altitude: res.altitude || 0,
speed: res.speed || -1,
timestamp: Date.now()
});
},
fail: (error) => {
console.error('获取位置失败:', error);
reject({
type: 'location_error',
message: error.errMsg || '定位失败',
error: error
});
}
};
wx.getLocation(locationOptions);
});
} catch (error) {
console.error('位置获取流程失败:', error);
throw error;
}
}
/**
* 计算两点距离
*/
static calculateDistance(point1, point2) {
const lat1 = point1.latitude * Math.PI / 180;
const lon1 = point1.longitude * Math.PI / 180;
const lat2 = point2.latitude * Math.PI / 180;
const lon2 = point2.longitude * Math.PI / 180;
const R = 6371000; // 地球半径(米)
const dLat = lat2 - lat1;
const dLon = lon2 - lon1;
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon/2) * Math.sin(dLon/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
/**
* 格式化距离显示
*/
static formatDistance(distance) {
if (distance < 1000) {
return `${Math.round(distance)}`;
} else if (distance < 10000) {
return `${(distance / 1000).toFixed(1)}公里`;
} else {
return `${Math.round(distance / 1000)}公里`;
}
}
/**
* 创建标记点
*/
static createMarker(data, type = 'friend') {
const markerConfig = MAP_CONFIG.markers[type] || MAP_CONFIG.markers.friend;
return {
id: data.id || Date.now(),
latitude: data.latitude,
longitude: data.longitude,
width: markerConfig.width,
height: markerConfig.height,
anchor: markerConfig.anchor,
callout: data.showCallout ? {
content: data.nickname || '用户',
color: '#333333',
fontSize: 12,
borderRadius: 4,
bgColor: '#ffffff',
padding: 8,
display: 'ALWAYS'
} : null,
customData: {
userId: data.userId,
nickname: data.nickname,
avatar: data.avatar,
distance: data.distance,
lastUpdateTime: data.lastUpdateTime
}
};
}
/**
* 获取地图区域
*/
static getMapRegion(centerPoint, markers = []) {
if (markers.length === 0) {
return {
latitude: centerPoint.latitude,
longitude: centerPoint.longitude,
scale: MAP_CONFIG.defaults.scale
};
}
// 计算包含所有标记点的区域
let minLat = centerPoint.latitude;
let maxLat = centerPoint.latitude;
let minLng = centerPoint.longitude;
let maxLng = centerPoint.longitude;
markers.forEach(marker => {
minLat = Math.min(minLat, marker.latitude);
maxLat = Math.max(maxLat, marker.latitude);
minLng = Math.min(minLng, marker.longitude);
maxLng = Math.max(maxLng, marker.longitude);
});
// 添加边距
const latPadding = (maxLat - minLat) * 0.3;
const lngPadding = (maxLng - minLng) * 0.3;
return {
latitude: (minLat + maxLat) / 2,
longitude: (minLng + maxLng) / 2,
scale: Math.max(Math.min(18 - Math.log2(Math.max(maxLat - minLat + latPadding, maxLng - minLng + lngPadding) * 111000), 18), 8)
};
}
}
module.exports = {
MAP_CONFIG,
PERMISSION_CONFIG,
MapUtils
};