有需要的拿去用,这方法都是一样的,省去封装时间了,
目录
formatDate,//时间格式化工具
timestampToDate,//时间戳转换为日期
generateDateArray,//生成指定时间范围内的日期数组
getDayOfWeek,//获取日期对应的星期几
getTimeUntilEnd,//计算当前时间距离结束时间的时间戳
formatCurrency,//金额格式化
convertToChinese,//金额转换为中文大写
generateRandomCode,//生成随机验证码
isEmail,//校验邮箱格式
isPhoneNumber,//校验手机号格式(中国手机号)
debounce,//防抖函数
throttle,//节流函数
deepClone,//深拷贝
mergeObjects,//对象合并
uniqueArray,//数组去重
generateRandomString,//生成随机字符串
validatePasswordStrength,//设置密码时验证密码强度
checkPwd,//检测密码强度等级
validateIDCard,//身份证校验
copyToClipboard,//复制剪切板
processImageUrl,//处理半截图片拼接
areAllFieldsNotNull,//验证对象中指定字段是否都有值 用于表单验
getValueByKey,//根据给定条件查找对象,并返回目标键的值,支持多个查找条件和深层嵌套的递归处理。
isPointInPolygon,//验证对象中指定字段是否都有值 用于表单验证,如果所有字段都有值,返回 true;否则返回 false,也有部分字段不需要验证
calculateDistance,//计算两点之间的地球表面距离(单位:千米)
calculateTotalDistance,//计算多个点之间的总距离
calculateArea,//计算一组经纬度点围成的多边形的面积
calculateCenterPoint,//计算多边形中心点的方法
// utils.js
import config from "../request/config.js";
import * as turf from '@turf/turf'
const { baseUrl } = config;
/**
* 时间格式化工具
* @param {Date|string|number} date - 日期对象、字符串或时间戳
* @param {string} format - 格式化字符串,默认为 'YYYY-MM-DD'
* @returns {string} - 格式化后的日期字符串
* 使用示例:
* formatDate(new Date(), 'YYYY-MM-DD'); // '2024-08-09' YYYY-MM-DD HH:mm:ss
*/
function formatDate(date, format = "YYYY-MM-DD") {
const d = new Date(date);
const year = d.getFullYear();
const month = `0${d.getMonth() + 1}`.slice(-2);
const day = `0${d.getDate()}`.slice(-2);
const hours = `0${d.getHours()}`.slice(-2);
const minutes = `0${d.getMinutes()}`.slice(-2);
const seconds = `0${d.getSeconds()}`.slice(-2);
return format
.replace("YYYY", year)
.replace("MM", month)
.replace("DD", day)
.replace("HH", hours)
.replace("mm", minutes)
.replace("ss", seconds);
}
/**
* 时间戳转换为日期
* @param {number} timestamp - Unix 时间戳(秒)
* @param {string} format - 格式化字符串,默认为 'YYYY-MM-DD'
* @returns {string} - 格式化后的日期字符串
* 使用示例:
* timestampToDate(1691577600); // '2023-08-09'
*/
function timestampToDate(timestamp, format = "YYYY-MM-DD") {
return formatDate(new Date(timestamp * 1000), format);
}
/**
* 生成指定时间范围内的日期数组
* @param {string|Date} startDate - 开始日期
* @param {string|Date} endDate - 结束日期
* @returns {string[]} - 日期数组
* 使用示例:
* generateDateArray('2023-08-01', '2023-08-03'); // ['2023-08-01', '2023-08-02', '2023-08-03']
*/
function generateDateArray(startDate, endDate) {
const start = new Date(startDate);
const end = new Date(endDate);
const dateArray = [];
while (start <= end) {
dateArray.push(formatDate(new Date(start)));
start.setDate(start.getDate() + 1);
}
return dateArray;
}
/**
* 获取日期对应的星期几
* @param {string|Date} date - 日期字符串或对象
* @returns {string} - 星期几
* 使用示例:
* getDayOfWeek('2023-08-09'); // 'Wednesday'
*/
function getDayOfWeek(date) {
const daysOfWeek = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
const dayIndex = new Date(date).getDay();
return daysOfWeek[dayIndex];
}
/**
* 计算当前时间距离结束时间的时间戳
* @param {string} [startTime] - 开始时间字符串,支持多种格式,默认为当前时间
* @param {string} endTime - 结束时间字符串,支持多种格式
* @returns {number} - 距离结束时间的时间戳(毫秒),如果已过期则返回 0
* 案例:getTimeUntilEnd('2024-9-30 18:00:00'), 14190223 // 倒计时时间
*/
function getTimeUntilEnd(endTime, startTime = new Date()) {
const currentTime = Date.now(); // 获取当前时间戳
const endTimeStamp = new Date(Date.parse(endTime)).getTime(); // 转换结束时间为时间戳
const startTimeStamp = new Date(Date.parse(startTime)).getTime(); // 转换开始时间为时间戳
if (isNaN(startTimeStamp) || isNaN(endTimeStamp)) {
throw new Error("Invalid start or end time format"); // 检查时间格式是否有效
}
if (currentTime < startTimeStamp) {
return Math.max(endTimeStamp - startTimeStamp, 0); // 如果当前时间在开始时间之前,返回结束时间与开始时间的差值
}
return Math.max(endTimeStamp - currentTime, 0); // 返回当前时间与结束时间的差值
}
/**
* 金额格式化
* @param {number|string} amount - 金额
* @param {number} decimals - 保留的小数位数,默认为 2
* @returns {string} - 格式化后的金额字符串
* 使用示例:
* formatCurrency(12345.678); // '12,345.68'
*/
function formatCurrency(amount, decimals = 2) {
return parseFloat(amount)
.toFixed(decimals)
.replace(/\d(?=(\d{3})+\.)/g, "$&,");
}
/**
* 金额转换为中文大写
* @param {number} num - 要转换的金额
* @returns {string} - 中文大写金额
* 使用示例:
* convertToChinese(12345.67); // '壹万贰仟叁佰肆拾伍元陆角柒分'
*/
function convertToChinese(num) {
const fraction = ["角", "分"];
const digit = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
const unit = [
["元", "万", "亿"],
["", "拾", "佰", "仟"],
];
let head = num < 0 ? "负" : "";
num = Math.abs(num);
let s = "";
for (let i = 0; i < fraction.length; i++) {
s += (
digit[Math.floor(num * 10 * Math.pow(10, i)) % 10] + fraction[i]
).replace(/零./, "");
}
s = s || "整";
num = Math.floor(num);
for (let i = 0; i < unit[0].length && num > 0; i++) {
let p = "";
for (let j = 0; j < unit[1].length && num > 0; j++) {
p = digit[num % 10] + unit[1][j] + p;
num = Math.floor(num / 10);
}
s = p.replace(/(零.)*零$/, "").replace(/^$/, "零") + unit[0][i] + s;
}
return (
head +
s
.replace(/(零.)*零元/, "元")
.replace(/(零.)+/g, "零")
.replace(/^整$/, "零元整")
);
}
/**
* 生成随机验证码
* @param {number} length - 验证码长度,默认为 6
* @returns {string} - 随机验证码
* 使用示例:
* generateRandomCode(6); // 'aB1cD2'
*/
function generateRandomCode(length = 6) {
const chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let code = "";
for (let i = 0; i < length; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
return code;
}
/**
* 校验邮箱格式
* @param {string} email - 要校验的邮箱
* @returns {boolean} - 返回校验结果
* 使用示例:
* isEmail('example@example.com'); // true
*/
function isEmail(email) {
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(email);
}
/**
* 校验手机号格式(中国手机号)
* @param {string} phone - 要校验的手机号
* @returns {boolean} - 返回校验结果
* 使用示例:
* isPhoneNumber('13800138000'); // true
*/
function isPhoneNumber(phone) {
const phonePattern = /^1[1-9]\d{9}$/;
return phonePattern.test(phone);
}
/**
* 防抖函数
* @param {Function} func - 要执行的函数
* @param {number} wait - 等待时间(毫秒)
* @returns {Function} - 返回防抖处理后的函数
* 使用示例:
* const handleClick = debounce((e) => {
console.log('按钮点击');
}, 1000);
*/
// function debounce(func, wait) {
// let timeout;
// return function (...args) {
// clearTimeout(timeout);
// timeout = setTimeout(() => func.apply(this, args), wait);
// };
// }
function debounce(func, wait) {
let timeout;
return function(...args) {
const callNow = !timeout; // 判断是否可以立即调用
clearTimeout(timeout); // 清除之前的计时器
timeout = setTimeout(() => {
timeout = null; // wait 时间过后,清除 timeout
}, wait);
if (callNow) {
func.apply(this, args); // 立即执行函数
}
};
}
/**
* 节流函数
* @param {Function} func - 要执行的函数
* @param {number} limit - 限制时间间隔(毫秒)
* @returns {Function} - 返回节流处理后的函数
* 使用示例:
* const handleScroll = throttle(() => console.log('Scroll Event'), 200);
*/
function throttle(func, limit) {
let lastFunc;
let lastRan;
return function(...args) {
const context = this;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if (Date.now() - lastRan >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
/**
* 深拷贝
* @param {object} obj - 要拷贝的对象
* @returns {object} - 拷贝后的新对象
* 使用示例:
* const newObj = deepClone(originalObj);
*/
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
/**
* 对象合并
* @param {object} target - 目标对象
* @param {object} source - 源对象
* @param {boolean} overwrite - 是否覆盖目标对象中已有的属性,默认为 true
* @returns {object} - 合并后的对象
* 使用示例:
* const mergedObj = mergeObjects(targetObj, sourceObj, false);
*/
function mergeObjects(target, source, overwrite = true) {
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (overwrite || !(key in target)) {
target[key] = source[key];
}
}
}
return target;
}
/**
* 数组去重
* @param {Array} arr - 要去重的数组
* @returns {Array} - 去重后的数组
* 使用示例:
* const uniqueArr = uniqueArray([1, 2, 2, 3, 4, 4, 5]); // [1, 2, 3, 4, 5]
*/
function uniqueArray(arr) {
return [...new Set(arr)];
}
/**
* 生成随机字符串
* @param {number} length - 字符串长度
* @returns {string} - 随机字符串
* 使用示例:
* const randomStr = generateRandomString(8); // 'aBcD1234'
*/
function generateRandomString(length) {
// const chars =
// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// let result = "";
// for (let i = 0; i < length; i++) {
// result += chars.charAt(Math.floor(Math.random() * chars.length));
// }
// return result;
return length <= 11 ?
Math.random().toString(36).slice(2, 2 + length).padEnd(length, '0') :
generateRandomString(11) + generateRandomString(length - 11)
}
/**
* 设置密码时验证密码强度
* @param {string} password - 用户输入的密码
* @param {Object} [options] - 配置选项
* @param {number} [options.minLength=8] - 密码最小长度
* @returns {Object} - 包含密码是否满足要求和提示信息
*/
function validatePasswordStrength(password, options = {}) {
const { minLength = 8 } = options;
const hasUpperCase = /[A-Z]/.test(password);
const hasLowerCase = /[a-z]/.test(password);
const hasDigit = /\d/.test(password);
const hasSpecialChar = /[^a-zA-Z0-9]/.test(password);
const isLengthValid = password.length >= minLength;
const isValid = isLengthValid && hasUpperCase && hasLowerCase && hasDigit && hasSpecialChar;
let message = '';
if (!isLengthValid) {
message = `密码长度必须至少 ${minLength} 位。`;
} else if (!hasUpperCase) {
message = '密码必须包含至少一个大写字母。';
} else if (!hasLowerCase) {
message = '密码必须包含至少一个小写字母。';
} else if (!hasDigit) {
message = '密码必须包含至少一个数字。';
} else if (!hasSpecialChar) {
message = '密码必须包含至少一个特殊字符。';
} else {
message = '密码强度符合要求。';
}
return {
isValid,
message
};
}
/**
* 检测密码强度等级
* @param str 字符串
* @returns 1:密码弱 2:密码中等 3:密码强 4:密码很强
*/
function checkPwd(str) {
let strength = 0;
const regexArr = [
'[A-Z]', // 匹配大写字母
'[a-z]', // 匹配小写字母
'[0-9]', // 匹配数字
'[!@#$%^&*()_+\\-={};\':",.<>?`~\\[\\]\\\\/]|\\\\', // 匹配特殊符号
];
for (let i = 0; i < regexArr.length; i++) {
if (new RegExp(regexArr[i]).test(str)) {
strength++;
}
}
return strength;
}
/**
* 身份证校验
*/
function validateIDCard(idCard) {
// 校验身份证长度,支持15位和18位身份证号
if (!/^\d{15}$|^\d{17}(\d|X|x)$/.test(idCard)) {
return false;
}
// 如果是15位身份证号,将其转成18位
if (idCard.length === 15) {
idCard = convertTo18Digits(idCard);
}
// 校验出生日期是否正确
const birthDate = idCard.substring(6, 14);
if (!isValidDate(birthDate)) {
return false;
}
// 校验校验码(最后一位)
return checkCode(idCard);
}
/**
* 验证日期格式是否正确
*/
function convertTo18Digits(idCard) {
const weights = [7, 9, 10, 5, 8, 4, 2]; // 前七位对应的权重
const sum = idCard
.slice(0, 6) + '19' + idCard.slice(6)
.split('')
.reduce((acc, num, i) => acc + num * weights[i % 7], 0);
const code = '10X98765432'.charAt(sum % 11);
return idCard.slice(0, 6) + '19' + idCard.slice(6) + code;
}
/**
* 验证日期格式是否正确
*/
function isValidDate(date) {
const year = parseInt(date.substring(0, 4), 10);
const month = parseInt(date.substring(4, 6), 10);
const day = parseInt(date.substring(6, 8), 10);
const dateObj = new Date(year, month - 1, day);
return (
dateObj.getFullYear() === year &&
dateObj.getMonth() === month - 1 &&
dateObj.getDate() === day
);
}
/**
*
* 校验身份证最后一位校验码是否正确
*
*/
function checkCode(idCard) {
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
const sum = idCard
.slice(0, 17)
.split('')
.reduce((acc, num, i) => acc + num * weights[i], 0);
const code = '10X98765432'.charAt(sum % 11);
return idCard.charAt(17).toUpperCase() === code;
}
/**
* 复制剪切板
*/
function copyToClipboard(text) {
uni.setClipboardData({
data: text,
success: function() {
uni.$uv.toast('已复制到剪贴板');
}
});
}
/**
* 处理半截图片拼接
*
*/
// const processImageUrl = (url) => {
// return !url ? '' : url.startsWith(baseUrl) ? url.replace(baseUrl, '') : `${baseUrl}${url}`;
// };
/**
* 处理半截图片拼接
*
* @param {string} url - 输入的图片 URL
* @param {boolean} shouldConcat - 决定是否拼接 baseUrl
* @returns {string} - 处理后的图片 URL
*/
const processImageUrl = (url, shouldConcat = true) => {
if (!url) return '';
return shouldConcat ?
url.startsWith(baseUrl) ? url.replace(baseUrl, '') : `${baseUrl}${url}` // 拼接 baseUrl
:
url.replace(baseUrl, ''); // 删除 baseUrl
};
/**
*
* 验证对象中指定字段是否都有值 用于表单验证,如果所有字段都有值,返回 true;否则返回 false,也有部分字段不需要验证
* @param {Object} obj - 要验证的对象
* @param {Object} obj - 要验证的对象
* @param {Object} [keys] - 可选,包含要检查字段的对象
* @returns {boolean} - 如果所有字段都有值,返回 true;否则返回 false。
*
*/
function areAllFieldsNotNull(obj, keys = obj) {
for (let key in keys) {
if (obj[key] === null || obj[key] === "" || obj[key] === undefined || obj[key] == 0) {
return false;
}
}
return true;
}
/**
* 根据给定条件查找对象,并返回目标键的值,支持多个查找条件和深层嵌套的递归处理。
* @param {Array} list - 要搜索的对象数组。
* @param {Object} conditions - 查找条件对象,键为条件名,值为条件值。
* @param {string} returnKeyPath - 要返回的深层嵌套键名,使用点(`.`)表示嵌套层级。
* @param {*} [defaultValue=null] - 找不到时的默认值,默认为 null。
* @returns {*} - 找到的对象中对应键的值,或默认值。
* 例:
* // list: [{
* // id: 1,
* // name: "50",
* // details: {
* // info: {
* // value: "Important",
* // title: {
* // type: "多级",
* // title: {
* // type: "多级2",
* // title: {
* // type: "多级3",
* // title: {
* // type: "多级4",
* // },
* // },
* // },
* // },
* // },
* // },
* // }]
*console.log(getValueByKey(this.list, { id: 1 }, 'details.info.title.title.title.title.type'))
*console.log(getValueByKey(this.list, { id: 1 }, 'name'))
*console.log(getValueByKey(this.list, { id: 1 }, 'details'))
*console.log(getValueByKey(this.list, { id: 1 }, 'details.info'))
*/
function getValueByKey(list, conditions, returnKeyPath, defaultValue = null) {
// 在列表中查找第一个符合所有条件的对象
const item = list.find(el => {
// 检查所有条件是否满足
return Object.keys(conditions).every(key => el[key] === conditions[key]);
});
// 递归处理深层嵌套的键名解析
function recursiveGet(obj, keyPathArray) {
if (!obj || keyPathArray.length === 0) return obj;
const [currentKey, ...rest] = keyPathArray;
return recursiveGet(obj[currentKey], rest);
}
// 如果找到项,处理深层嵌套返回
if (item) {
const keyPathArray = returnKeyPath.split('.');
return recursiveGet(item, keyPathArray);
}
// 找不到时返回默认值
return defaultValue;
}
/**
*
* 验证对象中指定字段是否都有值 用于表单验证,如果所有字段都有值,返回 true;否则返回 false,也有部分字段不需要验证
* @param {Object} point - 经纬度
* @param {list} polygon - 经纬度列表
* @returns {boolean} - 如果经纬度在当前区域内,返回 true;否则返回 false。可用于判断当抢位置是否在换车点呢
*
*/
function isPointInPolygon(point, polygon) {
const x = point.longitude,
y = point.latitude; // 提取经纬度
let inside = false;
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const xi = polygon[i].longitude,
yi = polygon[i].latitude;
const xj = polygon[j].longitude,
yj = polygon[j].latitude;
const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}
// 将角度转换为弧度
// 角度 * (π / 180) = 弧度
function toRad(degree) {
return degree * Math.PI / 180;
}
/**
* 计算两点之间的地球表面距离(单位:米)
* 使用 Haversine 公式计算两点间的大圆距离,适用于计算地球表面上两点的最短距离。
*
* @param {Object} point1 - 第一个点,包含 `latitude` 和 `longitude` 字段
* @param {Object} point2 - 第二个点,包含 `latitude` 和 `longitude` 字段
* @returns {number} - 返回两点之间的距离,单位为米
*
* @example
* const point1 = {latitude: 34.75372382069513, longitude: 113.6772739355822};
* const point2 = {latitude: 34.753721618214016, longitude: 113.67755406792321};
* const distance = calculateDistance(point1, point2);
* console.log(distance); // 输出:0.02803479946022938
*/
function calculateDistance(point1, point2) {
const R = 6371393; // 地球的半径,单位为米
// 将经纬度从度数转换为弧度
const lat1 = toRad(point1.latitude); // 第一个点的纬度转为弧度
const lon1 = toRad(point1.longitude); // 第一个点的经度转为弧度
const lat2 = toRad(point2.latitude); // 第二个点的纬度转为弧度
const lon2 = toRad(point2.longitude); // 第二个点的经度转为弧度
// 计算经纬度的差值
const dLat = lat2 - lat1; // 纬度差值
const dLon = lon2 - lon1; // 经度差值
// Haversine 公式计算球面距离
// 先计算 a 的值
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
// 计算 c 的值
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
// 计算两点之间的距离,单位为米
const distance = R * c;
return parseFloat(Math.ceil(distance));
}
/**
* 计算多个点之间的总距离(单位:米)
*
* @param {Array} points - 包含多个点的数组,每个点包含 `latitude` 和 `longitude`
* @returns {number} - 返回总距离,单位为米
*/
function calculateTotalDistance(points) {
let totalDistance = 0;
for (let i = 0; i < points.length - 1; i++) {
totalDistance += calculateDistance(points[i], points[i + 1]);
}
return parseFloat(Math.ceil(totalDistance));
}
/**
* 计算一组经纬度点围成的多边形的面积
*
* @param {Array} points - 包含多个经纬度点的数组,每个点是一个包含 `latitude` 和 `longitude` 的对象
* @returns {number} - 返回多边形的面积(单位:米)
*/
function calculateArea(points) {
// 将经纬度点转换为 GeoJSON 格式的坐标数组
const geojsonPoints = points.map(point => [point.longitude, point.latitude]);
// 创建一个闭合的多边形(闭合多边形需要第一个点和最后一个点相同)
const polygon = turf.polygon([geojsonPoints.concat([geojsonPoints[0]])]);
// 使用 Turf.js 计算面积(单位:平方米)
const areaInSquareMeters = turf.area(polygon);
// 转换为平方千米并返回
// return areaInSquareMeters / 1000000; // 返回单位为平方千米
return areaInSquareMeters.toFixed(2); // 返回单位为平方米
}
//
/**
* 计算多边形中心点的方法
*
* @param {Array} polygon - 包含多个经纬度点的数组,每个点是一个包含 `latitude` 和 `longitude` 的对象
* @returns {object} - longitude: 113.67785754570972,latitude: 34.75382727767499
*/
function calculateCenterPoint(polygon) {
let sumLongitude = 0;
let sumLatitude = 0;
const n = polygon.length;
polygon.forEach(point => {
sumLongitude += point.longitude;
sumLatitude += point.latitude;
});
const centerLongitude = sumLongitude / n;
const centerLatitude = sumLatitude / n;
return { longitude: centerLongitude, latitude: centerLatitude };
}
// 导出所有工具函数
export {
formatDate,//时间格式化工具
timestampToDate,//时间戳转换为日期
generateDateArray,//生成指定时间范围内的日期数组
getDayOfWeek,//获取日期对应的星期几
getTimeUntilEnd,//计算当前时间距离结束时间的时间戳
formatCurrency,//金额格式化
convertToChinese,//金额转换为中文大写
generateRandomCode,//生成随机验证码
isEmail,//校验邮箱格式
isPhoneNumber,//校验手机号格式(中国手机号)
debounce,//防抖函数
throttle,//节流函数
deepClone,//深拷贝
mergeObjects,//对象合并
uniqueArray,//数组去重
generateRandomString,//生成随机字符串
validatePasswordStrength,//设置密码时验证密码强度
checkPwd,//检测密码强度等级
validateIDCard,//身份证校验
copyToClipboard,//复制剪切板
processImageUrl,//处理半截图片拼接
areAllFieldsNotNull,//验证对象中指定字段是否都有值 用于表单验
getValueByKey,//根据给定条件查找对象,并返回目标键的值,支持多个查找条件和深层嵌套的递归处理。
isPointInPolygon,//验证对象中指定字段是否都有值 用于表单验证,如果所有字段都有值,返回 true;否则返回 false,也有部分字段不需要验证
calculateDistance,//计算两点之间的地球表面距离(单位:千米)
calculateTotalDistance,//计算多个点之间的总距离
calculateArea,//计算一组经纬度点围成的多边形的面积
calculateCenterPoint,//计算多边形中心点的方法
};