Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D ui3 425 create custom crs from lat lon in degrees #3534

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ CancellationToken cancellationToken
// Prompt the UI conversion started. Progress bar will swoosh.
onOperationProgressed?.Invoke("Converting", null);

// Browse for any trace of geolocation in non-GIS apps (e.g. Revit: implemented, Blender: todo on Blender side, Civil3d: ?)
CRSorigin? dataOrigin = null; // e.g. CRSorigin.FromRevitData(rootObject);

// save SpatialReference (overwrite default Map.SpatialRef), use it for dataset writing
if (dataOrigin is CRSorigin crsOrigin)
{
SpatialReference incomingSpatialRef = crsOrigin.CreateCustomCRS();
_contextStack.Current.Document.IncomingSpatialReference = incomingSpatialRef;
}

var objectsToConvert = _traverseFunction
.Traverse(rootObject)
.Where(ctx => ctx.Current is not Collection || IsGISType(ctx.Current))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using Speckle.Converters.Common;
using ArcGIS.Core.Geometry;

namespace Speckle.Converters.ArcGIS3;

Expand All @@ -13,12 +14,14 @@ public class ArcGISDocument
public Project Project { get; }
public Map Map { get; }
public Uri SpeckleDatabasePath { get; }
public SpatialReference IncomingSpatialReference { get; set; }

public ArcGISDocument()
{
Project = Project.Current;
Map = MapView.Active.Map;
SpeckleDatabasePath = EnsureOrAddSpeckleDatabase();
IncomingSpatialReference = MapView.Active.Map.SpatialReference;
}

private const string FGDB_NAME = "Speckle.gdb";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ public PointToHostConverter(IConversionContextStack<ArcGISDocument, ACG.Unit> co

public ACG.MapPoint Convert(SOG.Point target)
{
double scaleFactor = Units.GetConversionFactor(target.units, _contextStack.Current.SpeckleUnits);
double scaleFactor = Units.GetConversionFactor(
target.units,
_contextStack.Current.Document.IncomingSpatialReference.Unit.ToString()
);
return new ACG.MapPointBuilderEx(
target.x * scaleFactor,
target.y * scaleFactor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public FeatureClass Convert(VectorLayer target)
wktString = target.crs.wkt.ToString();
}
ACG.SpatialReference spatialRef = ACG.SpatialReferenceBuilder.CreateSpatialReference(wktString);
_contextStack.Current.Document.IncomingSpatialReference = spatialRef;

// create Fields
List<FieldDescription> fields = _fieldsUtils.GetFieldsFromSpeckleLayer(target);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using ArcGIS.Core.Geometry;
using Objects.BuiltElements.Revit;
using Speckle.Core.Models;

namespace Speckle.Converters.ArcGIS3.Utils;

/// <summary>
/// Container with origin coordinates and rotation angle
/// </summary>
public readonly struct CRSorigin
{
public double LatDegrees { get; }
public double LonDegrees { get; }

/// <summary>
/// Initializes a new instance of <see cref="CRSorigin"/>.
/// </summary>
/// <param name="latDegrees">Latitude (Y) in degrees.</param>
/// <param name="lonDegrees">Longitude (X) in degrees.</param>
public CRSorigin(double latDegrees, double lonDegrees)
{
LatDegrees = latDegrees;
LonDegrees = lonDegrees;
}

public static CRSorigin? FromRevitData(Base rootObject)
{
// rewrite function to take into account Local reference point in Revit, and Transformation matrix
foreach (KeyValuePair<string, object?> prop in rootObject.GetMembers(DynamicBaseMemberType.Dynamic))
{
if (prop.Key == "info")
{
ProjectInfo? revitProjInfo = (ProjectInfo?)rootObject[prop.Key];
if (revitProjInfo != null)
{
try
{
double lat = Convert.ToDouble(revitProjInfo["latitude"]);
double lon = Convert.ToDouble(revitProjInfo["longitude"]);
double trueNorth;
if (revitProjInfo["locations"] is List<Base> locationList && locationList.Count > 0)
{
Base location = locationList[0];
trueNorth = Convert.ToDouble(location["trueNorth"]);
}
return new CRSorigin(lat * 180 / Math.PI, lon * 180 / Math.PI);
}
catch (Exception ex) when (ex is FormatException || ex is InvalidCastException || ex is OverflowException)
{
// origin not found, do nothing
}
break;
}
}
}
return null;
}

public SpatialReference CreateCustomCRS()
{
string wktString =
// QGIS example: $"PROJCS[\"unknown\", GEOGCS[\"unknown\", DATUM[\"WGS_1984\", SPHEROID[\"WGS 84\", 6378137, 298.257223563], AUTHORITY[\"EPSG\", \"6326\"]], PRIMEM[\"Greenwich\", 0, AUTHORITY[\"EPSG\", \"8901\"]], UNIT[\"degree\", 0.0174532925199433]], PROJECTION[\"Transverse_Mercator\"], PARAMETER[\"latitude_of_origin\", {LatDegrees}], PARAMETER[\"central_meridian\", {LonDegrees}], PARAMETER[\"scale_factor\", 1], PARAMETER[\"false_easting\", 0], PARAMETER[\"false_northing\", 0], UNIT[\"metre\", 1, AUTHORITY[\"EPSG\", \"9001\"]], AXIS[\"Easting\", EAST], AXIS[\"Northing\", NORTH]]";
// replicating ArcGIS created custom WKT:
$"PROJCS[\"SpeckleSpatialReference_latlon_{LatDegrees}_{LonDegrees}\", GEOGCS[\"GCS_WGS_1984\", DATUM[\"D_WGS_1984\", SPHEROID[\"WGS_1984\", 6378137.0, 298.257223563]], PRIMEM[\"Greenwich\", 0.0], UNIT[\"Degree\", 0.0174532925199433]], PROJECTION[\"Transverse_Mercator\"], PARAMETER[\"False_Easting\", 0.0], PARAMETER[\"False_Northing\", 0.0], PARAMETER[\"Central_Meridian\", {LonDegrees}], PARAMETER[\"Scale_Factor\", 1.0], PARAMETER[\"Latitude_Of_Origin\", {LatDegrees}], UNIT[\"Meter\", 1.0]]";

return SpatialReferenceBuilder.CreateSpatialReference(wktString);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private void CreateDatasetInDatabase(
SchemaBuilder schemaBuilder = new(geodatabase);

// get Spatial Reference from the document
ACG.SpatialReference spatialRef = _contextStack.Current.Document.Map.SpatialReference;
ACG.SpatialReference spatialRef = _contextStack.Current.Document.IncomingSpatialReference;

// create Fields
List<(FieldDescription, Func<Base, object?>)> fieldsAndFunctions = _fieldUtils.CreateFieldsFromListOfBase(
Expand Down
Loading