import maplibregl from "maplibre-gl"; import { Geometry } from "@/lib/useEditorState"; type ModeGetter = () => "idle" | "draw" | "select" | "add-point" | "add-line" | "add-path" | "add-circle"; // Khởi tạo engine vẽ polygon tự do theo chuỗi click. export function initDrawing( map: maplibregl.Map, getMode: ModeGetter, onComplete: (geometry: Geometry) => void ) { let coords: [number, number][] = []; // Đóng vòng polygon nếu điểm cuối chưa trùng điểm đầu. function closePolygon(c: [number, number][]) { if (c.length < 3) return c; const first = c[0]; const last = c[c.length - 1]; if (first[0] !== last[0] || first[1] !== last[1]) { return [...c, first]; } return c; } // Cập nhật layer preview trong lúc đang vẽ. function update(c: [number, number][]) { const closed = closePolygon(c); (map.getSource("draw-preview") as maplibregl.GeoJSONSource)?.setData({ type: "FeatureCollection", features: [ { type: "Feature", properties: {}, geometry: { type: "Polygon", coordinates: [closed], }, }, ], }); } // Ghi nhận đỉnh polygon mới khi click map. function onClick(e: maplibregl.MapLayerMouseEvent) { if (getMode() !== "draw") return; coords.push([e.lngLat.lng, e.lngLat.lat] as [number, number]); update(coords); } // Render preview polygon với điểm chuột hiện tại. function onMove(e: maplibregl.MapLayerMouseEvent) { if (getMode() !== "draw" || coords.length === 0) return; const preview: [number, number][] = [ ...coords, [e.lngLat.lng, e.lngLat.lat] as [number, number], ]; update(preview); } // Hoàn tất polygon, trả geometry ra ngoài và reset preview. function finishDrawing() { if (getMode() !== "draw" || coords.length < 3) return; const geometry: Geometry = { type: "Polygon", coordinates: [closePolygon(coords)], }; onComplete(geometry); coords = []; (map.getSource("draw-preview") as maplibregl.GeoJSONSource | undefined)?.setData({ type: "FeatureCollection", features: [], }); } // Lắng nghe Enter để chốt polygon. function onKeyDown(e: KeyboardEvent) { if (e.key === "Enter") { finishDrawing(); } } map.on("click", onClick); map.on("mousemove", onMove); document.addEventListener("keydown", onKeyDown); return () => { map.off("click", onClick); map.off("mousemove", onMove); document.removeEventListener("keydown", onKeyDown); }; }