VR-Forces 4.0.4 Class Documentation
Add Terrain Features Example

The Add Terrain Features example demonstrates the following:

How to Run

This example demonstrates how to programmatically modify an existing GDB (VR-Forces native format) terrain database. It adds vector features to a terrain database.

Usage

(in bin directory)

addTerrainFeatures

To run the example:

  1. Run createTerrainDb to create a new flat terrain database named data\terrain\simpleTerrain.gdb.
  2. Run addTerrainFeatures.

In step 1, a simple terrain database named data\terrain\simpleTerrain.gdb will be created. This database has no features. The addTerrainFeatures application //! adds several features to the terrain, including a stream, a tree, and a couple of buildings. Open the terrain database using TDBTool to view the new features.

Main Application File

/*******************************************************************************
** Copyright (c) 2003 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
/*******************************************************************************
** $RCSfile: main.cxx,v $ $Revision: 1.18 $ $State: Exp $
*******************************************************************************/

#include "gdb/terrainDb.h"
#include "geometry/point.h"
#include "geometry/surface.h"
#include "gdb/triInd.h"
#include <vlutil/vlPrint.h>
#include "gdb/vecNetwrk.h"
#include "gdb/specification.h"
#include "gdb/netwrkNode.h"
#include "gdb/gdbNode.h"
#include "gdb/netwrkSeg.h"
#include "gdb/netwrkEdge.h"
#include "terrainDbFactory/tdbManager.h"


bool createTrees(DtVectorNetwork& vectorNetwork)
{
   // Get a convenience reference to the vector network's specification manager
   DtSpecificationManager& specificationManager = vectorNetwork.specificationManager();

   // Create a specification for a tree
   DtSpecification treeSpec;
   treeSpec.setColor(DtColor(0,200,0,0)); // r,g,b,a (0-255)
   treeSpec.setWidth(5.0);
   treeSpec.setLength(5.0);
   treeSpec.addIntegerAttribute("DtFidCode", 953);
   treeSpec.addIntegerAttribute("DtFacNumber", 0);
   treeSpec.addIntegerAttribute("DtFeatureType", 0);
   treeSpec.addStringAttribute("DtFeatureName","953 Evergreen Trees (including Mangrove and Nipa)");
   treeSpec.addIntegerAttribute("DtSmc", 12);
   treeSpec.addStringAttribute("DtFeatureGroupName", "Vegetation");
   treeSpec.addStringAttribute("DtFeatureGroup", "MAK040");
   treeSpec.addStringAttribute("DtDescription","Trees");
   treeSpec.addStringAttribute("ECC","EC030");
   treeSpec.addIntegerAttribute("DtSedrisCodes", 1);
   treeSpec.addStringAttribute("SEDRISCODE1","TRE002");
   treeSpec.addStringAttribute("TRE002","Evergreen");
   treeSpec.addIntegerAttribute("DtOrientation", 0);
   treeSpec.addIntegerAttribute("DtHeight", 5);

   // Add the tree specification to the vector network's specification manager
   DtSpecificationID treeSpecID;
   if(!specificationManager.addSpecification(treeSpec, treeSpecID))
   {
      DtWarn("Couldn't add tree specification to specification manager.\n");
      return false;
   }

   // Create a tree
   DtNetworkNode* treeNode = vectorNetwork.newNode();

   // Position it the upper right-hand quadrant of the terrain
   treeNode->setLocation(DtPoint(750, 750, 0));
   treeNode->setSpecificationID(treeSpecID);

   // Add it to the database
   vectorNetwork.addOn(*treeNode);

   // Create another tree (using the same specification)
   treeNode = vectorNetwork.newNode();

   // Position it the lower left-hand quadrant of the terrain
   treeNode->setLocation(DtPoint(250, 250, 0));
   treeNode->setSpecificationID(treeSpecID);

   // Add it to the database
   vectorNetwork.addOn(*treeNode);

   return true;
}


