制图图层定义(Drawing Layer Definition)

DWG与DWF数据应用
本文探讨了DWG格式地图数据的应用方法,包括将其分类导入空间数据库并使用向量图层管理和展示,以及将DWG文件转换为DWF文件,并通过制图图层进行显示。介绍了制图图层定义的主要元素。

    目前,仍然有大量地图数据是DWG的格式,如何利用这些DWG格式的地图数据呢?一种办法是分类(Classify)DWG数据,将这些数据导入到空间数据库中,使用向量图层来现实和管理这些数据。这种办法非常费时费力,但是用户可以充分利用向量图层提供的各种GIS功能,例如创建主题图、进行缓冲区分析等。另一种办法是将DWG文件转换为DWF文件,使用制图图层来显示和管理DWF文件。这种办法非常简单,但是许多功能无法应用于制图图层,例如无法创建复杂的主题图。所以,DrawingLayerDefinition的定义非常简单。
    制图图层定义的XML Schema如下图所示。下面的表格解释了制图图层定义的一些主要元素。

名称

描述

Sheet

DWF是由多个sheet组成的,Sheet元素用于指定图层使用DWF的那一个sheet

LayerFilter

用于指定显示sheet中的哪些DWF图层。如果不指定此项,显示sheet中的所有DWF图层。

Drawing Layer Definition

