How to access a difference surface when intersecting TINs and terrains


Accessing a difference surface when intersecting TINs and terrains

Triangulated irregular networks (TINs) and terrain datasets can be compared with one another to discover the difference between them. If TINs are only used, do this via ITinSurface3.Intersect. If at least one of the two surfaces is a terrain, do this via IDynamicSurface3.Intersect. Both of these methods have an explicit output feature class into which polygons are written. These outline the areas where one surface is above or below the other. In addition to this, you can also gain access to a difference surface as part of the Intersect process. The difference surface is a TIN that is held in memory.
You gain access to the difference surface via an event handler that listens for events triggered by the Intersect method. In the case of TIN based processing, the event is fired once and just one difference surface is made. In the case of a dynamic surface involving a terrain, the event handler will be called multiple times if the terrain is large enough that it must be processed in multiple blocks. In this case, the logical difference surface is really comprised of multiple tiled TINs.
The SurfaceDifference geoprocessing tool performs an intersection and supports the output difference TINs or rasters. Consider using the SurfaceDifference tool instead of the ArcObjects application programming interface (API).
Do the following steps to access a difference surface when intersecting TINs and terrains:
  1. Define the routine that handles the OnIntersect event that gets fired by the Intersect method. See the following code example:
[C#]
// This method is the event handler that saves the difference TIN to disk.
// It uses a global variable called "Counter" to simplify the task of generating a unique name
// for each TIN, when this might be called multiple times during one intersection to support
// the chunk based processing of terrains.
static void OnIntersect(ITinSurface DiffSurf)
{
    ITinAdvanced Tin = DiffSurf as ITinAdvanced;

    string OutTinName = "c:\\project\\diff_tin";
    OutTinName = OutTinName + PubVars.Counter.ToString();

    PubVars.Counter++;

    object Overwrite;
    Overwrite = true;
    Tin.SaveAs(OutTinName, ref Overwrite);
}
[VB.NET]
' This method is the event handler that saves the difference TIN to disk.
' It uses a global variable called "Counter" to simplify the task of generating a unique name
' for each TIN, when this might be called multiple times during one intersection to support
' the chunk based processing of terrains.
Private Shared Sub OnIntersect(ByVal DiffSurf As ITinSurface)
Dim Tin As ITinAdvanced = TryCast(DiffSurf, ITinAdvanced)

Dim OutTinName As String = "c:\project\diff_tin"
OutTinName = OutTinName + PubVars.Counter.ToString()

PubVars.Counter + = 1

Dim Overwrite As Object
Overwrite = True
Tin.SaveAs(OutTinName, Overwrite)
End Sub
  1. In the body of the calling routine, get your two input surfaces and output feature class set up in preparation for the call to Intersect. See the following code example:
[C#]
IDynamicSurface3 DynSurf_Ground = GroundTerrain.CreateDynamicSurface()as
    IDynamicSurface3;
IDynamicSurface3 DynSurf_Water = WaterTerrain.CreateDynamicSurface()as
    IDynamicSurface3;
IFeatureClass OutFC = FWS.OpenFeatureClass("intersect_fc");
[VB.NET]
Dim DynSurf_Ground As IDynamicSurface3 = TryCast(GroundTerrain.CreateDynamicSurface(), IDynamicSurface3)
Dim DynSurf_Water As IDynamicSurface3 = TryCast(WaterTerrain.CreateDynamicSurface(), IDynamicSurface3)
Dim OutFC As IFeatureClass = FWS.OpenFeatureClass("intersect_fc")
  1. Set up the event handler so it points to the OnIntersect method defined in Step 1, then call Intersect. See the following code example:
[C#]
ESRI.ArcGIS.GeoDatabaseExtensions.ISurfaceIntersectionEvents_Event SurfEvents = 
    (ESRI.ArcGIS.GeoDatabaseExtensions.ISurfaceIntersectionEvents_Event)
    DynSurf_Ground;
SurfEvents.OnIntersect += new
    ESRI.ArcGIS.GeoDatabaseExtensions.ISurfaceIntersectionEvents_OnIntersectEventHandler(OnIntersect);
DynSurf_Ground.Intersect(null, 10.0, DynSurf_Water, 0.0, false, OutFC, "Volume", 
    "Surf_Area", "Code", null);
[VB.NET]
Dim SurfEvents As ESRI.ArcGIS.GeoDatabaseExtensions.ISurfaceIntersectionEvents_Event = DirectCast(DynSurf_Ground, ESRI.ArcGIS.GeoDatabaseExtensions.ISurfaceIntersectionEvents_Event)
AddHandler SurfEvents.OnIntersect, AddressOf OnIntersect
DynSurf_Ground.Intersect(Nothing, 10R, DynSurf_Water, 0R, False, OutFC, _
                         "Volume", "Surf_Area", "Code", Nothing)






To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS for Desktop Basic: 3D Analyst ArcGIS for Desktop Basic: 3D Analyst
ArcGIS for Desktop Standard: 3D Analyst ArcGIS for Desktop Standard: 3D Analyst
ArcGIS for Desktop Advanced: 3D Analyst ArcGIS for Desktop Advanced: 3D Analyst
Engine Developer Kit Engine: 3D Analyst