dxf: split into layer-key and block-partition workflows
This commit is contained in:
119
dxf/layer_position_keys.mjs
Normal file
119
dxf/layer_position_keys.mjs
Normal file
@@ -0,0 +1,119 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import {
|
||||
boundsFromPoints,
|
||||
extractPolylineVertices,
|
||||
first,
|
||||
num,
|
||||
parseDxfText,
|
||||
pointsFromLWPolyline,
|
||||
readDxfText,
|
||||
} from "./lib/dxf_basic_parser.mjs";
|
||||
|
||||
function parseArgs(argv) {
|
||||
const out = {};
|
||||
for (let i = 0; i < argv.length; i += 1) {
|
||||
const token = argv[i];
|
||||
if (!token.startsWith("--")) continue;
|
||||
const key = token.slice(2);
|
||||
const value = argv[i + 1];
|
||||
if (!value || value.startsWith("--")) continue;
|
||||
out[key] = value;
|
||||
i += 1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function normalizeLayer(layerName) {
|
||||
return String(layerName || "0")
|
||||
.trim()
|
||||
.toUpperCase()
|
||||
.replace(/[^A-Z0-9_]/g, "_");
|
||||
}
|
||||
|
||||
function representativePoint(entity, entities, index) {
|
||||
if (entity.type === "INSERT") return { point: { x: num(entity, 10), y: num(entity, 20) }, nextIndex: index };
|
||||
if (entity.type === "LINE") {
|
||||
const x1 = num(entity, 10);
|
||||
const y1 = num(entity, 20);
|
||||
const x2 = num(entity, 11);
|
||||
const y2 = num(entity, 21);
|
||||
return { point: { x: (x1 + x2) / 2, y: (y1 + y2) / 2 }, nextIndex: index };
|
||||
}
|
||||
if (entity.type === "CIRCLE" || entity.type === "ARC") {
|
||||
return { point: { x: num(entity, 10), y: num(entity, 20) }, nextIndex: index };
|
||||
}
|
||||
if (entity.type === "LWPOLYLINE") {
|
||||
const points = pointsFromLWPolyline(entity);
|
||||
const box = boundsFromPoints(points);
|
||||
return { point: box ? { x: box.cx, y: box.cy } : null, nextIndex: index };
|
||||
}
|
||||
if (entity.type === "POLYLINE") {
|
||||
const parsed = extractPolylineVertices(entities, index);
|
||||
const box = boundsFromPoints(parsed.points);
|
||||
return { point: box ? { x: box.cx, y: box.cy } : null, nextIndex: parsed.nextIndex };
|
||||
}
|
||||
return { point: null, nextIndex: index };
|
||||
}
|
||||
|
||||
function buildLayerPositionKeys(dxfPath, cellSize) {
|
||||
const dxfText = readDxfText(dxfPath);
|
||||
const { entities, headerBounds } = parseDxfText(dxfText);
|
||||
const minX = Number.isFinite(headerBounds.minX) ? headerBounds.minX : 0;
|
||||
const minY = Number.isFinite(headerBounds.minY) ? headerBounds.minY : 0;
|
||||
|
||||
const items = [];
|
||||
const sequenceByLayer = new Map();
|
||||
|
||||
for (let i = 0; i < entities.length; i += 1) {
|
||||
const entity = entities[i];
|
||||
const layerRaw = first(entity, 8) ?? "0";
|
||||
const layer = normalizeLayer(layerRaw);
|
||||
|
||||
const extracted = representativePoint(entity, entities, i);
|
||||
i = extracted.nextIndex;
|
||||
if (!extracted.point) continue;
|
||||
|
||||
const col = Math.floor((extracted.point.x - minX) / cellSize);
|
||||
const row = Math.floor((extracted.point.y - minY) / cellSize);
|
||||
const seq = (sequenceByLayer.get(layer) ?? 0) + 1;
|
||||
sequenceByLayer.set(layer, seq);
|
||||
|
||||
const key = `${layer}::R${row}C${col}::${String(seq).padStart(4, "0")}`;
|
||||
items.push({
|
||||
key,
|
||||
layer,
|
||||
sourceLayer: layerRaw,
|
||||
type: entity.type,
|
||||
x: Number(extracted.point.x.toFixed(3)),
|
||||
y: Number(extracted.point.y.toFixed(3)),
|
||||
grid: { row, col },
|
||||
});
|
||||
}
|
||||
|
||||
const byLayer = {};
|
||||
for (const item of items) byLayer[item.layer] = (byLayer[item.layer] ?? 0) + 1;
|
||||
|
||||
return {
|
||||
meta: {
|
||||
source: path.basename(dxfPath),
|
||||
generatedAt: new Date().toISOString(),
|
||||
cellSize,
|
||||
entityCount: entities.length,
|
||||
keyedItemCount: items.length,
|
||||
bounds: headerBounds,
|
||||
},
|
||||
byLayer,
|
||||
items,
|
||||
};
|
||||
}
|
||||
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const scriptDir = path.dirname(new URL(import.meta.url).pathname);
|
||||
const dxfPath = path.resolve(args.input ?? path.join(scriptDir, "center.dxf"));
|
||||
const outputPath = path.resolve(args.output ?? path.join(scriptDir, "layer_position_keys.json"));
|
||||
const cellSize = Number(args.cell ?? 2000);
|
||||
|
||||
const result = buildLayerPositionKeys(dxfPath, Number.isFinite(cellSize) && cellSize > 0 ? cellSize : 2000);
|
||||
fs.writeFileSync(outputPath, `${JSON.stringify(result, null, 2)}\n`, "utf8");
|
||||
console.log(`saved: ${outputPath}`);
|
||||
Reference in New Issue
Block a user