.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

group texts that have same position X

6 REPLIES 6
Reply
Message 1 of 7
Ahmmed-saber
294 Views, 6 Replies

group texts that have same position X

I write code to select all texts
I want to group texts that have the same position X with a tolerance of 2 units
And output each group on a separate line using StreamWriter

 

 public void export_text()
        {
            
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;
            Editor ed = acDoc.Editor;
          
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
 
                BlockTable acBlkTbl;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                OpenMode.ForRead) as BlockTable;

                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                OpenMode.ForWrite) as BlockTableRecord;
                TypedValue[] tv = new TypedValue[1];
                tv.SetValue(new TypedValue((int)DxfCode.Start, "text"), 0);
                string npath = "D://test.txt";
                StreamWriter file = new StreamWriter(npath);
                file.WriteLine("List of text in selection: ");

                List<DBText> alltext = new List<DBText>();
                SelectionFilter filter = new SelectionFilter(tv);
              
                PromptSelectionResult ssPrompt;
                ssPrompt = ed.GetSelection(filter);
                if (ssPrompt.Status == PromptStatus.OK)
                {
                    SelectionSet ss = ssPrompt.Value;
                    foreach (SelectedObject sObj in ss)
                    {
                        DBText spoint = acTrans.GetObject(sObj.ObjectId, OpenMode.ForWrite) as DBText;
                        alltext.Add(spoint);                        
                    }
                    // i stop here cant complete the code


                    //var sotrtext = alltext.GroupBy(t => t.Position.X);
                    //foreach (DBText item in sotrtext)
                    //{
                    //    string xx = item.TextString;
                    //    file.WriteLine(xx);
                    //}
                }
                acTrans.Commit();
                file.Flush();
                file.Close();
            }
        }

 

Labels (2)
6 REPLIES 6
Message 2 of 7
_gile
in reply to: Ahmmed-saber

Hi,

Try like this:

        public static void ExportText()
        {
            var db = HostApplicationServices.WorkingDatabase;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var modelSpace = (BlockTableRecord)tr.GetObject(
                    SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
                var textGroups = modelSpace
                    .Cast<ObjectId>()
                    .Where(id => id.ObjectClass.DxfName == "TEXT")
                    .Select(id => (DBText)tr.GetObject(id, OpenMode.ForRead))
                    .GroupBy(txt => Math.Round(txt.Position.X / 2.0) * 2.0);
                using(var writer = new StreamWriter(@"D:\test.txt"))
                {
                    writer.WriteLine("List of text in selection: ");
                    foreach (var group in textGroups)
                    {
                        writer.WriteLine(string.Join("|", group.Select(txt => txt.TextString)));
                    }
                }
                tr.Commit();
            }
        }

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 7
essam-salah
in reply to: Ahmmed-saber

hi @Ahmmed-saber 

try this:

 

[CommandMethod("cieTextGrouping")]
        public static void TextGrouping()
        {
            var acDoc = aApp.Application.DocumentManager.MdiActiveDocument;
            var acCurDb = acDoc.Database;
            var ed = acDoc.Editor;
            var textInfos = new List<TextInfo>();

            // select text
            var filter = new SelectionFilter(new[] { new TypedValue((int)DxfCode.Start, "TEXT") });
            var selectRes = ed.GetSelection(filter);
            if (selectRes.Status != PromptStatus.OK /*|| selectRes.Value.Count < 1*/)
            {
                ed.WriteMessage("\n---- No Selection Found -----\n");
                return;
            }
            var ids = selectRes.Value.GetObjectIds();

            // read texts from databaase
            using (var acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                // read all texts
                foreach (var txtId in ids)
                {
                    var txt = txtId.GetObject(OpenMode.ForRead) as DBText;
                    textInfos.Add(new TextInfo(txt.TextString, txt.Position.X, txt.Position.Y));
                }
            }
            if (textInfos.Count < 2)
            {
                ed.WriteMessage("too small number of text");
                return;
            }

            // sort txts based on X
            textInfos = textInfos.OrderBy(txt => txt.X).ToList();

            // grouping txt with same position
            double tolorence = 0.5;            int currentGroup = 0;
            var previous = textInfos.First();
            previous.GroupId = currentGroup;

            foreach (var current in textInfos.Skip(1))
            {
                if (current.HasSameX(previous, tolorence) == false)
                {
                    currentGroup++;
                }
                current.GroupId = currentGroup;
                previous = current;
            }

            // compse string out of texts
            var builder = new StringBuilder();
            textInfos
                .GroupBy(txt => txt.GroupId)
                .Select(g => new { Id = g.Key, Texts = g.OrderBy(txt => txt.Y) }) // to order each group by y 
                .ToList().ForEach(group =>
                {
                    builder.AppendLine(string.Join("\t", group.Texts.Select(g => g.Text)));
                });
            //ed.WriteMessage($"\n{builder}");

            // write to file
            using (var file = new System.IO.StreamWriter(@"D:\test.txt"))
            {
                file.WriteLine(builder.ToString());
            }
        }

 

 

 public class TextInfo
    {
        public TextInfo(string text, double x, double y)
        {
            Text = text;
            X = x;
            Y = y;
        }

        public string Text { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
        public int GroupId { get; set; }

        public bool HasSameX(TextInfo other, double epsilon)
        {
            return (other.X > (this.X - epsilon)) 
                && (other.X < (this.X + epsilon)); 
        }
    }

using aApp = Autodesk.AutoCAD.ApplicationServices;

 

Message 4 of 7
essam-salah
in reply to: _gile

@_gile 

man, that's cool, (i have to go to sleep) :).

Message 5 of 7
essam-salah
in reply to: Ahmmed-saber

@Ahmmed-saber 

and if you want to got with @_gile  solution (the cleanest solution):

[CommandMethod("cieTextGrouping")]
        public static void TextGrouping()
        {
            var acDoc = aApp.Application.DocumentManager.MdiActiveDocument;
            var acCurDb = acDoc.Database;
            var ed = acDoc.Editor;

            // select text
            var filter = new SelectionFilter(new[] { new TypedValue((int)DxfCode.Start, "TEXT") });
            var selectRes = ed.GetSelection(filter);
            if (selectRes.Status != PromptStatus.OK /*|| selectRes.Value.Count < 1*/)
            {
                ed.WriteMessage("\n---- No Selection Found -----\n");
                return;
            }
            var ids = selectRes.Value.GetObjectIds();

            // read texts from databaase
            using (var tr = acCurDb.TransactionManager.StartTransaction())
            {              
                var textGroups= ids
                    //.Where(id => id.ObjectClass.DxfName == "TEXT")
                    .Select(id => (DBText)tr.GetObject(id, OpenMode.ForRead))
                    .GroupBy(txt => Math.Round(txt.Position.X / 2.0) * 2.0);

                using (var writer = new StreamWriter(@"C:\Users\essam\OneDrive\Desktop\t\New Text Document.txt"))
                {
                    writer.WriteLine("List of text in selection: ");
                    foreach (var group in textGroups)
                    {
                        writer.WriteLine(string.Join("|", group.Select(txt => txt.TextString)));
                    }
                }
            }
            
        }
Message 6 of 7
Ahmmed-saber
in reply to: _gile

@_gile  thank you, sir, its good

Message 7 of 7
Ahmmed-saber
in reply to: essam-salah

@essam-salah  thanks sir 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost