ProSnippets 3D Analyst Layers - Esri/arcgis-pro-sdk GitHub Wiki

Language:              C#  
Subject:               3DAnalystLayers  
Contributor:           ArcGIS Pro SDK Team <[email protected]>  
Organization:          esri, http://www.esri.com  
Date:                  10/22/2024  
ArcGIS Pro:            3.4  
Visual Studio:         2022  
.NET Target Framework: .Net 8  

Layer Methods for TIN, Terrain, LasDataset

Retrieve layers

// find the first TIN layer
var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();

// find the first Terrain layer
var terrainLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TerrainLayer>().FirstOrDefault();

// find the first LAS dataset layer
var lasDatasetLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<LasDatasetLayer>().FirstOrDefault();

// find the set of surface layers
var surfacelayers = MapView.Active.Map.GetLayersAsFlattenedList().OfType<SurfaceLayer>();

Retrieve dataset objects

//Must be on the QueuedTask.Run()

Envelope extent;
SpatialReference sr;
using (var tin = tinLayer.GetTinDataset())
{
  using (var tinDef = tin.GetDefinition())
  {
    extent = tinDef.GetExtent();
    sr = tinDef.GetSpatialReference();
  }
}

using (var terrain = terrainLayer.GetTerrain())
{
  using (var terrainDef = terrain.GetDefinition())
  {
    extent = terrainDef.GetExtent();
    sr = terrainDef.GetSpatialReference();
  }
}

using (var lasDataset = lasDatasetLayer.GetLasDataset())
{
  using (var lasDatasetDef = lasDataset.GetDefinition())
  {
    extent = lasDatasetDef.GetExtent();
    sr = lasDatasetDef.GetSpatialReference();
  }
}

Create a TinLayer

//Must be on the QueuedTask.Run()

string tinPath = @"d:\Data\Tin\TinDataset";
var tinURI = new Uri(tinPath);

var tinCP = new TinLayerCreationParams(tinURI);
tinCP.Name = "My TIN Layer";
tinCP.IsVisible = false;

//Create the layer to the TIN
var tinLayer = LayerFactory.Instance.CreateLayer<TinLayer>(tinCP, map);

Create a TinLayer from a dataset

//Must be on the QueuedTask.Run()

var tinCP_ds = new TinLayerCreationParams(tinDataset);
tinCP_ds.Name = "My TIN Layer";
tinCP_ds.IsVisible = false;

//Create the layer to the TIN

var tinLayer_ds = LayerFactory.Instance.CreateLayer<TinLayer>(tinCP_ds, map);

Create a TinLayer with renderers

//Must be on the QueuedTask.Run()

var tinCP_renderers = new TinLayerCreationParams(tinDataset);
tinCP_renderers.Name = "My TIN layer";
tinCP_renderers.IsVisible = true;

// define the node renderer - use defaults
var node_rd = new TinNodeRendererDefinition();

// define the face/surface renderer
var face_rd = new TinFaceClassBreaksRendererDefinition();
face_rd.ClassificationMethod = ClassificationMethod.NaturalBreaks;
// accept default color ramp, breakCount

// set up the renderer dictionary
var rendererDict = new Dictionary<SurfaceRendererTarget, TinRendererDefinition>();
rendererDict.Add(SurfaceRendererTarget.Points, node_rd);
rendererDict.Add(SurfaceRendererTarget.Surface, face_rd);

// assign the dictionary to the creation params
tinCP_renderers.RendererDefinitions = rendererDict;

// create the layer
var tinLayer_rd = LayerFactory.Instance.CreateLayer<TinLayer>(tinCP_renderers, MapView.Active.Map);

Create a TerrainLayer

//Must be on the QueuedTask.Run()

string terrainPath = @"d:\Data\Terrain\filegdb_Containing_A_Terrain.gdb";
var terrainURI = new Uri(terrainPath);

var terrainCP = new TerrainLayerCreationParams(terrainURI);
terrainCP.Name = "My Terrain Layer";
terrainCP.IsVisible = false;

//Create the layer to the terrain
var terrainLayer = LayerFactory.Instance.CreateLayer<TerrainLayer>(terrainCP, map);

Create a TerrainLayer from a dataset

//Must be on the QueuedTask.Run()

var terrainCP_ds = new TerrainLayerCreationParams(terrain);
terrainCP_ds.Name = "My Terrain Layer";
terrainCP_ds.IsVisible = true;

