const DEG_TO_RAD = Math.PI / 180; // 偏差值 let deviationValue = {} function lonLatToXY(lon, lat, lat0) { const R = 111320; // 每度约等于 111.32 km const cosLat = Math.cos(lat0 * DEG_TO_RAD); return {x: lon * R * cosLat, y: lat * R}; } function calcRectangleFromPoints(points) { if (!points || points.length !== 4) { // console.log("必须传入4个点"); return } const p1raw = points.find(p => p.name === "点位1") || points[0]; const p2raw = points.find(p => p.name === "点位2") || points[1]; const p3raw = points.find(p => p.name === "点位3") || points[2]; const p4raw = points.find(p => p.name === "点位4") || points[3]; const lat0 = (points.reduce((s, p) => s + p.lat, 0) / points.length); const p1 = lonLatToXY(p1raw.lon, p1raw.lat, lat0); const p2 = lonLatToXY(p2raw.lon, p2raw.lat, lat0); const p3 = lonLatToXY(p3raw.lon, p3raw.lat, lat0); const p4 = lonLatToXY(p4raw.lon, p4raw.lat, lat0); const dist = (a, b) => Math.hypot(a.x - b.x, a.y - b.y); const top = dist(p2, p3); const bottom = dist(p4, p1); const left = dist(p4, p3); const right = dist(p1, p2); const trapezoid = Math.abs(top - bottom) / Math.max(top, bottom) > 0.05; const width = trapezoid ? (top + bottom) / 2 : bottom; const height = trapezoid ? (left + right) / 2 : right; const bottomAngleRad = Math.atan2(p1.y - p4.y, p1.x - p4.x); const leftAngleRad = Math.atan2(p1.x - p2.x, p1.y - p2.y); // const angleDeg = leftAngleRad * 180 / Math.PI - bottomAngleRad * 180 / Math.PI; // const angleDeg = bottomAngleRad * 180 / Math.PI; const angleDeg = leftAngleRad * 180 / Math.PI; console.log(angleDeg) return { width: Number(width.toFixed(2)), height: Number(height.toFixed(2)), angle: Number(angleDeg.toFixed(6)) }; } function getLocalPositionRelativeToP4(point, rectPoints, rectInfo) { if (!rectInfo || typeof rectInfo.angle !== 'number') { // console.log("rectInfo.angle 必须是由 calcRectangleFromPoints 得到的角度"); return } const lat0 = rectPoints.reduce((a, b) => a + b.lat, 0) / rectPoints.length; const p4raw = rectPoints.find(p => p.name === "点位4") || rectPoints[3]; const p4 = lonLatToXY(p4raw.lon, p4raw.lat, lat0); const p = lonLatToXY(point.lon, point.lat, lat0); const dx = p.x - p4.x; const dy = p.y - p4.y; const rad = -rectInfo.angle * DEG_TO_RAD; const x_local = dx * Math.cos(rad) - dy * Math.sin(rad); const y_local = dx * Math.sin(rad) + dy * Math.cos(rad); const rotate_local = ((point.rotate ?? 0) + rectInfo.angle + 360) % 360; return { x: Number(x_local.toFixed(2)), y: Number(y_local.toFixed(2)), rotate: Number(rotate_local.toFixed(2)) }; } // 设置偏差值 const getDeviationValue = (e, areaPoints) => { if (!e) return const rectInfo = calcRectangleFromPoints(areaPoints); const local = getLocalPositionRelativeToP4(e, areaPoints, rectInfo); deviationValue = local; } // 修正偏差 const correctDeviation = (e) => { let numH = deviationValue.y || 0 let numW = deviationValue.x || 0 let Ratio = e?.y / numH return { ...e, x: e?.x - numW * Ratio } } const parseTime = (time, pattern) => { if (!time) { return null; } const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'; let date; if (typeof time === 'object') { date = time; } else { if (typeof time === 'string' && /^[0-9]+$/.test(time)) { time = parseInt(time); } else if (typeof time === 'string') { time = time .replace(new RegExp(/-/gm), '/') .replace('T', ' ') .replace(new RegExp(/\.[\d]{3}/gm), ''); } if (typeof time === 'number' && time.toString().length === 10) { time = time * 1000; } date = new Date(time); } let formatObj; formatObj = { y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate(), h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), a: date.getDay() }; return format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { let value = formatObj[key]; // Note: getDay() returns 0 on Sunday if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value]; } if (result.length > 0 && value < 10) { value = '0' + value; } return value || 0; }); } export { calcRectangleFromPoints, getLocalPositionRelativeToP4, getDeviationValue, correctDeviation,parseTime }