You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.5 KiB
JavaScript
136 lines
4.5 KiB
JavaScript
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 = bottomAngleRad * 180 / Math.PI;
|
|
console.log(leftAngleRad * 180 / Math.PI)
|
|
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
|
|
} |