//Create the layer to the terrain
var terrainLayer_ds = LayerFactory.Instance.CreateLayer<TerrainLayer>(terrainCP_ds, map);

Create a TerrainLayer with renderers

//Must be on the QueuedTask.Run()

var terrainCP_renderers = new TerrainLayerCreationParams(terrain);
terrainCP_renderers.Name = "My LAS Layer";
terrainCP_renderers.IsVisible = true;

// define the edge type renderer - use defaults
var edgeRD = new TinBreaklineRendererDefinition();

// define the face/surface renderer
var faceRD = new TinFaceClassBreaksRendererDefinition();
faceRD.ClassificationMethod = ClassificationMethod.NaturalBreaks;
// accept default color ramp, breakCount

// define the dirty area renderer - use defaults
var dirtyAreaRD = new TerrainDirtyAreaRendererDefinition();

// add renderers to dictionary
var t_dict = new Dictionary<SurfaceRendererTarget, TinRendererDefinition>();
t_dict.Add(SurfaceRendererTarget.Edges, edgeRD);
t_dict.Add(SurfaceRendererTarget.Surface, faceRD);
t_dict.Add(SurfaceRendererTarget.DirtyArea, dirtyAreaRD);

// assign dictionary to creation params
terrainCP_renderers.RendererDefinitions = t_dict;

//Create the layer to the terrain
var terrainLayer_rd = LayerFactory.Instance.CreateLayer<TerrainLayer>(terrainCP_renderers, map);

Create a LasDatasetLayer

//Must be on the QueuedTask.Run()

string lasPath = @"d:\Data\LASDataset.lasd";
var lasURI = new Uri(lasPath);

var lasCP = new LasDatasetLayerCreationParams(lasURI);
lasCP.Name = "My LAS Layer";
lasCP.IsVisible = false;

//Create the layer to the LAS dataset
var lasDatasetLayer = LayerFactory.Instance.CreateLayer<LasDatasetLayer>(lasCP, map);

Create a LasDatasetLayer from a LasDataset

//Must be on the QueuedTask.Run()

var lasCP_ds = new LasDatasetLayerCreationParams(lasDataset);
lasCP_ds.Name = "My LAS Layer";
lasCP_ds.IsVisible = false;

//Create the layer to the LAS dataset
var lasDatasetLayer_ds = LayerFactory.Instance.CreateLayer<LasDatasetLayer>(lasCP_ds, map);

Create a LasDatasetLayer with renderers

//Must be on the QueuedTask.Run()

var lasCP_renderers = new LasDatasetLayerCreationParams(lasDataset);
lasCP_renderers.Name = "My LAS Layer";
lasCP_renderers.IsVisible = false;

// create a point elevation renderer
var ptR = new LasStretchRendererDefinition();
// accept all defaults

// create a simple edge renderer
var edgeR = new TinEdgeRendererDefintion();
// accept all defaults

// add renderers to dictionary
var l_dict = new Dictionary<SurfaceRendererTarget, TinRendererDefinition>();
l_dict.Add(SurfaceRendererTarget.Points, ptR);
l_dict.Add(SurfaceRendererTarget.Edges, edgeR);

// assign dictionary to creation params
lasCP_renderers.RendererDefinitions = l_dict;

//Create the layer to the LAS dataset
var lasDatasetLayer_rd = LayerFactory.Instance.CreateLayer<LasDatasetLayer>(lasCP_renderers, map);

Renderers for TinLayer, TerrainLayer, LasDatasetLayer

Get Renderers

// get the list of renderers
IReadOnlyList<CIMTinRenderer> renderers = surfaceLayer.GetRenderers();

// get the renderers as a dictionary
Dictionary<SurfaceRendererTarget, CIMTinRenderer> dict = surfaceLayer.GetRenderersAsDictionary();

Simple Node Renderer

// applies to TIN layers only

var nodeRendererDef = new TinNodeRendererDefinition();
nodeRendererDef.Description = "Nodes";
nodeRendererDef.Label = "Nodes";
nodeRendererDef.SymbolTemplate = nodeSymbol.MakeSymbolReference();

var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();
if (tinLayer == null)
  return;

