WPF GraphicsLayer Limits, for large number of graphics and multiple layers

2876
1
02-26-2014 02:22 PM
Labels (1)
FarzanaYasmeen
New Contributor
We have a performance question on WPF "GraphicsLayer". Our desktop application uses ArcGIS Runtime SDK for WPF 10.2.
We are trying to determine the maximum number of graphics(points) that we can put on a graphicsLayer. We would also like to
know if any of the characteristics of the graphics are more costly than others, such as Maptip, attributes, zoom function, etc.

Also, if we spread them (the graphics) across multiple layers, what limits and
performance impacts (positive or negative) should we be aware of using multiple layers for these
large number of graphics?

Here is a snipppet from our applicaiton.

Scenario:
For some number of approximately 1 to 50 sets of groups of graphics
(with 1 to 200 groups in each set having 1 to 20 graphics per group) to be drawn on the map:
(potentially as much as 200,000 points)

Code:
Step 1:
for (<each group...>)
     AddPointsToGraphicsListDispatch(....);
 
Step 2:
AddGraphicsToLayerDispatch(...);


// Step 1: Adding graphics to a List
private bool AddPointsToGraphicsListDispatch(...)
{
List<Graphic> AddGraphicsList = GraphicsListParam;
Graphic gr = new Graphic
{
  Geometry = _mercator.FromGeographic(new MapPoint(longitudeLocal, latitudeLocal)),
  Symbol = newSymbol, // newSymbol is a SimpleMarkerSymbol (point)
  MapTip = CreateToolTip(userData, latitudeLocal, longitudeLocal, imeiData, imsiData, phoneNumberData, pair.ResultId, target.TargetId,
        requestId, pair.MLCTime.ToString(), reqType, null, GetCallingNumber(target.TargetId, requestId), null, accuracy),
};
gr.Attributes["Latitude"] = latitudeLocal;
gr.Attributes["Longitude"] = longitudeLocal;
gr.MouseEnter -= GraphicOnMouseEnter;
gr.MouseEnter += GraphicOnMouseEnter;
gr.MouseLeftButtonUp += GraphicMouseLeftButtonUp;
gr.SetZIndex(zOrder);
AddGraphicsList.Add(gr);

//second graphic
Graphic uigraphic = new Graphic
{
  Geometry = _mercator.FromGeographic(new MapPoint(longitudeLocal, latitudeLocal)),
  Symbol = symbol,
  MapTip = CreateToolTip(userData, latitudeLocal, longitudeLocal, imeiData, imsiData, phoneNumberData, pair.ResultId, target.TargetId,
        requestId, pair.MLCTime.ToString(), reqType, null, null, null, accuracy)                                                                                  
};
uigraphic.SetZIndex(zOrder);
zOrder = +zOrder;
AddGraphicsList.Add(uigraphic);
}

// Step 2:
// Remove old graphics from map
// Add new graphics from graphics list to graphicsLayer
private bool AddGraphicsToLayerDispatch(List<Graphic> GraphicsListParam, List<Graphic>> PrevGraphicsListParam)
{
   List<Graphic> AddGraphicsList = GraphicsListParam; // the list where graphics were added earlier
Dictionary<Tuple<Int32, Int32>, List<Graphic>> PrevGraphicsList = PrevGraphicsListParam; // previously added graphics were saved in a list for removal from map
if (null == (List<Graphic>)(PrevGraphicsListParam[new Tuple<int, int>(RequestId, TargetRef.TargetId)] = (this.Dispatcher.Invoke((new Func<List<Graphic>>(() =>
{
 
  var graphicsLayer = MainMap.Layers[Layer] as GraphicsLayer;
 
  if (null != PrevGraphicsList && PrevGraphicsList.ContainsKey(new Tuple<int, int>(RequestId, TargetRef.TargetId)))
  {
   foreach (Graphic gr in PrevGraphicsList[new Tuple<int, int>(RequestId, TargetRef.TargetId)])
   {
   // Remove old graphics before adding new ones
    if (graphicsLayer.Graphics.Contains(gr))
     graphicsLayer.Graphics.Remove(gr);
   }
   PrevGraphicsList.Remove(new Tuple<int, int>(RequestId, TargetRef.TargetId));
  }
 
  // Add new graphics to the graphicsLayer
  graphicsLayer.Graphics.AddRange(AddGraphicsList);
  graphicsLayer.Refresh();
  if (zoom) ZoomToLocate(_latitude, _longitude);
  }
 
  // Save the new list for the next removal
  return AddGraphicsList;
  ......
}
0 Kudos
1 Reply
MichaelBranscomb
Esri Frequent Contributor
Hi,

There are a number of optimizations available in the API when working with graphics. Firstly there's the map itself. You have the option of using the entirely WPF based map rendering pipeline which supports things like custom XAML symbols or you can use the GIS-optimized map rendering pipeline which provides greater performance but at the expense of those fancy animated symbols. To enable the latter set Map.UseAcceleratedDisplay to True.

For getting graphics into GraphicsLayers in the first place, I see you are already using AddRange which is good.

GraphicsLayers have two rendering modes - "Static" and "Dynamic". Dynamic is the traditional mode and provides a better visual experience when zooming in/out but is less suitable for larger numbers of graphics, which is where the static mode helps.

When symbolizing graphics you should try to use renderers (SimpleRenderer, UniqueValueRenderer, ClassBreaksRenderer) instead of setting symbols individually on graphics. If you would like to update the geometry of point graphics, there's a MoveTo method which provides greater performance over setting a new geometry into the graphic.

Regarding other aspects which affect performance, MapTips involve a hittest on mouse move and therefore are likely to be more expensive than say an InfoWindow which is displayed on mouse click.

Hope that helps

Cheers

Mike
0 Kudos