Author Topic: StreamReader Problem  (Read 14554 times)

0 Members and 1 Guest are viewing this topic.

wannabe

  • Guest
Re: StreamReader Problem
« Reply #30 on: April 25, 2009, 08:20:29 AM »
The aim is to take a text file which has coordinates and attributes and populate an AutoCAD drawing with blocks that use the data. Each line in the text file has an X & Y coord and potentially strings that are intended to place the block and populate the attributes, respectively.


pkohut

  • Guest
Re: StreamReader Problem
« Reply #31 on: April 25, 2009, 12:54:28 PM »
Hi Paul,

I'm not sure where key duplication comes into effect. Every time an array is added to the dictionary the counting integer should be increased by one.

Code: [Select]
http://www.theswamp.org/index.php?topic=28468.msg340666#msg340666
int charactersThisLine = thisLine.Length;
...
coordsList.Add(charactersThisLine, thisLinesValues);

That is from the 2nd example you posted.  The 3rd example is better in
that it does use a unique key.

pkohut

  • Guest
Re: StreamReader Problem
« Reply #32 on: April 25, 2009, 12:58:58 PM »
Also, is there a specific XML, XSD resource you recommend, please? I've done my homework on the structure of the language itself, but haven't found a good resource for explaining its strengths and weaknesses for use in this kind of context etc.

With hesitation, look up XSD and code generators.  Your not ready for that yet, nor do you need it
for your situation.

pkohut

  • Guest
Re: StreamReader Problem
« Reply #33 on: April 25, 2009, 01:18:00 PM »
The aim is to take a text file which has coordinates and attributes and populate an AutoCAD drawing with blocks that use the data. Each line in the text file has an X & Y coord and potentially strings that are intended to place the block and populate the attributes, respectively.
Ok, there is the custom data structure.  Just create and add a new block reference on the fly...


Quote
the code that will use this function will make judgments based on the previous and next element to determine how it will use the information in this element. To the best of my logic, I either needed to convert into an array now or later. Doing later would mean I have to create a new dictionary. So it seemed easier to code as is.
With just the smallest bit of code you can keep track of the previous element (block reference) and perform any
operations on it and the current element.  No need to store the whole file in concocted dictionaries and arrays, just
process the file line-by-line.

Now that you've got a bit of seat time in you should throw away the code you've done, rethink your approach,
and start over. 

wannabe

  • Guest
Re: StreamReader Problem
« Reply #34 on: April 25, 2009, 02:42:46 PM »
I've been rethinking it for large portions of the day. I was thinking about ways to condense the code and improve efficiency. With your hint in mind, I think will try and develop a routine that does it on the fly whilst reading from the txt file, line by line.

If I set up a method that inserts a block and populates the attributes, I'll just need to call it once for each line of the code.

Catch up with you soon.

wannabe

  • Guest
Re: StreamReader Problem
« Reply #35 on: April 27, 2009, 08:42:10 AM »
Using the comments and constructs in this thread I now have working code. Thanks for all the advice; I appreciate it all.

Now I'm going to tinker with my code until fully congenial. I'll post it up for your criticisms if you want/don't mind.

Cheers again.

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: StreamReader Problem
« Reply #36 on: April 27, 2009, 04:02:10 PM »
I'm in total agreement with Kerry.

1. Post as good a description as you can of what you're trying to accomplish overall and go into more detail on specific points you're stuck on.
2. Post a sample of the 'text' file you are using as your data input.
3. Indicate what version of AutoCAD you're targeting.
4. Indicate what version of the .NET Framwork you're targeting.
5. Indicate what version of Visual Studio (or other IDE) you're using.

Once members have this critical data, we can better help you, otherwise we are really only guessing based on experience and the alignment of the planets ;)
Also, I have a sneaking suspicion where this is going and if it's what I suspect, you're going to run into a rather large and rather solid wall very shortly. :)

This is becoming interesting...
Me

wannabe

  • Guest
Re: StreamReader Problem
« Reply #37 on: April 27, 2009, 06:03:44 PM »
1. I want to populate drawings with user-specified block(s) using a text file that contains 'to-be' coordinates and attributes on a per-line basis