if (tinLayer.CanCreateRenderer(nodeRendererDef))
{
  CIMTinRenderer renderer = tinLayer.CreateRenderer(nodeRendererDef);
  if (tinLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Points))
    tinLayer.SetRenderer(renderer, SurfaceRendererTarget.Points);
}

Elevation Node Renderer - Equal Breaks

// applies to TIN layers only

var equalBreaksNodeRendererDef = new TinNodeClassBreaksRendererDefinition();
equalBreaksNodeRendererDef.BreakCount = 7;

if (tinLayer.CanCreateRenderer(equalBreaksNodeRendererDef))
{
  CIMTinRenderer renderer = tinLayer.CreateRenderer(equalBreaksNodeRendererDef);
  if (tinLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Edges))
    tinLayer.SetRenderer(renderer, SurfaceRendererTarget.Edges);
}

Elevation Node Renderer - Defined Interval

// applies to TIN layers only

var defiendIntervalNodeRendererDef = new TinNodeClassBreaksRendererDefinition();
defiendIntervalNodeRendererDef.ClassificationMethod = ClassificationMethod.DefinedInterval;
defiendIntervalNodeRendererDef.IntervalSize = 4;
defiendIntervalNodeRendererDef.SymbolTemplate = nodeSymbol.MakeSymbolReference();

if (tinLayer.CanCreateRenderer(defiendIntervalNodeRendererDef))
{
  CIMTinRenderer renderer = tinLayer.CreateRenderer(defiendIntervalNodeRendererDef);
  if (tinLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Edges))
    tinLayer.SetRenderer(renderer, SurfaceRendererTarget.Edges);
}

Elevation Node Renderer - Standard Deviation

// applies to TIN layers only

var stdDevNodeRendererDef = new TinNodeClassBreaksRendererDefinition();
stdDevNodeRendererDef.ClassificationMethod = ClassificationMethod.StandardDeviation;
stdDevNodeRendererDef.DeviationInterval = StandardDeviationInterval.OneHalf;
stdDevNodeRendererDef.ColorRamp = ColorFactory.Instance.GetColorRamp("Cyan to Purple");

if (tinLayer.CanCreateRenderer(stdDevNodeRendererDef))
{
  CIMTinRenderer renderer = tinLayer.CreateRenderer(stdDevNodeRendererDef);
  if (tinLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Edges))
    tinLayer.SetRenderer(renderer, SurfaceRendererTarget.Edges);
}

Simple Edge Renderer

// applies to TIN or LAS dataset layers only

var edgeRendererDef = new TinEdgeRendererDefintion();
edgeRendererDef.Description = "Edges";
edgeRendererDef.Label = "Edges";
edgeRendererDef.SymbolTemplate = lineSymbol.MakeSymbolReference();

if (surfaceLayer.CanCreateRenderer(edgeRendererDef))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(edgeRendererDef);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Edges))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Edges);
}

Edge Type Renderer

var breaklineRendererDef = new TinBreaklineRendererDefinition();
// use default symbol for regular edge but specific symbols for hard,soft,outside
breaklineRendererDef.HardEdgeSymbol = hardEdgeSymbol.MakeSymbolReference();
breaklineRendererDef.SoftEdgeSymbol = softEdgeSymbol.MakeSymbolReference();
breaklineRendererDef.OutsideEdgeSymbol = outsideEdgeSymbol.MakeSymbolReference();

if (surfaceLayer.CanCreateRenderer(breaklineRendererDef))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(breaklineRendererDef);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Edges))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Edges);
}

Contour Renderer

var contourDef = new TinContourRendererDefinition();

// now customize with a symbol
contourDef.Label = "Contours";
contourDef.SymbolTemplate = contourLineSymbol.MakeSymbolReference();
contourDef.ContourInterval = 6;

contourDef.IndexLabel = "Index Contours";
contourDef.IndexSymbolTemplate = indexLineSymbol.MakeSymbolReference();
contourDef.ContourFactor = 4;
contourDef.ReferenceHeight = 7;

if (surfaceLayer.CanCreateRenderer(contourDef))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(contourDef);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Contours))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Contours);
}

Simple Face Renderer

var simpleFaceRendererDef = new TinFaceRendererDefinition();
simpleFaceRendererDef.SymbolTemplate = polySymbol.MakeSymbolReference();

if (surfaceLayer.CanCreateRenderer(simpleFaceRendererDef))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(simpleFaceRendererDef);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Surface))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Surface);
}

