Skip to content

Commit

Permalink
CNX-9446 create enums for arc gis custom types (#3429)
Browse files Browse the repository at this point in the history
* add layer geometry types class

* fix dataset overwriting caused by the fallback conversions

* class for FieldTypes

* declutter CreateDatasetInDatabase

* post-merge issues

* post-merge issues2

---------

Co-authored-by: Alan Rynne <[email protected]>
  • Loading branch information
KatKatKateryna and AlanRynne authored May 30, 2024
1 parent 9aa8249 commit 5469a12
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using ArcGIS.Core.Data;
using Speckle.Converters.ArcGIS3.Geometry;
using Speckle.Converters.Common;
using Speckle.Converters.ArcGIS3.Utils;

namespace Speckle.Converters.ArcGIS3.Features;

Expand Down Expand Up @@ -57,32 +58,23 @@ public SGIS.GisFeature Convert(Row target)
IReadOnlyList<Field> fields = target.GetFields();
foreach (Field field in fields)
{
string name = field.Name;
// POC: check for all possible reserved Shape names
if (field.FieldType == FieldType.Geometry) // ignore the field with geometry itself
{
hasGeometry = true;
geometryField = name;
geometryField = field.Name;
}
// Raster FieldType is not properly supported through API
else if (
field.FieldType == FieldType.Raster || field.FieldType == FieldType.Blob || field.FieldType == FieldType.XML
)
{
attributes[name] = null;
attributes[field.Name] = null;
}
// to not break serializer (DateOnly) and to simplify complex types
else if (
field.FieldType == FieldType.DateOnly
|| field.FieldType == FieldType.TimeOnly
|| field.FieldType == FieldType.TimestampOffset
)
{
attributes[name] = target[name]?.ToString();
}
else
{
attributes[name] = target[name];
attributes[field.Name] = GISAttributeFieldType.FieldValueToSpeckle(target, field);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using ArcGIS.Core.CIM;
using Speckle.Converters.ArcGIS3.Geometry;
using Speckle.Core.Models;
using Speckle.Converters.ArcGIS3.Utils;

namespace Speckle.Converters.ArcGIS3.Layers;

Expand Down Expand Up @@ -88,7 +89,7 @@ public SGIS.VectorLayer Convert(LasDatasetLayer target)
speckleLayer.name = target.Name;
speckleLayer.units = _contextStack.Current.SpeckleUnits;
speckleLayer.nativeGeomType = target.MapLayerType.ToString();
speckleLayer.geomType = "Pointcloud";
speckleLayer.geomType = GISLayerGeometryType.POINTCLOUD;

// prepare data for pointcloud
List<SOG.Point> specklePts = new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public string Convert(VectorLayer target)
// pointcloud layers need to be checked separately, because there is no ArcGIS Geometry type
// for Pointcloud. In ArcGIS it's a completely different layer class, so "GetLayerGeometryType"
// will return "Invalid" type
if (target.geomType == "Pointcloud")
if (target.geomType == GISLayerGeometryType.POINTCLOUD)
{
return _pointcloudLayerConverter.Convert(target).Name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using Speckle.Converters.ArcGIS3.Utils;
using ArcGIS.Core.CIM;

namespace Speckle.Converters.ArcGIS3.Layers;

Expand Down Expand Up @@ -35,26 +36,18 @@ public Base Convert(object target)
return Convert((FeatureLayer)target);
}

private string SpeckleGeometryType(string nativeGeometryType)
private string AssignSpeckleGeometryType(esriGeometryType nativeGeometryType)
{
string spekleGeometryType = "None";
if (nativeGeometryType.Contains("point", StringComparison.OrdinalIgnoreCase))
return nativeGeometryType switch
{
spekleGeometryType = "Point";
}
else if (nativeGeometryType.Contains("polyline", StringComparison.OrdinalIgnoreCase))
{
spekleGeometryType = "Polyline";
}
else if (nativeGeometryType.Contains("polygon", StringComparison.OrdinalIgnoreCase))
{
spekleGeometryType = "Polygon";
}
else if (nativeGeometryType.Contains("multipatch", StringComparison.OrdinalIgnoreCase))
{
spekleGeometryType = "Multipatch";
}
return spekleGeometryType;
esriGeometryType.esriGeometryMultipoint => GISLayerGeometryType.POINT,
esriGeometryType.esriGeometryPoint => GISLayerGeometryType.POINT,
esriGeometryType.esriGeometryLine => GISLayerGeometryType.POLYLINE,
esriGeometryType.esriGeometryPolyline => GISLayerGeometryType.POLYLINE,
esriGeometryType.esriGeometryPolygon => GISLayerGeometryType.POLYGON,
esriGeometryType.esriGeometryMultiPatch => GISLayerGeometryType.MULTIPATCH,
_ => GISLayerGeometryType.NONE,
};
}

public VectorLayer Convert(FeatureLayer target)
Expand Down Expand Up @@ -94,14 +87,13 @@ public VectorLayer Convert(FeatureLayer target)
continue;
}
addedFieldDescriptions.Add(field);
allLayerAttributes[name] = (int)field.Type;
allLayerAttributes[name] = GISAttributeFieldType.FieldTypeToSpeckle(field.Type);
}
}
speckleLayer.attributes = allLayerAttributes;
speckleLayer.nativeGeomType = target.ShapeType.ToString();

