dxf: split into layer-key and block-partition workflows

This commit is contained in:
hikim2 committed 2026-04-13 09:34:18 +09:00
1 parent be58c7ed3c
commit bd79da2b64
13 files changed
+38154

No files matched your search

+139
View File
@@ -0,0 +1,139 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>DXF block partition report</title>
<style>
:root {
--bg: #f2f4f8;
--card: #ffffff;
--line: #d8dee8;
--ink: #152230;
--muted: #6b7a8e;
--accent: #1861bf;
--accent-soft: rgba(24, 97, 191, 0.12);
}
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", "Pretendard", sans-serif; color: var(--ink); background: linear-gradient(180deg, #f8fafc 0%, var(--bg) 100%); }
.layout { display: grid; grid-template-columns: 1.8fr 1fr; gap: 14px; padding: 14px; min-height: 100vh; }
.panel { background: var(--card); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; box-shadow: 0 10px 24px rgba(28, 39, 58, 0.06); }
.header { padding: 12px 14px; border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.header strong { font-size: 14px; }
.header span { font-size: 12px; color: var(--muted); }
.canvas-wrap { padding: 12px; }
svg { width: 100%; height: 78vh; border: 1px solid var(--line); border-radius: 10px; background: #f9fbfd; }
.list { max-height: 84vh; overflow: auto; }
table { width: 100%; border-collapse: collapse; font-size: 12px; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid #ecf0f6; white-space: nowrap; }
th { position: sticky; top: 0; background: #f8fafc; z-index: 1; font-weight: 600; }
tr:hover td { background: var(--accent-soft); }
.tag { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; border: 1px solid #cadaf4; color: #124c95; background: #edf4ff; }
@media (max-width: 980px) {
.layout { grid-template-columns: 1fr; }
svg { height: 54vh; }
.list { max-height: none; }
}
</style>
</head>
<body>
<div class="layout">
<section class="panel">
<div class="header">
<strong>Block partition map</strong>
<span id="meta"></span>
</div>
<div class="canvas-wrap">
<svg id="map"></svg>
</div>
</section>
<section class="panel">
<div class="header">
<strong>Partition list</strong>
<span>754 items</span>
</div>
<div class="list">
<table>
<thead>
<tr>
<th>ID</th>
<th>Zone</th>
<th>Block</th>
<th>Layer</th>
<th>Size</th>
</tr>
</thead>
<tbody id="rows"></tbody>
</table>
</div>
</section>
</div>
<script>
const DATA = {"meta":{"source":"center.dxf","generatedAt":"2026-04-13T00:21:43.112Z","split":4,"partitionCount":754,"blockDefinitionCount":34,"headerBounds":{"minX":-112.3017486187149,"minY":-659.7598656276181,"maxX":61097.14285655645,"maxY":43199.99999958463}},"byBlock":{"보조테이블":5,"CH0015WAF":52,"CBR020CB":6,"장식장":15,"CCR124AT":7,"FDC442L":179,"TOH-55832LW":181,"FDD588N":179,"화분1":29,"블록 01":4,"SD362L":6,"CH2800A":4,"SP4303":6,"분리수거":6,"커피머신":2,"정수기":4,"하부장":4,"냉장고":3,"화분":37,"1P-T204":4,"SD912F":1,"A$C7DB26F73":3,"인조화분":10,"CH3301":4,"ZRC018":1,"받침대":1,"파쇄기":1},"byZone":{"Z-R4C1":51,"Z-R4C2":43,"Z-R4C3":8,"Z-R3C1":69,"Z-R3C3":73,"Z-R3C2":95,"Z-R3C4":9,"Z-R2C1":25,"Z-R2C2":81,"Z-R2C3":104,"Z-R2C4":30,"Z-R1C3":87,"Z-R1C2":43,"Z-R1C4":36},"partitions":[{"id":"P-0452","zoneKey":"Z-R4C1","blockName":"보조테이블","layer":"사무집기","handle":"172D","rotation":90,"scale":{"x":1,"y":0.9014},"center":{"x":5334.781,"y":41236.042},"bounds":{"minX":4974.231,"minY":41036.042,"maxX":5695.331,"maxY":41436.042,"width":721.1,"height":400},"blockEntityCount":10},{"id":"P-0055","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"$CHAR","handle":"E33","rotation":9.03,"scale":{"x":-1,"y":1},"center":{"x":12741.76,"y":40469.008},"bounds":{"minX":12109.059,"minY":39849.393,"maxX":13374.46,"maxY":41088.623,"width":1265.401,"height":1239.23},"blockEntityCount":57},{"id":"P-0057","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"$CHAR","handle":"E39","rotation":9.03,"scale":{"x":1,"y":1},"center":{"x":12006.888,"y":40356.845},"bounds":{"minX":11374.187,"minY":39737.23,"maxX":12639.588,"maxY":40976.46,"width":1265.401,"height":1239.23},"blockEntityCount":57},{"id":"P-0061","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"$CHAR","handle":"E41","rotation":9.03,"scale":{"x":-1,"y":1},"center":{"x":11256.561,"y":40232.938},"bounds":{"minX":10623.86,"minY":39613.323,"maxX":11889.261,"maxY":40852.553,"width":1265.401,"height":1239.23},"blockEntityCount":57},{"id":"P-0063","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"$CHAR","handle":"E47","rotation":9.03,"scale":{"x":1,"y":1},"center":{"x":10521.689,"y":40120.776},"bounds":{"minX":9888.988,"minY":39501.161,"maxX":11154.389,"maxY":40740.391,"width":1265.401,"height":1239.23},"blockEntityCount":57},{"id":"P-0056","zoneKey":"Z-R4C1","blockName":"CBR020CB","layer":"$TABL","handle":"E34","rotation":189.03,"scale":{"x":0.7519,"y":1},"center":{"x":12441.507,"y":40075.298},"bounds":{"minX":11281.996,"minY":39387.634,"maxX":13601.019,"maxY":40762.963,"width":2319.023,"height":1375.329},"blockEntityCount":304},{"id":"P-0067","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"$CHAR","handle":"E4F","rotation":9.03,"scale":{"x":-1,"y":1},"center":{"x":9771.361,"y":39996.869},"bounds":{"minX":9138.661,"minY":39377.254,"maxX":10404.062,"maxY":40616.484,"width":1265.401,"height":1239.23},"blockEntityCount":57},{"id":"P-0069","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"$CHAR","handle":"E55","rotation":9.03,"scale":{"x":1,"y":1},"center":{"x":9036.489,"y":39884.707},"bounds":{"minX":8403.789,"minY":39265.092,"maxX":9669.19,"maxY":40504.322,"width":1265.401,"height":1239.23},"blockEntityCount":57},{"id":"P-0062","zoneKey":"Z-R4C1","blockName":"CBR020CB","layer":"$TABL","handle":"E42","rotation":189.03,"scale":{"x":0.7519,"y":1},"center":{"x":10956.308,"y":39839.229},"bounds":{"minX":9796.797,"minY":39151.564,"maxX":12115.819,"maxY":40526.893,"width":2319.023,"height":1375.329},"blockEntityCount":304},{"id":"P-0051","zoneKey":"Z-R4C2","blockName":"CH0015WAF","layer":"회의실","handle":"C52","rotation":270,"scale":{"x":1,"y":1},"center":{"x":18930.794,"y":39807.206},"bounds":{"minX":18391.608,"minY":39252.265,"maxX":19469.981,"maxY":40362.146,"width":1078.373,"height":1109.881},"blockEntityCount":57},{"id":"P-0049","zoneKey":"Z-R4C2","blockName":"CH0015WAF","layer":"회의실","handle":"C4C","rotation":90,"scale":{"x":-1,"y":1},"center":{"x":17814.822,"y":39807.087},"bounds":{"minX":17275.635,"minY":39252.146,"maxX":18354.008,"maxY":40362.027,"width":1078.373,"height":1109.881},"blockEntityCount":57},{"id":"P-0459","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"회의실","handle":"1738","rotation":90,"scale":{"x":-1,"y":1},"center":{"x":3208.388,"y":39688.868},"bounds":{"minX":2669.201,"minY":39133.927,"maxX":3747.575,"maxY":40243.808,"width":1078.373,"height":1109.881},"blockEntityCount":57},{"id":"P-0462","zoneKey":"Z-R4C1","blockName":"CH0015WAF","layer":"회의실","handle":"1741","rotation":270,"scale":{"x":-1,"y":1},"center":{"x":4880.132,"y":39659.381},"bounds":{"minX":4340.945,"minY":39104.44,"maxX":5419.319,"maxY":40214.321,"width":1078.373,"height":1109.881},"blockEntityCount":57},{"id":"P-0446","zoneKey":"Z-R4C2","blockName":"장식장","layer":"가구","handle":"16FB","rotation":270,"scale":{"x":1,"y":1},"center":{"x":20095.396,"y":39659.213},"bounds":{"minX":19920.396,"minY"Line truncated
const map = document.getElementById("map");
const rows = document.getElementById("rows");
const meta = document.getElementById("meta");
const W = 1600;
const H = 980;
map.setAttribute("viewBox", `0 0 ${W} ${H}`);
meta.textContent = `${DATA.meta.source} | partitions: ${DATA.meta.partitionCount}`;
const bounds = DATA.meta.headerBounds;
const worldW = Math.max(1, bounds.maxX - bounds.minX);
const worldH = Math.max(1, bounds.maxY - bounds.minY);
const pad = 30;
const drawW = W - pad * 2;
const drawH = H - pad * 2;
function tx(x) { return pad + ((x - bounds.minX) / worldW) * drawW; }
function ty(y) { return pad + ((bounds.maxY - y) / worldH) * drawH; }
const bg = document.createElementNS("http://www.w3.org/2000/svg", "rect");
bg.setAttribute("x", pad);
bg.setAttribute("y", pad);
bg.setAttribute("width", drawW);
bg.setAttribute("height", drawH);
bg.setAttribute("fill", "#ffffff");
bg.setAttribute("stroke", "#dde5ef");
map.appendChild(bg);
DATA.partitions.forEach((item, index) => {
const x = tx(item.bounds.minX);
const y = ty(item.bounds.maxY);
const width = Math.max(2, tx(item.bounds.maxX) - tx(item.bounds.minX));
const height = Math.max(2, ty(item.bounds.minY) - ty(item.bounds.maxY));
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("x", x);
rect.setAttribute("y", y);
rect.setAttribute("width", width);
rect.setAttribute("height", height);
rect.setAttribute("fill", "rgba(24,97,191,0.12)");
rect.setAttribute("stroke", "rgba(24,97,191,0.8)");
rect.setAttribute("stroke-width", "1.1");
map.appendChild(rect);
if (index % 4 === 0) {
const label = document.createElementNS("http://www.w3.org/2000/svg", "text");
label.setAttribute("x", x + 3);
label.setAttribute("y", Math.max(16, y + 12));
label.setAttribute("fill", "#0e3d7b");
label.setAttribute("font-size", "11");
label.textContent = item.id;
map.appendChild(label);
}
const tr = document.createElement("tr");
tr.innerHTML = `
<td>${item.id}</td>
<td><span class="tag">${item.zoneKey}</span></td>
<td>${item.blockName}</td>
<td>${item.layer}</td>
<td>${item.bounds.width} x ${item.bounds.height}</td>
`;
rows.appendChild(tr);
});
</script>
</body>
</html>