Aspect Face Renderer

var aspectFaceRendererDef = new TinFaceClassBreaksAspectRendererDefinition();
aspectFaceRendererDef.SymbolTemplate = polySymbol.MakeSymbolReference();
// accept default color ramp

if (surfaceLayer.CanCreateRenderer(aspectFaceRendererDef))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(aspectFaceRendererDef);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Surface))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Surface);
}

Slope Face Renderer - Equal Interval

var slopeFaceClassBreaksEqual = new TinFaceClassBreaksRendererDefinition(TerrainDrawCursorType.FaceSlope);
// accept default breakCount, symbolTemplate, color ramp

if (surfaceLayer.CanCreateRenderer(slopeFaceClassBreaksEqual))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(slopeFaceClassBreaksEqual);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Surface))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Surface);
}

Slope Face Renderer - Quantile

var slopeFaceClassBreaksQuantile = new TinFaceClassBreaksRendererDefinition(TerrainDrawCursorType.FaceSlope);
slopeFaceClassBreaksQuantile.ClassificationMethod = ClassificationMethod.Quantile;
// accept default breakCount, symbolTemplate, color ramp

if (surfaceLayer.CanCreateRenderer(slopeFaceClassBreaksQuantile))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(slopeFaceClassBreaksQuantile);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Surface))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Surface);
}

Elevation Face Renderer - Equal Interval

var elevFaceClassBreaksEqual = new TinFaceClassBreaksRendererDefinition();
// accept default breakCount, symbolTemplate, color ramp

if (surfaceLayer.CanCreateRenderer(slopeFaceClassBreaksEqual))
{
  CIMTinRenderer renderer = surfaceLayer.CreateRenderer(slopeFaceClassBreaksEqual);
  if (surfaceLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Surface))
    surfaceLayer.SetRenderer(renderer, SurfaceRendererTarget.Surface);
}

Dirty Area Renderer

// applies to Terrain layers only

var dirtyAreaRendererDef = new TerrainDirtyAreaRendererDefinition();
// accept default labels, symbolTemplate

var terrainLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TerrainLayer>().FirstOrDefault();
if (terrainLayer == null)
  return;

if (terrainLayer.CanCreateRenderer(dirtyAreaRendererDef))
{
  CIMTinRenderer renderer = terrainLayer.CreateRenderer(dirtyAreaRendererDef);
  if (terrainLayer.CanSetRenderer(renderer, SurfaceRendererTarget.DirtyArea))
    terrainLayer.SetRenderer(renderer, SurfaceRendererTarget.DirtyArea);
}

Terrain Point Class Breaks Renderer

// applies to Terrain layers only

var terrainPointClassBreaks = new TerrainPointClassBreaksRendererDefinition();
// accept defaults

if (terrainLayer.CanCreateRenderer(terrainPointClassBreaks))
{
  CIMTinRenderer renderer = terrainLayer.CreateRenderer(terrainPointClassBreaks);
  if (terrainLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Points))
    terrainLayer.SetRenderer(renderer, SurfaceRendererTarget.Points);
}

LAS Points Classification Unique Value Renderer

// applies to LAS dataset layers only

var lasPointsClassificationRendererDef = new LasUniqueValueRendererDefinition(LasAttributeType.Classification);
// accept the defaults for color ramp, symbolTemplate, symbol scale factor

var lasDatasetLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<LasDatasetLayer>().FirstOrDefault();
if (lasDatasetLayer == null)
  return;

if (lasDatasetLayer.CanCreateRenderer(lasPointsClassificationRendererDef))
{
  CIMTinRenderer renderer = lasDatasetLayer.CreateRenderer(lasPointsClassificationRendererDef);
  if (lasDatasetLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Points))
    lasDatasetLayer.SetRenderer(renderer, SurfaceRendererTarget.Points);
}

LAS Points Returns Unique Value Renderer

// applies to LAS dataset layers only

var lasPointsReturnsRendererDef = new LasUniqueValueRendererDefinition(LasAttributeType.ReturnNumber);
lasPointsReturnsRendererDef.ModulateUsingIntensity = true;
lasPointsReturnsRendererDef.SymbolScaleFactor = 1.0;
// accept the defaults for color ramp, symbolTemplate

