Join an External Table without Refreshing the Map

206
9
12-11-2018 10:29 AM
DominicChen1
New Contributor II

I need to join an external file (dbf) to a FeatureClass with ArcGIS Pro SDK. To approach this I need to run Geoprocessing Tool "Add Join", which forces the map refresh totally (including base map and all layers). If I join multiple FeatureClasses at one time, the map will refresh several times. That will cause low performance of map display.

I'm wondering if there's any solution to avoid that refresh, or any alternative approach to join external tables instead of Geoprocessing Tool to do the join. Thank you very much!.

Tags (1)
Reply
0 Kudos
9 Replies
GintautasKmieliauskas
Regular Contributor

Hi Dominic,

You can use geoprocessing from sdk for joining, but you need to change geoprocessing flags. Do not use GPExecuteToolFlags.AddOutputsToMap, GPExecuteToolFlags.Default or GPExecuteToolFlags.RefreshProjectItems flags. More info here:

https://github.com/esri/arcgis-pro-sdk/wiki/ProConcepts-Geoprocessing

Reply
0 Kudos
DominicChen1
New Contributor II

Thanks, Gintautas. I changed the GP flag to GPExecuteToolFlags.None and it doesn't flash. Thanks for your help!

Reply
0 Kudos
DominicChen1
New Contributor II

I'm sorry but that issue still exists. It seems that all GP Tools have this problem even if you set the GPExecuteToolFlags param. If you run multiple GP Tools at one function, you have to refresh the map again and again even though it's not necessary to  update the map (like the join action).

Is there any alternative solution? Thank you very much.

Reply
0 Kudos
GintautasKmieliauskas
Regular Contributor

Hi Dominic,

I use a lot of geoprocessing in my code and GPExecureToolFlags works for me. Could you please send me a piece of code where you call geoprocessing tool?

Reply
0 Kudos
DominicChen1
New Contributor II

Thanks, Gintautas. My code is listed as follows:

public static async Task<bool> JoinTable(string sLayerName, string sInField, string sJoinTable, string sJoinField, bool bKeepAll)
{
    return await QueuedTask.Run(async () =>
    {
        try
        {
            string sJoinType = "KEEP_COMMON";
            if (bKeepAll) sJoinType = "KEEP_ALL";

            var parameters = Geoprocessing.MakeValueArray
            (sLayerName, sInField, sJoinTable, sJoinField, sJoinType);

            var cts = new CancellationTokenSource();
            var results = await Geoprocessing.ExecuteToolAsync("management.AddJoin", parameters, null, cts.Token,
                (eventName, o) =>
                {
                //Debug.WriteLine($@"GP event: {eventName}");
            }, GPExecuteToolFlags.None);
            return (!results.IsFailed);
        }
        catch (Exception ex)
        {
            //MessageBox.Show(ex.ToString());
            return false;
        }
    });
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

When I run the Geoprocessing.ExecuteToolAsync() function, all the layers are forced to refresh even if I set GPExecuteToolFlags to None. I can't find a way to avoid that. Thank you very much.

Reply
0 Kudos
GintautasKmieliauskas
Regular Contributor

Hi Dominic,

Your code does not work from my add-in from ArcGIS Pro 2.3 Beta. I have change it in my style at it works fine without refreshing.

public static bool JoinTable(string sLayerName, string sInField, string sJoinTable, string sJoinField, bool bKeepAll)

{

try

{

var gpresult1 = Task.Run(() =>

{

string sJoinType = "KEEP_COMMON";

if (bKeepAll) sJoinType = "KEEP_ALL";

var parameters = Geoprocessing.MakeValueArray(sLayerName, sInField, sJoinTable, sJoinField, sJoinType);

return Geoprocessing.ExecuteToolAsync("AddJoin_management", parameters, null,

CancelableProgressor.None, GPExecuteToolFlags.AddToHistory);

});

return !gpresult1.Result.IsFailed;

}

catch (Exception ex)

{

//MessageBox.Show(ex.ToString());

return false;

}

}

I have never used geoprocessing tool naming like you do: "management.AddJoin" . I use naming like this "AddJoin_management".

Reply
0 Kudos
DominicChen1
New Contributor II

Hi Gintautas,

Thank you for your help. I tried your code but the program get stuck when I run Task.Run() function. I have to make it asynchronous (adding async, await keyword), which again causes the refresh. Since this refresh after join also occurs in ArcPro, I think it must be related to multithread in ArcGIS Pro.

Reply
0 Kudos
GintautasKmieliauskas
Regular Contributor

Hi Dominic,

I think you can use different geoprocessing tool "Join Field" (Join Field—Data Management toolbox | ArcGIS Desktop ). It works without layers so it does not need to refresh the content of map. But at first you need to make a copy of your data and run join field geoprocessing tool on it because this tool adds joined fields permanently. After your calculations are completed you need to delete copy of your data. I do not know which way will be faster with geoprocessing but it will not refresh your screen

Reply
0 Kudos
DominicChen1
New Contributor II

Thank you for your help, Gintautas. I tried another way to settle the problem. I set "MapView.Active.DrawingPaused = true; "before running GP and  "MapView.Active.DrawingPaused = false;" after. That will cause the map rendering suspended and avoid refreshing many times. I think that's an proper way considering current situation. There are still many inconvenience for those who are familiar with ArcObjects but try to use Pro SDK.

Sorry for the delay!

Dominic