Skip to content

ProSnippets 3D Analyst Data

UmaHarano edited this page Nov 6, 2024 · 3 revisions
Language:              C#  
Subject:               3DAnalystData  
Contributor:           ArcGIS Pro SDK Team <arcgisprosdk@esri.com>  
Organization:          esri, http://www.esri.com  
Date:                  10/22/2024  
ArcGIS Pro:            3.4  
Visual Studio:         2022  
.NET Target Framework: .Net 8  

TIN

Open a TIN Dataset

public async Task OpenTinDataset()
{
  try
  {
    await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
    {
      string path = @"d:\Data\Tin";
      var fileConnection = new FileSystemConnectionPath(new Uri(path), FileSystemDatastoreType.Tin);

      using (FileSystemDatastore dataStore = new FileSystemDatastore(fileConnection))
      {
        // TIN is in a folder at d:\Data\Tin\TinDataset

        string dsName = "TinDataset";

        using (var dataset = dataStore.OpenDataset<ArcGIS.Core.Data.Analyst3D.TinDataset>(dsName))
        {

        }
      }
    });
  }
  catch (GeodatabaseNotFoundOrOpenedException exception)
  {
    // Handle Exception.
  }
}

Get a TIN Defintion

public async Task GetTinDatasetDefinition()
{
  try
  {
    await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
    {
      string path = @"d:\Data\Tin";
      var fileConnection = new FileSystemConnectionPath(new Uri(path), FileSystemDatastoreType.Tin);

      using (FileSystemDatastore dataStore = new FileSystemDatastore(fileConnection))
      {
        // TIN is in a folder at d:\Data\Tin\TinDataset

        string dsName = "TinDataset";

        using (var def = dataStore.GetDefinition<ArcGIS.Core.Data.Analyst3D.TinDatasetDefinition>(dsName))
        {

        }
      }
    });
  }
  catch (GeodatabaseNotFoundOrOpenedException exception)
  {
    // Handle Exception.
  }
}

Get Super Node Extent

var superNodeExtent = tinDataset.GetSuperNodeExtent();

Get Data Area

var dataArea = tinDataset.GetDataArea();

Element Counts

var nodeCount = tinDataset.GetNodeCount();
var outsideNodeCount = tinDataset.GetOutsideNodeCount();
var edgeCount = tinDataset.GetEdgeCount();
var outsideEdgecount = tinDataset.GetOutsideEdgeCount();
var triCount = tinDataset.GetTriangleCount();
var outsideTriCount = tinDataset.GetOutsideTriangleCount();

Tin Properties

var isEmpty = tinDataset.GetIsEmpty();
var hasHardEdges = tinDataset.HasHardEdges();
var hasSoftEdges = tinDataset.HasSoftEdges();

var isConstrainedDelaunay = tinDataset.UsesConstrainedDelaunay();

Access TIN Elements By Index

using (ArcGIS.Core.Data.Analyst3D.TinNode node = tinDataset.GetNodeByIndex(23))
{

}

using (ArcGIS.Core.Data.Analyst3D.TinEdge edge = tinDataset.GetEdgeByIndex(45))
{

}
using (ArcGIS.Core.Data.Analyst3D.TinTriangle triangle = tinDataset.GetTriangleByIndex(22))
{

}

Search for TIN Nodes

// search all nodes
using (ArcGIS.Core.Data.Analyst3D.TinNodeCursor nodeCursor = tinDataset.SearchNodes(null))
{
  while (nodeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinNode node = nodeCursor.Current)
    {

    }
  }
}

// search within an extent
ArcGIS.Core.Data.Analyst3D.TinNodeFilter nodeFilter = new ArcGIS.Core.Data.Analyst3D.TinNodeFilter();
nodeFilter.FilterEnvelope = envelope;
using (ArcGIS.Core.Data.Analyst3D.TinNodeCursor nodeCursor = tinDataset.SearchNodes(nodeFilter))
{
  while (nodeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinNode node = nodeCursor.Current)
    {

    }
  }
}

// search all "inside" nodes
nodeFilter = new ArcGIS.Core.Data.Analyst3D.TinNodeFilter();
nodeFilter.FilterType = ArcGIS.Core.Data.Analyst3D.TinFilterType.InsideDataArea;
using (ArcGIS.Core.Data.Analyst3D.TinNodeCursor nodeCursor = tinDataset.SearchNodes(nodeFilter))
{
  while (nodeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinNode node = nodeCursor.Current)
    {

    }
  }
}

// search for super nodes only
nodeFilter = new ArcGIS.Core.Data.Analyst3D.TinNodeFilter();
nodeFilter.FilterEnvelope = tinDataset.GetSuperNodeExtent();
nodeFilter.SuperNode = true;
using (ArcGIS.Core.Data.Analyst3D.TinNodeCursor nodeCursor = tinDataset.SearchNodes(nodeFilter))
{
  while (nodeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinNode node = nodeCursor.Current)
    {

    }
  }
}