if (lasDatasetLayer.CanCreateRenderer(lasPointsReturnsRendererDef))
{
  CIMTinRenderer renderer = lasDatasetLayer.CreateRenderer(lasPointsReturnsRendererDef);
  if (lasDatasetLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Points))
    lasDatasetLayer.SetRenderer(renderer, SurfaceRendererTarget.Points);
}

LAS Points Elevation Stretch Renderer

// applies to LAS dataset layers only

var elevLasStretchRendererDef = new LasStretchRendererDefinition(ArcGIS.Core.CIM.LASStretchAttribute.Elevation);
// accept the defaults for color ramp, etc

if (lasDatasetLayer.CanCreateRenderer(elevLasStretchRendererDef))
{
  CIMTinRenderer renderer = lasDatasetLayer.CreateRenderer(elevLasStretchRendererDef);
  if (lasDatasetLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Points))
    lasDatasetLayer.SetRenderer(renderer, SurfaceRendererTarget.Points);
}


// OR use a stretch renderer with stretchType standard Deviations
var elevLasStretchStdDevRendererDef = new LasStretchRendererDefinition(ArcGIS.Core.CIM.LASStretchAttribute.Elevation);
elevLasStretchStdDevRendererDef.StretchType = LASStretchType.StandardDeviations;
elevLasStretchStdDevRendererDef.NumberOfStandardDeviations = 2;
// accept the defaults for color ramp,  etc

if (lasDatasetLayer.CanCreateRenderer(elevLasStretchStdDevRendererDef))
{
  CIMTinRenderer renderer = lasDatasetLayer.CreateRenderer(elevLasStretchStdDevRendererDef);
  if (lasDatasetLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Points))
    lasDatasetLayer.SetRenderer(renderer, SurfaceRendererTarget.Points);
}

LAS Points Classified Elevation Renderer

// applies to LAS dataset layers only

var lasPointsClassBreaksRendererDef = new LasPointClassBreaksRendererDefinition();
lasPointsClassBreaksRendererDef.ClassificationMethod = ClassificationMethod.NaturalBreaks;
lasPointsClassBreaksRendererDef.ModulateUsingIntensity = true;
// increase the symbol size by a factor
lasPointsClassBreaksRendererDef.SymbolScaleFactor = 1.0;

if (lasDatasetLayer.CanCreateRenderer(lasPointsClassBreaksRendererDef))
{
  CIMTinRenderer renderer = lasDatasetLayer.CreateRenderer(lasPointsClassBreaksRendererDef);
  if (lasDatasetLayer.CanSetRenderer(renderer, SurfaceRendererTarget.Points))
    lasDatasetLayer.SetRenderer(renderer, SurfaceRendererTarget.Points);
}

Remove an edge renderer

var layer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<SurfaceLayer>().FirstOrDefault();
if (layer == null)
  return;

QueuedTask.Run(() =>
{
  layer.RemoveRenderer(SurfaceRendererTarget.Edges);
});

TIN Layer Searching

Seach for TIN Nodes, Edges, Triangles

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

    }
  }
}

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

    }
  }
}

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

    }
  }
}


// search all edges within an extent
//    this could include outside or edges attached to super nodes depending upon the extent
ArcGIS.Core.Data.Analyst3D.TinEdgeFilter edgeFilterAll = new ArcGIS.Core.Data.Analyst3D.TinEdgeFilter();
edgeFilterAll.FilterEnvelope = envelope;
edgeFilterAll.DataElementsOnly = false;
using (ArcGIS.Core.Data.Analyst3D.TinEdgeCursor edgeCursor = tinLayer.SearchEdges(edgeFilterAll))
{
  while (edgeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinEdge edge = edgeCursor.Current)
    {
    }
  }
}


// search for hard edges in the TIN
var 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 = tinLayer.SearchEdges(edgeFilter))
{
  while (edgeCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinEdge edge = edgeCursor.Current)
    {

    }
  }
}


// search for "inside" triangles in an extent
ArcGIS.Core.Data.Analyst3D.TinTriangleFilter triangleFilter = new ArcGIS.Core.Data.Analyst3D.TinTriangleFilter();
triangleFilter.FilterEnvelope = envelope;
triangleFilter.DataElementsOnly = true;
using (ArcGIS.Core.Data.Analyst3D.TinTriangleCursor triangleCursor = tinLayer.SearchTriangles(triangleFilter))
{
  while (triangleCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.TinTriangle triangle = triangleCursor.Current)
    {
    }
  }
}

