| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- /**
- * 地图工具函数模块
- * 提供腾讯地图相关的通用工具函数
- *
- * 主要功能:
- * - 坐标格式转换
- * - 坐标有效性验证
- * - 地图实例管理辅助函数
- */
- /**
- * 验证坐标是否有效
- * @param {number} lng 经度
- * @param {number} lat 纬度
- * @returns {boolean} 坐标是否有效
- */
- // export function isValidCoordinate(lng, lat) { // 高德
- // return (
- // lng !== null &&
- // lng !== undefined &&
- // lat !== null &&
- // lat !== undefined &&
- // lng >= -180 &&
- // lng <= 180 &&
- // lat >= -90 &&
- // lat <= 90 &&
- // !isNaN(lng) &&
- // !isNaN(lat)
- // )
- // }
- export function isValidCoordinate(lat, lng) {
- return (
- lat !== null &&
- lat !== undefined &&
- lng !== null &&
- lng !== undefined &&
- lat >= -90 &&
- lat <= 90 &&
- lng >= -180 &&
- lng <= 180 &&
- !isNaN(lat) &&
- !isNaN(lng)
- )
- }
- /**
- * 将点对象数组转换为 TMap.LatLng 对象数组
- * @param {Array<{lng: number, lat: number}>} points 点对象数组
- * @returns {Array<TMap.LatLng>} TMap.LatLng 对象数组
- */
- export function convertPointsToLatLng(points) {
- if (!points || !Array.isArray(points)) {
- return []
- }
-
- return points
- .filter(p => p && isValidCoordinate(p.lng, p.lat))
- .map(p => new TMap.LatLng(p.lat, p.lng))
- }
- /**
- * 将经纬度数组转换为 TMap.LatLng 对象数组
- * @param {Array<[number, number]>} lngLatArray 经纬度数组 [[lng, lat], ...]
- * @returns {Array<TMap.LatLng>} TMap.LatLng 对象数组
- */
- export function convertLngLatArrayToLatLng(lngLatArray) {
- if (!lngLatArray || !Array.isArray(lngLatArray)) {
- return []
- }
-
- return lngLatArray
- .filter(([lng, lat]) => isValidCoordinate(lng, lat))
- .map(([lng, lat]) => new TMap.LatLng(lat, lng))
- }
- /**
- * 安全地设置地图中心点
- * @param {Object} map 地图实例
- * @param {number} lng 经度
- * @param {number} lat 纬度
- * @param {number} zoom 缩放级别(可选)
- * @returns {boolean} 是否设置成功
- */
- export function safeSetMapCenter(map, lat, lng, zoom) {
- if (!map || !isValidCoordinate(lat, lng)) {
- console.warn('[mapUtils] 无效的地图实例或坐标')
- return false
- }
-
- try {
- const center = new TMap.LatLng(lat, lng)
- map.setCenter(center)
-
- if (typeof zoom === 'number' && zoom >= 3 && zoom <= 20) {
- map.setZoom(zoom)
- }
-
- return true
- } catch (err) {
- console.error('[mapUtils] 设置地图中心失败', err)
- return false
- }
- }
- /**
- * 安全地获取地图中心点
- * @param {Object} map 地图实例
- * @returns {Object|null} 包含 lng, lat 的对象,失败返回 null
- */
- export function safeGetMapCenter(map) {
- if (!map || typeof map.getCenter !== 'function') {
- return null
- }
-
- try {
- const center = map.getCenter()
- return {
- lat: center.lat,
- lng: center.lng
- }
- } catch (err) {
- console.error('[mapUtils] 获取地图中心失败', err)
- return null
- }
- }
- /**
- * 格式化坐标显示
- * @param {Object} point 点对象 {lng, lat}
- * @param {number} precision 精度(小数位数),默认 5
- * @returns {string} 格式化后的坐标字符串
- */
- export function formatCoordinate(point, precision = 5) {
- if (!point || !isValidCoordinate(point.lng, point.lat)) {
- return '--'
- }
-
- return `${point.lng.toFixed(precision)}, ${point.lat.toFixed(precision)}`
- }
- /**
- * 计算两点之间的距离(米)
- * 使用 Haversine 公式
- * @param {Object} point1 点1 {lng, lat}
- * @param {Object} point2 点2 {lng, lat}
- * @returns {number} 距离(米)
- */
- export function calculateDistance(point1, point2) {
- if (!isValidCoordinate(point1.lng, point1.lat) ||
- !isValidCoordinate(point2.lng, point2.lat)) {
- return 0
- }
-
- const R = 6371000 // 地球半径(米)
- const lat1 = point1.lat * Math.PI / 180
- const lat2 = point2.lat * Math.PI / 180
- const deltaLat = (point2.lat - point1.lat) * Math.PI / 180
- const deltaLng = (point2.lng - point1.lng) * Math.PI / 180
-
- const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
- Math.cos(lat1) * Math.cos(lat2) *
- Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2)
-
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
-
- return R * c
- }
- /**
- * 判断点是否在多边形内
- * 使用射线法
- * @param {Object} point 点 {lng, lat}
- * @param {Array<Object>} polygon 多边形顶点数组 [{lng, lat}, ...]
- * @returns {boolean} 点是否在多边形内
- */
- export function isPointInPolygon(point, polygon) {
- if (!isValidCoordinate(point.lng, point.lat) ||
- !polygon || polygon.length < 3) {
- return false
- }
-
- let inside = false
- const x = point.lng
- const y = point.lat
-
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
- const xi = polygon[i].lng
- const yi = polygon[i].lat
- const xj = polygon[j].lng
- const yj = polygon[j].lat
-
- const intersect = ((yi > y) !== (yj > y)) &&
- (x < (xj - xi) * (y - yi) / (yj - yi) + xi)
-
- if (intersect) {
- inside = !inside
- }
- }
-
- return inside
- }
|