AddOverlay Performance

941
7
Jump to solution
09-17-2020 12:35 PM
KrisCulin
Occasional Contributor

Hello,

We are in the process of porting our application from ArcMap to ArcGIS Pro. 

 

We have a need to dynamically embellish the map display.  We have several variations of this; we’ll do things like display a different symbol over a subset of point features, draw a thicker line over polylines/polygons, or add polygons to highlight a region around some features, etc.  The data we are using to determine the display is external to ArcGIS Pro.  These embellishments are often fairly short-lived.

 

In our ArcMap implementation we are making use of AfterDraw (AfterDraw event IActiveViewEvents_AfterDraw).  In ArcGIS Pro, we are trying to use Overlays.  The api’s appear to be fairly comparable and offer similar benefits: we can dynamically add/remove the “afterdraw/overlay” to the map pretty seamlessly, there is no impact on undo/redo, we have a good variety of options for displaying points/polylines/polygons.

 

The problem we are bumping into under ArcGIS Pro is related to performance when creating overlays.  As you can see from these timings, things get fairly slow at 5K overlays, and become unusable pretty quickly.

 

Number of Overlays

Create Overlay: ArcGIS Pro

Create AfterDraw:

ArcMap

1,000

0m 05s

 0m 1s

5,000

0m 26s

 0m 1s 

10,000

0m 50s

 0m 1s 

20,000

1m 31s

 0m 1s 

50,000

4m 23s

 0m 1s 

100,000

9m 02s

 0m 3s

550,000

~45 m

 0m 8s

 

The timing for 550k elements in ArcGIS Pro is an estimate.  Logically, 9 minutes at 100k will take approximately 45 minutes at 550k.  it is possible that it takes less or more than 45 minutes.  I just don't have the time to sit and wait until it finishes to find out for sure.

I've attached an ArcGIS Pro add-in showing the code I use to add the overlays to the map.  Perhaps someone can review to ensure we are not doing anything wrong.  Note: For this add-in I've only created point overlays, but we do make use of polylines and polygons as well.  Also note that for the add-in, the color is uniform across all points.  However, we have use cases where the color will be different so we cannot use a single pointSymbol/SymbolReference in all cases.

The add-in requires no geodatabase or external datasource.  It will simply create the overlays over any map you select.  I used the geographic center of the United States as the starting point.  We do not rely on 3D maps for our software so please use a 2D map when running the add-in.

 

TIA,

Kris

0 Kudos
1 Solution

Accepted Solutions
UmaHarano
Esri Regular Contributor

Hi Kris,

One way you can optimize your workflow is by using multipoint geometry.  (Multipart for polylines and polygons).

I modified your code like this and saw a substantial improvement in performance.