LAS Dataset Layer Display Filter

Get and Set Display Filter

// get the current display filter
LasPointDisplayFilter ptFilter = lasDatasetLayer.GetDisplayFilter();


// display only ground points
lasDatasetLayer.SetDisplayFilter(LasPointDisplayFilterType.Ground);

// display first return points
lasDatasetLayer.SetDisplayFilter(LasPointDisplayFilterType.FirstReturnPoints);

// set display filter to a set of classification codes
List<int> classifications = new List<int>() { 4, 5, 7, 10 };
lasDatasetLayer.SetDisplayFilter(classifications);

// set display filter to a set of returns
List<ArcGIS.Core.Data.Analyst3D.LasReturnType> returns = new List<ArcGIS.Core.Data.Analyst3D.LasReturnType>()
        { ArcGIS.Core.Data.Analyst3D.LasReturnType.ReturnFirstOfMany};
lasDatasetLayer.SetDisplayFilter(returns);

// set up a display filter
var newDisplayFilter = new LasPointDisplayFilter();
newDisplayFilter.Returns = new List<ArcGIS.Core.Data.Analyst3D.LasReturnType>()
        { ArcGIS.Core.Data.Analyst3D.LasReturnType.ReturnFirstOfMany, ArcGIS.Core.Data.Analyst3D.LasReturnType.ReturnLastOfMany};
newDisplayFilter.ClassCodes = new List<int>() { 2, 4 };
newDisplayFilter.KeyPoints = true;
newDisplayFilter.WithheldPoints = false;
newDisplayFilter.SyntheticPoints = false;
newDisplayFilter.NotFlagged = false;
lasDatasetLayer.SetDisplayFilter(returns);

Active Surface Constraints

var activeSurfaceConstraints = lasDatasetLayer.GetActiveSurfaceConstraints();

// clear all surface constraints (i.e. none are active)
lasDatasetLayer.SetActiveSurfaceConstraints(null);

// set all surface constraints active
using (var lasDataset = lasDatasetLayer.GetLasDataset())
{
  var surfaceConstraints = lasDataset.GetSurfaceConstraints();
  var names = surfaceConstraints.Select(sc => sc.DataSourceName).ToList();
  lasDatasetLayer.SetActiveSurfaceConstraints(names);
}

LAS Dataset Layer Searching

Search for LAS Points

// searching on the LasDatasetLayer will honor any LasPointDisplayFilter

// search all points
using (ArcGIS.Core.Data.Analyst3D.LasPointCursor ptCursor = lasDatasetLayer.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 = lasDatasetLayer.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 = lasDatasetLayer.SearchPoints(pointFilter))
{
  while (ptCursor.MoveNext())
  {
    using (ArcGIS.Core.Data.Analyst3D.LasPoint point = ptCursor.Current)
    {

    }
  }
}

Search using pre initialized arrays

// search all points and process with a set size of array retrieving only coordinates
using (ArcGIS.Core.Data.Analyst3D.LasPointCursor ptCursor = lasDatasetLayer.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 = lasDatasetLayer.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();

  }
}

LAS Dataset Layer Eye Dome Lighting

Eye Dome Lighting

// get current EDL settings
bool isEnabled = lasDatasetLayer.IsEyeDomeLightingEnabled;
var radius = lasDatasetLayer.EyeDomeLightingRadius;
var strength = lasDatasetLayer.EyeDomeLightingStrength;

// set EDL values
lasDatasetLayer.SetEyeDomeLightingEnabled(true);
lasDatasetLayer.SetEyeDomeLightingStrength(65.0);
lasDatasetLayer.SetEyeDomeLightingRadius(2.0);

Line of Sight

Get Line of Sight

var losParams = new LineOfSightParams();
losParams.ObserverPoint = observerPoint;
losParams.TargetPoint = targetPoint;

// add offsets if appropriate
// losParams.ObserverHeightOffset = observerOffset;
// losParams.TargetHeightOffset = targerOffset;

// set output spatial reference
losParams.OutputSpatialReference = MapView.Active.Map.SpatialReference;

LineOfSightResult results = null;
try
{
  if (tinLayer.CanGetLineOfSight(losParams))
    results = tinLayer.GetLineOfSight(losParams);
}
catch (Exception ex)
{
  // log exception message
}

