Tin statistics
TinStats.cpp
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

  

// TinStats
//
// This sample shows how to open up an existing tin programatically
// and display some of the tin's statistics to standard output.

#include "TinStats.h"

int main(int argc, char* argv[])
{
  char* sourceFilePath = 0;
  
  // Parse command line
  if (argc < 2) 
  {
    Usage();
    AoExit(0);
  }
  sourceFilePath = argv[1];
  
  // Initialize ArcEngine
  if (!InitializeApp(esriLicenseExtensionCode3DAnalyst))
  {
    ShutdownApp(esriLicenseExtensionCode3DAnalyst);
    AoExit(0);
  }

  // Calculate tin statistics
  HRESULT hr = CalculateTinStatistics(sourceFilePath);
  
  // Check returned HRESULT
  switch (hr)
  {
  case S_OK:
    std::cerr << "hr is S_OK" << std::endl;
    break;
  case E_FAIL:
    std::cerr << "hr is E_FAIL" << std::endl;
    break;
  case E_POINTER:
    std::cerr << "hr is E_POINTER" << std::endl;
    break;
  default:
    std::cerr << "hr is 0x" << std::hex << hr << std::dec << " " << hr << std::endl;
    break;
  }

  // Uninitialize ArcEngine
  ShutdownApp(esriLicenseExtensionCode3DAnalyst);
  AoExit(0);
}

// Calculate tin statistics
HRESULT CalculateTinStatistics(char *sourceFilePath)
{
  using std::wcerr;
  using std::cerr;
  using std::endl;
  
  // Parse full path into directory and file name
  CComBSTR bsPath;
  CComBSTR bsName;
  HRESULT hr = GetParentDirFromFullPath(sourceFilePath, &bsPath, false);
  if (FAILED(hr) || bsPath.Length() == 0) 
  {
    cerr << "Error parsing path to tin" << endl;
    return hr;
  }
  hr = GetFileFromFullPath(sourceFilePath, &bsName);
  if (FAILED(hr) || bsName.Length() == 0) 
  {
    cerr << "Error parsing path to tin" << endl;
    return hr;
  }
  
  // Open tin
  IWorkspaceFactoryPtr ipWorkspaceFactory(CLSID_TinWorkspaceFactory);
  IWorkspacePtr ipWork;
  ITinPtr ipTin;
  hr = ipWorkspaceFactory->OpenFromFile(bsPath, 0, &ipWork);
  if (FAILED(hr) || ipWork == 0)
  {
    cerr << "Couldn't find workspace\n";
    if (FAILED(hr))
      return hr;
    else
      return E_FAIL;
  }
  
  ITinWorkspacePtr ipTinWork (ipWork);
  hr = ipTinWork->OpenTin(bsName, &ipTin);
  if (FAILED(hr) || ipTin == 0)
  {
    cerr << "Couldn't open tin\n";
    if (FAILED(hr))
      return hr;
    else
      return E_FAIL;
  }
  
  // Calculate statistics
  double volume, surfaceArea, reference;
  IEnvelopePtr ipEnv;
  ipTin->get_Extent(&ipEnv);
  ipEnv->get_ZMin(&reference); // Use zMin as reference for calculation
  ((ITinSurfacePtr)ipTin)->GetVolume(reference, esriPlaneReferenceAbove, &volume);
  ((ITinSurfacePtr)ipTin)->GetSurfaceArea(reference, esriPlaneReferenceAbove, &surfaceArea);
  
  // Ouput stats
  wcerr << L"Statistics:\n" 
        << L"----------\n"
        << L"Name: " << (BSTR) bsName << endl
        << L"Volume: " << volume << endl
        << L"Surface Area: " << surfaceArea << endl;

  return S_OK;
}

// Display usage information
void Usage()
{
  std::cerr << "Usage: tinstats [path to tin]\n";
}