Adding Elements to Layouts Progamatically

4566
12
03-21-2016 12:55 PM
ThomasCox
Occasional Contributor


I hesitate to ask this question as I fear it will reveal a major part of the new ArcGIS Pro sdk that I probably should already be aware of . Specifically, I have been looking at the various help resources ( sdk reference, snippets, etc...)  for an example of adding graphic elements and map surround type objects to a layout through code.  Coming from ArcObjects I was looking for a pattern following the familiar ArcObjects IGraphicsContainer.

The Pro Layout Snippet examples appear to be confined changing elements already present in the layout.  I have looked at the LayoutProjectItem as well the Layout class itself.  I can see the method to return Elements from the pro Layout class. However, I have not figured out how to add new elements of even determine whether it is possible.

Any assistance would be appreciated.

0 Kudos
12 Replies
AlexanderGray
Occasional Contributor III

Don't apologize or hesitate to ask.  We are all pretty new at ArcGIS Pro SDK (I have 15 years AO but 5 days of Pro SDK.)  Any question you have, I sure others do to.

The collection is read only I suppose for a specific purpose.  Perhaps if you posted the end goal of what you want, there may be a completely different way to do what you want with Pro.

0 Kudos
ThomasCox
Occasional Contributor

Thanks Alex.  As a fellow AO vet, I appreciate your insight.

We have numerous Engine and ArcMap applications that rely on the pattern of using the IGraphicsContainer interface associated with the PageLayout.  Typically, the apps perform the required analysis and then passes the results along with all of the ancillary layout information (text, text location, map, layout size, symbols etc...) to a method that adds these elements to the layout graphics container.  In fact, we have built numerous helper classes that specifically handle adding these elements to a layout graphics collection. Once the layout is 'built', it is exported to whatever format the user specifies.

Here is a bit of code to illustrate:

public void BuildLayout ( IMxDoc pDoc, IActiveView pActiveView, IMap pMap, string strTitle double[] dblEnvArray...)

{

            DeleteAllGraphElementsExceptMapFrame(pDoc);  //method that removes all graphics
            pDoc.ActiveView.Refresh();
            pDoc.PageLayout.Page.Orientation = Convert.ToInt16(intOrient);
            pDoc.PageLayout.Page.PutCustomSize(dblCustSizeX, dblCustSizeY);
            pDoc.PageLayout.RulerSettings.SmallestDivision = 1;
            pDoc.PageLayout.ZoomToWhole();
            pDoc.ActiveView.Refresh();
            pActiveView = pDoc.ActiveView;

            // testing calling routine for map to page transformation

            IGraphicsContainer pGC;
            pGC = (IGraphicsContainer)pDoc.PageLayout;
            pGC.Reset();
            IElement pElem;
            pElem = pGC.Next();
            IEnvelope pMapEnvelope;
  
  
             pActiveView.Refresh();

            while (pElem != null)
            {
                if (pElem is IMapFrame)
                {
                    pMapEnvelope = pElem.Geometry.Envelope;
                    pMapEnvelope.XMin = dblEnvArray[0];
                    pMapEnvelope.YMin = dblEnvArray[1];
                    pMapEnvelope.XMax = dblEnvArray[2];
                    pMapEnvelope.YMax = dblEnvArray[3];
                    pElem.Geometry = pMapEnvelope;
                    IMapFrame pMapFrame = (IMapFrame)pElem;
                    pMapFrame.MapScale = pMap.MapScale;

                }
                pElem = pGC.Next();
            } //end while
  

            LayoutGeneric.AddTextToLayout(pActiveView, strTitle, 1, 1.5)  //calling helper routine to add text
             ......
  
           Export to PDF.....
  
  

}