// get a simple geometry type
string spekleGeometryType = SpeckleGeometryType(speckleLayer.nativeGeomType);
string spekleGeometryType = AssignSpeckleGeometryType(target.ShapeType);
speckleLayer.geomType = spekleGeometryType;

// search the rows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,54 +16,6 @@ public ArcGISFieldUtils(ICharacterCleaner characterCleaner)
_characterCleaner = characterCleaner;
}

public object? FieldValueToNativeType(FieldType fieldType, object? value)
{
// Geometry: ignored
// Blob, Raster, TimestampOffset, XML: converted to String (field type already converted to String on Send)
switch (fieldType)
{
case FieldType.GUID:
return value;
case FieldType.OID:
return value;
}

if (value is not null)
{
try
{
switch (fieldType)
{
case FieldType.String:
return (string)value;
case FieldType.Single:
return (float)(double)value;
case FieldType.Integer:
// need this step because sent "ints" seem to be received as "longs"
return (int)(long)value;
case FieldType.BigInteger:
return (long)value;
case FieldType.SmallInteger:
return (short)(long)value;
case FieldType.Double:
return (double)value;
case FieldType.Date:
return DateTime.Parse((string)value, null);
case FieldType.DateOnly:
return DateOnly.Parse((string)value);
case FieldType.TimeOnly:
return TimeOnly.Parse((string)value);
}
}
catch (InvalidCastException)
{
return value;
}
}

return value;
}

public RowBuffer AssignFieldValuesToRow(RowBuffer rowBuffer, List<FieldDescription> fields, GisFeature feat)
{
foreach (FieldDescription field in fields)
Expand All @@ -79,7 +31,7 @@ public RowBuffer AssignFieldValuesToRow(RowBuffer rowBuffer, List<FieldDescripti
// POC: get all values in a correct format
try
{
rowBuffer[key] = FieldValueToNativeType(fieldType, value);
rowBuffer[key] = GISAttributeFieldType.SpeckleValueToNativeFieldType(fieldType, value);
}
catch (GeodatabaseFeatureException)
{
Expand All @@ -101,11 +53,6 @@ public RowBuffer AssignFieldValuesToRow(RowBuffer rowBuffer, List<FieldDescripti
return rowBuffer;
}

public FieldType GetFieldTypeFromInt(int fieldType)
{
return (FieldType)fieldType;
}

public List<FieldDescription> GetFieldsFromSpeckleLayer(VectorLayer target)
{
List<FieldDescription> fields = new();
Expand All @@ -121,7 +68,7 @@ public List<FieldDescription> GetFieldsFromSpeckleLayer(VectorLayer target)
if (field.Value is not null)
{
string key = field.Key;
FieldType fieldType = GetFieldTypeFromInt((int)(long)field.Value);
FieldType fieldType = GISAttributeFieldType.FieldTypeToNative(field.Value);

FieldDescription fieldDescription =
new(_characterCleaner.CleanCharacters(key), fieldType) { AliasName = key };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,54 +85,15 @@ List<FieldDescription> fields
public ACG.GeometryType GetLayerGeometryType(VectorLayer target)
{
string? originalGeomType = target.geomType != null ? target.geomType : target.nativeGeomType;

if (string.IsNullOrEmpty(originalGeomType))
{
throw new SpeckleConversionException($"Unknown geometry type for layer {target.name}");
}
return GetGeometryTypeFromString(originalGeomType.ToLower());
}

public ACG.GeometryType GetGeometryTypeFromString(string target)
{
// POC: find better pattern
if (target.Contains("none", StringComparison.OrdinalIgnoreCase))
return originalGeomType switch
{
return ACG.GeometryType.Unknown;
}
else if (target.Contains("pointcloud", StringComparison.OrdinalIgnoreCase))
{
return ACG.GeometryType.Unknown;
}
else if (target.Contains("point", StringComparison.OrdinalIgnoreCase))
{
return ACG.GeometryType.Multipoint;
}
else if (
target.Contains("line", StringComparison.OrdinalIgnoreCase)
|| target.Contains("curve", StringComparison.OrdinalIgnoreCase)
|| target.Contains("arc", StringComparison.OrdinalIgnoreCase)
|| target.Contains("circle", StringComparison.OrdinalIgnoreCase)
|| target.Contains("ellipse", StringComparison.OrdinalIgnoreCase)
)
{
return ACG.GeometryType.Polyline;
}
else if (target.Contains("polygon", StringComparison.OrdinalIgnoreCase))
{
return ACG.GeometryType.Polygon;
}
else if (target.Contains("multipatch", StringComparison.OrdinalIgnoreCase))
{
return ACG.GeometryType.Multipatch;
}
else if (target.Contains("mesh", StringComparison.OrdinalIgnoreCase))
{
return ACG.GeometryType.Multipatch;
}
else
{
throw new SpeckleConversionException($"Unknown geometry type {target}");
}
GISLayerGeometryType.NONE => ACG.GeometryType.Unknown,
GISLayerGeometryType.POINT => ACG.GeometryType.Multipoint,
GISLayerGeometryType.POLYGON => ACG.GeometryType.Polygon,
GISLayerGeometryType.POLYLINE => ACG.GeometryType.Polyline,
GISLayerGeometryType.MULTIPATCH => ACG.GeometryType.Multipatch,
GISLayerGeometryType.POLYGON3D => ACG.GeometryType.Multipatch,
_ => throw new ArgumentOutOfRangeException(nameof(target)),
};
}
}
Loading

0 comments on commit 5469a12

Please sign in to comment.