Search for TIN Edges

// search all edges
using (ArcGIS.Core.Data.Analyst3D.TinEdgeCursor edgeCursor = tinDataset.SearchEdges(null))
{
  while (edgeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinEdge edge = edgeCursor.Current)
    {

    }
  }
}

// search within an extent
ArcGIS.Core.Data.Analyst3D.TinEdgeFilter edgeFilter = new ArcGIS.Core.Data.Analyst3D.TinEdgeFilter();
edgeFilter.FilterEnvelope = envelope;
using (ArcGIS.Core.Data.Analyst3D.TinEdgeCursor edgeCursor = tinDataset.SearchEdges(edgeFilter))
{
  while (edgeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinEdge edge = edgeCursor.Current)
    {

    }
  }
}

// search all "inside" edges
edgeFilter = new ArcGIS.Core.Data.Analyst3D.TinEdgeFilter();
edgeFilter.FilterType = ArcGIS.Core.Data.Analyst3D.TinFilterType.InsideDataArea;
using (ArcGIS.Core.Data.Analyst3D.TinEdgeCursor edgeCursor = tinDataset.SearchEdges(edgeFilter))
{
  while (edgeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinEdge edge = edgeCursor.Current)
    {

    }
  }
}

// search for hard edges
edgeFilter = new ArcGIS.Core.Data.Analyst3D.TinEdgeFilter();
edgeFilter.FilterByEdgeType = true;
edgeFilter.EdgeType = ArcGIS.Core.Data.Analyst3D.TinEdgeType.HardEdge;
using (ArcGIS.Core.Data.Analyst3D.TinEdgeCursor edgeCursor = tinDataset.SearchEdges(edgeFilter))
{
  while (edgeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinEdge edge = edgeCursor.Current)
    {

    }
  }
}

Search for TIN Triangles

// search all triangles
using (ArcGIS.Core.Data.Analyst3D.TinTriangleCursor triangleCursor = tinDataset.SearchTriangles(null))
{
  while (triangleCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinTriangle triangle = triangleCursor.Current)
    {

    }
  }
}

// search within an extent
ArcGIS.Core.Data.Analyst3D.TinTriangleFilter triangleFilter = new ArcGIS.Core.Data.Analyst3D.TinTriangleFilter();
triangleFilter.FilterEnvelope = envelope;
using (ArcGIS.Core.Data.Analyst3D.TinTriangleCursor triangleCursor = tinDataset.SearchTriangles(triangleFilter))
{
  while (triangleCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinTriangle triangle = triangleCursor.Current)
    {

    }
  }
}

// search all "inside" triangles
triangleFilter = new ArcGIS.Core.Data.Analyst3D.TinTriangleFilter();
triangleFilter.FilterType = ArcGIS.Core.Data.Analyst3D.TinFilterType.InsideDataArea;
using (ArcGIS.Core.Data.Analyst3D.TinTriangleCursor triangleCursor = tinDataset.SearchTriangles(triangleFilter))
{
  while (triangleCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinTriangle triangle = triangleCursor.Current)
    {

    }
  }
}

Access TIN Elements by MapPoint

// "identify" the closest node, edge, triangle
using (var nearestNode = tinDataset.GetNearestNode(mapPoint))
{
}

using (var nearestEdge = tinDataset.GetNearestEdge(mapPoint))
{
}
using (var triangle = tinDataset.GetTriangleByPoint(mapPoint))
{

}

// get the set of natural neighbours 
// (set of nodes that "mapPoint" would connect with to form triangles if it was added to the TIN)
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.TinNode> naturalNeighbors = tinDataset.GetNaturalNeighbors(mapPoint);

// get the set of triangles whose circumscribed circle contains "mapPoint" 
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.TinTriangle> triangles = tinDataset.GetTriangleNeighborhood(mapPoint);

TIN Nodes

// node coordinates
var coord3D = node.Coordinate3D;
var mapPoint = node.ToMapPoint();
// is the node "inside"
var isInsideNode = node.IsInsideDataArea;

// get all other nodes connected to "node" 
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.TinNode> adjNodes = node.GetAdjacentNodes();

// get all edges that share "node" as a from node. 
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.TinEdge> edges = node.GetIncidentEdges();

// get all triangles that share "node"
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.TinTriangle> triangles = node.GetIncidentTriangles();

TIN Edges

// nodes of the edge
var nodes = edge.Nodes;

// edge geometry
var polyline = edge.ToPolyline();
// edge length
var length = edge.Length;
// is the edge "inside"
var isInsideEdge = edge.IsInsideDataArea;
// edge type - regular/hard/soft
var edgeType = edge.EdgeType;

