Mosaic rasters
MosaicRaster.cpp
// Copyright 2011 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.
// 

  

// MosaicRaster
//
// This sample shows how to mosaic adjacent rasters together using the
// IMosaicRaster interface and persist the output using the ISaveAs
// interface.  The sample supports mosaicing up to 4 rasters.

#include "MosaicRaster.h"

int main(int argc, char* argv[])
{
  using std::cerr;
  
  char *path = 0;
  char *outFormat = 0;
  char *outName = 0;
  const char *inNames[4];
  int ind = 0;
  int paramCount = 0;
  int inNamesCount = 0;
  
  
  // Parse the command line
  for (int i = 1; i < argc; i++)
  {
    if (strcmp(argv[i], "-h") == 0)
    {
      Usage();
      AoExit(0);
    }
    if (strcmp(argv[i], "-p") == 0)
    {
      path = argv[++i];
      paramCount++;
    }
    if (strcmp(argv[i], "-f") == 0)
    {
      outFormat = argv[++i];
      if (!strcmp(outFormat, "IMAGINE"))
        outFormat = "IMAGINE Image";
      paramCount++;
    }
    if (strcmp(argv[i], "-i") == 0)
    {
      inNames[ind++] = argv[++i];
      inNamesCount++;
      paramCount++;
    }
    if (strcmp(argv[i], "-o") == 0)
    {
      outName = argv[++i];
      paramCount++;
    }
  }
  
  // Check we got all parameters and they are valid
  if ((paramCount < 5) || (path == 0) || (outFormat == 0) || (outName == 0) || (inNames[0] == 0) || (inNames[1] == 0))
  {
    Usage();
    AoExit(0);
  }
  
  // Initialize ArcEngine
  if (!InitializeApp())
  {
    ShutdownApp();
    AoExit(0);
  }
  
  // Perform mosaic operation
  HRESULT hr = MosaicRasters(path, inNames, inNamesCount, outName, outFormat);
    
  // 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();
  AoExit(0);
}

HRESULT MosaicRasters(const char *inPath, const char *inNames[], int inNamesCount, const char *outputName, const char *outputFormat)
{
  using std::cerr;
  using std::endl;
  
  // Get workspace and check to see if it is valid
  IWorkspaceFactoryPtr ipWorkspaceFactory(CLSID_RasterWorkspaceFactory);
  VARIANT_BOOL chk;
  HRESULT hr = ipWorkspaceFactory->IsWorkspace(CComBSTR(inPath), &chk);
  if (FAILED(hr)) 
  {
    cerr << "Couldn't check workspace\n";
    return hr;
  }
  else
  {
    if (chk == VARIANT_FALSE)
    {
      cerr << "Invalid workspace\n";
      return E_FAIL;
    }
  }  
  IWorkspacePtr ipWork;
  ipWorkspaceFactory->OpenFromFile(CComBSTR(inPath), 0, &ipWork);    
  IRasterWorkspacePtr ipRastWork (ipWork);
  
  // Check to see if a raster with outputName already exists in the output directory
  IRasterDatasetPtr ipCheckIfExistsAlready;
  hr = ipRastWork->OpenRasterDataset(CComBSTR(outputName), &ipCheckIfExistsAlready);
  if (SUCCEEDED(hr) && ipCheckIfExistsAlready != 0) 
  {
    cerr << "Dataset with name " << outputName << " already exists!\n";
    return E_FAIL;
  }
  
  IMosaicRasterPtr ipMosaicRaster(CLSID_MosaicRaster);
  IRasterCollectionPtr ipRastColl (ipMosaicRaster);
  
  // Open input IRasterDataset2s
  IRasterDatasetPtr ipRastDataset;
  IRasterPtr ipRaster;
  int count = 0;
  for (int i=0; i<inNamesCount; i++)
  {
    hr = ipRastWork->OpenRasterDataset(CComBSTR(inNames[i]), &ipRastDataset);
    if (FAILED(hr) || ipRastDataset == 0) 
    {
      cerr << "Couldn't open " << inNames[i] << endl;
    }
    else
    {
      ((IRasterDataset2Ptr)ipRastDataset)->CreateFullRaster(&ipRaster);
      ipRastColl->Append(ipRaster);
      ++count;
    }
  }
  if (count < 2)
  {
    cerr << "Less than 2 of the input rasters could be opened so no mosaic can be performed.\n";
    return E_FAIL;
  }
  
  // Set the parameters for IMosaicRaster.  You could have these
  // parameters passed in on the command line or hardcode them to
  // suit your needs.  There are also other IMosaicRaster properties
  // as well as IRasterProps properties (which you can
  // QueryInterface to from IMosaicRaster) that may be set, consult
  // the documentation.
  ipMosaicRaster->put_MosaicOperatorType (MT_MEAN);
  ipMosaicRaster->put_MosaicColormapMode (MM_FIRST);
  
  ISaveAsPtr ipSaveAs = ipRastColl;
  VARIANT_BOOL canSaveAs;
  ipSaveAs->CanSaveAs(CComBSTR(outputFormat), &canSaveAs);
  if (canSaveAs)
  {
    IDatasetPtr ipUnused;
    hr = ipSaveAs->SaveAs(CComBSTR(outputName), ipWork, CComBSTR(outputFormat), &ipUnused);
  }
  else
  {
    cerr << "Cannot save as format " << outputFormat << endl;
    return E_FAIL;
  }
  
  return hr;
}

// Print out the usage details
void Usage(void)
{
  std::cout << "Usage: -p [path to input] -f [output format (GRID, TIFF, IMAGINE)] -i [input raster name, must have 2, may have up to 4] -o [output raster name]\n";
}