fix update changed IDs (#209)
* fix update changed IDs * better naming * remove initial count * move layer order method also to mapMemberUtils * loop * better names * comment * fix * split layers and tables * refactor layer loop
This commit is contained in:
@@ -8,6 +8,7 @@ using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Autofac.DependencyInjection;
|
||||
using Speckle.Connectors.ArcGIS.Filters;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
@@ -38,6 +39,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<ArcGISSendBinding> _logger;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
@@ -58,7 +60,8 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
CancellationManager cancellationManager,
|
||||
ISendConversionCache sendConversionCache,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<ArcGISSendBinding> logger
|
||||
ILogger<ArcGISSendBinding> logger,
|
||||
MapMembersUtils mapMemberUtils
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
@@ -69,6 +72,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_topLevelExceptionHandler = parent.TopLevelExceptionHandler;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
@@ -199,23 +203,37 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
}
|
||||
|
||||
// get the path of the edited dataset
|
||||
var datasetURI = args.Row.GetTable().GetPath();
|
||||
Uri datasetPath = args.Row.GetTable().GetPath();
|
||||
|
||||
// find all layers & tables reading from the dataset
|
||||
foreach (Layer layer in MapView.Active.Map.Layers)
|
||||
{
|
||||
if (layer.GetPath() == datasetURI)
|
||||
try
|
||||
{
|
||||
ChangedObjectIds[layer.URI] = 1;
|
||||
if (layer.GetPath() == datasetPath)
|
||||
{
|
||||
ChangedObjectIds[layer.URI] = 1;
|
||||
}
|
||||
}
|
||||
catch (UriFormatException) // layer.GetPath() or table.GetPath() can throw this error, if data source was removed from the hard drive
|
||||
{
|
||||
// ignore layers with invalid source URI
|
||||
}
|
||||
}
|
||||
foreach (StandaloneTable table in MapView.Active.Map.StandaloneTables)
|
||||
{
|
||||
if (table.GetPath() == datasetURI)
|
||||
try
|
||||
{
|
||||
ChangedObjectIds[table.URI] = 1;
|
||||
if (table.GetPath() == datasetPath)
|
||||
{
|
||||
ChangedObjectIds[table.URI] = 1;
|
||||
}
|
||||
}
|
||||
catch (UriFormatException) // layer.GetPath() or table.GetPath() can throw this error, if data source was removed from the hard drive
|
||||
{
|
||||
// ignore layers with invalid source URI
|
||||
}
|
||||
}
|
||||
|
||||
RunExpirationChecks(false);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -68,7 +68,9 @@ public class ArcGISConnectorModule : ISpeckleModule
|
||||
builder.AddScoped<SendOperation<MapMember>>();
|
||||
builder.AddScoped<ArcGISRootObjectBuilder>();
|
||||
builder.AddScoped<IRootObjectBuilder<MapMember>, ArcGISRootObjectBuilder>();
|
||||
|
||||
builder.AddScoped<ArcGISColorManager>();
|
||||
builder.AddScoped<MapMembersUtils>();
|
||||
|
||||
builder.AddScoped<ILocalToGlobalUnpacker, LocalToGlobalUnpacker>();
|
||||
|
||||
|
||||
+8
-31
@@ -5,6 +5,7 @@ using ArcGIS.Desktop.Internal.Mapping;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.Utils.Builders;
|
||||
using Speckle.Connectors.Utils.Caching;
|
||||
using Speckle.Connectors.Utils.Conversion;
|
||||
@@ -30,6 +31,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
private readonly ISendConversionCache _sendConversionCache;
|
||||
private readonly ArcGISColorManager _colorManager;
|
||||
private readonly IConversionContextStack<ArcGISDocument, Unit> _contextStack;
|
||||
private readonly MapMembersUtils _mapMemberUtils;
|
||||
private readonly ILogger<ArcGISRootObjectBuilder> _logger;
|
||||
|
||||
public ArcGISRootObjectBuilder(
|
||||
@@ -37,6 +39,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
ArcGISColorManager colorManager,
|
||||
IConversionContextStack<ArcGISDocument, Unit> contextStack,
|
||||
IRootToSpeckleConverter rootToSpeckleConverter,
|
||||
MapMembersUtils mapMemberUtils,
|
||||
ILogger<ArcGISRootObjectBuilder> logger
|
||||
)
|
||||
{
|
||||
@@ -44,6 +47,7 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
_colorManager = colorManager;
|
||||
_contextStack = contextStack;
|
||||
_rootToSpeckleConverter = rootToSpeckleConverter;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -66,7 +70,10 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
List<(GroupLayer, Collection)> nestedGroups = new();
|
||||
|
||||
// reorder selected layers by Table of Content (TOC) order
|
||||
List<(MapMember, int)> layersWithDisplayPriority = GetLayerDisplayPriority(MapView.Active.Map, objects);
|
||||
List<(MapMember, int)> layersWithDisplayPriority = _mapMemberUtils.GetLayerDisplayPriority(
|
||||
MapView.Active.Map,
|
||||
objects
|
||||
);
|
||||
|
||||
onOperationProgressed?.Invoke("Converting", null);
|
||||
|
||||
@@ -181,36 +188,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<MapMember>
|
||||
return new RootObjectBuilderResult(rootObjectCollection, results);
|
||||
}
|
||||
|
||||
// Gets the layer display priority for selected layers
|
||||
public List<(MapMember, int)> GetLayerDisplayPriority(Map map, IReadOnlyList<MapMember> mapMembers)
|
||||
{
|
||||
// first get all map layers
|
||||
Dictionary<MapMember, int> layersIndices = new();
|
||||
int count = 0;
|
||||
var layers = map.Layers;
|
||||
count = UnpackLayersOrder(layersIndices, layers, count);
|
||||
|
||||
// iterate through tables
|
||||
foreach (var layer in map.StandaloneTables)
|
||||
{
|
||||
layersIndices[layer] = count + 100; // random number, will be recalculated below
|
||||
}
|
||||
|
||||
// recalculate selected layer priority from all map layers
|
||||
List<(MapMember, int)> selectedLayers = new();
|
||||
int newCount = 0;
|
||||
foreach (KeyValuePair<MapMember, int> valuePair in layersIndices)
|
||||
{
|
||||
if (mapMembers.Contains(valuePair.Key))
|
||||
{
|
||||
selectedLayers.Add((valuePair.Key, newCount));
|
||||
newCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return selectedLayers;
|
||||
}
|
||||
|
||||
private int UnpackLayersOrder(
|
||||
Dictionary<MapMember, int> layersIndices,
|
||||
IEnumerable<ArcLayer> layersToUnpack,
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using ArcGIS.Desktop.Internal.Mapping;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
public class MapMembersUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns all Layers and Standalone Tables present on the Map
|
||||
/// </summary>
|
||||
/// <param name="map"></param>
|
||||
/// <returns></returns>
|
||||
public List<MapMember> GetAllMapMembers(Map map)
|
||||
{
|
||||
// first get all map layers
|
||||
List<MapMember> mapMembers = new();
|
||||
var layerMapMembers = UnpackMapLayers(map.Layers);
|
||||
mapMembers.AddRange(layerMapMembers);
|
||||
|
||||
// add tables
|
||||
var standaloneTableMapMembers = UnpackMapLayers(map.StandaloneTables);
|
||||
mapMembers.AddRange(standaloneTableMapMembers);
|
||||
return mapMembers;
|
||||
}
|
||||
|
||||
public List<MapMember> UnpackMapLayers(IEnumerable<MapMember> mapMembersToUnpack)
|
||||
{
|
||||
List<MapMember> mapMembers = new();
|
||||
foreach (var layer in mapMembersToUnpack)
|
||||
{
|
||||
switch (layer)
|
||||
{
|
||||
case GroupLayer subGroup:
|
||||
mapMembers.Add(layer);
|
||||
var subGroupMapMembers = UnpackMapLayers(subGroup.Layers);
|
||||
mapMembers.AddRange(subGroupMapMembers);
|
||||
break;
|
||||
case ILayerContainerInternal subLayerContainerInternal:
|
||||
mapMembers.Add(layer);
|
||||
var subLayerMapMembers = UnpackMapLayers(subLayerContainerInternal.InternalLayers);
|
||||
mapMembers.AddRange(subLayerMapMembers);
|
||||
break;
|
||||
default:
|
||||
mapMembers.Add(layer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mapMembers;
|
||||
}
|
||||
|
||||
// Gets the layer display priority for selected layers
|
||||
public List<(MapMember, int)> GetLayerDisplayPriority(Map map, IReadOnlyList<MapMember> selectedMapMembers)
|
||||
{
|
||||
// first get all map layers
|
||||
List<MapMember> allMapMembers = GetAllMapMembers(map);
|
||||
|
||||
// recalculate selected layer priority from all map layers
|
||||
List<(MapMember, int)> selectedLayers = new();
|
||||
int newCount = 0;
|
||||
foreach (MapMember mapMember in allMapMembers)
|
||||
{
|
||||
if (selectedMapMembers.Contains(mapMember))
|
||||
{
|
||||
selectedLayers.Add((mapMember, newCount));
|
||||
newCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return selectedLayers;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user