bool createArealBuilding(DtVectorNetwork& vectorNetwork)
{
   // Get a convenience reference to the vector network's specification manager
   DtSpecificationManager& specificationManager = vectorNetwork.specificationManager();

   // Create a specification for an areal building feature
   DtSpecification arealBuildingSpec;
   arealBuildingSpec.setColor(DtColor(255,145,0,0)); // r,g,b,a (0-255)
   arealBuildingSpec.addIntegerAttribute("DtFidCode", 181);
   arealBuildingSpec.addIntegerAttribute("DtFacNumber", 1);
   arealBuildingSpec.addIntegerAttribute("DtFeatureType", 2);
   arealBuildingSpec.addStringAttribute("DtFeatureName","181 building");
   arealBuildingSpec.addIntegerAttribute("DtSmc", 3);
   arealBuildingSpec.addStringAttribute("DtFeatureGroupName", "Feature");
   arealBuildingSpec.addStringAttribute("DtFeatureGroup", "MAK000");
   arealBuildingSpec.addStringAttribute("DtDescription","Building");
   arealBuildingSpec.addStringAttribute("ECC","AL015");
   arealBuildingSpec.addIntegerAttribute("DtSedrisCodes", 0);
   arealBuildingSpec.addStringAttribute("SEDRISCODE1","TRE002");
   arealBuildingSpec.addStringAttribute("TRE002","Evergreen");
   arealBuildingSpec.addIntegerAttribute("DtOrientation", 0);
   arealBuildingSpec.addIntegerAttribute("DtHeight", 100);
   
   // 100 meters long (centered at 650 meters along X-axis)
   arealBuildingSpec.addRealAttribute("DtXMin", 610);
   arealBuildingSpec.addRealAttribute("DtXMax", 710);
   
   // 50 meters wide (centered at 625 meters along Y-axis)
   arealBuildingSpec.addRealAttribute("DtYMin", 610.0);
   arealBuildingSpec.addRealAttribute("DtYMax", 660.0);

   arealBuildingSpec.addRealAttribute("DtZMin", 0.0);
   arealBuildingSpec.addRealAttribute("DtZMax", 100.0);

   DtSpecificationID arealBuildingSpecID;
   if(!specificationManager.addSpecification(arealBuildingSpec, arealBuildingSpecID))
   {
      DtWarn("Couldn't add arealBuilding specification to the specification manager.\n");
      return false;
   }

   // Create the areal buildings start/end node
   DtNetworkNode* arealBuildingStartNode = vectorNetwork.newNode();
   assert(arealBuildingStartNode != NULL);
   arealBuildingStartNode->setLocation(DtPoint(710, 610, 0));
   arealBuildingStartNode->setSpecificationID(arealBuildingSpecID);
   vectorNetwork.addOn(*arealBuildingStartNode);

   DtNetworkNode* arealBuildingEndNode = arealBuildingStartNode; // for areal features, end is start

   // Create the building's centroid node
   DtNetworkNode* arealBuildingCentroidNode = vectorNetwork.newNode();
   assert(arealBuildingCentroidNode != NULL);
   arealBuildingCentroidNode->setLocation(DtPoint(660, 635, 0));
   arealBuildingCentroidNode->setSpecificationID(arealBuildingSpecID);
   vectorNetwork.addOn(*arealBuildingCentroidNode);

   
   // Create the edges.  Like the segments, there are 2 edges (one is the
   // reverse of the other).  Configure it with endpoints and segments.
   // Set the specification to the river specification we made above.
   DtNetworkEdge* buildingPerimeter = vectorNetwork.newEdge();
   assert(buildingPerimeter != NULL);
   buildingPerimeter->setSpecificationID(arealBuildingSpecID);
   buildingPerimeter->setStartNode(arealBuildingStartNode);
   buildingPerimeter->setEndNode(arealBuildingEndNode);

   // Add the edges that will make up the building
   // First create the segments.  Create them two at a time to be consistent
   // with the topology.
   buildingPerimeter->addPoint(DtPoint(710, 610, 0));
   buildingPerimeter->addPoint(DtPoint(710, 660, 0));
   buildingPerimeter->addPoint(DtPoint(610, 660, 0));
   buildingPerimeter->addPoint(DtPoint(610, 610, 0));
   buildingPerimeter->addPoint(DtPoint(710, 610, 0));

   return true;
}


bool createPointBuilding(DtVectorNetwork& vectorNetwork)
{
   // Get a convenience reference to the vector network's specification manager
   DtSpecificationManager& specificationManager = vectorNetwork.specificationManager();

   // Create a specification for a building
   DtSpecification buildingSpec;
   buildingSpec.setColor(DtColor(255,145,0,0)); // r,g,b,a (0-255)
   buildingSpec.setWidth(12.0);
   buildingSpec.setLength(15.0);
   buildingSpec.addIntegerAttribute("DtFidCode", 181);
   buildingSpec.addIntegerAttribute("DtFacNumber", 1);
   buildingSpec.addIntegerAttribute("DtFeatureType", 0);
   buildingSpec.addStringAttribute("DtFeatureName","181 building");
   buildingSpec.addIntegerAttribute("DtSmc", 3);
   buildingSpec.addStringAttribute("DtFeatureGroupName", "Feature");
   buildingSpec.addStringAttribute("DtFeatureGroup", "MAK000");
   buildingSpec.addStringAttribute("DtDescription","Building");
   buildingSpec.addStringAttribute("ECC","AL015");
   buildingSpec.addIntegerAttribute("DtSedrisCodes", 0);
   buildingSpec.addStringAttribute("SEDRISCODE1","TRE002");
   buildingSpec.addStringAttribute("TRE002","Evergreen");
   buildingSpec.addIntegerAttribute("DtOrientation", 0);
   buildingSpec.addIntegerAttribute("DtHeight", 10);

   DtSpecificationID buildingSpecID;
   if(!specificationManager.addSpecification(buildingSpec, buildingSpecID))
   {
      DtWarn("Couldn't add building specification to the specification manager.\n");
      return false;
   }

   // Create a building
   DtNetworkNode* building = vectorNetwork.newNode();

   // Position it near the center of the terrain
   building->setLocation(DtPoint(500, 550, 0));
   building->setSpecificationID(buildingSpecID);

   // Add it to the database
   vectorNetwork.addOn(*building);

   return true;
}


