UNPKG

iobroker.roborock

Version:
125 lines (103 loc) 3.69 kB
import type { B01MapData } from "../b01/types"; import type { Q10CreatorArea, Q10MapPixelPoint, Q10PixelPose } from "./types"; export const Q10_CANVAS_SCALE = 8; const ROOM_TAG_REFERENCE_VIEW_WIDTH = 360; const ROOM_TAG_REFERENCE_VIEW_HEIGHT = 780; export function getOriginalQ10MapRate(width: number, height: number): number { const maxSide = Math.max(width, height, 1); return Math.max(1, Math.floor(2000 / maxSide)); } export function getQ10ExportCanvasScale(width: number, height: number): number { const originalScale = getOriginalQ10MapRate(width, height); return Math.max(3, Math.ceil(originalScale / 3) * 3); } export interface Q10AreaPlacement { centerX: number; centerY: number; width: number; height: number; angleRad: number; angleDeg: number; } export class Q10MapGeometry { public constructor( private readonly data: B01MapData, private readonly viewScale = 1, private readonly canvasScale = Q10_CANVAS_SCALE ) {} public mapPoint(point: Q10MapPixelPoint): Q10MapPixelPoint { return { x: point.x * this.canvasScale, y: point.y * this.canvasScale }; } public mapPose(pose: Q10PixelPose | undefined): Q10PixelPose | undefined { if (!pose) return undefined; return { x: pose.x * this.canvasScale, y: pose.y * this.canvasScale, phi: pose.phi }; } public mapLength(length: number): number { return length * this.canvasScale; } public layoutLengthInMap(layoutUnits: number): number { return this.layoutLength(layoutUnits) / this.canvasScale; } public layoutLength(layoutUnits: number): number { return (layoutUnits * this.overlayExportScale()) / Math.max(this.viewScale, 0.001); } public imgRateLength(layoutUnits: number): number { return layoutUnits * this.roomTagReferenceKImgRate() * this.overlayExportScale(); } public quarterMeterTileLengthInMap(): number { return 0.25 / Math.max(this.data.header.resolution, 0.01); } public quarterMeterTileLength(): number { return this.quarterMeterTileLengthInMap() * this.canvasScale; } public mapCanvasSize(): { width: number; height: number } { return { width: Math.max(1, this.data.header.sizeX * this.canvasScale), height: Math.max(1, this.data.header.sizeY * this.canvasScale) }; } public originalMapRate(): number { return getOriginalQ10MapRate(this.data.header.sizeX, this.data.header.sizeY); } public exportCanvasScale(): number { return getQ10ExportCanvasScale(this.data.header.sizeX, this.data.header.sizeY); } public canvasScaleValue(): number { return this.canvasScale; } public areaPlacement(area: Q10CreatorArea, outputSpace: "map" | "canvas" = "map"): Q10AreaPlacement { const scale = outputSpace === "canvas" ? this.canvasScale : 1; const p0 = area.points[0]!; const p1 = area.points[1]!; const p3 = area.points[3]!; const angleRad = Math.atan2(p1.y - p0.y, p1.x - p0.x); return { centerX: ((area.points[0]!.x + area.points[2]!.x) / 2) * scale, centerY: ((area.points[0]!.y + area.points[2]!.y) / 2) * scale, width: Math.hypot(p1.x - p0.x, p1.y - p0.y) * scale, height: Math.hypot(p3.x - p0.x, p3.y - p0.y) * scale, angleRad, angleDeg: (angleRad * 180) / Math.PI }; } public roomTagReferenceKImgRate(): number { const width = Math.max(1, this.data.header.sizeX); const height = Math.max(1, this.data.header.sizeY); const fitRateX = ROOM_TAG_REFERENCE_VIEW_WIDTH / width; const fitRateY = ROOM_TAG_REFERENCE_VIEW_HEIGHT / height; return Math.max(1, Math.min(fitRateX, fitRateY)); } public overlayExportScale(): number { return this.canvasScale / this.roomTagReferenceKImgRate(); } public roomTagExportScale(): number { return this.overlayExportScale(); } }