From 3191365691e4b2901ebe8b83065ddb693cde473f Mon Sep 17 00:00:00 2001 From: KatKatKateryna <89912278+KatKatKateryna@users.noreply.github.com> Date: Wed, 5 Jun 2024 17:46:04 +0800 Subject: [PATCH] Arcgis documentation kate jedd (#3459) * expanding context stack Document from Map to (Project, Map) * move all database operations to context stack (it should only be called once per any operation and results (e.g. database path) accessible throughout converters) * fix Uri format needed for adding layers * Register ArcGISDocument * database URI fix --------- Co-authored-by: oguzhankoral --- .../Operations/Receive/HostObjectBuilder.cs | 29 +++-- .../ArcGISConverterModule.cs | 5 +- .../ArcGISConversionContextStack.cs | 100 +++++++++++++++++- .../Features/GisRasterToSpeckleConverter.cs | 8 +- .../MultipatchFeatureToSpeckleConverter.cs | 5 +- .../PointFeatureToSpeckleConverter.cs | 9 +- .../PolylineFeatureToSpeckleConverter.cs | 9 +- .../Geometry/EnvelopBoxToSpeckleConverter.cs | 9 +- .../CircleToHostConverter.cs | 5 +- .../Geometry/PointSingleToHostConverter.cs | 5 +- .../Geometry/PointToSpeckleConverter.cs | 11 +- .../SegmentCollectionToSpeckleConverter.cs | 5 +- .../Layers/FeatureClassToHostConverter.cs | 16 +-- .../PointcloudLayerToSpeckleConverter.cs | 6 +- .../Layers/RasterLayerToSpeckleConverter.cs | 9 +- .../Layers/TableToHostConverter.cs | 11 +- .../Layers/TableToSpeckleConverter.cs | 8 +- .../Layers/VectorLayerToHostConverter.cs | 5 +- .../Layers/VectorLayerToSpeckleConverter.cs | 6 +- .../Utils/ArcGISProjectUtils.cs | 82 -------------- .../Utils/IArcGISProjectUtils.cs | 7 -- .../Utils/NonNativeFeaturesUtils.cs | 22 +--- 22 files changed, 171 insertions(+), 201 deletions(-) delete mode 100644 DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/ArcGISProjectUtils.cs delete mode 100644 DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/IArcGISProjectUtils.cs diff --git a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs index 2d80e9bb33..ccbf054609 100644 --- a/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs +++ b/DUI3-DX/Connectors/ArcGIS/Speckle.Connectors.ArcGIS3/Operations/Receive/HostObjectBuilder.cs @@ -9,29 +9,27 @@ using ArcGIS.Core.Geometry; using Objects.GIS; using Speckle.Core.Models.GraphTraversal; +using Speckle.Converters.ArcGIS3; namespace Speckle.Connectors.ArcGIS.Operations.Receive; public class ArcGISHostObjectBuilder : IHostObjectBuilder { private readonly IRootToHostConverter _converter; - private readonly IArcGISProjectUtils _arcGISProjectUtils; private readonly INonNativeFeaturesUtils _nonGisFeaturesUtils; // POC: figure out the correct scope to only initialize on Receive - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; private readonly GraphTraversal _traverseFunction; public ArcGISHostObjectBuilder( IRootToHostConverter converter, - IArcGISProjectUtils arcGISProjectUtils, - IConversionContextStack contextStack, + IConversionContextStack contextStack, INonNativeFeaturesUtils nonGisFeaturesUtils, GraphTraversal traverseFunction ) { _converter = converter; - _arcGISProjectUtils = arcGISProjectUtils; _contextStack = contextStack; _nonGisFeaturesUtils = nonGisFeaturesUtils; _traverseFunction = traverseFunction; @@ -59,14 +57,16 @@ List objectIds return (objPath, converted); } - public string AddDatasetsToMap((string, string) databaseObj, string databasePath) + public string AddDatasetsToMap((string, string) databaseObj) { try { return LayerFactory.Instance .CreateLayer( - new Uri($"{databasePath}\\{databaseObj.Item2}"), - _contextStack.Current.Document, + new Uri( + $"{_contextStack.Current.Document.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{databaseObj.Item2}" + ), + _contextStack.Current.Document.Map, layerName: databaseObj.Item1 ) .URI; @@ -75,8 +75,10 @@ public string AddDatasetsToMap((string, string) databaseObj, string databasePath { return StandaloneTableFactory.Instance .CreateStandaloneTable( - new Uri($"{databasePath}\\{databaseObj.Item2}"), - _contextStack.Current.Document, + new Uri( + $"{_contextStack.Current.Document.SpeckleDatabasePath.AbsolutePath.Replace('/', '\\')}\\{databaseObj.Item2}" + ), + _contextStack.Current.Document.Map, tableName: databaseObj.Item1 ) .URI; @@ -115,11 +117,6 @@ CancellationToken cancellationToken // Prompt the UI conversion started. Progress bar will swoosh. onOperationProgressed?.Invoke("Converting", null); - // create and add Geodatabase to a project - - string databasePath = _arcGISProjectUtils.GetDatabasePath(); - _arcGISProjectUtils.AddDatabaseToProject(databasePath); - // POC: This is where we will define our receive strategy, or maybe later somewhere else according to some setting pass from UI? var objectsToConvert = _traverseFunction .Traverse(rootObject) @@ -193,7 +190,7 @@ CancellationToken cancellationToken { try { - bakedLayersURIs.Add(AddDatasetsToMap(databaseObj, databasePath)); + bakedLayersURIs.Add(AddDatasetsToMap(databaseObj)); } catch (Exception e) when (!e.IsFatal()) { diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs index a2bc5383a9..30a739310b 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3.DependencyInjection/ArcGISConverterModule.cs @@ -1,5 +1,4 @@ using ArcGIS.Core.Geometry; -using ArcGIS.Desktop.Mapping; using Speckle.Autofac.DependencyInjection; using Speckle.Converters.ArcGIS3.Utils; using Speckle.Converters.Common; @@ -17,12 +16,12 @@ public void Load(SpeckleContainerBuilder builder) builder.AddScoped(); builder.AddScoped(); builder.AddScoped(); - builder.AddScoped(); builder.AddScoped(); + builder.AddScoped(); builder.AddScoped, ArcGISToSpeckleUnitConverter>(); // single stack per conversion - builder.AddScoped, ArcGISConversionContextStack>(); + builder.AddScoped, ArcGISConversionContextStack>(); } } diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionContextStack.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionContextStack.cs index 6290242235..1649d205dc 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionContextStack.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionContextStack.cs @@ -1,18 +1,110 @@ using System.Diagnostics.CodeAnalysis; -using ArcGIS.Core.Geometry; +using ArcGIS.Core.Data.DDL; +using ArcGIS.Core.Data; +using ArcGIS.Desktop.Core; +using ArcGIS.Desktop.Framework.Threading.Tasks; using ArcGIS.Desktop.Mapping; using Speckle.Converters.Common; namespace Speckle.Converters.ArcGIS3; +public class ArcGISDocument +{ + public Project Project { get; } + public Map Map { get; } + public Uri SpeckleDatabasePath { get; } + + public ArcGISDocument() + { + Project = Project.Current; + Map = MapView.Active.Map; + SpeckleDatabasePath = EnsureOrAddSpeckleDatabase(); + } + + private const string FGDB_NAME = "Speckle.gdb"; + + public Uri EnsureOrAddSpeckleDatabase() + { + return AddDatabaseToProject(GetDatabasePath()); + } + + public Uri GetDatabasePath() + { + try + { + var parentDirectory = Directory.GetParent(Project.Current.URI); + if (parentDirectory == null) + { + throw new ArgumentException($"Project directory {Project.Current.URI} not found"); + } + var fGdbPath = new Uri(parentDirectory.FullName); + return new Uri($"{fGdbPath}/{FGDB_NAME}"); + } + catch (Exception ex) + when (ex + is IOException + or UnauthorizedAccessException + or ArgumentException + or NotSupportedException + or System.Security.SecurityException + ) + { + throw; + } + } + + public Uri AddDatabaseToProject(Uri databasePath) + { + // Create a FileGeodatabaseConnectionPath with the name of the file geodatabase you wish to create + FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = new(databasePath); + // Create actual database in the specified Path unless already exists + try + { + Geodatabase geodatabase = SchemaBuilder.CreateGeodatabase(fileGeodatabaseConnectionPath); + geodatabase.Dispose(); + } + catch (ArcGIS.Core.Data.Exceptions.GeodatabaseWorkspaceException) + { + // geodatabase already exists, do nothing + } + + // Add a folder connection to a project + var parentFolder = Path.GetDirectoryName(databasePath.AbsolutePath); + if (parentFolder == null) + { + // POC: customize the exception type + throw new ArgumentException($"Invalid path: {databasePath}"); + } + var fGdbName = databasePath.Segments[^1]; + Item folderToAdd = ItemFactory.Instance.Create(parentFolder); + // POC: QueuedTask + QueuedTask.Run(() => Project.Current.AddItem(folderToAdd as IProjectItem)); + + // Add a file geodatabase or a SQLite or enterprise database connection to a project + var gdbToAdd = folderToAdd + .GetItems() + .FirstOrDefault(folderItem => folderItem.Name.Equals(fGdbName, StringComparison.Ordinal)); + if (gdbToAdd is not null) + { + // POC: QueuedTask + var addedGeodatabase = QueuedTask.Run(() => Project.Current.AddItem(gdbToAdd as IProjectItem)); + } + + return databasePath; + } +} + // POC: Suppressed naming warning for now, but we should evaluate if we should follow this or disable it. [SuppressMessage( "Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "Name ends in Stack but it is in fact a Stack, just not inheriting from `System.Collections.Stack`" )] -public class ArcGISConversionContextStack : ConversionContextStack +public class ArcGISConversionContextStack : ConversionContextStack { - public ArcGISConversionContextStack(IHostToSpeckleUnitConverter unitConverter) - : base(MapView.Active.Map, MapView.Active.Map.SpatialReference.Unit, unitConverter) { } + public ArcGISConversionContextStack( + IHostToSpeckleUnitConverter unitConverter, + ArcGISDocument arcGisDocument + ) + : base(arcGisDocument, MapView.Active.Map.SpatialReference.Unit, unitConverter) { } } diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/GisRasterToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/GisRasterToSpeckleConverter.cs index bcee923315..af3e268b8b 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/GisRasterToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/GisRasterToSpeckleConverter.cs @@ -3,19 +3,17 @@ using Objects.GIS; using ArcGIS.Core.Data.Raster; using Speckle.Converters.Common; -using ArcGIS.Desktop.Mapping; -using ArcGIS.Core.Geometry; namespace Speckle.Converters.ArcGIS3.Features; public class GisRasterToSpeckleConverter : ITypedConverter { - private readonly ITypedConverter> _geometryConverter; - private readonly IConversionContextStack _contextStack; + private readonly ITypedConverter> _geometryConverter; + private readonly IConversionContextStack _contextStack; public GisRasterToSpeckleConverter( ITypedConverter> geometryConverter, - IConversionContextStack contextStack + IConversionContextStack contextStack ) { _geometryConverter = geometryConverter; diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/MultipatchFeatureToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/MultipatchFeatureToSpeckleConverter.cs index 2da8dd6bf1..2e15ae765b 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/MultipatchFeatureToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/MultipatchFeatureToSpeckleConverter.cs @@ -1,6 +1,5 @@ using Speckle.Converters.Common.Objects; using Speckle.Converters.Common; -using ArcGIS.Desktop.Mapping; using Speckle.Core.Models; using Speckle.Converters.ArcGIS3.Geometry; @@ -8,11 +7,11 @@ namespace Speckle.Converters.ArcGIS3.Features; public class MultipatchFeatureToSpeckleConverter : ITypedConverter> { - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; private readonly ITypedConverter _pointConverter; public MultipatchFeatureToSpeckleConverter( - IConversionContextStack contextStack, + IConversionContextStack contextStack, ITypedConverter pointConverter ) { diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PointFeatureToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PointFeatureToSpeckleConverter.cs index 5be96b9357..7b53a664de 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PointFeatureToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PointFeatureToSpeckleConverter.cs @@ -1,16 +1,15 @@ using Speckle.Converters.Common.Objects; using Speckle.Core.Models; using Speckle.Converters.Common; -using ArcGIS.Desktop.Mapping; namespace Speckle.Converters.ArcGIS3.Features; [NameAndRankValue(nameof(ACG.MapPoint), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)] public class PointFeatureToSpeckleConverter : IToSpeckleTopLevelConverter, ITypedConverter { - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; - public PointFeatureToSpeckleConverter(IConversionContextStack contextStack) + public PointFeatureToSpeckleConverter(IConversionContextStack contextStack) { _contextStack = contextStack; } @@ -20,12 +19,12 @@ public PointFeatureToSpeckleConverter(IConversionContextStack con public Base Convert(ACG.MapPoint target) { if ( - ACG.GeometryEngine.Instance.Project(target, _contextStack.Current.Document.SpatialReference) + ACG.GeometryEngine.Instance.Project(target, _contextStack.Current.Document.Map.SpatialReference) is not ACG.MapPoint reprojectedPt ) { throw new SpeckleConversionException( - $"Conversion to Spatial Reference {_contextStack.Current.Document.SpatialReference} failed" + $"Conversion to Spatial Reference {_contextStack.Current.Document.Map.SpatialReference} failed" ); } List geometry = diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PolylineFeatureToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PolylineFeatureToSpeckleConverter.cs index b28ad710c4..92bc6ff70e 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PolylineFeatureToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Features/PolylineFeatureToSpeckleConverter.cs @@ -1,4 +1,3 @@ -using ArcGIS.Desktop.Mapping; using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; @@ -7,11 +6,11 @@ namespace Speckle.Converters.ArcGIS3.Features; public class PolyineFeatureToSpeckleConverter : ITypedConverter> { private readonly ITypedConverter _segmentConverter; - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; public PolyineFeatureToSpeckleConverter( ITypedConverter segmentConverter, - IConversionContextStack contextStack + IConversionContextStack contextStack ) { _segmentConverter = segmentConverter; @@ -27,8 +26,8 @@ public PolyineFeatureToSpeckleConverter( // segmentize the polylines with curves using precision value of the Map's Spatial Reference if (target.HasCurves is true) { - double tolerance = _contextStack.Current.Document.SpatialReference.XYTolerance; - double conversionFactorToMeter = _contextStack.Current.Document.SpatialReference.Unit.ConversionFactor; + double tolerance = _contextStack.Current.Document.Map.SpatialReference.XYTolerance; + double conversionFactorToMeter = _contextStack.Current.Document.Map.SpatialReference.Unit.ConversionFactor; var densifiedPolyline = ACG.GeometryEngine.Instance.DensifyByDeviation( target, tolerance * conversionFactorToMeter diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/EnvelopBoxToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/EnvelopBoxToSpeckleConverter.cs index 5a101f250f..15dad97faf 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/EnvelopBoxToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/EnvelopBoxToSpeckleConverter.cs @@ -1,18 +1,17 @@ using ArcGIS.Core.Geometry; using Speckle.Converters.Common.Objects; using Speckle.Converters.Common; -using ArcGIS.Desktop.Mapping; using Objects.Primitive; namespace Speckle.Converters.ArcGIS3.Geometry; public class EnvelopToSpeckleConverter : ITypedConverter { - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; private readonly ITypedConverter _pointConverter; public EnvelopToSpeckleConverter( - IConversionContextStack contextStack, + IConversionContextStack contextStack, ITypedConverter pointConverter ) { @@ -26,13 +25,13 @@ public SOG.Box Convert(Envelope target) target.XMin, target.YMin, target.ZMin, - _contextStack.Current.Document.SpatialReference + _contextStack.Current.Document.Map.SpatialReference ).ToGeometry(); MapPoint pointMax = new MapPointBuilderEx( target.XMax, target.YMax, target.ZMax, - _contextStack.Current.Document.SpatialReference + _contextStack.Current.Document.Map.SpatialReference ).ToGeometry(); SOG.Point minPtSpeckle = _pointConverter.Convert(pointMin); SOG.Point maxPtSpeckle = _pointConverter.Convert(pointMax); diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/ISpeckleObjectToHost/CircleToHostConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/ISpeckleObjectToHost/CircleToHostConverter.cs index 7e3ce179f2..d4ffe06c35 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/ISpeckleObjectToHost/CircleToHostConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/ISpeckleObjectToHost/CircleToHostConverter.cs @@ -1,4 +1,3 @@ -using ArcGIS.Desktop.Mapping; using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; using Speckle.Core.Kits; @@ -10,11 +9,11 @@ namespace Speckle.Converters.ArcGIS3.Geometry.ISpeckleObjectToHost; public class CircleToHostConverter : IToHostTopLevelConverter, ITypedConverter { private readonly ITypedConverter _pointConverter; - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; public CircleToHostConverter( ITypedConverter pointConverter, - IConversionContextStack contextStack + IConversionContextStack contextStack ) { _pointConverter = pointConverter; diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointSingleToHostConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointSingleToHostConverter.cs index d444c193ad..e30ec589e5 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointSingleToHostConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointSingleToHostConverter.cs @@ -1,4 +1,3 @@ -using ArcGIS.Desktop.Mapping; using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; using Speckle.Core.Kits; @@ -8,9 +7,9 @@ namespace Speckle.Converters.ArcGIS3.Geometry; public class PointToHostConverter : ITypedConverter { - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; - public PointToHostConverter(IConversionContextStack contextStack) + public PointToHostConverter(IConversionContextStack contextStack) { _contextStack = contextStack; } diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointToSpeckleConverter.cs index 96a2efe233..198af4e5ee 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/PointToSpeckleConverter.cs @@ -1,15 +1,14 @@ using ArcGIS.Core.Geometry; using Speckle.Converters.Common.Objects; using Speckle.Converters.Common; -using ArcGIS.Desktop.Mapping; namespace Speckle.Converters.ArcGIS3.Geometry; public class PointToSpeckleConverter : ITypedConverter { - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; - public PointToSpeckleConverter(IConversionContextStack contextStack) + public PointToSpeckleConverter(IConversionContextStack contextStack) { _contextStack = contextStack; } @@ -19,12 +18,12 @@ public SOG.Point Convert(MapPoint target) try { if ( - GeometryEngine.Instance.Project(target, _contextStack.Current.Document.SpatialReference) + GeometryEngine.Instance.Project(target, _contextStack.Current.Document.Map.SpatialReference) is not MapPoint reprojectedPt ) { throw new SpeckleConversionException( - $"Conversion to Spatial Reference {_contextStack.Current.Document.SpatialReference} failed" + $"Conversion to Spatial Reference {_contextStack.Current.Document.Map.SpatialReference} failed" ); } return new(reprojectedPt.X, reprojectedPt.Y, reprojectedPt.Z, _contextStack.Current.SpeckleUnits); @@ -32,7 +31,7 @@ is not MapPoint reprojectedPt catch (ArgumentException ex) { throw new SpeckleConversionException( - $"Conversion to Spatial Reference {_contextStack.Current.Document.SpatialReference} failed", + $"Conversion to Spatial Reference {_contextStack.Current.Document.Map.SpatialReference} failed", ex ); } diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/SegmentCollectionToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/SegmentCollectionToSpeckleConverter.cs index 0e13f55260..2d3c93fce8 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/SegmentCollectionToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Geometry/SegmentCollectionToSpeckleConverter.cs @@ -1,4 +1,3 @@ -using ArcGIS.Desktop.Mapping; using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; @@ -6,11 +5,11 @@ namespace Speckle.Converters.ArcGIS3.Geometry; public class SegmentCollectionToSpeckleConverter : ITypedConverter { - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; private readonly ITypedConverter _pointConverter; public SegmentCollectionToSpeckleConverter( - IConversionContextStack contextStack, + IConversionContextStack contextStack, ITypedConverter pointConverter ) { diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/FeatureClassToHostConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/FeatureClassToHostConverter.cs index e05be2a71e..0a084ffee8 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/FeatureClassToHostConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/FeatureClassToHostConverter.cs @@ -1,9 +1,9 @@ using ArcGIS.Core.Data; using ArcGIS.Core.Data.DDL; using ArcGIS.Core.Data.Exceptions; -using ArcGIS.Core.Geometry; using Objects.GIS; using Speckle.Converters.ArcGIS3.Utils; +using Speckle.Converters.Common; using Speckle.Converters.Common.Objects; using Speckle.Core.Models; using FieldDescription = ArcGIS.Core.Data.DDL.FieldDescription; @@ -15,19 +15,19 @@ public class FeatureClassToHostConverter : ITypedConverter, ACG.Geometry> _gisGeometryConverter; private readonly IFeatureClassUtils _featureClassUtils; private readonly IArcGISFieldUtils _fieldsUtils; - private readonly IArcGISProjectUtils _arcGISProjectUtils; + private readonly IConversionContextStack _contextStack; public FeatureClassToHostConverter( ITypedConverter, ACG.Geometry> gisGeometryConverter, IFeatureClassUtils featureClassUtils, IArcGISFieldUtils fieldsUtils, - IArcGISProjectUtils arcGISProjectUtils + IConversionContextStack contextStack ) { _gisGeometryConverter = gisGeometryConverter; _featureClassUtils = featureClassUtils; _fieldsUtils = fieldsUtils; - _arcGISProjectUtils = arcGISProjectUtils; + _contextStack = contextStack; } private List RecoverOutdatedGisFeatures(VectorLayer target) @@ -74,10 +74,10 @@ private List RecoverOutdatedGisFeatures(VectorLayer target) public FeatureClass Convert(VectorLayer target) { - GeometryType geomType = _featureClassUtils.GetLayerGeometryType(target); + ACG.GeometryType geomType = _featureClassUtils.GetLayerGeometryType(target); - string databasePath = _arcGISProjectUtils.GetDatabasePath(); - FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = new(new Uri(databasePath)); + FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = + new(_contextStack.Current.Document.SpeckleDatabasePath); Geodatabase geodatabase = new(fileGeodatabaseConnectionPath); SchemaBuilder schemaBuilder = new(geodatabase); @@ -87,7 +87,7 @@ public FeatureClass Convert(VectorLayer target) { wktString = target.crs.wkt.ToString(); } - SpatialReference spatialRef = SpatialReferenceBuilder.CreateSpatialReference(wktString); + ACG.SpatialReference spatialRef = ACG.SpatialReferenceBuilder.CreateSpatialReference(wktString); // create Fields List fields = _fieldsUtils.GetFieldsFromSpeckleLayer(target); diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/PointcloudLayerToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/PointcloudLayerToSpeckleConverter.cs index bf23636895..6c1590aaa3 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/PointcloudLayerToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/PointcloudLayerToSpeckleConverter.cs @@ -16,12 +16,12 @@ public class PointCloudToSpeckleConverter { private readonly ITypedConverter _pointConverter; private readonly ITypedConverter _boxConverter; - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; public PointCloudToSpeckleConverter( ITypedConverter pointConverter, ITypedConverter boxConverter, - IConversionContextStack contextStack + IConversionContextStack contextStack ) { _pointConverter = pointConverter; @@ -77,7 +77,7 @@ public SGIS.VectorLayer Convert(LasDatasetLayer target) SGIS.VectorLayer speckleLayer = new(); // get document CRS (for writing geometry coords) - var spatialRef = _contextStack.Current.Document.SpatialReference; + var spatialRef = _contextStack.Current.Document.Map.SpatialReference; speckleLayer.crs = new SGIS.CRS { wkt = spatialRef.Wkt, diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/RasterLayerToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/RasterLayerToSpeckleConverter.cs index f5f96584ad..3afee5b6c3 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/RasterLayerToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/RasterLayerToSpeckleConverter.cs @@ -2,7 +2,6 @@ using Speckle.Core.Models; using Objects.GIS; using Speckle.Converters.Common; -using ArcGIS.Desktop.Mapping; using ArcGIS.Core.Geometry; using RasterLayer = ArcGIS.Desktop.Mapping.RasterLayer; using ArcGIS.Core.Data.Raster; @@ -13,11 +12,11 @@ namespace Speckle.Converters.ArcGIS3.Layers; public class RasterLayerToSpeckleConverter : IToSpeckleTopLevelConverter, ITypedConverter { private readonly ITypedConverter _gisRasterConverter; - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; public RasterLayerToSpeckleConverter( ITypedConverter gisRasterConverter, - IConversionContextStack contextStack + IConversionContextStack contextStack ) { _gisRasterConverter = gisRasterConverter; @@ -34,7 +33,7 @@ public SGIS.RasterLayer Convert(RasterLayer target) var speckleLayer = new SGIS.RasterLayer(); // get document CRS (for writing geometry coords) - var spatialRef = _contextStack.Current.Document.SpatialReference; + var spatialRef = _contextStack.Current.Document.Map.SpatialReference; speckleLayer.crs = new CRS { wkt = spatialRef.Wkt, @@ -47,7 +46,7 @@ public SGIS.RasterLayer Convert(RasterLayer target) // get active map CRS if layer CRS is empty if (spatialRefRaster.Unit is null) { - spatialRefRaster = _contextStack.Current.Document.SpatialReference; + spatialRefRaster = _contextStack.Current.Document.Map.SpatialReference; } speckleLayer.rasterCrs = new CRS { diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToHostConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToHostConverter.cs index b330f26dc5..374f09c23d 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToHostConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToHostConverter.cs @@ -5,6 +5,7 @@ using Speckle.Converters.ArcGIS3.Utils; using Speckle.Converters.Common.Objects; using FieldDescription = ArcGIS.Core.Data.DDL.FieldDescription; +using Speckle.Converters.Common; namespace Speckle.Converters.ArcGIS3.Layers; @@ -12,23 +13,23 @@ public class TableLayerToHostConverter : ITypedConverter { private readonly IFeatureClassUtils _featureClassUtils; private readonly IArcGISFieldUtils _fieldsUtils; - private readonly IArcGISProjectUtils _arcGISProjectUtils; + private readonly IConversionContextStack _contextStack; public TableLayerToHostConverter( IFeatureClassUtils featureClassUtils, - IArcGISProjectUtils arcGISProjectUtils, + IConversionContextStack contextStack, IArcGISFieldUtils fieldsUtils ) { _featureClassUtils = featureClassUtils; - _arcGISProjectUtils = arcGISProjectUtils; + _contextStack = contextStack; _fieldsUtils = fieldsUtils; } public Table Convert(VectorLayer target) { - string databasePath = _arcGISProjectUtils.GetDatabasePath(); - FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = new(new Uri(databasePath)); + FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = + new(_contextStack.Current.Document.SpeckleDatabasePath); Geodatabase geodatabase = new(fileGeodatabaseConnectionPath); SchemaBuilder schemaBuilder = new(geodatabase); diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToSpeckleConverter.cs index 31ee4bf6fc..110f752fc9 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/TableToSpeckleConverter.cs @@ -4,7 +4,6 @@ using Speckle.Converters.Common; using ArcGIS.Desktop.Mapping; using ArcGIS.Core.Data; -using ArcGIS.Core.Geometry; namespace Speckle.Converters.ArcGIS3.Layers; @@ -14,15 +13,10 @@ public class StandaloneTableToSpeckleConverter ITypedConverter { private readonly ITypedConverter _gisFeatureConverter; - private readonly IConversionContextStack _contextStack; - public StandaloneTableToSpeckleConverter( - ITypedConverter gisFeatureConverter, - IConversionContextStack contextStack - ) + public StandaloneTableToSpeckleConverter(ITypedConverter gisFeatureConverter) { _gisFeatureConverter = gisFeatureConverter; - _contextStack = contextStack; } public Base Convert(object target) diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToHostConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToHostConverter.cs index 58297364df..d4438f7339 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToHostConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToHostConverter.cs @@ -1,5 +1,4 @@ using ArcGIS.Core.Data; -using ArcGIS.Core.Geometry; using ArcGIS.Desktop.Mapping; using Objects.GIS; using Speckle.Converters.ArcGIS3.Utils; @@ -43,8 +42,8 @@ public string Convert(VectorLayer target) } // check if Speckle VectorLayer should become a FeatureClass, StandaloneTable or PointcloudLayer - GeometryType geomType = _featureClassUtils.GetLayerGeometryType(target); - if (geomType != GeometryType.Unknown) // feature class + ACG.GeometryType geomType = _featureClassUtils.GetLayerGeometryType(target); + if (geomType != ACG.GeometryType.Unknown) // feature class { return _featureClassConverter.Convert(target).GetName(); } diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToSpeckleConverter.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToSpeckleConverter.cs index cf38ebc4d4..5712ecc8ee 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToSpeckleConverter.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Layers/VectorLayerToSpeckleConverter.cs @@ -16,13 +16,13 @@ public class VectorLayerToSpeckleConverter : IToSpeckleTopLevelConverter, ITyped private readonly ITypedConverter _gisFeatureConverter; private readonly IFeatureClassUtils _featureClassUtils; private readonly IArcGISFieldUtils _fieldsUtils; - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; public VectorLayerToSpeckleConverter( ITypedConverter gisFeatureConverter, IFeatureClassUtils featureClassUtils, IArcGISFieldUtils fieldsUtils, - IConversionContextStack contextStack + IConversionContextStack contextStack ) { _gisFeatureConverter = gisFeatureConverter; @@ -55,7 +55,7 @@ public VectorLayer Convert(FeatureLayer target) VectorLayer speckleLayer = new(); // get document CRS (for writing geometry coords) - var spatialRef = _contextStack.Current.Document.SpatialReference; + var spatialRef = _contextStack.Current.Document.Map.SpatialReference; speckleLayer.crs = new CRS { wkt = spatialRef.Wkt, diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/ArcGISProjectUtils.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/ArcGISProjectUtils.cs deleted file mode 100644 index bf38a876bd..0000000000 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/ArcGISProjectUtils.cs +++ /dev/null @@ -1,82 +0,0 @@ -using ArcGIS.Core.Data; -using ArcGIS.Core.Data.DDL; -using ArcGIS.Desktop.Core; -using ArcGIS.Desktop.Framework.Threading.Tasks; - -namespace Speckle.Converters.ArcGIS3.Utils; - -public class ArcGISProjectUtils : IArcGISProjectUtils -{ - private const string FGDB_NAME = "Speckle.gdb"; - - public string GetDatabasePath() - { - string fGdbPath; - try - { - var parentDirectory = Directory.GetParent(Project.Current.URI); - if (parentDirectory == null) - { - throw new ArgumentException($"Project directory {Project.Current.URI} not found"); - } - fGdbPath = parentDirectory.ToString(); - } - catch (Exception ex) - when (ex - is IOException - or UnauthorizedAccessException - or ArgumentException - or NotSupportedException - or System.Security.SecurityException - ) - { - throw; - } - - return $"{fGdbPath}\\{FGDB_NAME}"; - } - - public string AddDatabaseToProject(string databasePath) - { - // Create a FileGeodatabaseConnectionPath with the name of the file geodatabase you wish to create - FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = new(new Uri(databasePath)); - // Create actual database in the specified Path unless already exists - try - { - Geodatabase geodatabase = SchemaBuilder.CreateGeodatabase(fileGeodatabaseConnectionPath); - geodatabase.Dispose(); - } - catch (ArcGIS.Core.Data.Exceptions.GeodatabaseWorkspaceException) - { - // geodatabase already exists, do nothing - } - - // Add a folder connection to a project - var parentFolder = Directory.GetParent(databasePath); - if (parentFolder == null) - { - // POC: customize the exception type - throw new ArgumentException($"Invalid path: {databasePath}"); - } - - string parentFolderPath = parentFolder.ToString(); - var fGdbName = databasePath.Replace(parentFolderPath + '\\', string.Empty, StringComparison.Ordinal); - - string fGdbPath = parentFolder.ToString(); - Item folderToAdd = ItemFactory.Instance.Create(fGdbPath); - // POC: QueuedTask - QueuedTask.Run(() => Project.Current.AddItem(folderToAdd as IProjectItem)); - - // Add a file geodatabase or a SQLite or enterprise database connection to a project - var gdbToAdd = folderToAdd - .GetItems() - .FirstOrDefault(folderItem => folderItem.Name.Equals(fGdbName, StringComparison.Ordinal)); - if (gdbToAdd is not null) - { - // POC: QueuedTask - var addedGeodatabase = QueuedTask.Run(() => Project.Current.AddItem(gdbToAdd as IProjectItem)); - } - - return fGdbName; - } -} diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/IArcGISProjectUtils.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/IArcGISProjectUtils.cs deleted file mode 100644 index c86e271073..0000000000 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/IArcGISProjectUtils.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Speckle.Converters.ArcGIS3.Utils; - -public interface IArcGISProjectUtils -{ - string GetDatabasePath(); - string AddDatabaseToProject(string databasePath); -} diff --git a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/NonNativeFeaturesUtils.cs b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/NonNativeFeaturesUtils.cs index 544ccc553f..cdb5226076 100644 --- a/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/NonNativeFeaturesUtils.cs +++ b/DUI3-DX/Converters/ArcGIS/Speckle.Converters.ArcGIS3/Utils/NonNativeFeaturesUtils.cs @@ -2,10 +2,7 @@ using ArcGIS.Core.Data; using ArcGIS.Core.Data.DDL; using ArcGIS.Core.Data.Exceptions; -using ArcGIS.Desktop.Mapping; using Speckle.Converters.Common; -using Speckle.Converters.Common.Objects; -using Speckle.Core.Models; using FieldDescription = ArcGIS.Core.Data.DDL.FieldDescription; using Speckle.Core.Logging; @@ -13,24 +10,15 @@ namespace Speckle.Converters.ArcGIS3.Utils; public class NonNativeFeaturesUtils : INonNativeFeaturesUtils { - private readonly ITypedConverter, ACG.Geometry> _gisGeometryConverter; - private readonly IArcGISFieldUtils _fieldsUtils; private readonly IFeatureClassUtils _featureClassUtils; - private readonly IArcGISProjectUtils _arcGISProjectUtils; - private readonly IConversionContextStack _contextStack; + private readonly IConversionContextStack _contextStack; public NonNativeFeaturesUtils( - ITypedConverter, ACG.Geometry> gisGeometryConverter, - IArcGISFieldUtils fieldsUtils, IFeatureClassUtils featureClassUtils, - IArcGISProjectUtils arcGISProjectUtils, - IConversionContextStack contextStack + IConversionContextStack contextStack ) { - _gisGeometryConverter = gisGeometryConverter; - _fieldsUtils = fieldsUtils; _featureClassUtils = featureClassUtils; - _arcGISProjectUtils = arcGISProjectUtils; _contextStack = contextStack; } @@ -96,13 +84,13 @@ public NonNativeFeaturesUtils( private string CreateDatasetInDatabase(string speckle_type, List geomList, string? parentId) { - string databasePath = _arcGISProjectUtils.GetDatabasePath(); - FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = new(new Uri(databasePath)); + FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = + new(_contextStack.Current.Document.SpeckleDatabasePath); Geodatabase geodatabase = new(fileGeodatabaseConnectionPath); SchemaBuilder schemaBuilder = new(geodatabase); // get Spatial Reference from the document - ACG.SpatialReference spatialRef = _contextStack.Current.Document.SpatialReference; + ACG.SpatialReference spatialRef = _contextStack.Current.Document.Map.SpatialReference; // TODO: create Fields List fields = new(); // _fieldsUtils.GetFieldsFromSpeckleLayer(target);