public void AddTextToLayout(IActiveView pActiveView, string strTitle, double dblX, double dblY, int intFontSize)
{
     if(pActiveView is IPageLayout)
     {

            IGraphicsContainer pGraphicsContainer;
            ITextElement pTextElement = new TextElementClass();;
            IPageLayout pPageLayout;
            ISimpleTextSymbol pTextSym;
            pTextSym = new TextSymbolClass();

            pPageLayout = (IPageLayout) pActiveView;
            pGraphicsContainer = (IGraphicsContainer) pPageLayout;
            IElement pElement;
            IGroupElement pGroupElement = new GroupElementClass();

            IPoint pPoint;
            pPoint = new PointClass();
            pPoint.PutCoords(dblX, dblY - 0.1);
            pTextElement.Text = strTitle;

            pTextSym.Font.Name = "Arial";
            pTextSym.Size = intFontSize;
            pTextSym.HorizontalAlignment = ESRI.ArcGIS.Display.esriTextHorizontalAlignment.esriTHALeft;
            pTextSym.VerticalAlignment = ESRI.ArcGIS.Display.esriTextVerticalAlignment.esriTVABaseline;
   
            pTextSym.Font.Bold = true;
            pTextElement.Symbol = pTextSym;
            pElement = (IElement)pTextElement;

            pElement.Geometry = (IGeometry) pPoint;
            pGraphicsContainer.AddElement(pElement,0);
            pActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGraphics,null,null);
   
         }

}

When looking at the Pro version of the Layout class and the LayoutProjectItem, there does not appear to be any way to add elements to the layout.  There are examples of Pro code manipulating elements already present. As we have discussed, the elements collection returned from the layout appears to be read only. Presently, in my Pro efforts, I am reading a 'layout file' (.pagx) into the Project.  This layout file only contains the layout dimensions.  I was hoping to be able to add the elements I needed to the element collection associated with this layout.  I hope I don't have to have a 'boiler plate' layout file for each type of layout I will need to produce, with all of the text and symbols present, with my code only swapping the values.  If this is the case, I am not sure how I would handle custom graphics I want to add to the layout that could not be part of the boiler plate layout file(.pagx) approach.

Thanks again for your interest.

0 Kudos
JeffBarrette
Esri Regular Contributor

Creating new layout elements in Pro is currently not possible.  There are future plans to accommodate this requirement but it won't happen during the 1.3 or 1.4 releases.

0 Kudos
AlexanderGray
Occasional Contributor III

Hi Jeff, is there published versions of the "future plans" anywhere?  This would really help in making a decision to go Pro now or later.

0 Kudos
AlexanderGray
Occasional Contributor III

Would this be something data driven pages would help?

0 Kudos
ThomasCox
Occasional Contributor

Alex,

Thanks for the suggestion.  We do use data driven pages for other efforts that don't require the analytic effort these applications do.  Additionally, some of this involves users graphically interacting with the map control.  Based off Jeff Barrette's response, this will eventually be part of the sdk.  However, I am not familiar with the Pro SDK release schedule, but it sounds at least a year out.  Long live AO!

Thanks for your time.

0 Kudos
ThomasCox
Occasional Contributor

I know this is the Pro SDK forum, but does anyone know if the Runtime supports adding elements to a layout?

Thanks

0 Kudos
JeremyBridges
Occasional Contributor

It does. The API surface looks different. But, it certainly does. The Map has an arbitrary list of Layer objects. If you add a GraphicsLayer to this Layers collection and add a Graphic to its Graphics collection, it will appear on the map. Make sure to set a a symbol on your Graphic:

var graphicsLayer = new GraphicsLayer();

_mapView.Map.Layers.Add(graphicsLayer);

var graphic = new Graphic

{

   Symbol = new SimpleMarkerSymbol

                        {

                            Color = Color.FromRgb(255, 255, 255),

                            Size = 12,

                            Style = SimpleMarkerStyle.X

                        }

};

graphicsLayer.Graphics.Add(graphic);

0 Kudos
ThomasCox
Occasional Contributor

Jeremy,

Thanks for your input.  I have been pulled back into ArcObjects efforts and just found my way back to Pro efforts including this forum.

If I follow your code snippet, the graphic is being added to the map view.  I am interested in adding graphics (symbols and text ) to a layout.  Jeff Barrette mentioned adding graphics to a layout won't be available in 1.3 or 1.4.  I am hoping this feature will come sooner than later.

Thanks again for responding.

0 Kudos