[cig-commits] r12759 - cs/spatialdata-0.1/trunk/libsrc/spatialdb
brad at geodynamics.org
brad at geodynamics.org
Sat Aug 30 19:57:23 PDT 2008
Author: brad
Date: 2008-08-30 19:57:22 -0700 (Sat, 30 Aug 2008)
New Revision: 12759
Added:
cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.cc
cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.hh
Log:
Initial implementation of composite spatial database. No testing yet.
Added: cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.cc
===================================================================
--- cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.cc (rev 0)
+++ cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.cc 2008-08-31 02:57:22 UTC (rev 12759)
@@ -0,0 +1,328 @@
+// -*- C++ -*-
+//
+// ----------------------------------------------------------------------
+//
+// Brad T. Aagaard
+// U.S. Geological Survey
+//
+// <LicenseText>
+//
+// ----------------------------------------------------------------------
+//
+
+#include <portinfo>
+
+#include "SpatialDB.hh" // ISA SpatialDB object
+#include "CompositeDB.hh" // Implementation of class methods
+
+#include <stdexcept> // USES std::runtime_error
+
+#include <sstream> // USES std::ostringsgream
+#include <strings.h> // USES strcasecmp()
+#include <assert.h> // USES assert()
+
+// ----------------------------------------------------------------------
+/// Default constructor
+spatialdata::spatialdb::CompositeDB::CompositeDB(void) :
+ _dbA(0),
+ _dbB(0),
+ _infoA(0),
+ _infoB(0)
+{ // constructor
+} // constructor
+
+// ----------------------------------------------------------------------
+/// Constructor with label
+spatialdata::spatialdb::CompositeDB::CompositeDB(const char* label) :
+ SpatialDB(label),
+ _dbA(0),
+ _dbB(0),
+ _infoA(0),
+ _infoB(0)
+{ // constructor
+} // constructor
+
+// ----------------------------------------------------------------------
+/// Default destructor
+spatialdata::spatialdb::CompositeDB::~CompositeDB(void)
+{ // destructor
+ // Don't manage memory for dbA and dbB
+
+ if (0 != _infoA) {
+ delete[] _infoA->query_buffer; _infoA->query_buffer = 0;
+ delete[] _infoA->query_indices; _infoA->query_indices = 0;
+ delete[] _infoA->names_values; _infoA->names_values = 0;
+ } // if
+ delete _infoA; _infoA = 0;
+
+ if (0 != _infoB) {
+ delete[] _infoB->query_buffer; _infoB->query_buffer = 0;
+ delete[] _infoB->query_indices; _infoB->query_indices = 0;
+ delete[] _infoB->names_values; _infoB->names_values = 0;
+ } // if
+ delete _infoB; _infoB = 0;
+} // destructor
+
+// ----------------------------------------------------------------------
+// Set database A.
+void
+spatialdata::spatialdb::CompositeDB::dbA(SpatialDB* db,
+ const char** names,
+ const int numNames)
+{ // dbA
+ assert(0 != db);
+ assert(names != 0);
+ assert(numNames > 0);
+
+ // Clear out old data
+ if (0 != _infoA) {
+ delete[] _infoA->query_buffer; _infoA->query_buffer = 0;
+ delete[] _infoA->query_indices; _infoA->query_indices = 0;
+ delete[] _infoA->names_values; _infoA->names_values = 0;
+ } else
+ _infoA = new dbinfo;
+
+ // Initialize data
+ _infoA->query_buffer = 0;
+ _infoA->query_indices = 0;
+ _infoA->names_values = 0;
+ _infoA->query_size = 0;
+ _infoA->num_names = 0;
+
+ // Set data
+ if (numNames > 0) {
+ _infoA->names_values = new std::string[numNames];
+ _infoA->num_names = numNames;
+ for (int i=0; i < numNames; ++i)
+ _infoA->names_values[i] = names[i];
+ } // if
+} // dbA
+
+// ----------------------------------------------------------------------
+// Set database B.
+void
+spatialdata::spatialdb::CompositeDB::dbB(SpatialDB* db,
+ const char** names,
+ const int numNames)
+{ // dbB
+ assert(0 != db);
+ assert(names != 0);
+ assert(numNames > 0);
+
+ // Clear out old data
+ if (0 != _infoB) {
+ delete[] _infoB->query_buffer; _infoB->query_buffer = 0;
+ delete[] _infoB->query_indices; _infoB->query_indices = 0;
+ delete[] _infoB->names_values; _infoB->names_values = 0;
+ } else
+ _infoB = new dbinfo;
+
+ // Initialize data
+ _infoB->query_buffer = 0;
+ _infoB->query_indices = 0;
+ _infoB->names_values = 0;
+ _infoB->query_size = 0;
+ _infoB->num_names = 0;
+
+ // Set data
+ if (numNames > 0) {
+ _infoB->names_values = new std::string[numNames];
+ _infoB->num_names = numNames;
+ for (int i=0; i < numNames; ++i)
+ _infoB->names_values[i] = names[i];
+ } // if
+} // dbB
+
+// ----------------------------------------------------------------------
+// Open the database and prepare for querying.
+void
+spatialdata::spatialdb::CompositeDB::open(void)
+{ // open
+ if (0 == _dbA)
+ throw std::runtime_error("Cannot open database A. Database was not set.");
+ if (0 == _dbB)
+ throw std::runtime_error("Cannot open database B. Database was not set.");
+
+ _dbA->open();
+ _dbB->open();
+} // open
+
+// ----------------------------------------------------------------------
+// Close the database.
+void
+spatialdata::spatialdb::CompositeDB::close(void)
+{ // close
+ if (0 == _dbA)
+ throw std::runtime_error("Cannot close database A. Database was not set.");
+ if (0 == _dbB)
+ throw std::runtime_error("Cannot close database B. Database was not set.");
+
+ _dbA->close();
+ _dbB->close();
+} // close
+
+// ----------------------------------------------------------------------
+// Set values to be returned by queries.
+void
+spatialdata::spatialdb::CompositeDB::queryVals(const char** names,
+ const int numVals)
+{ // queryVals
+ assert(0 != _dbA);
+ assert(0 != _infoA);
+ assert(0 != _dbB);
+ assert(0 != _infoB);
+
+ if (0 == numVals) {
+ std::ostringstream msg;
+ msg
+ << "Number of values for query in spatial database " << label()
+ << "\n must be positive.\n";
+ throw std::runtime_error(msg.str());
+ } // if
+ assert(0 != names && 0 < numVals);
+
+ _infoA->query_size = 0;
+ _infoB->query_size = 0;
+ const int numNamesA = _infoA->num_names;
+ const int numNamesB = _infoB->num_names;
+ for (int iVal=0; iVal < numVals; ++iVal) {
+ bool foundA = false;
+ bool foundB = false;
+
+ // Search database A names for name
+ int iName = 0;
+ while (iName < numNamesA) {
+ if (0 == strcasecmp(names[iVal], _infoA->names_values[iName].c_str())) {
+ foundA = true;
+ ++_infoA->query_size;
+ break;
+ } // if
+ ++iName;
+ } // while
+
+ // Search database B names for name
+ iName = 0;
+ while (iName < numNamesB) {
+ if (0 == strcasecmp(names[iVal], _infoB->names_values[iName].c_str())) {
+ foundB = true;
+ ++_infoB->query_size;
+ break;
+ } // if
+ ++iName;
+ } // while
+
+ if (!foundA && !foundB) {
+ std::ostringstream msg;
+ msg
+ << "Value " << names[iVal]
+ << " not found in either database A or database B.";
+ throw std::runtime_error(msg.str());
+ } else if (foundA && foundB) {
+ std::ostringstream msg;
+ msg
+ << "Value " << names[iVal]
+ << " found in both database A or database B.";
+ throw std::runtime_error(msg.str());
+ } // if/else
+ } // for
+ assert(_infoA->query_size + _infoB->query_size == numVals);
+
+ // Setup query values for A
+ const int qsizeA = _infoA->query_size;
+ char** queryValsA = (qsizeA > 0) ? new char*[qsizeA] : 0;
+ delete[] _infoA->query_indices;
+ _infoA->query_indices = (qsizeA > 0) ? new int[qsizeA] : 0;
+ delete[] _infoA->query_buffer;
+ _infoA->query_buffer = (qsizeA > 0) ? new double[qsizeA] : 0;
+
+ // Setup query values for B
+ const int qsizeB = _infoB->query_size;
+ char** queryValsB = (qsizeB > 0) ? new char*[qsizeB] : 0;
+ delete[] _infoB->query_indices;
+ _infoB->query_indices = (qsizeB > 0) ? new int[qsizeB] : 0;
+ delete[] _infoB->query_buffer;
+ _infoB->query_buffer = (qsizeB > 0) ? new double[qsizeB] : 0;
+
+ for (int iVal=0, indexA=0, indexB=0; iVal < numVals; ++iVal) {
+ int iName = 0;
+ // Search database A names
+ while (iName < numNamesA) {
+ if (0 == strcasecmp(names[iVal], _infoA->names_values[iName].c_str())) {
+ assert(indexA < qsizeA);
+ _infoA->query_indices[indexA] = iVal;
+ queryValsA[indexA] = const_cast<char*>(names[iVal]);
+ ++indexA;
+ break;
+ } // if
+ ++iName;
+ } // while
+
+ // Search database B names
+ while (iName < numNamesB) {
+ if (0 == strcasecmp(names[iVal], _infoB->names_values[iName].c_str())) {
+ assert(indexB < qsizeB);
+ _infoB->query_indices[indexB] = iVal;
+ queryValsB[indexB] = const_cast<char*>(names[iVal]);
+ ++indexB;
+ break;
+ } // if
+ ++iName;
+ } // while
+ } // for
+ _dbA->queryVals(const_cast<const char**>(queryValsA), qsizeA);
+ _dbB->queryVals(const_cast<const char**>(queryValsB), qsizeB);
+
+ delete[] queryValsA; queryValsA = 0;
+ delete[] queryValsB; queryValsB = 0;
+} // queryVals
+
+// ----------------------------------------------------------------------
+// Query the database.
+int
+spatialdata::spatialdb::CompositeDB::query(
+ double* vals,
+ const int numVals,
+ const double* coords,
+ const int numDims,
+ const spatialdata::geocoords::CoordSys* pCSQuery)
+{ // query
+ assert(0 != _dbA);
+ assert(0 != _infoA);
+ assert(0 != _dbB);
+ assert(0 != _infoB);
+
+ const int qsizeA = _infoA->query_size;
+ const int qsizeB = _infoB->query_size;
+ const int querySize = qsizeA + qsizeB;
+ if (0 == querySize) {
+ std::ostringstream msg;
+ msg
+ << "Values to be returned by spatial database " << label() << "\n"
+ << "have not been set. Please call queryVals() before query().\n";
+ throw std::runtime_error(msg.str());
+ } // if
+ else if (numVals != querySize) {
+ std::ostringstream msg;
+ msg
+ << "Number of values to be returned by spatial database "
+ << label() << "\n"
+ << "(" << querySize << ") does not match size of array provided ("
+ << numVals << ").\n";
+ throw std::runtime_error(msg.str());
+ } // if
+
+ // Query database A
+ _dbA->query(_infoA->query_buffer, qsizeA, coords, numDims, pCSQuery);
+ for (int i=0; i < qsizeA; ++i)
+ vals[_infoA->query_indices[i]] = _infoA->query_buffer[i];
+
+ // Query database B
+ _dbB->query(_infoB->query_buffer, qsizeB, coords, numDims, pCSQuery);
+ for (int i=0; i < qsizeB; ++i)
+ vals[_infoB->query_indices[i]] = _infoB->query_buffer[i];
+
+ return 0;
+} // query
+
+
+// End of file
Added: cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.hh
===================================================================
--- cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.hh (rev 0)
+++ cs/spatialdata-0.1/trunk/libsrc/spatialdb/CompositeDB.hh 2008-08-31 02:57:22 UTC (rev 12759)
@@ -0,0 +1,139 @@
+// -*- C++ -*-
+//
+// ----------------------------------------------------------------------
+//
+// Brad T. Aagaard
+// U.S. Geological Survey
+//
+// <LicenseText>
+//
+// ----------------------------------------------------------------------
+//
+
+/** @file libsrc/spatialdb/CompositeDB.hh
+ *
+ * @brief C++ manager for simple spatial database.
+ */
+
+#if !defined(spatialdata_spatialdb_compositedb_hh)
+#define spatialdata_spatialdb_compositedb_hh
+
+#include "SpatialDB.hh"
+
+#include <string> // HASA std::string
+
+namespace spatialdata {
+ namespace spatialdb {
+ class SpatialDB; // ISA SpatialDB
+ class CompositeDB;
+ class TestCompositeDB; // unit testing
+ } // spatialdb
+} // spatialdata
+
+/// C++ manager for simple spatial database.
+class spatialdata::spatialdb::CompositeDB : public SpatialDB
+{ // class CompositeDB
+ friend class TestCompositeDB; // unit testing
+
+ public :
+ // PUBLIC METHODS /////////////////////////////////////////////////////
+
+ /// Default constructor.
+ CompositeDB(void);
+
+ /** Constructor with label.
+ *
+ * @param label Label of database
+ */
+ CompositeDB(const char* label);
+
+ /// Default destructor.
+ ~CompositeDB(void);
+
+ /** Set database A.
+ *
+ * @param db Pointer to database.
+ * @param names Array of names of values to use with database.
+ * @param numNames Size of array of names.
+ */
+ void dbA(SpatialDB* db,
+ const char** names,
+ const int numNames);
+
+ /** Set database B.
+ *
+ * @param db Pointer to database.
+ * @param names Array of names of values to use with database.
+ * @param numNames Size of array of names.
+ */
+ void dbB(SpatialDB* db,
+ const char** names,
+ const int numNames);
+
+ /// Open the database and prepare for querying.
+ void open(void);
+
+ /// Close the database.
+ void close(void);
+
+ /** Set values to be returned by queries.
+ *
+ * @pre Must call open() before queryVals()
+ *
+ * @param names Names of values to be returned in queries
+ * @param numVals Number of values to be returned in queries
+ */
+ void queryVals(const char** names,
+ const int numVals);
+
+ /** Query the database.
+ *
+ * @pre Must call open() before query()
+ *
+ * @param vals Array for computed values (output from query), vals
+ * must be allocated BEFORE calling query().
+ * @param numVals Number of values expected (size of pVals array)
+ * @param coords Coordinates of point for query
+ * @param numDims Number of dimensions for coordinates
+ * @param pCSQuery Coordinate system of coordinates
+ *
+ * @returns 0 on success, 1 on failure (i.e., could not interpolate
+ * so values set to 0)
+ */
+ int query(double* vals,
+ const int numVals,
+ const double* coords,
+ const int numDims,
+ const spatialdata::geocoords::CoordSys* pCSQuery);
+
+private :
+ // NOT IMPLEMENTED ////////////////////////////////////////////////////
+
+ CompositeDB(const CompositeDB& data); ///< Not implemented
+ const CompositeDB& operator=(const CompositeDB& data); ///< Not implemented
+
+private :
+ // PRIVATE STRUCTS ////////////////////////////////////////////////////
+
+ struct dbinfo {
+ double* query_buffer;
+ int* query_indices;
+ std::string* names_values;
+ int query_size;
+ int num_names;
+ }; // dbinfo
+
+private :
+ // PRIVATE MEMBERS /////////////////////////////////////////////////////
+
+ SpatialDB* _dbA; ///< Spatial database A
+ SpatialDB* _dbB; ///< Spatial database B
+
+ dbinfo* _infoA; ///< Information for database A
+ dbinfo* _infoB; ///< Information for database B
+}; // class CompositeDB
+
+#endif // spatialdata_spatialdb_compositedb_hh
+
+
+// End of file
More information about the cig-commits
mailing list