private void CreateQuadrant(MapView mapView, SpatialReference sr, MapPoint centerPoint, int quadrant, double dx, double dy)
{
    List<MapPoint> list = new List<MapPoint>();
    var pointSymbol = CreatePoinSymbol(Color.FromArgb(255, 0, 255, 255), 10.0);
    MapPoint point = MapPointBuilder.CreateMapPoint(centerPoint.X + dx, centerPoint.Y + dy, sr);
    for (int Row = 0; Row < quadrant; ++Row){
        for (int Col = 0; Col < quadrant; ++Col){
             list.Add(point);
             //Graphics.Add(mapView.AddOverlay(point, pointSymbol.MakeSymbolReference()));
             point = MapPointBuilder.CreateMapPoint(point.X + dx, point.Y, sr);
             list.Add(point);
         }

         point = MapPointBuilder.CreateMapPoint(centerPoint.X + dx, point.Y + dy, sr);
       }

       Multipoint multiPoint = MultipointBuilder.CreateMultipoint(list);
       Graphics.Add(mapView.AddOverlay(multiPoint, pointSymbol.MakeSymbolReference()));
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Let me know how it goes!

Thanks

Uma

View solution in original post

7 Replies
KrisCulin
Occasional Contributor

Hey Everyone,

Does anyone have a solution to this performance issue?  Am I doing something wrong with the API that is causing the slow down?

I hope someone from ESRI can respond.  We are shipping on October 30.  Even if you don't have a fix for this, at least we can prep for dealing with user inquiries about it.

Kind Regards,

Kris Culin

0 Kudos
UmaHarano
Esri Regular Contributor

Hi Kris,

One way you can optimize your workflow is by using multipoint geometry.  (Multipart for polylines and polygons).

I modified your code like this and saw a substantial improvement in performance.

private void CreateQuadrant(MapView mapView, SpatialReference sr, MapPoint centerPoint, int quadrant, double dx, double dy)
{
    List<MapPoint> list = new List<MapPoint>();
    var pointSymbol = CreatePoinSymbol(Color.FromArgb(255, 0, 255, 255), 10.0);
    MapPoint point = MapPointBuilder.CreateMapPoint(centerPoint.X + dx, centerPoint.Y + dy, sr);
    for (int Row = 0; Row < quadrant; ++Row){
        for (int Col = 0; Col < quadrant; ++Col){
             list.Add(point);
             //Graphics.Add(mapView.AddOverlay(point, pointSymbol.MakeSymbolReference()));
             point = MapPointBuilder.CreateMapPoint(point.X + dx, point.Y, sr);
             list.Add(point);
         }

         point = MapPointBuilder.CreateMapPoint(centerPoint.X + dx, point.Y + dy, sr);
       }

       Multipoint multiPoint = MultipointBuilder.CreateMultipoint(list);
       Graphics.Add(mapView.AddOverlay(multiPoint, pointSymbol.MakeSymbolReference()));
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Let me know how it goes!

Thanks

Uma

KrisCulin
Occasional Contributor

Uma,

THANK YOU, THANK YOU, THANK YOU!!!

That worked wonders for the performance, especially for points. It's on par with ArcMap and that is simply amazing.

Polylines are nearly as fast (not quite, but in the ballpark).  It took me about 20 minutes to figure out how to create the multipart but your API documentation helped out there.

Since we don't expect a large number of polygons in our models, I am not going to do the changes for those.  Points and polylines were the bottlenecks.

Now, if you can seriously consider including overlays with the export options (i.e. metafile) that would be icing on the cake.

Thank you again.

Kris Culin

0 Kudos
KrisCulin
Occasional Contributor

Hi Uma Harano,

As I was implementing the new code I had to figure out how to create a Multipart for polylines and polygons.

The only way I could figure this out is to use a PolylineBuilder and call AddPart on it passing in the points of my polyline.  Then once I have all the parts added, call ToGeometry() and use that with the AddOverlay method.

Is this the correct procedure or is there a different way of doing this?  So far I have found this approach to be slower than points but faster than the original implementation.

Also keep in mind that colors can vary.  I could have 10 links that are blue and then the next 10 links red.  I've already handled this with points (just a map of color to list of points which are used with the MultipointBuilder).  I've done something similar for links but instead of a list of points, it is a PolylineBuilder.

Thanks,

Kris

0 Kudos
UmaHarano
Esri Regular Contributor

Hi Kris,

Your workflow with adding the parts is exactly correct!

You might have already seen this example in the API Reference. But in case you haven't, here is a code sample. It uses points, but similar for lines also.

AddPart Method: ArcGIS Pro 2.6 API Reference Guide 

Thanks

Uma

0 Kudos
UmaHarano
Esri Regular Contributor

Hi Kris,

One more piece of information that I want to share with you about performance with what you are doing:

It is a good idea to use Coordinate2D instead of MapPoints.  Use these Coordinate2D points in the MultipointBuilder that consumes points. MapPointBuilder is quite slow in comparison.

https://pro.arcgis.com/en/pro-app/sdk/api-reference/#topic8567.html

Thanks!

Uma

0 Kudos
KrisCulin
Occasional Contributor

Thanks Uma!  That's good information to know.  I will look into this as soon as I can.

Kris

0 Kudos