diff --git a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs index 44cb30e72..6ef531c23 100644 --- a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs +++ b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSelectionBinding.cs @@ -1,5 +1,6 @@ using ArcGIS.Desktop.Mapping; using ArcGIS.Desktop.Mapping.Events; +using Speckle.Connectors.ArcGIS.Utils; using Speckle.Connectors.DUI.Bindings; using Speckle.Connectors.DUI.Bridge; @@ -7,11 +8,13 @@ namespace Speckle.Connectors.ArcGIS.Bindings; public class ArcGISSelectionBinding : ISelectionBinding { + private readonly MapMembersUtils _mapMemberUtils; public string Name => "selectionBinding"; public IBrowserBridge Parent { get; } - public ArcGISSelectionBinding(IBrowserBridge parent) + public ArcGISSelectionBinding(IBrowserBridge parent, MapMembersUtils mapMemberUtils) { + _mapMemberUtils = mapMemberUtils; Parent = parent; var topLevelHandler = parent.TopLevelExceptionHandler; @@ -52,14 +55,8 @@ public SelectionInfo GetSelection() List allNestedMembers = new(); foreach (MapMember member in selectedMembers) { - if (member is GroupLayer group) - { - GetLayersFromGroup(group, allNestedMembers); - } - else - { - allNestedMembers.Add(member); - } + var layerMapMembers = _mapMemberUtils.UnpackMapLayers(selectedMembers); + allNestedMembers.AddRange(layerMapMembers); } List objectTypes = allNestedMembers diff --git a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs index 2e72ef14c..b7eb88c8f 100644 --- a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs +++ b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Bindings/ArcGISSendBinding.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Speckle.Connectors.ArcGIS.Filters; +using Speckle.Connectors.ArcGIS.Utils; using Speckle.Connectors.Common.Caching; using Speckle.Connectors.Common.Cancellation; using Speckle.Connectors.Common.Operations; @@ -54,6 +55,7 @@ public sealed class ArcGISSendBinding : ISendBinding private List SubscribedLayers { get; set; } = new(); private List SubscribedTables { get; set; } = new(); + private readonly MapMembersUtils _mapMemberUtils; public ArcGISSendBinding( DocumentModelStore store, @@ -64,7 +66,8 @@ public ArcGISSendBinding( ISendConversionCache sendConversionCache, IOperationProgressManager operationProgressManager, ILogger logger, - IArcGISConversionSettingsFactory arcGisConversionSettingsFactory + IArcGISConversionSettingsFactory arcGisConversionSettingsFactory, + MapMembersUtils mapMemberUtils ) { _store = store; @@ -76,6 +79,7 @@ IArcGISConversionSettingsFactory arcGisConversionSettingsFactory _logger = logger; _topLevelExceptionHandler = parent.TopLevelExceptionHandler; _arcGISConversionSettingsFactory = arcGisConversionSettingsFactory; + _mapMemberUtils = mapMemberUtils; Parent = parent; Commands = new SendBindingUICommands(parent); @@ -275,36 +279,14 @@ private async Task GetIdsForStandaloneTablesRemovedEvent(StandaloneTableEventArg await RunExpirationChecks(true).ConfigureAwait(false); } - private void AddChangedNestedObjectIds(GroupLayer group) - { - ChangedObjectIds[group.URI] = 1; - foreach (var member in group.Layers) - { - if (member is GroupLayer subGroup) - { - AddChangedNestedObjectIds(subGroup); - } - else - { - ChangedObjectIds[member.URI] = 1; - } - } - } - private async Task GetIdsForMapPropertyChangedEvent(MapPropertyChangedEventArgs args) { foreach (Map map in args.Maps) { - foreach (MapMember member in map.Layers) + List allMapMembers = _mapMemberUtils.GetAllMapMembers(map); + foreach (MapMember member in allMapMembers) { - if (member is GroupLayer group) - { - AddChangedNestedObjectIds(group); - } - else - { - ChangedObjectIds[member.URI] = 1; - } + ChangedObjectIds[member.URI] = 1; } } await RunExpirationChecks(false).ConfigureAwait(false); diff --git a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/HostApp/ArcGISColorManager.cs b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/HostApp/ArcGISColorManager.cs index bfa8db2f5..970feb224 100644 --- a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/HostApp/ArcGISColorManager.cs +++ b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/HostApp/ArcGISColorManager.cs @@ -316,6 +316,11 @@ private void ProcessFeatureLayerColors(FeatureLayer layer, int displayPriority) int count = 1; using (RowCursor rowCursor = layer.Search()) { + // if layer doesn't have a valid data source (and the conversion likely failed), don't create a colorProxy + if (rowCursor is null) + { + return; + } while (rowCursor.MoveNext()) { string elementAppId = $"{layer.URI}_{count}"; @@ -451,6 +456,11 @@ private bool TryGetUniqueRendererColor( out int color ) { + if (uniqueRenderer.DefaultSymbol is null) + { + color = RbgToInt(255, 255, 255, 255); + return false; + } if (!TryGetSymbolColor(uniqueRenderer.DefaultSymbol.Symbol, out color)) // get default color { return false; @@ -493,6 +503,11 @@ out int color // set the group color to class symbol color if conditions are met if (groupConditionsMet) { + if (groupClass.Symbol is null) + { + color = RbgToInt(255, 255, 255, 255); + return false; + } if (!TryGetSymbolColor(groupClass.Symbol.Symbol, out color)) { return false; @@ -544,6 +559,11 @@ private bool TryGetGraduatedRendererColor( out int color ) { + if (graduatedRenderer.DefaultSymbol is null) + { + color = RbgToInt(255, 255, 255, 255); + return false; + } if (!TryGetSymbolColor(graduatedRenderer.DefaultSymbol.Symbol, out color)) // get default color { return false; diff --git a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Send/ArcGISRootObjectBuilder.cs b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Send/ArcGISRootObjectBuilder.cs index 7384ae992..148d5ef99 100644 --- a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Send/ArcGISRootObjectBuilder.cs +++ b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Send/ArcGISRootObjectBuilder.cs @@ -71,7 +71,7 @@ public async Task Build( List results = new(objects.Count); var cacheHitCount = 0; - List<(GroupLayer, Collection)> nestedGroups = new(); + List<(ILayerContainer, Collection)> nestedGroups = new(); // reorder selected layers by Table of Content (TOC) order List<(MapMember, int)> layersWithDisplayPriority = _mapMemberUtils.GetLayerDisplayPriority( @@ -112,7 +112,7 @@ public async Task Build( // don't use cache for group layers if ( - mapMember is not GroupLayer + mapMember is not ILayerContainer && _sendConversionCache.TryGetValue(sendInfo.ProjectId, applicationId, out ObjectReference? value) ) { @@ -121,7 +121,7 @@ mapMember is not GroupLayer } else { - if (mapMember is GroupLayer group) + if (mapMember is ILayerContainer group) { // group layer will always come before it's contained layers // keep active group last in the list diff --git a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Utils/MapMembersUtils.cs b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Utils/MapMembersUtils.cs index 95951cae3..f03092c5d 100644 --- a/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Utils/MapMembersUtils.cs +++ b/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Utils/MapMembersUtils.cs @@ -1,4 +1,3 @@ -using ArcGIS.Desktop.Internal.Mapping; using ArcGIS.Desktop.Mapping; namespace Speckle.Connectors.ArcGIS.Utils; @@ -28,21 +27,13 @@ public List UnpackMapLayers(IEnumerable mapMembersToUnpack List mapMembers = new(); foreach (var layer in mapMembersToUnpack) { + mapMembers.Add(layer); 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); + case ILayerContainer subGroup: + var subLayerMapMembers = UnpackMapLayers(subGroup.Layers); mapMembers.AddRange(subLayerMapMembers); break; - default: - mapMembers.Add(layer); - break; } }