// get next (clockwise) edge in the triangle
var nextEdge = edge.GetNextEdgeInTriangle();
// get previous (anti-clockwise) edge in the triangle
var prevEdge = edge.GetPreviousEdgeInTriangle();

// get opposite edge
var oppEdge = edge.GeNeighbor();

// get left triangle
var leftTriangle = edge.LeftTriangle;
// get right triangle
var rightTriangle = edge.RightTriangle;

TIN Triangles

// nodes, edges of the triangle
var triNnodes = triangle.Nodes;
var triEdges = triangle.Edges;

// triangle geometry
var polygon = triangle.ToPolygon();
// triangle length
var triLength = triangle.Length;
// triangle area 
var triArea = triangle.Area;
// is the triangle "inside"
var isInsideTriangle = triangle.IsInsideDataArea;

// triangle aspect and slope  (radians)
var aspect = triangle.Aspect;
var slope = triangle.Slope;

// get centroid
var centroid = triangle.GetCentroid();

// get normal
var normal = triangle.GetNormal();

// get adjacent triangles
var adjTriangles = triangle.GetAdjacentTriangles();

// get area of triangle that falls between the z values
double minZ = 1.0;
double maxZ = 3.0;
IReadOnlyList<Coordinate3D> coords = triangle.GetPointsBetweenZs(minZ, maxZ);

Terrain

Open a Terrain

public async Task OpenTerrain()
{
  try
  {
    await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
    {
      string path = @"d:\Data\Terrain\filegdb_Containing_A_Terrain.gdb";
      var fileConnection = new FileGeodatabaseConnectionPath(new Uri(path));

      using (Geodatabase dataStore = new Geodatabase(fileConnection))
      {
        string dsName = "nameOfTerrain";

        using (var dataset = dataStore.OpenDataset<ArcGIS.Core.Data.Analyst3D.Terrain>(dsName))
        {
        }
      }
    });
  }
  catch (GeodatabaseNotFoundOrOpenedException exception)
  {
    // Handle Exception.
  }
}

Get a Terrain Definition

public async Task GetTerrainDefinition()
{
  try
  {
    await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
    {
      string path = @"d:\Data\Terrain\filegdb_Containing_A_Terrain.gdb";
      var fileConnection = new FileGeodatabaseConnectionPath(new Uri(path));

      using (Geodatabase dataStore = new Geodatabase(fileConnection))
      {
        string dsName = "nameOfTerrain";

        using (var terrainDef = dataStore.GetDefinition<ArcGIS.Core.Data.Analyst3D.TerrainDefinition>(dsName))
        {
          // get the feature class names that are used in the terrain
          var fcNames = terrainDef.GetFeatureClassNames();
        }
      }
    });
  }
  catch (GeodatabaseNotFoundOrOpenedException exception)
  {
    // Handle Exception.
  }
}

Get datasources from a Terrain

var dsCount = terrain.GetDataSourceCount();
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.TerrainDataSource> dataSources = terrain.GetDataSources();
foreach (var ds in dataSources)
{
  var dsName = ds.DataSourceName;
  var surfaceType = ds.SurfaceType;
  var maxResolution = ds.MaximumResolution;
  var minResolution = ds.MinimumResolution;
}

Get Pyramid Level Information from a Terrain

var levelCount = terrain.GetPyramidLevelCount();
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.TerrainPyramidLevel> pyramidLevels = terrain.GetPyramidLevels();
foreach (var pyramidLevel in pyramidLevels)
{
  var resolution = pyramidLevel.Resolution;
  var maxScale = pyramidLevel.MaximumScale;
}

Get Tile Information from a Terrain

var tileInfo = terrain.GetTileProperties();
var colCount = tileInfo.ColumnCount;
var rowCount = tileInfo.RowCount;
var tileSize = tileInfo.TileSize;
var tileCount = tileInfo.TileCount;

Get Pyramid Information from a TerrainDefinition

var pyramidType = terrainDef.GetPyramidType();
var pyramidProps = terrainDef.GetPyramidWindowSizeProperties();

var method = pyramidProps.Method;
var threshold = pyramidProps.ZThreshold;
var strategy = pyramidProps.ZThresholdStrategy;

LAS Dataset

Open a LAS Dataset

public async Task OpenLasDataset()
{
  try
  {
    await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
    {
      string path = @"d:\Data\LASDataset";
      var fileConnection = new FileSystemConnectionPath(new Uri(path), FileSystemDatastoreType.LasDataset);

      using (FileSystemDatastore dataStore = new FileSystemDatastore(fileConnection))
      {
        string name = "utrecht_tile.lasd";      // can specify with or without the .lasd extension

        using (var dataset = dataStore.OpenDataset<ArcGIS.Core.Data.Analyst3D.LasDataset>(name))
        {

        }
      }
    });
  }
  catch (GeodatabaseNotFoundOrOpenedException exception)
  {
    // Handle Exception.
  }
}

