using Clipper2Lib; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DeepNestLib { public class DfdParser { public DfdParser() { } public static HashSet ExportPlacements(IEnumerable polygons, IEnumerable sheets , double offsetX = 0, double offsetY = 0, Func fun = null) { List> lstWell = new List>(); foreach (var item in polygons) { if (!sheets.Contains(item)) { if (!item.fitted) continue; } var m = new Matrix(); m.Translate((float)(item.x + offsetX), (float)(item.y + offsetY)); m.Rotate(item.rotation); PointF[] pp = null; int nLayerType = 0; // 写出井支 if (item.Name != null) { if (item.Name.Equals("双侧")) { pp = fun?.Invoke(item, 0); nLayerType = 0; } else if (item.Name.Equals("单侧")) { pp = fun?.Invoke(item, 1); nLayerType = 1; } } else { pp = item.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray(); } m.TransformPoints(pp); lstWell.Add(new KeyValuePair(nLayerType, pp)); } // 剔除重复的井位 HashSet removed = FindDuplicate(lstWell); return removed; } public static HashSet Export(string path, IEnumerable polygons, IEnumerable sheets , double offsetX = 0, double offsetY = 0, Func fun=null) { List> lstBorder = new List>(); List> lstWell = new List>(); int nFirstBorder = 0; foreach(var item in sheets) { var m = new Matrix(); m.Translate((float)(item.x + offsetX), (float)(item.y + offsetY)); m.Rotate(item.rotation); PointF[] pp = item.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray(); int nLayerType = 2; if (nFirstBorder == 0) // 边界 { nLayerType = 3; } else { pp = fun?.Invoke(item, 2); } m.TransformPoints(pp); lstBorder.Add(new KeyValuePair(nLayerType, pp)); nFirstBorder++; if (item.children != null) { foreach (var child in item.children) { //if (nLayerType == 3) // 边界 //{ pp = fun?.Invoke(child, 2); // 断层 // nLayerType = 2; //} //else //{ // pp = child.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray(); //} m.TransformPoints(pp); lstBorder.Add(new KeyValuePair(nLayerType, pp)); } } } foreach (var item in polygons)//.Union(sheets) { if (!sheets.Contains(item)) { if (!item.fitted) continue; } var m = new Matrix(); m.Translate((float)(item.x + offsetX), (float)(item.y+ offsetY)); m.Rotate(item.rotation); PointF[] pp = null; int nLayerType = 0; // 写出井支 if (item.Name != null) { if (item.Name.Equals("双侧")) { pp = fun?.Invoke(item, 0); nLayerType = 0; } else if (item.Name.Equals("单侧")) { pp = fun?.Invoke(item, 1); nLayerType = 1; } } else { pp = item.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray(); } m.TransformPoints(pp); lstWell.Add(new KeyValuePair(nLayerType, pp)); } // 剔除重复的井位 HashSet removed = FindDuplicate(lstWell); StringBuilder sb = new StringBuilder(); foreach(var item in lstBorder) { string strLayer = "断层"; if(item.Key == 3) { strLayer = "边界"; } sb.AppendLine($"Layer M {strLayer}"); sb.AppendLine($"Pline"); foreach (var pt in item.Value) { sb.AppendLine($"{pt.X},{pt.Y}"); } sb.AppendLine(); } for (int i=0;i< lstWell.Count;i++) { if (removed.Contains(i)) { continue; } KeyValuePair item = lstWell[i]; string strLayer = "部署\\双侧"; if(item.Key==1) { strLayer = "部署\\单侧"; } sb.AppendLine($"Layer M {strLayer}"); sb.AppendLine($"Pline"); foreach (var pt in item.Value) { sb.AppendLine($"{pt.X},{pt.Y}"); } sb.AppendLine(); } File.WriteAllText(path, sb.ToString(), Encoding.Default); return removed; } public static HashSet FindDuplicate(List> sourcePolygons) { // 存储最终结果的列表 //List result = new List(); PathsD pathsSource = new PathsD(); foreach (var nfp in sourcePolygons) { PathD path = new PathD(); foreach (var pt in nfp.Value) { path.Add(new Clipper2Lib.PointD(pt.X, pt.Y)); } pathsSource.Add(path); } // 标记删除的多边形 HashSet removedIndices = new HashSet(); for (int i = 0; i < pathsSource.Count; i++) { if (removedIndices.Contains(i)) continue; // 如果已经被移除,则跳过 for (int j = i + 1; j < pathsSource.Count; j++) { if (removedIndices.Contains(j)) continue; // 如果已经被移除,则跳过 // 检查两个多边形是否相交 PathsD intersection = Clipper.BooleanOp(ClipType.Intersection, new PathsD { pathsSource[i] }, new PathsD { pathsSource[j] }, FillRule.NonZero); if (intersection != null && intersection.Count > 0) { // 移除单侧部井的多边形 if (sourcePolygons[i].Key == 1) { removedIndices.Add(i); } else if(sourcePolygons[j].Key == 1) { removedIndices.Add(j); } //double area1 = Clipper.Area(pathsSource[i]); //double area2 = Clipper.Area(pathsSource[j]); //// 保留面积较大的多边形 //if (Math.Abs(area1) >= Math.Abs(area2)) //{ // removedIndices.Add(j); // 移除面积较小的多边形 //} //else //{ // removedIndices.Add(i); // 移除面积较小的多边形 //} } } //// 如果当前多边形未被移除,则加入结果 //if (!removedIndices.Contains(i)) //{ // result.Add(sourcePolygons[i]); //} } return removedIndices; } } }