if (results != null)
{
  bool targetIsVisibleFromObserverPoint = results.IsTargetVisibleFromObserverPoint;
  //These properties are not used. They will always be false
  // results.IsTargetVisibleFromVisibleLine;
  // results.IsTargetVisibleFromInvisibleLine;


  if (results.VisibleLine != null)
    MapView.Active.AddOverlay(results.VisibleLine, visibleLineSymbol.MakeSymbolReference());
  if (results.InvisibleLine != null)
    MapView.Active.AddOverlay(results.VisibleLine, invisibleLineSymbol.MakeSymbolReference());
  if (results.ObstructionPoint != null)
    MapView.Active.AddOverlay(results.ObstructionPoint, obstructionPointSymbol.MakeSymbolReference());
}

TIN Layer Functionalities

Get Elevation, Slope, Aspect from TIN layer at a location

var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();
await QueuedTask.Run(() =>
{
  // get elevation, slope and aspect values
  SurfaceValues values = tinLayer.GetSurfaceValues(mapPoint);
  var elev = values.Elevation;
  var slopeRadians = values.Slope;
  var slopeDegrees = values.SlopeDegrees;
  var slopePercent = values.SlopePercent;
  var aspectRadians = values.Aspect;
  var aspectDegrees = values.AspectDegrees;
});

Get Z values from a TIN Layer

var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();
await QueuedTask.Run(() =>
{
  if (tinLayer.CanGetZs())
  {
    // get z value for a mapPoint
    var zResult = tinLayer.GetZs(mapPoint);
    if (zResult.Status == SurfaceZsResultStatus.Ok)
    {
      // cast to a mapPoint
      var mapPointZ = zResult.Geometry as MapPoint;
      var z = mapPointZ.Z;
    }

    // get z values for a polyline
    zResult = tinLayer.GetZs(polyline);
    if (zResult.Status == SurfaceZsResultStatus.Ok)
    {
      // cast to a Polyline
      var polylineZ = zResult.Geometry as Polyline;
    }
  }
});

Interpolate Shape

var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();
await QueuedTask.Run(() =>
{
  Geometry output = null;
  // interpolate z values for a geometry
  if (tinLayer.CanInterpolateShape(polyline))
    output = tinLayer.InterpolateShape(polyline, SurfaceInterpolationMethod.NaturalNeighbor);

  if (output != null)
  {
    // process the output
  }


  // densify the shape before interpolating
  if (tinLayer.CanInterpolateShape(polygon))
    output = tinLayer.InterpolateShape(polygon, SurfaceInterpolationMethod.Linear, 0.01, 0);

  if (output != null)
  {
    // process the output
  }

});

Interpolate Shape Verticies

var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();
await QueuedTask.Run(() =>
{
  // interpolate z values at the geometry vertices only
  Geometry output = tinLayer.InterpolateShapeVertices(polyline, SurfaceInterpolationMethod.NaturalNeighbor);
  if (output != null)
  {
    // process the output
  }

  // or use a different interpolation method
  output = tinLayer.InterpolateShapeVertices(polyline, SurfaceInterpolationMethod.Linear);
});

Interpolate Z at an x,y location

var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();
await QueuedTask.Run(() =>
{
  // interpolate values at the specified x,y location
  double z = tinLayer.InterpolateZ(x, y, SurfaceInterpolationMethod.NaturalNeighborZNearest);

  // or use a different interpolation method
  z = tinLayer.InterpolateZ(x, y, SurfaceInterpolationMethod.Linear);
});

Get 3D length of multipart by interpolating heights

var tinLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<TinLayer>().FirstOrDefault();
await QueuedTask.Run(() =>
{
  // interpolate heights and calculate the sum of 3D distances between the vertices
  double length3d = tinLayer.GetSurfaceLength(polygon, SurfaceInterpolationMethod.NaturalNeighbor);

  // or use a different interpolation method
  length3d = tinLayer.GetSurfaceLength(polyline, SurfaceInterpolationMethod.NaturalNeighborZNearest);


  // densify the shape before interpolating
  length3d = tinLayer.GetSurfaceLength(polygon, SurfaceInterpolationMethod.NaturalNeighbor, 0.01, 0);
});
⚠️ **GitHub.com Fallback** ⚠️