Friday 9 June 2017

Map-Plot extension - iusse with FDO hatches in a rotated viewport

As mentioned already - back then for Map 2013 - there is an issue with hatches in a rotated viewport when using Map (FDO) layers. For details see here. The issue has not been resolved yet (Map 2017 SP1).

To get around it we basically replaced the problematic Map layer hatch with an AutoCAD hatch. We created 3 drawings (one for each of the print scales: 1:500, 1:1000 and 1:2000) containing only the hatches which cause issues, these hatches are plain AutoCAD hatches which print fine in a rotated viewport. These drawings were created by Map-DWG export.

As we use our own batch plot extension (as mentioned here) I just needed to extend it in order to attach one of the three drawings as XREF automatically before the layout gets printed off.

Map 2017, SP1


 ...  
 IPlot plot = myLibrary.FindPlot(FIDPlot);  
 PltPlotRenderer r = PltPlotRendererFactory.CreateRenderer(RendererConfiguration.Plot, plot, RenderingCompatibility.CurrentVersion);  
 r.Render(); // renders the plot as AutoCAD layout  
 ...  
 // xrefs   
 string xref_pfad = "S:\\GIS\\Va\\Map3D2017\\Startbilder\\";  
 string xref_500 = "Wald_500.dwg";  
 string xref_1000 = "Wald_1000.dwg";  
 string xref_2000 = "Wald_2000.dwg";  
 ...  
 string plotname = plot.Name;          
 string xref = xref_500;  
 if (plotname.Contains("500"))  
      xref = xref_500;  
 else if (plotname.Contains("1000"))  
      xref = xref_1000;  
 else  
      xref = xref_2000;  
 //attach matching xref            
 attachDrawing2(xref_pfad, xref);  
 //send xref to bottom  
 toBack();  
 // regenerate all viewports  
 RegenAll();  
 ....  
           //copy and paste from AutoCAD forum ? - didn't keep the link,   
           public static void RegenAll()  
     {  
       Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;  
       Editor ed = doc.Editor;  
       Database db = doc.Database;  
       Viewport vp;  
       using (DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument())  
       {  
         using (Transaction tr = db.TransactionManager.StartTransaction())  
         {  
           LayoutManager lm = LayoutManager.Current;  
           if (lm.CurrentLayout.ToLower() == "model") db.TileMode = false;  
           lm.CurrentLayout = lm.CurrentLayout;  
           Layout layout = tr.GetObject(lm.GetLayoutId(lm.CurrentLayout), OpenMode.ForRead) as Layout;  
           ObjectIdCollection vpIds = layout.GetViewports();  
           if (vpIds.Count < 2) { ed.Regen(); return; }  
           ed.SwitchToModelSpace();  
           for (int i = 1; i < vpIds.Count; i++)  
           {  
             vp = tr.GetObject(vpIds[i], OpenMode.ForWrite) as Viewport;  
             ed.SwitchToModelSpace();  
             Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("Cvport", vp.Number);  
             ed.Regen();  
             ed.SwitchToPaperSpace();  
           }  
           tr.Commit();  
         }  
       }  
     }  
           ...  
     //copy and paste from :_http://through-the-interface.typepad.com/through_the_interface/2015/11/attaching-autocad-xrefs-and-inserting-them-at-the-origin-using-net.html  
     public void attachDrawing2(string filepath, string filename)  
     {  
       Database acCurDb;  
       acCurDb = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;  
       string f = filepath + filename;  
       if (!File.Exists(f))  
         return ;       
       string  name = Path.GetFileNameWithoutExtension(f);  
       try  
       {  
         using (var tr = acCurDb.TransactionManager.StartOpenCloseTransaction())  
         {  
           DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();  
           using (docLock)  
           {  
             var xId = acCurDb.AttachXref(f, name);  
             if (xId.IsValid)  
             {  
               BlockTable acBlkTbl;  
               acBlkTbl = tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;  
               var btr = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;  
               Point3d insPt = new Point3d(0, 0, 0);  
               var br = new BlockReference(insPt, xId);  
               btr.AppendEntity(br);  
               tr.AddNewlyCreatedDBObject(br, true);  
             }  
             tr.Commit();  
           }  
           Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.Regen();            
         }  
       }  
       catch (Autodesk.AutoCAD.Runtime.Exception e)  
       {  
         MessageBox.Show(e.ToString());  
       }  
     }  
           ...  
           //send XREF to bottom of draw order, copy and paste - didnt keep link  
     public void toBack()  
     {  
       Database acCurDb;  
       acCurDb = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;  
       try  
       {  
         using (var tr = acCurDb.TransactionManager.StartTransaction())  
         {  
           DocumentLock docLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument();  
           using (docLock)  
           {  
             //var bt = (BlockTable)tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead);  
             //var ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);  
             var bt = tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;  
             var ms = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;  
             DrawOrderTable drawOrderTab = tr.GetObject(ms.DrawOrderTableId, OpenMode.ForWrite) as DrawOrderTable;  
             ObjectIdCollection ids = new ObjectIdCollection();  
             // Loop through the contents of the modelspace  
             foreach (var id in ms)  
             {  
               // We only care about BlockReferences  
               var br = tr.GetObject(id, OpenMode.ForRead) as BlockReference;  
               if (br != null)  
               {  
                 // Check whether the associated BlockTableRecord is  
                 // an external reference  
                 var bd = (BlockTableRecord)tr.GetObject(br.BlockTableRecord, OpenMode.ForRead);  
                 if (bd.IsFromExternalReference)  
                 {  
                   ids.Add(br.ObjectId);  
                 }  
               }  
             }  
             if(ids.Count> 0)  
               drawOrderTab.MoveToBottom(ids);  
           }  
           tr.Commit();  
         }