using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using System; using System.Collections.Generic; using System.Windows.Forms; // 使用别名解决命名冲突 using AcApp = Autodesk.AutoCAD.ApplicationServices.Application; using WinApp = System.Windows.Forms.Application; // 程序集特性必须放在命名空间之前 [assembly: CommandClass(typeof(InsertFramePlugin.InsertFrameCommands))] namespace InsertFramePlugin { public class InsertFrameCommands { [CommandMethod("IFR", CommandFlags.Modal)] public void InsertFrame() { Document doc = AcApp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { var form = new InsertFrameForm(); DialogResult result = AcApp.ShowModalDialog(form); if (result == DialogResult.OK) { ed.WriteMessage("\n图框插入操作完成。"); } } catch (System.Exception ex) { ed.WriteMessage($"\n错误: {ex.Message}"); } } } // 标题栏属性编辑窗体 public class TitleBlockEditForm : Form { private TextBox tbUnitName, tbProjectManager, tbSpecialtyManager, tbTechManager, tbProjectName, tbDrawingName, tbSubPart, tbDrawingNo, tbScale, tbDate; private TextBox tbDrawer, tbChecker, tbApprover; private Button btnOK, btnCancel; public Dictionary<string, string> AttributeValues { get; private set; } public TitleBlockEditForm(Dictionary<string, string> currentValues) { AttributeValues = new Dictionary<string, string>(); InitializeComponents(currentValues); } private void InitializeComponents(Dictionary<string, string> currentValues) { this.Text = "标题栏属性编辑"; this.Size = new System.Drawing.Size(500, 450); this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; int yPos = 10; int labelWidth = 80; int textBoxWidth = 200; // 第一行 var lblUnitName = new Label { Text = "单位名称:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbUnitName = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("单位名称") ? currentValues["单位名称"] : "" }; this.Controls.Add(lblUnitName); this.Controls.Add(tbUnitName); yPos += 30; var lblProjectName = new Label { Text = "工程名称:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbProjectName = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("工程名称") ? currentValues["工程名称"] : "" }; this.Controls.Add(lblProjectName); this.Controls.Add(tbProjectName); yPos += 30; var lblSubPart = new Label { Text = "分部分项:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbSubPart = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("分部分项") ? currentValues["分部分项"] : "" }; this.Controls.Add(lblSubPart); this.Controls.Add(tbSubPart); // 第二行 yPos += 30; var lblDrawer = new Label { Text = "制图人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbDrawer = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("制图人") ? currentValues["制图人"] : "" }; this.Controls.Add(lblDrawer); this.Controls.Add(tbDrawer); yPos += 30; var lblProjectManager = new Label { Text = "工程负责人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbProjectManager = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("工程负责人") ? currentValues["工程负责人"] : "" }; this.Controls.Add(lblProjectManager); this.Controls.Add(tbProjectManager); yPos += 30; var lblDrawingNo = new Label { Text = "图号:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbDrawingNo = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("图号") ? currentValues["图号"] : "" }; this.Controls.Add(lblDrawingNo); this.Controls.Add(tbDrawingNo); // 第三行 yPos += 30; var lblChecker = new Label { Text = "审核人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbChecker = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("审核人") ? currentValues["审核人"] : "" }; this.Controls.Add(lblChecker); this.Controls.Add(tbChecker); yPos += 30; var lblSpecialtyManager = new Label { Text = "专业负责人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbSpecialtyManager = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("专业负责人") ? currentValues["专业负责人"] : "" }; this.Controls.Add(lblSpecialtyManager); this.Controls.Add(tbSpecialtyManager); yPos += 30; var lblDrawingName = new Label { Text = "图纸名称:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbDrawingName = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("图纸名称") ? currentValues["图纸名称"] : "" }; this.Controls.Add(lblDrawingName); this.Controls.Add(tbDrawingName); yPos += 30; var lblScale = new Label { Text = "比例:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbScale = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("比例") ? currentValues["比例"] : "" }; this.Controls.Add(lblScale); this.Controls.Add(tbScale); // 第四行 yPos += 30; var lblApprover = new Label { Text = "审定人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbApprover = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("审定人") ? currentValues["审定人"] : "" }; this.Controls.Add(lblApprover); this.Controls.Add(tbApprover); yPos += 30; var lblTechManager = new Label { Text = "技术负责人:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbTechManager = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("技术负责人") ? currentValues["技术负责人"] : "" }; this.Controls.Add(lblTechManager); this.Controls.Add(tbTechManager); yPos += 30; var lblDate = new Label { Text = "日期:", Location = new System.Drawing.Point(10, yPos), Width = labelWidth }; tbDate = new TextBox { Location = new System.Drawing.Point(100, yPos), Width = textBoxWidth, Text = currentValues.ContainsKey("日期") ? currentValues["日期"] : DateTime.Now.ToString("yyyy-MM-dd") }; this.Controls.Add(lblDate); this.Controls.Add(tbDate); // 按钮 yPos += 40; btnOK = new Button { Text = "确定", Location = new System.Drawing.Point(150, yPos), Width = 80 }; btnCancel = new Button { Text = "取消", Location = new System.Drawing.Point(250, yPos), Width = 80 }; btnOK.Click += (s, e) => { // 保存所有值 AttributeValues["单位名称"] = tbUnitName.Text; AttributeValues["工程名称"] = tbProjectName.Text; AttributeValues["分部分项"] = tbSubPart.Text; AttributeValues["制图人"] = tbDrawer.Text; AttributeValues["工程负责人"] = tbProjectManager.Text; AttributeValues["图号"] = tbDrawingNo.Text; AttributeValues["审核人"] = tbChecker.Text; AttributeValues["专业负责人"] = tbSpecialtyManager.Text; AttributeValues["图纸名称"] = tbDrawingName.Text; AttributeValues["比例"] = tbScale.Text; AttributeValues["审定人"] = tbApprover.Text; AttributeValues["技术负责人"] = tbTechManager.Text; AttributeValues["日期"] = tbDate.Text; this.DialogResult = DialogResult.OK; this.Close(); }; btnCancel.Click += (s, e) => { this.DialogResult = DialogResult.Cancel; this.Close(); }; this.Controls.Add(btnOK); this.Controls.Add(btnCancel); } } public partial class InsertFrameForm : Form { // 窗体控件 private RadioButton rbA0, rbA1, rbA2, rbA3, rbA4; private ComboBox cbExtension; private RadioButton rbHorizontal, rbVertical; private TextBox tbLength, tbWidth; private CheckBox cbTitleBlock; private TextBox tbScale; private Button btnAuto, btnManual, btnCancel; // 图幅尺寸定义 (mm) private readonly Dictionary<string, PaperSize> paperSizes = new Dictionary<string, PaperSize> { {"A0", new PaperSize(841, 1189)}, {"A1", new PaperSize(594, 841)}, {"A2", new PaperSize(420, 594)}, {"A3", new PaperSize(297, 420)}, {"A4", new PaperSize(210, 297)} }; // 加长系数 private readonly Dictionary<string, double> extensions = new Dictionary<string, double> { {"A0+1/8", 1.125}, {"A0+1/4", 1.25}, {"A0+3/8", 1.375}, {"A0+1/2", 1.5}, {"A0+5/8", 1.625}, {"A0+3/4", 1.75}, {"A0+7/8", 1.875}, {"A0+1", 2.0} }; public InsertFrameForm() { InitializeComponents(); } private void InitializeComponents() { // 窗体设置 this.Text = "插入图框 v1.0"; this.Size = new System.Drawing.Size(450, 300); this.StartPosition = FormStartPosition.CenterScreen; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; // 第一行:图幅选择 var groupPaperSize = new GroupBox { Text = "图幅", Location = new System.Drawing.Point(10, 10), Size = new System.Drawing.Size(420, 50) }; rbA0 = new RadioButton { Text = "A0", Location = new System.Drawing.Point(10, 20), AutoSize = true }; rbA1 = new RadioButton { Text = "A1", Location = new System.Drawing.Point(60, 20), AutoSize = true }; rbA2 = new RadioButton { Text = "A2", Location = new System.Drawing.Point(110, 20), AutoSize = true, Checked = true }; rbA3 = new RadioButton { Text = "A3", Location = new System.Drawing.Point(160, 20), AutoSize = true }; rbA4 = new RadioButton { Text = "A4", Location = new System.Drawing.Point(210, 20), AutoSize = true }; cbExtension = new ComboBox { Location = new System.Drawing.Point(260, 18), Width = 150, DropDownStyle = ComboBoxStyle.DropDownList }; cbExtension.Items.AddRange(new object[] { "无加长", "A0+1/8", "A0+1/4", "A0+3/8", "A0+1/2", "A0+5/8", "A0+3/4", "A0+7/8", "A0+1" }); cbExtension.SelectedIndex = 0; groupPaperSize.Controls.AddRange(new Control[] { rbA0, rbA1, rbA2, rbA3, rbA4, cbExtension }); // 第二行:方向与尺寸 var groupOrientation = new GroupBox { Text = "方向", Location = new System.Drawing.Point(10, 70), Size = new System.Drawing.Size(120, 50) }; rbHorizontal = new RadioButton { Text = "横式", Location = new System.Drawing.Point(10, 20), AutoSize = true, Checked = true }; rbVertical = new RadioButton { Text = "立式", Location = new System.Drawing.Point(65, 20), AutoSize = true }; groupOrientation.Controls.AddRange(new Control[] { rbHorizontal, rbVertical }); var groupDimensions = new GroupBox { Text = "自定义尺寸 (mm)", Location = new System.Drawing.Point(140, 70), Size = new System.Drawing.Size(290, 50) }; tbLength = new TextBox { Location = new System.Drawing.Point(50, 20), Width = 80, Text = "594" }; tbWidth = new TextBox { Location = new System.Drawing.Point(180, 20), Width = 80, Text = "420" }; groupDimensions.Controls.AddRange(new Control[] { new Label { Text = "长:", Location = new System.Drawing.Point(10, 23), AutoSize = true }, tbLength, new Label { Text = "宽:", Location = new System.Drawing.Point(140, 23), AutoSize = true }, tbWidth }); // 第三行:标题栏和比例 var groupSettings = new GroupBox { Text = "设置", Location = new System.Drawing.Point(10, 130), Size = new System.Drawing.Size(420, 50) }; cbTitleBlock = new CheckBox { Text = "标准标题栏", Location = new System.Drawing.Point(10, 20), AutoSize = true, Checked = true }; tbScale = new TextBox { Text = "100", Location = new System.Drawing.Point(350, 20), Width = 50 }; groupSettings.Controls.AddRange(new Control[] { cbTitleBlock, new Label { Text = "比例 1:", Location = new System.Drawing.Point(300, 23), AutoSize = true }, tbScale }); // 第四行:操作按钮 btnAuto = new Button { Text = "框选图自动布置图框", Location = new System.Drawing.Point(10, 190), Width = 140, BackColor = System.Drawing.Color.LightBlue }; btnManual = new Button { Text = "手动插入", Location = new System.Drawing.Point(160, 190), Width = 100, BackColor = System.Drawing.Color.LightGreen }; btnCancel = new Button { Text = "取消", Location = new System.Drawing.Point(270, 190), Width = 100, BackColor = System.Drawing.Color.LightSalmon }; // 事件处理 btnAuto.Click += BtnAuto_Click; btnManual.Click += BtnManual_Click; btnCancel.Click += (s, e) => { this.DialogResult = DialogResult.Cancel; this.Close(); }; // 单选按钮事件处理 rbA0.CheckedChanged += PaperSizeChanged; rbA1.CheckedChanged += PaperSizeChanged; rbA2.CheckedChanged += PaperSizeChanged; rbA3.CheckedChanged += PaperSizeChanged; rbA4.CheckedChanged += PaperSizeChanged; rbHorizontal.CheckedChanged += (s, e) => UpdateDimensionsFromSelection(); rbVertical.CheckedChanged += (s, e) => UpdateDimensionsFromSelection(); // 加长系数选择事件 cbExtension.SelectedIndexChanged += (s, e) => UpdateDimensionsFromSelection(); // 初始化尺寸显示 UpdateDimensionsFromSelection(); // 添加所有控件 this.Controls.AddRange(new Control[] { groupPaperSize, groupOrientation, groupDimensions, groupSettings, btnAuto, btnManual, btnCancel }); } private void PaperSizeChanged(object sender, EventArgs e) { if (rbA0.Checked) UpdateDimensions("A0"); else if (rbA1.Checked) UpdateDimensions("A1"); else if (rbA2.Checked) UpdateDimensions("A2"); else if (rbA3.Checked) UpdateDimensions("A3"); else if (rbA4.Checked) UpdateDimensions("A4"); } private void UpdateDimensions(string sizeKey) { if (paperSizes.TryGetValue(sizeKey, out PaperSize size)) { // 修复方向问题:现在横式就是宽度>高度,立式就是高度>宽度 if (rbHorizontal.Checked) { // 横式:宽度 > 高度 tbLength.Text = Math.Max(size.Width, size.Height).ToString(); tbWidth.Text = Math.Min(size.Width, size.Height).ToString(); } else { // 立式:高度 > 宽度 tbLength.Text = Math.Min(size.Width, size.Height).ToString(); tbWidth.Text = Math.Max(size.Width, size.Height).ToString(); } // 应用加长系数 if (cbExtension.SelectedItem != null && cbExtension.SelectedIndex > 0 && extensions.TryGetValue(cbExtension.SelectedItem.ToString(), out double extFactor)) { if (rbHorizontal.Checked) { // 横式时加长长边(长度) double newLength = double.Parse(tbLength.Text) * extFactor; tbLength.Text = Math.Round(newLength).ToString(); } else { // 立式时加长长边(宽度) double newWidth = double.Parse(tbWidth.Text) * extFactor; tbWidth.Text = Math.Round(newWidth).ToString(); } } } } private void UpdateDimensionsFromSelection() { if (rbA0.Checked) UpdateDimensions("A0"); else if (rbA1.Checked) UpdateDimensions("A1"); else if (rbA2.Checked) UpdateDimensions("A2"); else if (rbA3.Checked) UpdateDimensions("A3"); else if (rbA4.Checked) UpdateDimensions("A4"); } private void BtnAuto_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.OK; this.Close(); Document doc = AcApp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { // 获取选择集 PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\n选择要包围的图形对象: "; PromptSelectionResult selRes = ed.GetSelection(pso); if (selRes.Status != PromptStatus.OK) { return; } using (Transaction tr = db.TransactionManager.StartTransaction()) { Extents3d overallExtent = new Extents3d(); bool first = true; foreach (SelectedObject selObj in selRes.Value) { Entity ent = tr.GetObject(selObj.ObjectId, OpenMode.ForRead) as Entity; if (ent != null) { Extents3d entExtents = ent.GeometricExtents; if (first) { overallExtent = entExtents; first = false; } else { overallExtent.AddExtents(entExtents); } } } if (first) { ed.WriteMessage("\n未选择到有效的图形对象。"); return; } // 计算图框尺寸 PaperSize frameSize = CalculateFrameSize(); double frameWidth = frameSize.Width; double frameHeight = frameSize.Height; // 计算内容尺寸 double contentWidth = overallExtent.MaxPoint.X - overallExtent.MinPoint.X; double contentHeight = overallExtent.MaxPoint.Y - overallExtent.MinPoint.Y; if (contentWidth <= 0 || contentHeight <= 0) { ed.WriteMessage("\n选择的图形没有有效的范围。"); return; } // 添加边距 double margin = Math.Min(contentWidth, contentHeight) * 0.1; // 计算缩放比例以确保内容适合图框 double scaleX = (frameWidth - 2 * margin) / contentWidth; double scaleY = (frameHeight - 2 * margin) / contentHeight; double scale = Math.Min(scaleX, scaleY); // 如果内容比图框小很多,使用1:1比例 if (scale > 1) scale = 1; // 计算内容中心点 Point3d contentCenter = new Point3d( (overallExtent.MinPoint.X + overallExtent.MaxPoint.X) / 2, (overallExtent.MinPoint.Y + overallExtent.MaxPoint.Y) / 2, 0); // 计算图框插入点(使内容居中于图框) Point2d insertionPoint = new Point2d( contentCenter.X - (frameWidth / 2 / scale), contentCenter.Y - (frameHeight / 2 / scale)); // 插入图框 InsertFrameBlock(insertionPoint, frameWidth, frameHeight, tr, db); tr.Commit(); ed.WriteMessage($"\n图框自动布置完成! 图框尺寸: {frameWidth:F0} x {frameHeight:F0}"); } } catch (System.Exception ex) { ed.WriteMessage($"\n自动布置错误: {ex.Message}"); } } private void BtnManual_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.OK; this.Close(); Document doc = AcApp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { // 获取插入点 PromptPointOptions ppo = new PromptPointOptions("\n指定图框左下角点: "); PromptPointResult ptRes = ed.GetPoint(ppo); if (ptRes.Status != PromptStatus.OK) { return; } // 计算图框尺寸 PaperSize frameSize = CalculateFrameSize(); double frameWidth = frameSize.Width; double frameHeight = frameSize.Height; // 插入图框 using (Transaction tr = db.TransactionManager.StartTransaction()) { InsertFrameBlock(new Point2d(ptRes.Value.X, ptRes.Value.Y), frameWidth, frameHeight, tr, db); tr.Commit(); ed.WriteMessage($"\n图框插入完成! 图框尺寸: {frameWidth:F0} x {frameHeight:F0}"); } } catch (System.Exception ex) { ed.WriteMessage($"\n手动插入错误: {ex.Message}"); } } private PaperSize CalculateFrameSize() { double width = 0; double height = 0; // 从自定义尺寸获取 if (double.TryParse(tbLength.Text, out double length) && double.TryParse(tbWidth.Text, out double w)) { width = length; height = w; } // 如果自定义尺寸无效,使用选择的图幅尺寸 if (width <= 0 || height <= 0) { if (rbA0.Checked && paperSizes.TryGetValue("A0", out PaperSize size0)) { width = rbHorizontal.Checked ? Math.Max(size0.Width, size0.Height) : Math.Min(size0.Width, size0.Height); height = rbHorizontal.Checked ? Math.Min(size0.Width, size0.Height) : Math.Max(size0.Width, size0.Height); } else if (rbA1.Checked && paperSizes.TryGetValue("A1", out PaperSize size1)) { width = rbHorizontal.Checked ? Math.Max(size1.Width, size1.Height) : Math.Min(size1.Width, size1.Height); height = rbHorizontal.Checked ? Math.Min(size1.Width, size1.Height) : Math.Max(size1.Width, size1.Height); } else if (rbA2.Checked && paperSizes.TryGetValue("A2", out PaperSize size2)) { width = rbHorizontal.Checked ? Math.Max(size2.Width, size2.Height) : Math.Min(size2.Width, size2.Height); height = rbHorizontal.Checked ? Math.Min(size2.Width, size2.Height) : Math.Max(size2.Width, size2.Height); } else if (rbA3.Checked && paperSizes.TryGetValue("A3", out PaperSize size3)) { width = rbHorizontal.Checked ? Math.Max(size3.Width, size3.Height) : Math.Min(size3.Width, size3.Height); height = rbHorizontal.Checked ? Math.Min(size3.Width, size3.Height) : Math.Max(size3.Width, size3.Height); } else if (rbA4.Checked && paperSizes.TryGetValue("A4", out PaperSize size4)) { width = rbHorizontal.Checked ? Math.Max(size4.Width, size4.Height) : Math.Min(size4.Width, size4.Height); height = rbHorizontal.Checked ? Math.Min(size4.Width, size4.Height) : Math.Max(size4.Width, size4.Height); } else { // 默认A2尺寸 width = rbHorizontal.Checked ? 594 : 420; height = rbHorizontal.Checked ? 420 : 594; } } // 应用加长系数 if (cbExtension.SelectedItem != null && cbExtension.SelectedIndex > 0 && extensions.TryGetValue(cbExtension.SelectedItem.ToString(), out double extFactor)) { if (rbHorizontal.Checked) { width *= extFactor; } else { height *= extFactor; } } // 应用比例 double scale = double.TryParse(tbScale.Text, out double s) ? s : 100; width *= scale; height *= scale; // 确保最小尺寸 if (width < 10) width = 420 * scale; if (height < 10) height = 594 * scale; return new PaperSize((int)width, (int)height); } private void InsertFrameBlock(Point2d basePoint, double width, double height, Transaction tr, Database db) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); // 获取比例 double scale = double.TryParse(tbScale.Text, out double s) ? s : 100; // 1. 创建外框(粗线) using (Polyline outerFrame = new Polyline()) { outerFrame.AddVertexAt(0, basePoint, 0, 0, 0); outerFrame.AddVertexAt(1, new Point2d(basePoint.X + width, basePoint.Y), 0, 0, 0); outerFrame.AddVertexAt(2, new Point2d(basePoint.X + width, basePoint.Y + height), 0, 0, 0); outerFrame.AddVertexAt(3, new Point2d(basePoint.X, basePoint.Y + height), 0, 0, 0); outerFrame.Closed = true; outerFrame.Layer = "0"; outerFrame.ColorIndex = 7; // 白色 outerFrame.LineWeight = LineWeight.LineWeight050; // 粗线 btr.AppendEntity(outerFrame); tr.AddNewlyCreatedDBObject(outerFrame, true); } // 2. 创建内框(细线) double innerMargin = 5 * scale; // 内边距5mm using (Polyline innerFrame = new Polyline()) { innerFrame.AddVertexAt(0, new Point2d(basePoint.X + innerMargin, basePoint.Y + innerMargin), 0, 0, 0); innerFrame.AddVertexAt(1, new Point2d(basePoint.X + width - innerMargin, basePoint.Y + innerMargin), 0, 0, 0); innerFrame.AddVertexAt(2, new Point2d(basePoint.X + width - innerMargin, basePoint.Y + height - innerMargin), 0, 0, 0); innerFrame.AddVertexAt(3, new Point2d(basePoint.X + innerMargin, basePoint.Y + height - innerMargin), 0, 0, 0); innerFrame.Closed = true; innerFrame.Layer = "0"; innerFrame.ColorIndex = 7; // 白色 innerFrame.ConstantWidth = 1 * scale; // 1mm线宽 btr.AppendEntity(innerFrame); tr.AddNewlyCreatedDBObject(innerFrame, true); } // 3. 创建底部标题栏区域 if (cbTitleBlock.Checked) { CreateTitleBlock(btr, tr, basePoint, width, height, scale); } // 4. 添加比例文本到图框右上角 using (DBText scaleText = new DBText()) { scaleText.Position = new Point3d(basePoint.X + width - 50 * scale, basePoint.Y + height - 20 * scale, 0); scaleText.Height = 5 * scale; scaleText.TextString = $"比例 1:{tbScale.Text}"; scaleText.Layer = "0"; scaleText.ColorIndex = 7; btr.AppendEntity(scaleText); tr.AddNewlyCreatedDBObject(scaleText, true); } // 5. 添加图幅尺寸文本到图框顶部中间 using (DBText sizeText = new DBText()) { sizeText.Position = new Point3d(basePoint.X + width / 2, basePoint.Y + height - 20 * scale, 0); sizeText.Height = 5 * scale; sizeText.HorizontalMode = TextHorizontalMode.TextCenter; sizeText.VerticalMode = TextVerticalMode.TextBase; sizeText.AlignmentPoint = new Point3d(basePoint.X + width / 2, basePoint.Y + height - 20 * scale, 0); sizeText.TextString = $"{width / scale:F0} x {height / scale:F0}"; sizeText.Layer = "0"; sizeText.ColorIndex = 7; btr.AppendEntity(sizeText); tr.AddNewlyCreatedDBObject(sizeText, true); } } // 创建标题栏 - 直接在图框内创建,不使用块 private void CreateTitleBlock(BlockTableRecord btr, Transaction tr, Point2d basePoint, double width, double height, double scale) { double innerMargin = 5 * scale; double titleBlockHeight = 40 * scale; // 标题栏高度 double titleBlockWidth = width - 2 * innerMargin; // 标题栏宽度 // 标题栏外框 using (Polyline titleBlockOuter = new Polyline()) { titleBlockOuter.AddVertexAt(0, new Point2d(basePoint.X + innerMargin, basePoint.Y + innerMargin), 0, 0, 0); titleBlockOuter.AddVertexAt(1, new Point2d(basePoint.X + innerMargin + titleBlockWidth, basePoint.Y + innerMargin), 0, 0, 0); titleBlockOuter.AddVertexAt(2, new Point2d(basePoint.X + innerMargin + titleBlockWidth, basePoint.Y + innerMargin + titleBlockHeight), 0, 0, 0); titleBlockOuter.AddVertexAt(3, new Point2d(basePoint.X + innerMargin, basePoint.Y + innerMargin + titleBlockHeight), 0, 0, 0); titleBlockOuter.Closed = true; titleBlockOuter.Layer = "0"; titleBlockOuter.ColorIndex = 7; titleBlockOuter.LineWeight = LineWeight.LineWeight025; btr.AppendEntity(titleBlockOuter); tr.AddNewlyCreatedDBObject(titleBlockOuter, true); } // 按照要求的8列布局定义列宽 double[] columnWidths = { 25 * scale, // 第1列 25 * scale, // 第2列 25 * scale, // 第3列 25 * scale, // 第4列 40 * scale, // 第5列 25 * scale, // 第6列 25 * scale, // 第7列 25 * scale // 第8列 }; // 定义行高(4行,平均分配高度) double rowHeight = titleBlockHeight / 4; // 创建网格线 CreateTitleBlockGridLines(btr, tr, basePoint, innerMargin, titleBlockWidth, titleBlockHeight, columnWidths, rowHeight, scale); // 创建标签文本和输入区域 CreateTitleBlockContent(btr, tr, basePoint, innerMargin, titleBlockWidth, titleBlockHeight, columnWidths, rowHeight, scale); } // 创建标题栏网格线 private void CreateTitleBlockGridLines(BlockTableRecord btr, Transaction tr, Point2d basePoint, double innerMargin, double width, double height, double[] columnWidths, double rowHeight, double scale) { double startX = basePoint.X + innerMargin; double startY = basePoint.Y + innerMargin; // 计算列起始位置 double[] columnStarts = new double[columnWidths.Length + 1]; columnStarts[0] = startX; for (int i = 0; i < columnWidths.Length; i++) { columnStarts[i + 1] = columnStarts[i] + columnWidths[i]; } // 垂直线 for (int i = 1; i < columnStarts.Length - 1; i++) { using (Line line = new Line( new Point3d(columnStarts[i], startY, 0), new Point3d(columnStarts[i], startY + height, 0))) { line.Layer = "0"; line.ColorIndex = 7; line.LineWeight = LineWeight.LineWeight000; btr.AppendEntity(line); tr.AddNewlyCreatedDBObject(line, true); } } // 水平线 for (int i = 1; i < 4; i++) { double yPos = startY + i * rowHeight; using (Line line = new Line( new Point3d(startX, yPos, 0), new Point3d(startX + width, yPos, 0))) { line.Layer = "0"; line.ColorIndex = 7; line.LineWeight = LineWeight.LineWeight000; btr.AppendEntity(line); tr.AddNewlyCreatedDBObject(line, true); } } // 擦除合并单元格的线 EraseMergedCellLines(btr, tr, startX, startY, width, height, columnWidths, rowHeight, scale); } // 擦除合并单元格的线 private void EraseMergedCellLines(BlockTableRecord btr, Transaction tr, double startX, double startY, double width, double height, double[] columnWidths, double rowHeight, double scale) { // 计算列起始位置 double[] columnStarts = new double[columnWidths.Length + 1]; columnStarts[0] = startX; for (int i = 0; i < columnWidths.Length; i++) { columnStarts[i + 1] = columnStarts[i] + columnWidths[i]; } // 擦除单位名称至工程名称之间的三格合并线(第2-4列合并) EraseVerticalLineAtX(btr, tr, columnStarts[2], startY, startY + rowHeight); // 第2列线 EraseVerticalLineAtX(btr, tr, columnStarts[3], startY, startY + rowHeight); // 第3列线 EraseVerticalLineAtX(btr, tr, columnStarts[4], startY, startY + rowHeight); // 第4列线 // 擦除图纸名称三单元格合并线(第5列的第2-4行合并) EraseHorizontalLineAtY(btr, tr, columnStarts[4], columnStarts[5], startY + rowHeight); // 第2行线 EraseHorizontalLineAtY(btr, tr, columnStarts[4], columnStarts[5], startY + 2 * rowHeight); // 第3行线 EraseHorizontalLineAtY(btr, tr, columnStarts[4], columnStarts[5], startY + 3 * rowHeight); // 第4行线 } // 擦除指定X位置的垂直线段 private void EraseVerticalLineAtX(BlockTableRecord btr, Transaction tr, double x, double yStart, double yEnd) { foreach (ObjectId id in btr) { Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity; if (ent is Line line) { // 检查是否是垂直线且在指定X位置 if (Math.Abs(line.StartPoint.X - line.EndPoint.X) < 0.001 && Math.Abs(line.StartPoint.X - x) < 0.001 && Math.Abs(line.StartPoint.Y - yStart) < 0.001 && Math.Abs(line.EndPoint.Y - yEnd) < 0.001) { line.UpgradeOpen(); line.Erase(); break; } } } } // 擦除指定Y位置的水平线段 private void EraseHorizontalLineAtY(BlockTableRecord btr, Transaction tr, double xStart, double xEnd, double y) { foreach (ObjectId id in btr) { Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity; if (ent is Line line) { // 检查是否是水平线且在指定Y位置 if (Math.Abs(line.StartPoint.Y - line.EndPoint.Y) < 0.001 && Math.Abs(line.StartPoint.Y - y) < 0.001 && Math.Abs(line.StartPoint.X - xStart) < 0.001 && Math.Abs(line.EndPoint.X - xEnd) < 0.001) { line.UpgradeOpen(); line.Erase(); break; } } } } // 创建标题栏内容 private void CreateTitleBlockContent(BlockTableRecord btr, Transaction tr, Point2d basePoint, double innerMargin, double width, double height, double[] columnWidths, double rowHeight, double scale) { double startX = basePoint.X + innerMargin; double startY = basePoint.Y + innerMargin; double textHeight = 3.5 * scale; // 计算列起始位置 double[] columnStarts = new double[columnWidths.Length + 1]; columnStarts[0] = startX; for (int i = 0; i < columnWidths.Length; i++) { columnStarts[i + 1] = columnStarts[i] + columnWidths[i]; } // 第一行 CreateText(btr, tr, "单位名称", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 3.5, 0), textHeight); // 单位名称输入单元格(合并第2-4列) CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + (columnWidths[1] + columnWidths[2] + columnWidths[3]) / 2, startY + rowHeight * 3.5, 0), textHeight); CreateText(btr, tr, "工程名称", new Point3d(columnStarts[4] + 2 * scale, startY + rowHeight * 3.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[5] + columnWidths[5] / 2, startY + rowHeight * 3.5, 0), textHeight); CreateText(btr, tr, "分部分项", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 3.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 3.5, 0), textHeight); // 第二行 CreateText(btr, tr, "制图人", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 2.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + columnWidths[1] / 2, startY + rowHeight * 2.5, 0), textHeight); CreateText(btr, tr, "工程负责人", new Point3d(columnStarts[2] + 2 * scale, startY + rowHeight * 2.5, 0), textHeight); // 修复:放在第3列 CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[3] + columnWidths[3] / 2, startY + rowHeight * 2.5, 0), textHeight); // 图纸名称(合并第5列的第2-4行) CreateText(btr, tr, "图纸名称", new Point3d(columnStarts[4] + 2 * scale, startY + rowHeight * 2, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[5] + columnWidths[5] / 2, startY + rowHeight * 2, 0), textHeight); CreateText(btr, tr, "图号", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 2.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 2.5, 0), textHeight); // 第三行 CreateText(btr, tr, "审核人", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 1.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + columnWidths[1] / 2, startY + rowHeight * 1.5, 0), textHeight); CreateText(btr, tr, "专业负责人", new Point3d(columnStarts[2] + 2 * scale, startY + rowHeight * 1.5, 0), textHeight); // 修复:放在第3列 CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[3] + columnWidths[3] / 2, startY + rowHeight * 1.5, 0), textHeight); CreateText(btr, tr, "比例", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 1.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 1.5, 0), textHeight); // 第四行 CreateText(btr, tr, "审定人", new Point3d(columnStarts[0] + 2 * scale, startY + rowHeight * 0.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[1] + columnWidths[1] / 2, startY + rowHeight * 0.5, 0), textHeight); CreateText(btr, tr, "技术负责人", new Point3d(columnStarts[2] + 2 * scale, startY + rowHeight * 0.5, 0), textHeight); // 修复:放在第3列 CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[3] + columnWidths[3] / 2, startY + rowHeight * 0.5, 0), textHeight); CreateText(btr, tr, "日期", new Point3d(columnStarts[6] + 2 * scale, startY + rowHeight * 0.5, 0), textHeight); CreateText(btr, tr, "输入单元格", new Point3d(columnStarts[7] + columnWidths[7] / 2, startY + rowHeight * 0.5, 0), textHeight); } // 创建文本 private void CreateText(BlockTableRecord btr, Transaction tr, string text, Point3d position, double height) { using (DBText dbText = new DBText()) { dbText.Position = position; dbText.Height = height; dbText.TextString = text; dbText.Layer = "0"; dbText.ColorIndex = 7; btr.AppendEntity(dbText); tr.AddNewlyCreatedDBObject(dbText, true); } } // 使用PaperSize替代Size避免命名冲突 private class PaperSize { public int Width { get; } public int Height { get; } public PaperSize(int width, int height) { Width = width; Height = height; } } } } 1、插入的图框内框上方改为不显示如“1189x841”和比例1:100 2、标题栏列宽和表格样式修改如下: 下面按A4方向横向插入为例尺寸: 从右向左第1列宽2500mm;第二列宽2000mm;第三列宽4500mm;第四列宽2000mm;第五列宽2500mm;第六列宽2000mm;第七列宽2500mm;第八列宽2000mm;“标题栏”列宽与行高统一1000mm始终不变,“标题栏”随插入的图框大小尺寸自动缩放“标题栏”,“标题栏”顶第一根线宽与内框同线宽, 3、“标题栏”必须自动生成为可编辑的属性,能够双击后弹窗显示“标题栏”属性编辑窗口;窗口布局如下: 第一行:“属性”按钮;“文字选项”按钮 第二行“属性”按钮后:输入框;输入框内分为三列:左列表头“标记”向右第二列表头“提示”,向右第三列表头“值”(标记与提示是“标题栏”已有的名称,“值”列为输入单元格),举例: 标记 提示 值 制图制图人 张三 图纸名称 图纸名称 一层平面布置图 第二行“文字选项”按钮后:文字样式:可输可选框;字体大小:可输可选框; 第三行:确认 取消
最新发布
10-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值