| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993 |
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.EditorInput;
- using Autodesk.AutoCAD.Geometry;
- using GeoAPI.Geometries;
- using NetTopologySuite.Geometries;
- using NetTopologySuite.Operation.Linemerge;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
-
- namespace CADTools
- {
- public partial class JQXLabel_grid : Form
- {
- public JQXLabel_grid()
- {
- InitializeComponent();
- }
-
- public class PointPolylinePair
- {
- public Point3d Point { get; set; }
- public Polyline Polyline { get; set; }
- public double curvature { get; set; }
- }
-
- int nodirection = 0;
- private void JQXLabel_grid_Load(object sender, EventArgs e)
- {
- //自动填充下拉框
- Database database = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices.WorkingDatabase;
- using (Transaction traction = database.TransactionManager.StartTransaction())
- {
- //存放所有图层名
- List<string> alllayername = new List<string>();
- LayerTable layertable = traction.GetObject(database.LayerTableId, OpenMode.ForRead) as LayerTable;
- foreach (ObjectId objid in layertable)
- {
- LayerTableRecord layertablerecord = traction.GetObject(objid, OpenMode.ForRead) as LayerTableRecord;
- alllayername.Add(layertablerecord.Name);
- }
-
- alllayername.Sort();
- for (int i = 0; i < alllayername.Count; i++)
- {
- this.comboBox_jqx.Items.Add(alllayername[i]);
- this.comboBox_sqx.Items.Add(alllayername[i]);
- this.comboBox_bz.Items.Add(alllayername[i]);
- this.comboBox_tk.Items.Add(alllayername[i]);
- }
- if (alllayername.Contains("8120"))
- {
- int index = alllayername.IndexOf("8120");
- this.comboBox_jqx.SelectedIndex = index;
- }
- if (alllayername.Contains("8110"))
- {
- int index = alllayername.IndexOf("8110");
- this.comboBox_sqx.SelectedIndex = index;
- }
- if (alllayername.Contains("tk") || alllayername.Contains("TK"))
- {
- if (alllayername.Contains("tk"))
- {
- int index = alllayername.IndexOf("tk");
- this.comboBox_tk.SelectedIndex = index;
- }
- else
- {
- int index = alllayername.IndexOf("TK");
- this.comboBox_tk.SelectedIndex = index;
- }
- }
- traction.Commit();
- }
- this.textBox_decimal.Text = "0";
- }
-
- private void button_ok_Click(object sender, EventArgs e)
- {
- if (comboBox_jqx.Text == "")
- {
- MessageBox.Show("计曲线图层不能为空!");
- return;
- }
- if (comboBox_sqx.Text == "")
- {
- MessageBox.Show("首曲线图层不能为空!");
- return;
- }
- if (comboBox_tk.Text == "")
- {
- MessageBox.Show("图框图层不能为空!");
- return;
- }
- if (comboBox_blc.Text == "")
- {
- MessageBox.Show("比例尺不能为空!");
- return;
- }
- if (comboBox_bz.Text == "")
- {
- MessageBox.Show("等高线标注图层不能为空!");
- return;
- }
- jqxLabelbyGrid();
- MessageBox.Show("标注完成。\n有" + nodirection.ToString() + "处无法确定方向,移动到“无法确定方向”图层");
- this.Close();
- }
-
- private void jqxLabelbyGrid()
- {
- //计曲线
- string jqx = comboBox_jqx.Text;
- //图框
- string tk = comboBox_tk.Text;
- //比例尺
- string blctext = comboBox_blc.Text;
- int blcindex = blctext.LastIndexOf(':');
- string strblc = blctext.Substring(blcindex + 1);
- int blc = Convert.ToInt32(strblc);
- //图框顶点列表
- List<Polyline> tks = new List<Polyline>();
-
- Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
- Database db = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices.WorkingDatabase;
- //获取所有图框,记录图框的最大点和最小点
- TypedValue[] typedvalue = new TypedValue[2];
- typedvalue.SetValue(new TypedValue((int)DxfCode.LayerName, tk), 0);
- typedvalue.SetValue(new TypedValue((int)DxfCode.Start, "LWPOLYLINE"), 1);
- SelectionFilter selectionfilter = new SelectionFilter(typedvalue);
- PromptSelectionResult psr = ed.SelectAll(selectionfilter);
- if (psr.Status == PromptStatus.OK)
- {
- SelectionSet ss = psr.Value;
- ObjectId[] tkids = ss.GetObjectIds();
- for (int i = 0; i < tkids.Length; i++)
- {
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- Polyline pl = tr.GetObject(tkids[i], OpenMode.ForRead) as Polyline;
- tks.Add(pl);
- tr.Commit();
- }
- }
- }
- else
- {
- MessageBox.Show("未找到图框!");
- return;
- }
-
- //创建标记字体
- CreateSheetMap cs = new CreateSheetMap();
- cs.createTextStyle();
- ObjectId HZ = cs.gettextstyleID("HZ");
- //遍历图框顶点列表,按顶点范围搜索等高线
- for (int i = 0; i < tks.Count; i++)
- {
- ZoomView(ed, tks[i].Bounds.Value.MinPoint, tks[i].Bounds.Value.MaxPoint);
- List<Polyline> pllist = new List<Polyline>();
- TypedValue[] typedvalue_pl = new TypedValue[2];
- typedvalue_pl.SetValue(new TypedValue((int)DxfCode.LayerName, jqx), 0);
- typedvalue_pl.SetValue(new TypedValue((int)DxfCode.Start, "LWPOLYLINE"), 1);
- SelectionFilter selectionfilter_pl = new SelectionFilter(typedvalue_pl);
- PromptSelectionResult psr_pl = ed.SelectCrossingWindow(tks[i].Bounds.Value.MinPoint, tks[i].Bounds.Value.MaxPoint, selectionfilter_pl);
- if (psr_pl.Status == PromptStatus.OK)
- {
- SelectionSet ss = psr_pl.Value;
- ObjectId[] plids = ss.GetObjectIds();
-
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- for (int ii = 0; ii < plids.Length; ii++)
- {
- Polyline pl = tr.GetObject(plids[ii], OpenMode.ForRead) as Polyline;
- if (IsPolylineInsideOrIntersecting(pl, tks[i].Bounds.Value.MinPoint, tks[i].Bounds.Value.MaxPoint))
- {
- pllist.Add(pl);
- }
- }
- tr.Commit();
- }
-
- //绘制图框
- double x = (tks[i].Bounds.Value.MinPoint.X + tks[i].Bounds.Value.MaxPoint.X) / 2;
- double y = (tks[i].Bounds.Value.MinPoint.Y + tks[i].Bounds.Value.MaxPoint.Y) / 2;
- Point3d centralpt = new Point3d(x, y, 0);
- if (pllist.Count > 0)
- {
- //var result = getPll(pllist, tk1, centralpt);
- var target = getPosition(pllist, tks[i], centralpt);
- makeMark(target, db, blc, centralpt, HZ);
- pllist.Clear();
- }
- }
- }
- }
-
- private PointPolylinePair getPosition(List<Polyline> pllist, Polyline tk, Point3d central)
- {
- List<PointPolylinePair> ptpllist = new List<PointPolylinePair>();
- List<PointPolylinePair> ptpllist1 = new List<PointPolylinePair>();
- List<Polyline> plinsidetk = new List<Polyline>();
- Polyline labelpll = new Polyline();
- int index = 0;
- // 找到距离中心点最近的等高线
- var pllist_sorted = pllist.OrderBy(c => c.GetClosestPointTo(new Point3d(central.X, central.Y, c.Elevation), new Vector3d(0, 0, 1), false)
- .DistanceTo(new Point3d(central.X, central.Y, c.Elevation))).ToList();
- while (ptpllist1.Count == 0)
- {
- labelpll = pllist_sorted[index];
- plinsidetk = GetPolylineInsideFrame(labelpll, tk);
- ptpllist1.Clear();
-
- for (int i = 0; i < plinsidetk.Count; i++)
- {
- Polyline pl_temp = plinsidetk[i];
-
- // 获取顶点数量
- int vertexCount = pl_temp.NumberOfVertices;
-
- // 每5个点取一个点
- int step = 5;
- int sampleCount = Math.Max(1, vertexCount / step);
-
- // 存储连续平缓点的索引
- List<int> consecutiveFlatIndices = new List<int>();
-
- for (int j = 1; j <= sampleCount; j++)
- {
- // 计算顶点索引
- int vertexIndex = Math.Min(j * step, vertexCount - 1);
- double curvature = GetCurvatureAtVertex(pl_temp, vertexIndex, step);
- // 检查是否为平缓点
- if (curvature <= 0.05)
- {
- consecutiveFlatIndices.Add(vertexIndex);
-
- // 检查是否有连续10个平缓点
- if (consecutiveFlatIndices.Count >= 2)
- {
- // 使用弦高差法验证是否整体平缓
- bool isOverallFlat = ValidateFlatRegionByChordHeight(pl_temp, consecutiveFlatIndices);
-
- if (isOverallFlat)
- {
- // 取中间点
- int middleIndex = consecutiveFlatIndices[consecutiveFlatIndices.Count / 2];
- Point3d middlePoint = pl_temp.GetPoint3dAt(middleIndex);
-
- PointPolylinePair pair = new PointPolylinePair();
- pair.Point = middlePoint;
- pair.Polyline = pllist_sorted[index];
- pair.curvature = curvature;
- ptpllist.Add(pair);
-
- // 清空连续记录,避免重复添加
- consecutiveFlatIndices.Clear();
- }
- else
- {
- // 如果不平缓,清空并继续,避免从这个区域继续累积
- consecutiveFlatIndices.Clear();
- }
- }
- }
- else
- {
- // 遇到非平缓点,重置连续计数
- consecutiveFlatIndices.Clear();
- }
- }
- }
-
- // 筛选长度大于15的等高线对应的点
- ptpllist1 = ptpllist.Where(p => p.Polyline.Length > 15).ToList();
- index++;
- if (index == pllist_sorted.Count) break;
- }
- PointPolylinePair target = new PointPolylinePair();
-
- // 处理 ptpllist1 和 ptpllist 为空的情况
- if (ptpllist1.Count == 0)
- {
- // 如果 ptpllist 不为空,按曲率排序取最小的
- if (ptpllist.Count > 0)
- {
- target = ptpllist.OrderBy(p => p.curvature).First();
- }
- else
- {
- // 如果 ptpllist 也为空,获取离中心点最近点
- var pl_label = pllist.OrderBy(c => c.GetClosestPointTo(new Point3d(central.X, central.Y, c.Elevation), new Vector3d(0, 0, 1), false)
- .DistanceTo(new Point3d(central.X, central.Y, c.Elevation))).First();
- PointPolylinePair pair = new PointPolylinePair();
- pair.Point = pl_label.GetClosestPointTo(central, new Vector3d(0, 0, 1), false);
- pair.Polyline = pl_label;
- pair.curvature = 0;
- target = pair;
- }
- }
- else if (ptpllist1.Count > 0)
- {
- target = ptpllist1.OrderBy(p => p.Point.DistanceTo(central)).First();
- }
- else
- {
- // ptpllist1 为空但还有等高线未处理,返回最接近中心的点
- target = ptpllist.OrderBy(p => p.Point.DistanceTo(central)).FirstOrDefault();
- }
-
- return target;
- }
-
- #region
- //private Polyline mergePl(List<Polyline> plllist, Polyline tk)
- //{
- // List<Polyline> interse = new List<Polyline>();
- // List<Polyline> result = new List<Polyline>(plllist);
- // for (int i = 0; i < plllist.Count - 1; i++)
- // {
- // Point3d start1 = plllist[i].GetPoint3dAt(0);
- // Point3d end1 = plllist[i].GetPoint3dAt(plllist[i].NumberOfVertices - 1);
- // for (int j = i + 1; j < plllist.Count; j++)
- // {
- // Point3d start2 = plllist[j].GetPoint3dAt(0);
- // Point3d end2 = plllist[j].GetPoint3dAt(plllist[j].NumberOfVertices - 1);
- // if (start1 == start2 || start1 == end2 || end1 == start2 || end1 == end2)
- // {
- // interse.Add(plllist[i]);
- // interse.Add(plllist[j]);
- // if (result.Contains(plllist[i])) result.Remove(plllist[i]);
- // if (result.Contains(plllist[j])) result.Remove(plllist[j]);
- // }
- // }
- // }
- // if (interse.Count > 0)
- // {
- // // 转换为NTS线串
- // var lineStrings = new List<Geometry>();
- // foreach (var pl in interse)
- // {
- // var lineString1 = ConvertPolylineToNtsGeometry(pl);
- // lineStrings.Add(lineString1);
- // }
- // // 使用线合并器
- // var merger = new LineMerger();
- // merger.Add(lineStrings);
-
- // // 获取合并结果
- // var mergedCollection = merger.GetMergedLineStrings();
-
- // // 转换回AutoCAD多段线
- // foreach (var geometry in mergedCollection)
- // {
- // if (geometry is LineString mergedLineString)
- // {
- // var mergedPolyline = ConvertNtsLineStringToPolyline(mergedLineString);
- // if (mergedPolyline != null)
- // {
- // mergedPolyline.Elevation = plllist[0].Elevation;
- // result.Add(mergedPolyline);
- // }
- // }
- // }
- // }
- // var plinside = new List<Polyline>();
- // foreach (var item in result)
- // {
- // var pls = GetPolylineInsideFrame(item, tk);
- // foreach (var l in pls)
- // {
- // plinside.Add(l);
- // }
- // }
- // return plinside.OrderByDescending(g => g.Length).First();
- //}
- #endregion
-
- private double GetCurvatureAtVertex(Polyline pl, int vertexIndex, int step)
- {
- int vertexCount = pl.NumberOfVertices;
-
- // 获取前一个顶点
- int prevIndex = Math.Max(0, vertexIndex - step);
- Point3d p0 = pl.GetPoint3dAt(prevIndex);
-
- // 获取当前顶点
- Point3d p1 = pl.GetPoint3dAt(vertexIndex);
-
- // 获取后一个顶点
- int nextIndex = Math.Min(vertexCount - 1, vertexIndex + step);
- Point3d p2 = pl.GetPoint3dAt(nextIndex);
-
- // 计算向量
- Vector3d v1 = p1 - p0;
- Vector3d v2 = p2 - p1;
-
- double v1Len = v1.Length;
- double v2Len = v2.Length;
-
- // 计算曲率
- double curvature = 0;
- if (v1Len > 1e-6 && v2Len > 1e-6)
- {
- // 计算方向变化角度
- double cosAngle = v1.DotProduct(v2) / (v1Len * v2Len);
- cosAngle = Math.Max(-1, Math.Min(1, cosAngle));
- double angle = Math.Acos(cosAngle);
-
- // 计算弧长
- double arcLength = v1Len + v2Len;
-
- // 曲率 = 角度变化 / 弧长
- curvature = angle / arcLength;
- }
-
- return curvature;
- }
-
- /// <summary>
- /// 通过弦高差(中间点到首尾点连线的距离)验证区域是否平缓
- /// </summary>
- private bool ValidateFlatRegionByChordHeight(Polyline pl, List<int> sampledIndices)
- {
- // 获取首尾顶点索引(使用采样点的首尾)
- int startVertex = sampledIndices[0];
- int endVertex = sampledIndices[sampledIndices.Count - 1];
-
- // 获取首尾点坐标
- Point3d startPoint = pl.GetPoint3dAt(startVertex);
- Point3d endPoint = pl.GetPoint3dAt(endVertex);
-
- // 计算弦长
- Vector3d chordVector = endPoint - startPoint;
- double chordLength = chordVector.Length;
-
- if (chordLength < 1e-6) return false;
-
- // 检查从 startVertex 到 endVertex 之间的所有顶点
- double maxDistance = 0;
- int totalPoints = 0;
- double sumDistance = 0;
-
- for (int i = startVertex; i <= endVertex; i++)
- {
- Point3d point = pl.GetPoint3dAt(i);
- double distance = PointToLineDistance(point, startPoint, endPoint);
-
- maxDistance = Math.Max(maxDistance, distance);
- sumDistance += distance;
- totalPoints++;
-
- // 早期退出:如果任何点距离超过阈值,直接返回false
- if (maxDistance > 0.5)
- {
- return false;
- }
- }
-
- // 判断条件:最大距离和平均距离都满足要求
- bool isFlat = maxDistance <= 0.5;
-
- return isFlat;
- }
-
- /// <summary>
- /// 计算点到线段的距离
- /// </summary>
- private double PointToLineDistance(Point3d point, Point3d lineStart, Point3d lineEnd)
- {
- Vector3d lineVector = lineEnd - lineStart;
- Vector3d pointVector = point - lineStart;
-
- double lineLengthSq = lineVector.DotProduct(lineVector);
- if (lineLengthSq < 1e-6) return pointVector.Length;
-
- // 计算投影参数 t
- double t = pointVector.DotProduct(lineVector) / lineLengthSq;
-
- // 找到线段上的最近点
- Point3d closestPoint;
- if (t < 0)
- closestPoint = lineStart;
- else if (t > 1)
- closestPoint = lineEnd;
- else
- closestPoint = lineStart + lineVector * t;
-
- return point.DistanceTo(closestPoint);
- }
-
- private void makeMark(PointPolylinePair pair, Database db, int blc, Point3d central, ObjectId HZ)
- //private void makeMark(Polyline pll, Database db, int blc, Point3d central, ObjectId HZ)
- {
- Polyline pll = pair.Polyline;
- Point3d label_pos = pair.Point;
- Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
- Polyline labelpll = (Polyline)pll.Clone();
-
- //Point3d label_pos = labelpll.GetClosestPointTo(central, new Vector3d(0, 0, 1), false);
- if (labelpll.StartPoint.X > labelpll.EndPoint.X)
- labelpll.ReverseCurve();
- //计算放置注记处的方向
- Vector3d tangent = labelpll.GetFirstDerivative(labelpll.GetParameterAtPoint(label_pos));
- double angle = tangent.GetAngleTo(Vector3d.XAxis);
- //调整角度范围(0到2Π)
- if (tangent.Y < 0)
- angle = 2 * Math.PI - angle;
- //法线向量
- Vector3d normal = new Vector3d(-tangent.Y, tangent.X, 0);
- //单位化
- normal = normal.GetNormal();
-
- List<Polyline> pllist = new List<Polyline>();
- var angle1 = angle;
- var angle2 = angle + Math.PI;
- int trans_index1 = 0;
- int trans_index2 = 0;
- //以标注所在位置点为基点做基于该点的法线射线进行搜索(正向搜索)
- Point3d startPoint = label_pos;
- Point3d endPoint = label_pos + normal * 200;
- Point3dCollection ptcoll = new Point3dCollection() { startPoint, endPoint };
- List<Point3d> intersepts_y = new List<Point3d>();
- Line l = new Line(startPoint, endPoint);
- ZoomView(ed, startPoint, endPoint);
- TypedValue[] typedvalue_pl = new TypedValue[2];
- typedvalue_pl.SetValue(new TypedValue((int)DxfCode.LayerName, comboBox_jqx.Text + "," + comboBox_sqx.Text), 0);
- typedvalue_pl.SetValue(new TypedValue((int)DxfCode.Start, "LWPOLYLINE"), 1);
- SelectionFilter selectionfilter_pl = new SelectionFilter(typedvalue_pl);
- PromptSelectionResult psr_pl = ed.SelectFence(ptcoll, selectionfilter_pl);
- if (psr_pl.Status == PromptStatus.OK)
- {
- SelectionSet ss = psr_pl.Value;
- ObjectId[] plids = ss.GetObjectIds();
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- for (int ii = 0; ii < plids.Length; ii++)
- {
- Polyline dgx = tr.GetObject(plids[ii], OpenMode.ForRead) as Polyline;
- if (dgx.Elevation == pll.Elevation && dgx.Length - labelpll.Length < 0.0001 &&
- (dgx.StartPoint == labelpll.EndPoint || dgx.StartPoint == labelpll.StartPoint))
- {
- intersepts_y = GetIntersections(dgx, l);
- continue;
- }
- pllist.Add(dgx);
- }
- tr.Commit();
- }
- if (pllist.Count != 0)
- trans_index1 = Iftransdirection(pllist, label_pos, intersepts_y, l);
- }
- //反向搜索
- if (trans_index1 != 1)
- {
- intersepts_y = new List<Point3d>();
- endPoint = label_pos - normal * 200;
- ptcoll = new Point3dCollection() { startPoint, endPoint };
- ZoomView(ed, startPoint, endPoint);
- PromptSelectionResult psr_pl1 = ed.SelectFence(ptcoll, selectionfilter_pl);
- if (psr_pl1.Status == PromptStatus.OK)
- {
- SelectionSet ss = psr_pl1.Value;
- ObjectId[] plids = ss.GetObjectIds();
- l = new Line(startPoint, endPoint);
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- for (int ii = 0; ii < plids.Length; ii++)
- {
- Polyline dgx = tr.GetObject(plids[ii], OpenMode.ForRead) as Polyline;
- if (dgx.Elevation == pll.Elevation && dgx.Length - labelpll.Length < 0.0001 &&
- (dgx.StartPoint == labelpll.EndPoint || dgx.StartPoint == labelpll.StartPoint))
- {
- intersepts_y = GetIntersections(dgx, l);
- continue;
- }
- pllist.Add(dgx);
- }
- tr.Commit();
- }
- if (pllist.Count != 0)
- trans_index2 = Iftransdirection(pllist, label_pos, intersepts_y, l);
- }
- }
- if (trans_index1 != 0 || trans_index2 != 0)
- {
- if (trans_index1 == 0 && trans_index2 == 1 || trans_index1 == -1 && trans_index2 == 0||
- trans_index1 == -1 && trans_index2 == 1) angle = angle2;
- //1:2000字高4,以此为基础计算其他比例尺的字高
- double labelheight = 4;
- if (blc == 500)
- labelheight = labelheight * ((double)500 / 2000);
- if (blc == 1000)
- labelheight = labelheight * ((double)1000 / 2000);
- if (blc == 5000)
- labelheight = labelheight * ((double)5000 / 2000);
- if (blc == 10000)
- labelheight = labelheight * ((double)10000 / 2000);
- string ele = labelpll.Elevation.ToString("F" + textBox_decimal.Text);
- using (DocumentLock doclock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
- {
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
- BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
- DBText ele_txt = new DBText();
- ele_txt.Height = labelheight;
- ele_txt.TextString = ele;
- ele_txt.TextStyleId = HZ;
- ele_txt.HorizontalMode = TextHorizontalMode.TextMid;
- ele_txt.Position = label_pos;
- ele_txt.AlignmentPoint = label_pos;
- ele_txt.Rotation = angle;
- ele_txt.Layer = comboBox_bz.Text;
- ele_txt.WidthFactor = 0.75;
- btr.AppendEntity(ele_txt);
- tr.AddNewlyCreatedDBObject(ele_txt, true);
- tr.Commit();
- }
- }
- }
- else
- {
- nodirection = nodirection + 1;
- LayerControl layerscontrol = new LayerControl();
- string layname = "无法判断方向";
- if (layerscontrol.haslayername(layname) == false)
- {
- colorgb col = new colorgb(255, 0, 0);
- layerscontrol.creatlayer(layname, col);
- }
- //1:2000字高4,以此为基础计算其他比例尺的字高
- double labelheight = 4;
- if (blc == 500)
- labelheight = labelheight * ((double)500 / 2000);
- if (blc == 1000)
- labelheight = labelheight * ((double)1000 / 2000);
- if (blc == 5000)
- labelheight = labelheight * ((double)5000 / 2000);
- if (blc == 10000)
- labelheight = labelheight * ((double)10000 / 2000);
-
- string ele = labelpll.Elevation.ToString("F" + textBox_decimal.Text);
- using (DocumentLock doclock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())
- {
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
- BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
- DBText ele_txt = new DBText();
- ele_txt.Height = labelheight;
- ele_txt.TextString = ele;
- ele_txt.TextStyleId = HZ;
- ele_txt.HorizontalMode = TextHorizontalMode.TextMid;
- ele_txt.Position = label_pos;
- ele_txt.AlignmentPoint = label_pos;
- ele_txt.Rotation = angle;
- ele_txt.Layer = "无法判断方向";
- ele_txt.WidthFactor = 0.75;
- btr.AppendEntity(ele_txt);
- tr.AddNewlyCreatedDBObject(ele_txt, true);
- tr.Commit();
- }
- }
- }
- pllist.Clear();
- psr_pl = null;
- #region
- //Polyline templine = pllist[0].Clone() as Polyline;
-
- //// 计算平移向量(以图框起点为基准,移动至原点)
- //Vector3d translation = -tk.StartPoint.GetAsVector();
- //Matrix3d translateMatrix = Matrix3d.Displacement(translation);
- //// 应用平移变换
- //tk.TransformBy(translateMatrix);
- //templine.TransformBy(translateMatrix);
-
- //Point3dCollection translatedPoints = new Point3dCollection();
- //var plane = new Plane(Point3d.Origin, Vector3d.ZAxis);
- //tk.IntersectWith(templine, Intersect.OnBothOperands, plane, translatedPoints, IntPtr.Zero, IntPtr.Zero);
-
- //// 计算逆平移矩阵
- //Matrix3d inverseMatrix = Matrix3d.Displacement(-translation);
- //if (translatedPoints.Count > 0)
- //{
- // // 获取平移后的交点
- // foreach (Point3d item in translatedPoints)
- // {
- // // 恢复交点坐标
- // var pt = item.TransformBy(inverseMatrix);
-
- // }
- //}
- #endregion
- }
-
-
- /// <summary>
- /// 获取多段线在图框内部的线段部分
- /// </summary>
- public static List<Polyline> GetPolylineInsideFrame(Polyline sourcePolyline, Polyline framePolygon)
- {
- var insidePolylines = new List<Polyline>();
-
- // 转换图框为NTS多边形
- var ntsFrame = ConvertPolylineToNtsPolygon(framePolygon);
-
- // 转换源多段线为NTS几何对象
- var ntsSource = ConvertPolylineToNtsGeometry(sourcePolyline);
-
- // 计算交集(图框 ∩ 多段线)
- var intersection = ntsFrame.Intersection(ntsSource);
-
- // 处理交集结果
- if (intersection != null && !intersection.IsEmpty)
- {
- if (intersection is LineString lineString)
- {
- // 单个线串
- var polyline = ConvertNtsLineStringToPolyline(lineString);
- polyline.Elevation = sourcePolyline.Elevation;
- insidePolylines.Add(polyline);
- }
- else if (intersection is MultiLineString multiLineString)
- {
- // 多个线串(多段线被分割成多段)
- for (int i = 0; i < multiLineString.NumGeometries; i++)
- {
- LineString segment = multiLineString.GetGeometryN(i) as LineString;
- var polyline = ConvertNtsLineStringToPolyline(segment);
- polyline.Elevation = sourcePolyline.Elevation;
- insidePolylines.Add(polyline);
- }
- }
- //else if (intersection is GeometryCollection collection)
- //{
- // // 几何集合
- // for (int i = 0; i < collection.NumGeometries; i++)
- // {
- // LineString segment = collection.GetGeometryN(i) as LineString;
- // var polyline = ConvertNtsLineStringToPolyline(segment);
- // polyline.Elevation = sourcePolyline.Elevation;
- // insidePolylines.Add(polyline);
- // }
- //}
- }
-
- ntsFrame = null;
- ntsSource = null;
- return insidePolylines;
- }
-
- /// <summary>
- /// 将AutoCAD多段线转换为NTS多边形
- /// </summary>
- private static Polygon ConvertPolylineToNtsPolygon(Polyline polyline)
- {
- var coordinates = new List<Coordinate>();
-
- for (int i = 0; i < polyline.NumberOfVertices; i++)
- {
- Point3d point = polyline.GetPoint3dAt(i);
- coordinates.Add(new Coordinate(point.X, point.Y));
- }
-
- // 闭合多边形
- if (polyline.Closed == true && coordinates[0] != coordinates[coordinates.Count - 1])
- coordinates.Add(new Coordinate(coordinates[0].X, coordinates[0].Y));
-
- var geometryFactory = new GeometryFactory();
- return (Polygon)geometryFactory.CreatePolygon(coordinates.ToArray());
- }
-
- /// <summary>
- /// 将AutoCAD多段线转换为NTS几何对象
- /// </summary>
- private static Geometry ConvertPolylineToNtsGeometry(Polyline polyline)
- {
- var coordinates = new List<Coordinate>();
-
- for (int i = 0; i < polyline.NumberOfVertices; i++)
- {
- Point3d point = polyline.GetPoint3dAt(i);
- coordinates.Add(new Coordinate(point.X, point.Y));
- }
-
- var geometryFactory = new GeometryFactory();
- return (LineString)geometryFactory.CreateLineString(coordinates.ToArray());
- }
-
- /// <summary>
- /// 将NTS线串转换回AutoCAD多段线
- /// </summary>
- private static Polyline ConvertNtsLineStringToPolyline(LineString lineString)
- {
- if (lineString == null || lineString.IsEmpty || lineString.NumPoints < 2)
- return null;
-
- var polyline = new Polyline();
- var coordinates = lineString.Coordinates;
-
- for (int i = 0; i < coordinates.Length; i++)
- {
- polyline.AddVertexAt(i, new Point2d(coordinates[i].X, coordinates[i].Y), 0, 0, 0);
- }
-
-
- return polyline;
- }
-
- // 检查多段线是否有部分在框内
- private bool IsPolylineInsideOrIntersecting(Polyline pl, Point3d minPoint, Point3d maxPoint)
- {
- // 方法1:检查是否有顶点在框内
- for (int j = 0; j < pl.NumberOfVertices; j++)
- {
- Point3d vertex = pl.GetPoint3dAt(j);
- if (IsPointInside(vertex, minPoint, maxPoint))
- return true; // 有顶点在框内,说明线有部分在框内
- }
-
- // 方法2:检查线的包围盒是否与选择框相交
- Extents3d plExtents = pl.GeometricExtents;
- if (plExtents.MinPoint.X <= maxPoint.X && plExtents.MaxPoint.X >= minPoint.X &&
- plExtents.MinPoint.Y <= maxPoint.Y && plExtents.MaxPoint.Y >= minPoint.Y)
- {
- // 包围盒相交,进一步检查线段
- return true;
- }
-
- return false;
- }
-
- // 检查点是否在矩形内(不包括边界)
- private bool IsPointInside(Point3d point, Point3d minPoint, Point3d maxPoint)
- {
- return point.X > minPoint.X && point.X < maxPoint.X &&
- point.Y > minPoint.Y && point.Y < maxPoint.Y;
- }
-
- // 检查点是否在矩形内或边界上
- private bool IsPointInsideOrOnBoundary(Point3d point, Point3d minPoint, Point3d maxPoint)
- {
- return point.X >= minPoint.X && point.X <= maxPoint.X &&
- point.Y >= minPoint.Y && point.Y <= maxPoint.Y;
- }
-
- private List<Point3d> GetIntersections(Polyline pll, Line line)
- {
- List<Point3d> result = new List<Point3d>();
- // 创建临时副本
- Polyline tempLine1 = (Polyline)pll.Clone();
- Point3d p1 = new Point3d(line.StartPoint.X, line.StartPoint.Y, pll.Elevation);
- Point3d p2 = new Point3d(line.EndPoint.X, line.EndPoint.Y, pll.Elevation);
- Line tempLine2 = new Line(p1, p2);
-
- // 计算平移向量(以线1起点为基准,移动至原点)
- Vector3d translation = -tempLine1.StartPoint.GetAsVector();
- Matrix3d translateMatrix = Matrix3d.Displacement(translation);
-
- // 应用平移变换
- tempLine1.TransformBy(translateMatrix);
- tempLine2.TransformBy(translateMatrix);
-
- Point3dCollection translatedPoints = new Point3dCollection();
- var plane = new Plane(Point3d.Origin, Vector3d.ZAxis);
- tempLine1.IntersectWith(tempLine2, Intersect.OnBothOperands, plane, translatedPoints, IntPtr.Zero, IntPtr.Zero);
-
- // 计算逆平移矩阵
- Matrix3d inverseMatrix = Matrix3d.Displacement(-translation);
- if (translatedPoints.Count > 0)
- {
- // 获取平移后的交点
- foreach (Point3d item in translatedPoints)
- {
- // 恢复交点坐标
- var pt = item.TransformBy(inverseMatrix);
- result.Add(pt);
- }
- }
- return result;
- }
-
-
- /// <summary>
- /// 计算点到线段的距离
- /// <returns>-1表示反向,1表示同向,0表示不确定</returns>
- /// </summary>
- int Iftransdirection(List<Polyline> pllist,Point3d label_pos, List<Point3d> intersepts_y,Line l)
- {
- Polyline closest = null;
- double minDistance = double.MaxValue;
- List<Point3d> intersepts_l = new List<Point3d>();
- foreach (Polyline dgx in pllist)
- {
- Polyline dgx_copy = dgx;
- var pts = GetIntersections(dgx_copy, l);
- // 计算距离
- if (pts.Count != 0)
- {
- foreach (Point3d item in pts)
- {
- // 避免创建新的Point3d对象
- double distance = Math.Sqrt(
- Math.Pow(item.X - label_pos.X, 2) +
- Math.Pow(item.Y - label_pos.Y, 2)
- );
-
- if (distance < minDistance)
- {
- minDistance = distance;
- closest = dgx;
- intersepts_l = pts;
- }
- }
- }
- }
- int count_intersepts_y = intersepts_y.Count;
- intersepts_y.AddRange(intersepts_l);
- var points = intersepts_y.OrderBy(p => Math.Sqrt(Math.Pow(l.StartPoint.X - p.X, 2) + Math.Pow(l.StartPoint.Y - p.Y, 2))).ToList();
- if (count_intersepts_y == 1&& intersepts_l.Count!=0&&Math.Abs(closest.Elevation-label_pos.Z)>0.001)
- {
- if (closest.Elevation > label_pos.Z) return 1;
- else if (closest.Elevation < label_pos.Z) return -1;
- }
- else if (intersepts_l.Count > 0 && intersepts_y.Count > 2 && Math.Abs(closest.Elevation - label_pos.Z) > 0.001)
- {
- double x = closest.Elevation;
- double y = label_pos.Z;
- // 找到第一个高程为y的点的索引
- int firstIndex = -1;
- for (int i = 0; i < points.Count; i++)
- {
- if (Math.Abs(points[i].Z - y) < 1e-6)
- {
- firstIndex = i;
- break;
- }
- }
- if (firstIndex == -1) return 0;
-
- // 找到第二个高程为y的点的索引
- int secondIndex = -1;
- for (int i = firstIndex + 1; i < points.Count; i++)
- {
- if (Math.Abs(points[i].Z - y) < 1e-6)
- {
- secondIndex = i;
- break;
- }
- }
- if (secondIndex == -1) return 0;
- bool haspt = false;
- // 检查两个索引之间是否存在高程为x的点
- for (int i = firstIndex + 1; i < secondIndex; i++)
- {
- if (Math.Abs(points[i].Z - x) < 1e-6)
- haspt = true;
- }
- if (haspt && closest.Elevation > label_pos.Z) return 1;
- else if (haspt && closest.Elevation < label_pos.Z) return -1;
- else if (!haspt) return 0;
- }
-
- return 0;
- }
-
- private void ZoomView(Editor edit, Point3d pt1, Point3d pt2)
- {
- var x_min = Math.Min(pt1.X, pt2.X);
- var y_min = Math.Min(pt1.Y, pt2.Y);
- using (ViewTableRecord currview1 = edit.GetCurrentView())
- {
- currview1.CenterPoint = new Point2d(Math.Abs((pt2.X - pt1.X) / 2) + x_min,
- Math.Abs((pt2.Y - pt1.Y) / 2) + y_min);
- currview1.Width = Math.Abs(pt2.X - pt1.X)+ 10;
- currview1.Height = Math.Abs(pt2.Y - pt1.Y) + 10;
- edit.SetCurrentView(currview1);
- }
- edit.UpdateScreen();
- }
- }
- }
|