bool createRiver(DtVectorNetwork& vectorNetwork)
{
   // Get a convenience reference to the vector network's specification manager
   DtSpecificationManager& specificationManager = vectorNetwork.specificationManager();

   // Create a river specification
   DtSpecification riverSpec;
   riverSpec.setColor(DtColor(0,0,200,0)); // r,g,b,a (0-255)
   riverSpec.addIntegerAttribute("DtFidCode", 945);
   riverSpec.addIntegerAttribute("DtFeatureType", 1);
   riverSpec.addStringAttribute("DtFeatureName","945 Non-perennial Stream");
   riverSpec.addIntegerAttribute("DtSmc", 6);
   riverSpec.addStringAttribute("DtFeatureGroupName", "Waterway");
   riverSpec.addStringAttribute("DtFeatureGroup", "MAK030");
   riverSpec.addStringAttribute("DtDescription","River/Stream");
   riverSpec.addStringAttribute("ECC","BH140");
   riverSpec.addIntegerAttribute("DtSedrisCodes", 0);
   riverSpec.addIntegerAttribute("DtOrientation", 0);
   riverSpec.addIntegerAttribute("DtHeight", 0);
   riverSpec.setWidth(10);
   riverSpec.setLength(0);

   DtSpecificationID riverSpecID;
   if(!specificationManager.addSpecification(riverSpec, riverSpecID))
   {
      DtWarn("Couldn't add river specification to the specification manager.\n");
      return false;
   }

   // Create the edge that makes up the river.

   // Create the endpoints of our river, node1 and node2.  Set the
   // specification to the river specification we made above.
   DtNetworkNode* riverStartNode = vectorNetwork.newNode();
   riverStartNode->setLocation(DtPoint(0, 100, 0));
   riverStartNode->setSpecificationID(riverSpecID);
   vectorNetwork.addOn(*riverStartNode);

   DtNetworkNode* riverEndNode = vectorNetwork.newNode();
   riverEndNode->setLocation(DtPoint(300,1000,0));
   riverEndNode->setSpecificationID(riverSpecID);
   vectorNetwork.addOn(*riverEndNode);

   // Create the edges.  Like the segments, there are 2 edges (one is the
   // reverse of the other).  Configure it with endpoints and segments.
   // Set the specification to the river specification we made above.
   DtNetworkEdge* edge = vectorNetwork.newEdge();
   edge->addPoint(DtPoint(0, 100, 0));
   edge->addPoint(DtPoint(300,1000,0));
   edge->setSpecificationID(riverSpecID);
   edge->setStartNode(riverStartNode);
   edge->setEndNode(riverEndNode);

   return true;
}


// This example demonstrates how to use the terrain API to add terrain features
// to an existing terrain database (in this case some trees, a building, and a
// river).  The modified terrain database is saved out to file in MAK gdb 
// format.
//
// It loads the ..\data\terrain\simpleTerrain.gdb database (created by the 
// createTerrainDb example), and saves out the modified terrain database to the
// file ..\data\terrain\simpleFeatures.gdb.

int main(int argc, char** argv)
{
   DtTdbManager manager;

   // Load the simpleTerrain.gdb database (in the bin directory).  It contains
   // terrain skin only (a 1000 x 1000 meter square plane comprised of 4 quadrants
   // of two triangles each).
   // 
   // Load the terrain database using a terrain reader that knows how to load 
   // MAK gdb terrain files.

   if(!manager.load("..\\data\\terrain\\simpleTerrain.gdb"))
   {
      DtWarn("Couldn't load terrain database file -- please run createTerrainDb to create simpleTerrain.gdb\n");
      return 1;
   }

   // Get a convenience pointer to the terrain database's vector network
   DtVectorNetwork* vectorNetwork = manager.terrainDatabase()->vectorNetwork();
   assert(vectorNetwork != NULL);

   if (!createTrees(*vectorNetwork))
   {
      DtWarn("Couldn't create point tree features.\n");
      return 1;
   }

   if (!createRiver(*vectorNetwork))
   {
      DtWarn("Couldn't create linear river feature.\n");
      return 1;
   }

   if (!createPointBuilding(*vectorNetwork))
   {
      DtWarn("Couldn't create point building feature.\n");
      return 1;
   }

   if (!createArealBuilding(*vectorNetwork))
   {
      DtWarn("Couldn't create areal building feature.\n");
      return 1;
   }

   if (! vectorNetwork->validity())
   {
      DtWarn("Error - created invalid vector network.\n");
      return 1;
   }

   // Save modified terrain database to file
   manager.save("..\\data\\terrain\\simpleFeatures.gdb");

   return 0;
}




Document ID: Generated on Fri Jun 29 16:33:32 EDT 2012 from SVN revision 116588
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)