Group graphic elements so they move together

390
4
Jump to solution
01-27-2023 11:13 AM
AndrewAlexander1
New Contributor II

Hello,

I'm creating two (for now) graphic elements, one is a polygon, using PolygonBuilder.CreatePolygon.

And then a CIMCharacterMarker using SymbolFactory.Instance.ConstructMarker().

I need to be able to group those two so that when moving the polygon with the mouse, both those elements move together as one element.

I initially place the marker inside the polygon and would like it to stay there when the polygon is moved.

Thanks
Andy

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
CharlesMacleod
Esri Regular Contributor

if I am understanding your code snippet correctly, u are adding _two_ elements to your graphics layer (one with some text and another with a marker symbol)?

Namely:

symLayer.AddElement(polyTxtGra);

symLayer.AddElement(symPtGraphic);

Is that right?

Therefore, can you not simply group the two elements together (into a group element) to achieve the same thing....or must this all be combined into a single symbol (as I was illustrating)?

Creating a group element would look like this:

var elem1 = symLayer.AddElement(polyTxtGra);

var elem2 = symLayer.AddElement(symPtGraphic);

symLayer.GroupElements(new List<Element>() { elem1, elem2 });

https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic29336.html

 

 

View solution in original post

0 Kudos
4 Replies
CharlesMacleod
Esri Regular Contributor

Sometimes to solve these kinds of things see if u can make the symbol first and then deconstruct it. Usually, if u cant make a symbol via the UI then the symbol probably can't be made via the api either (not always but in most cases).

So in the Pro help we have Position and place marker symbol layers .which contains an "At Center" placement for markers in polys.

A bit of fiddling with the symbology UI gives:

symbol_properties2.jpg

The last bit is deconstructing the symbol which involves a bit of trial and error. There are three symbol layers - the marker, a stroke, and a fill. The marker has a placement set to position it "At Center".

Note: I notice that Pro removes the stroke from the char marker to have it scale correctly when it is resized.

internal class LayoutTool1 : LayoutTool {

  private CIMPolygonSymbol _polygonSymbol = null;

  public LayoutTool1() {
    SketchType = SketchGeometryType.Polygon;
  }
  protected override Task OnToolActivateAsync(bool active) {
    return base.OnToolActivateAsync(active);
  }
  protected override Task<bool> OnSketchCompleteAsync(Geometry geometry) {
    return QueuedTask.Run(() => {
      if (_polygonSymbol == null)
         _polygonSymbol = MakePolySymbol();
      ElementFactory.Instance.CreateGraphicElement(
          this.ActiveElementContainer, geometry, _polygonSymbol);
      return true;
    });
  }

  private CIMPolygonSymbol MakePolySymbol() {
    var char_index = 80;
    var font = "ESRI Default Marker";
    var char_marker = SymbolFactory.Instance.ConstructMarker(
  	  char_index, font) as CIMCharacterMarker;

    char_marker.Size = 16;
    var grey = ColorFactory.Instance.CreateRGBColor(110, 110, 110);
    var violet = ColorFactory.Instance.CreateRGBColor(236, 212, 252);
    var purple = ColorFactory.Instance.CreateRGBColor(132, 0, 168);

    //change the fill
    //also, for some reason the stroke must be removed to have
    //the symbol scaled correctly
    foreach (var layer in char_marker.Symbol.SymbolLayers)
    {
  	if (layer is CIMSolidFill)
  	{
          ((CIMSolidFill)layer).Color = purple;
  	}
  	else if (layer is CIMSolidStroke)
  	{
          ((CIMSolidStroke)layer).Width = 0.0;
  	}
    }
    //set the placement for the marker within the poly
    var center_placement = new CIMMarkerPlacementPolygonCenter()
    {
       Method = PlacementPolygonCenterMethod.OnPolygon
    };
    //assign the marker placement
    char_marker.MarkerPlacement = center_placement;

    //make the poly outline and fill
    var stroke = SymbolFactory.Instance.ConstructStroke(grey, 2.0);
    var fill = SymbolFactory.Instance.ConstructSolidFill(violet);

    //make the final symbol
    return new CIMPolygonSymbol()
    {
       SymbolLayers = new List<CIMSymbolLayer>()
       {
          char_marker, stroke, fill
       }.ToArray()
    };
  }
}

Final symbol:

char_marker_in_poly.jpg

 

 

 

0 Kudos
AndrewAlexander1
New Contributor II

Thanks for the reply.

I'm still having trouble. I'm putting things together differently and especially when making the polygon, I don't seem to be able to do it that way, and keep the other properties I have for it.

I can definitely create both items in the API.  I also don't need to sketch anything. I'd like them to be grouped in the API when they are created.

To summarize the code I have now:
var polygon = PolygonBuilder.CreatePolygon(listPoints, MapView.Active.Map.SpatialReference);

CIMTextSymbol sym = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.BlackRGB, 10, "Arial", "Regular");

(attaching text to the polygon)
GraphicElement polyTxtElm = LayoutElementFactory.Instance.CreatePolygonParagraphGraphicElement(newLayout, polygon, text, sym);

//create marker from the Font, char index,size,color
var cimMarker = SymbolFactory.Instance.ConstructMarker(213, "ESRI Geometric Symbols", "Regular", 25, ColorFactory.Instance.GreenRGB) as CIMCharacterMarker;
var polygonMarker = cimMarker.Symbol;

CIMGraphic polyTxtGra = polyTxtElm.GetGraphic();

var pointSymbol = SymbolFactory.Instance.ConstructPointSymbol(cimMarker);

MapPoint symPt = null;
Coordinate2D newCoord = new Coordinate2D(pX1, pY1+110);
symPt = MapPointBuilder.CreateMapPoint(newCoord);

var symPtGraphic = new CIMPointGraphic()
{
Symbol = pointSymbol.MakeSymbolReference(),
Location = symPt
};

symLayer.AddElement(polyTxtGra);

symLayer.AddElement(symPtGraphic);

That looks like this:

AndrewAlexander1_0-1675109311249.png

 

But of course, moving the polygon or the green element with the mouse does not bring them both together.

I know that's because I'm adding them to the layer separately, but I haven't been able to group them in the code.  I've tried the pertinent elements in your code, but my elements seem to be of different types that don't allow it.

But I'm sure I am putting the whole thing together not in the right way.

Thanks
Andy

 

 

 

 

0 Kudos
CharlesMacleod
Esri Regular Contributor

if I am understanding your code snippet correctly, u are adding _two_ elements to your graphics layer (one with some text and another with a marker symbol)?

Namely:

symLayer.AddElement(polyTxtGra);

symLayer.AddElement(symPtGraphic);

Is that right?

Therefore, can you not simply group the two elements together (into a group element) to achieve the same thing....or must this all be combined into a single symbol (as I was illustrating)?

Creating a group element would look like this:

var elem1 = symLayer.AddElement(polyTxtGra);

var elem2 = symLayer.AddElement(symPtGraphic);

symLayer.GroupElements(new List<Element>() { elem1, elem2 });

https://pro.arcgis.com/en/pro-app/latest/sdk/api-reference/topic29336.html

 

 

0 Kudos
AndrewAlexander1
New Contributor II

Right, I admitted that I was currently adding the two items separately.  Because I can't get them combined into one item.

The one element is a polygon with text, the CreatePolygonParagraphGraphicElement.

Things I was trying kept telling me I was using the wrong type of object.

However... the last line you gave works!
The symLayer.GroupElements

Obviously, I had no idea it was that simple.  

Thank you very much.
Andy

 

0 Kudos