Get a LAS Dataset Defintion

public async Task GetLasDatasetDefinition()
{
  try
  {
    await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
    {
      string path = @"d:\Data\LASDataset";
      var fileConnection = new FileSystemConnectionPath(new Uri(path), FileSystemDatastoreType.LasDataset);

      using (FileSystemDatastore dataStore = new FileSystemDatastore(fileConnection))
      {
        string name = "utrecht_tile.lasd";      // can specify with or without the .lasd extension

        using (var dataset = dataStore.GetDefinition<ArcGIS.Core.Data.Analyst3D.LasDatasetDefinition>(name))
        {

        }
      }
    });
  }
  catch (GeodatabaseNotFoundOrOpenedException exception)
  {
    // Handle Exception.
  }
}

Get Individual File Information from a LAS Dataset

var (lasFileCount, zLasFileCount) = lasDataset.GetFileCounts();
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.LasFile> fileInfo = lasDataset.GetFiles();
foreach (var file in fileInfo)
{
  var path = file.FilePath;
  var name = file.FileName;
  var ptCount = file.PointCount;
  var zMin = file.ZMin;
  var zMax = file.ZMax;
}

Get Surface Constraint information from a LAS Dataset

var constraintCount = lasDataset.GetSurfaceConstraintCount();
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.SurfaceConstraint> constraints = lasDataset.GetSurfaceConstraints();
foreach (var constraint in constraints)
{
  var dsName = constraint.DataSourceName;
  var wksPath = constraint.WorkspacePath;
  var heightField = constraint.HeightField;
  var surfaceType = constraint.SurfaceType;
}

Get classification codes / Returns from a LAS Dataset

var classCodes = lasDataset.GetUniqueClassCodes();
var returns = lasDataset.GetUniqueReturns();

Access LAS Points by ID

// access by ID
IReadOnlyList<ArcGIS.Core.Data.Analyst3D.LasPoint> pts = lasDataset.GetPointByID(123456);

pts = lasDataset.GetPointByID(123456, envelope);
ArcGIS.Core.Data.Analyst3D.LasPoint pt = pts.FirstOrDefault();

var coords = pt.Coordinate3D;
var mapPoint = pt.ToMapPoint();

Search LAS Points

// search all points
using (ArcGIS.Core.Data.Analyst3D.LasPointCursor ptCursor = lasDataset.SearchPoints(null))
{
  while (ptCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.LasPoint point = ptCursor.Current)
    {

    }
  }
}

// search within an extent
ArcGIS.Core.Data.Analyst3D.LasPointFilter pointFilter = new ArcGIS.Core.Data.Analyst3D.LasPointFilter();
pointFilter.FilterGeometry = envelope;
using (ArcGIS.Core.Data.Analyst3D.LasPointCursor ptCursor = lasDataset.SearchPoints(pointFilter))
{
  while (ptCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.LasPoint point = ptCursor.Current)
    {

    }
  }
}

// search within an extent and limited to specific classification codes
pointFilter = new ArcGIS.Core.Data.Analyst3D.LasPointFilter();
pointFilter.FilterGeometry = envelope;
pointFilter.ClassCodes = new List<int> { 4, 5 };
using (ArcGIS.Core.Data.Analyst3D.LasPointCursor ptCursor = lasDataset.SearchPoints(pointFilter))
{
  while (ptCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.LasPoint point = ptCursor.Current)
    {

    }
  }
}

Search using pre initialized arrays

// search all points
using (ArcGIS.Core.Data.Analyst3D.LasPointCursor ptCursor = lasDataset.SearchPoints(null))
{
  int count;
  Coordinate3D[] lasPointsRetrieved = new Coordinate3D[10000];
  while (ptCursor.MoveNextArray(lasPointsRetrieved, null, null, null, out count))
  {
    var points = lasPointsRetrieved.ToList();
  
    // ...
  }
}

// search within an extent
// use MoveNextArray retrieving coordinates, fileIndex and pointIds
ArcGIS.Core.Data.Analyst3D.LasPointFilter filter = new ArcGIS.Core.Data.Analyst3D.LasPointFilter();
filter.FilterGeometry = envelope;
using (ArcGIS.Core.Data.Analyst3D.LasPointCursor ptCursor = lasDataset.SearchPoints(filter))
{
  int count;
  Coordinate3D[] lasPointsRetrieved = new Coordinate3D[50000];
  int[] fileIndexes = new int[50000];
  double[] pointIds = new double[50000];
  while (ptCursor.MoveNextArray(lasPointsRetrieved, null, fileIndexes, pointIds, out count))
  {
    var points = lasPointsRetrieved.ToList();

  }
}
Clone this wiki locally