**I have achieved this task - tested and working - thanks for all the help**

However, to be able to insert in the AutoCAD drafting "Wblock" fashion is proving a little tricky. But I'll only want help when I accept defeat.... if I've not expended my quota already.

2. Attached is a text file and, because I'm nice, a block as well.

3. I'm targeting AutoCAD 2008.

4 & 5 visual Studio C# Express 08 with 3.5 framework.

Quote
public class Commands
    {
        [CommandMethod("MultiBlocks")]
        public void MultiBlocks()
        {
            OpenFileDialog coordsSelectDialog = new OpenFileDialog("Coodinate Selection", "", "txt",
                                                       "Select a Coordinate File", OpenFileDialog.OpenFileDialogFlags.NoUrls);
                bool coordsSelected = false;//So we can loop until valid file selected or user cancels
                while (!coordsSelected)
                {
                    System.Windows.Forms.DialogResult coordsResult = coordsSelectDialog.ShowDialog();

                    if (coordsResult == System.Windows.Forms.DialogResult.Cancel)
                        return;

                    if (coordsResult != System.Windows.Forms.DialogResult.OK)
                    {
                        System.Windows.Forms.MessageBox.Show("Select Another File");
                    }
                    else
                    {
                    coordsSelected = true; //Loop will no longer execute & we have a valid file
                    }
                }
            using (TextReader coordsFile = new StreamReader(coordsSelectDialog.Filename))
            {
                Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
                string blockName = "";
                bool isStringValid = false;//Enabling us to loop until string is valid or user cancels
                while (!isStringValid)
                {
                    PromptStringOptions psoBlockSelect = new PromptStringOptions("Enter The Name of The Block to 'Multi-Insert'");
                    PromptResult prBlockSelected = ed.GetString(psoBlockSelect);

                    if (prBlockSelected.Status == PromptStatus.Cancel)
                        return;

                    if (prBlockSelected.Status != PromptStatus.OK)
                        System.Windows.Forms.MessageBox.Show("Error With User Input - Try Again or Cancel");
                    else
                    {
                        isStringValid = true;
                        blockName = prBlockSelected.StringResult;
                    }
                }

                while (true)
                    try
                    {
                        string lineRead = coordsFile.ReadLine();

                        if (String.IsNullOrEmpty(lineRead))
                            break;

                        string[] lineSeparated = lineRead.Trim().Split(' ');

                        //Convert first two elements to double for our insertion point
                        Point3d insPoint = new Point3d(Double.Parse(lineSeparated[0]), Double.Parse(lineSeparated[1]), 0);

                        Database db = HostApplicationServices.WorkingDatabase;
                        using (Transaction trans = db.TransactionManager.StartTransaction())
                        {
                            BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                            ObjectId blockId;

                            //Iterate the Block Table, searching for our Block
                            if (!bt.Has(blockName.ToString()))
                            {
                                System.Windows.Forms.MessageBox.Show("Specified Block Name Not Valid in This Document"
                                                                     , "Input Error");
                                                                       
                                return;
                            }

                            blockId = bt[blockName.ToString()];//Essentially our "Block Definition"
                            BlockReference blockRef = new BlockReference(insPoint, blockId);

                            //Add to ModelSpace immediately to ensure successful attribute population
                            BlockTableRecord mSpace = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                            mSpace.AppendEntity(blockRef);
                            trans.AddNewlyCreatedDBObject(blockRef, true);

                            if (lineSeparated.Count() > 2)//If true, we have attribute data
                            {
                                BlockTableRecord thisBlock = (BlockTableRecord)trans.GetObject(blockId, OpenMode.ForRead);
                                int counter = 2; //Element in "lineSeparated" where attribute information will begin - after coordinates
                                foreach (ObjectId obj in thisBlock)
                                {
                                    Entity ent = (Entity)trans.GetObject(obj, OpenMode.ForRead);

                                    if (ent is AttributeDefinition)
                                    {
                                        AttributeDefinition attDef = (AttributeDefinition)(ent);

                                        AttributeReference attRef = new AttributeReference();
                                        attRef.SetPropertiesFrom(ent);
                                        attRef.TextString = lineSeparated[counter];
                                        attRef.Position = new Point3d(blockRef.Position.X + attDef.Position.X,
                                                                      blockRef.Position.Y + attDef.Position.Y,
                                                                      0);
                                        attRef.Tag = attDef.Tag;
                                        attRef.Height = attDef.Height;
                                        attRef.Rotation = attDef.Rotation;

                                        //Add this attribute to the "Block Reference" & the transaction
                                        blockRef.AttributeCollection.AppendAttribute(attRef);
                                        trans.AddNewlyCreatedDBObject(attRef, true);

                                        //Increment the counter so the next attribute will utilise the next array element
                                        counter++;
                                    }

                                }
                            }
                            //Complete by adding Block Referenc to transaction
                            trans.Commit();
                        }
                    }

                    catch
                    {
                        System.Windows.Forms.MessageBox.Show("Error - Application Terminated", "Error");
                        return;
                    }
                }
            }   

There is the code.

I've got plans to make it more robust and to be able to use a "Wblock". But I need to get my head around "Database.Insert(), DeepClone(), Wblock()" etc.

Also I need to add some user information that specifies that attributes will be populated sequentially corresponding to their order in the AutoCAD "Block Attribute Manager".

Fun, fun...

kdub

  • Mesozoic relic
  • SuperMod
  • Swamp Rat
  • Posts: 1382
  • class keyThumper<T>:ILazy<T>
Re: StreamReader Problem
« Reply #38 on: April 27, 2009, 07:24:44 PM »

Can't make time to have a look, but how do you get out of the while (true) ....  loop.
... and are you sure that's what you want to think of the logic

ie would
while (what condition is true )
be easier to understand next month when you re-visit the code ..


///Kerry
called Kerry in my other life

Sometimes the question is more important than the answer.
#ridesober

pkohut

  • Guest
Re: StreamReader Problem
« Reply #39 on: April 27, 2009, 07:34:07 PM »
He's breaking out when streamread realine is empty.

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: StreamReader Problem
« Reply #40 on: April 28, 2009, 03:44:26 AM »
Doing a 'While True' is never a good idea in my opinion, not the least of which is confusion.
Have a look at some of the examples I've posted using TextReader (as I suggested earlier) for a better way of using a loop to read each line from a file and breaking out when at the end.

Other than that, coming along well.
Me

Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: StreamReader Problem
« Reply #41 on: April 28, 2009, 03:47:13 AM »
Also, using ToString() on a String object is well....redundant.
Me

pkohut

  • Guest
Re: StreamReader Problem
« Reply #42 on: April 28, 2009, 05:07:50 AM »
Doing a 'While True' is never a good idea in my opinion, not the least of which is confusion.
Have a look at some of the examples I've posted using TextReader (as I suggested earlier) for a better way of using a loop to read each line from a file and breaking out when at the end.

Other than that, coming along well.

Personally, no problem with while(true) ( c++, while(1) ) and for( ; ; ) in the
right context.  The compiler optimizes the while loops to be as effecent as the for loop here, and the
intent is known.  But in Wannabe's sample, he is better served with while(coordsFile.Peek() >= 0)


Glenn R

  • Water Moccasin
  • Posts: 1932
  • What idiot child of married cousins wrote this?!
Re: StreamReader Problem
« Reply #43 on: April 28, 2009, 05:19:49 AM »
Agreed, however, in inexperienced hands, these sort of constructs can lead to infinite loops - this was where I was coming from.
Forever loops are ok in the right circumstances, but this isn't one of them.
Me

pkohut

  • Guest
Re: StreamReader Problem
« Reply #44 on: April 28, 2009, 05:47:09 AM »
Agreed, however, in inexperienced hands, these sort of constructs can lead to infinite loops - this was where I was coming from.
Forever loops are ok in the right circumstances, but this isn't one of them.

Yeah, I'll admit that with it not being my code I had to look for the exit condition as it wasn't
readily apparent. 

You mentioned he might run into a solid wall soon, care to share?  I'm not seeing it.