cpp35Example_main.cpp

R-Tree example (see R-Tree CPP Example). This example needs a compiled schema, cpp35Example.sdl.

/* ----------------------------------------------------------------------------
*
* Raima Database Manager
*
* Copyright (c) 2020 Raima Inc., All rights reserved.
*
* Use of this software, whether in source code format, or in executable,
* binary object code form, is governed by the Raima LICENSE which
* is fully described in the LICENSE.TXT file, included within this
* distribution of files.
*
* ----------------------------------------------------------------------------
*/
#include "rdm.h"
#include "rdmstartupapi.h"
#include "rdmapi.h"
#include "rdmtfsapi.h"
#include "cpp35Example_structs.h"
#include "cpp35Example_cat.h"
#include "cpp35Example_gen_api.h"
#include "cpp-tfs.h"
#include "cpp-exception.h"
#include "cpp-transaction.h"
#include <iostream>
using namespace RDM_CPP;
using namespace RDM_CPP::CPP35EXAMPLE;
#define FIXED_FLOAT(x) std::fixed << (x)
/* \file rtreeExample.c
\brief Simple r-tree example using the RDM C++ API
This example will show you how to manage 2 dimensional data, using an
r-tree index.
The example will insert several rows containing point data which
will be put into an r-tree.
The example will then perform a series of queries to retrieve the data
that meet specific criteria.
*/
/* \brief Delete all data from the database
This function will remove all rows from all tables in the database.
*/
static void delete_data (Db_cpp35Example db)
{
RDM_TABLE_ID tablesToLock[1] = {TABLE_RTREE_TABLE};
std::cout << "Removing all data from the database" << std::endl;
/* Start an update transaction */
db.StartUpdate (tablesToLock, 1);
try
{
db.DeleteAllRows ();
db.End ();
} catch (rdm_exception e)
{
db.EndRollback ();
throw;
}
}
/* \brief Print the contents of a rectangle
*/
static void printRectangle (double rect[4])
{
std::cout << "{ (" << std::fixed << rect[0] << ", " << rect[1] << "), ("
<< rect[2] << ", " << rect[3] << ") }";
}
/* \brief Insert rows into the RTREE_TABLE table
This function will insert two rows into the RTREE_TABLE table.
*/
static void insert_data (Db_cpp35Example db)
{
uint32_t ii;
RDM_TABLE_ID tablesToLock[1] = {TABLE_RTREE_TABLE};
RTREE_TABLE row_data[] =
{/* utm coordinates */
/* id | x-min | y-min | x-max | y-max
*/
{"T_SIG_4356_UTM",
{536606.1538, 5279277.737, 536606.1538, 5279277.737}},
{"T_SIG_4357_UTM",
{536610.0608, 5279253.421, 536610.0608, 5279253.421}},
{"T_SIG_4358_UTM",
{536584.7699, 5279251.706, 536584.7699, 5279251.706}},
{"T_SIG_4359_UTM",
{536588.0522, 5279278.956, 536588.0522, 5279278.956}},
{"T_SIG_4405_UTM",
{536175.4322, 5278455.695, 536175.4322, 5278455.695}},
{"T_SIG_4406_UTM",
{536159.8151, 5278443.372, 536159.8151, 5278443.372}},
{"T_SIG_4407_UTM",
{536143.4427, 5278455.941, 536143.4427, 5278455.941}},
{"T_SIG_4408_UTM",
{536150.6135, 5278474.102, 536150.6135, 5278474.102}},
{"T_SIG_4458_UTM",
{536201.2532, 5278082.970, 536201.2532, 5278082.970}},
{"T_SIG_4459_UTM",
{536191.8691, 5278070.464, 536191.8691, 5278070.464}},
{"T_SIG_4460_UTM",
{536182.6727, 5278076.075, 536182.6727, 5278076.075}},
{"T_SIG_4461_UTM",
{536192.0458, 5278090.360, 536192.0458, 5278090.360}},
/* geo coordinates */
/* id | x-min | y-min | x-max | y-max */
{"T_SIG_4356_GEO", {47.665856, 9.487589, 47.665856, 9.487589}},
{"T_SIG_4357_GEO", {47.665637, 9.487639, 47.665637, 9.487639}},
{"T_SIG_4358_GEO", {47.665623, 9.487302, 47.665623, 9.487302}},
{"T_SIG_4359_GEO", {47.665868, 9.487348, 47.665868, 9.487348}},
{"T_SIG_4405_GEO", {47.658484, 9.481784, 47.658484, 9.481784}},
{"T_SIG_4406_GEO", {47.658374, 9.481575, 47.658374, 9.481575}},
{"T_SIG_4407_GEO", {47.658488, 9.481358, 47.658488, 9.481358}},
{"T_SIG_4408_GEO", {47.658651, 9.481455, 47.658651, 9.481455}},
{"T_SIG_4458_GEO", {47.655129, 9.482097, 47.655129, 9.482097}},
{"T_SIG_4459_GEO", {47.655017, 9.481971, 47.655017, 9.481971}},
{"T_SIG_4460_GEO", {47.655068, 9.481849, 47.655068, 9.481849}},
{"T_SIG_4461_GEO", {47.655196, 9.481975, 47.655196, 9.481975}}};
/* First we will remove all existing data from the database */
delete_data (db);
std::cout << "Inserting data..." << std::endl;
/* Start a transaction */
db.StartUpdate (tablesToLock, 1);
try
{
for (ii = 0; ii < RDM_LEN (row_data); ii++)
{
db.Insert_rtree_table_Row (row_data[ii]);
std::cout << " ** Inserted Row id: " << row_data[ii].id
<< ", rect = ";
printRectangle (row_data[ii].rect);
std::cout << std::endl;
}
db.End ();
} catch (rdm_exception e)
{
db.EndRollback ();
throw;
}
}
/* \brief Print the current for of a cursor based on the RTREE_TABLE
*/
static void printCurrentRtreeTableRow (Cursor_rtree_table cursor)
{
RTREE_TABLE row;
/* Read the value of the current row into a structure */
cursor.ReadRow (row);
/* Print the row that was read */
std::cout << " ** Found Row id: " << row.id << ", rect = ";
printRectangle (row.rect);
std::cout << std::endl;
}
/* \brief Look up rectangles that meet the specified criteria
This function will read create a cursor containing all rectangles in the
r-tree that meet the bounding box criteria. It will then iterate through
the cursor and display the rows.
*/
static void displayRectangles (
Db_cpp35Example db, /*< [in] database handle */
RDM_RTREE_TYPE type, /*< [in] The query type */
double boundingBox[4] /*< [in] The bounding box */
)
{
Cursor_rtree_table cursor;
RDM_TABLE_ID tablesToLock[] = {TABLE_RTREE_TABLE};
/* Get a read lock on the RTREE_TABLE table */
db.StartRead (tablesToLock, RDM_LEN (tablesToLock));
try
{
/* Create the cursor using the r-tree */
cursor = db.Get_rtree_table_RowsBy_rect (boundingBox, type);
/* Move to the first resulting row */
cursor.MoveToFirst ();
while (cursor.GetStatus () == CURSOR_AT_ROW)
{
found = RDM_TRUE;
/* Print the current cursor row */
printCurrentRtreeTableRow (cursor);
/* Move to the next row */
cursor.MoveToNext ();
}
/* Free the locks */
db.End ();
} catch (rdm_exception e)
{
std::cerr << "Error in displayRectangles";
db.End ();
throw;
}
/* Display a message if we didn't retrieve any rows */
if (found == RDM_FALSE)
{
std::cout << " ** No Rows Found" << std::endl;
}
}
/* \brief Look up rectangles contained by the specified bounding box
*/
static void displayContainedRectangles (
Db_cpp35Example db, /*< [IN} The database handle */
double boundingBox[4] /*< [IN] The bounding box value */
)
{
displayRectangles (db, RDM_RTREE_CONTAINS, boundingBox);
}
/* \brief Look up rectangles overlapping the specified bounding box
*/
static void displayOverlappingRectangles (
Db_cpp35Example db, /*< [IN] The database handle */
double boundingBox[4] /*< [IN] The bounding box value */
)
{
displayRectangles (db, RDM_RTREE_OVERLAP, boundingBox);
}
/* \brief The main function
This function will do initialization and cleanup as well as call
the functions that insert/retrieve data
*/
int32_t main_rtreeCPP (int32_t argc, const char *const *argv)
{
TFS tfs = NULL;
Db_cpp35Example db;
double boundingBox[4];
RDM_UNREF (argc);
RDM_UNREF (argv);
try
{
/* Allocate RDM_TFS handle */
tfs = TFS::Alloc ("");
/* Allocate RDM_DB handle */
db = tfs.AllocDatabase ();
/* Open database */
db.Open ("cpp35Example");
/* Insert data */
insert_data (db);
/* Do lookups with a bounding box that contains two of the rows in the
table that use utm coordinates. In this case there are tree
candidates for the X value, but only 2 matches for the Y value */
boundingBox[0] = 536100.0000; /* Min X Value */
boundingBox[1] = 5278440.0000; /* Min Y Value */
boundingBox[2] = 536159.0000; /* Max X Value */
boundingBox[3] = 5278475.000; /* Max Y Value */
std::cout << std::endl
<< std::endl
<< "Looking for rows CONTAINED by the bounding box ";
printRectangle (boundingBox);
std::cout << std::endl << "There should be 2 rows found" << std::endl;
displayContainedRectangles (db, boundingBox);
/* Do lookups with a bounding box that contains two of the rows in the
* table that use geo coordinates */
boundingBox[0] = 47.655000; /* Min X Value */
boundingBox[1] = 9.481000; /* Min Y Value */
boundingBox[2] = 47.665600; /* Max X Value */
boundingBox[3] = 9.482000; /* Max Y Value */
std::cout << std::endl
<< std::endl
<< "Looking for rows CONTAINED by the bounding box ";
printRectangle (boundingBox);
std::cout << std::endl << "There should be 7 rows found" << std::endl;
displayContainedRectangles (db, boundingBox);
/* Do lookups with a bounding box that doesn't contain rows from
either of the coordinate systems */
boundingBox[0] = 6; /* Min X Value */
boundingBox[1] = 14; /* Min Y Value */
boundingBox[2] = 19; /* Max X Value */
boundingBox[3] = 25; /* Max Y Value */
std::cout << std::endl
<< std::endl
<< "Looking for rows CONTAINED by the bounding box ";
printRectangle (boundingBox);
std::cout << std::endl << "There should be 0 rows found" << std::endl;
displayContainedRectangles (db, boundingBox);
} catch (rdm_exception e)
{
std::cerr << "Database Error: " << e.GetEnum () << " - "
<< e.GetDescription () << std::endl;
}
return 0;
}
RDM_RTREE_TYPE
Query types for an R-tree index.
Definition: rdmtypes.h:78
Header for the native RDM Runtime API.
Header for the RDM Core API.
Header for C++ exceptions.
@ RDM_FALSE
Definition: psptypes.h:59
Header for the C++ Transaction File Server (TFS) API.
uint32_t RDM_TABLE_ID
Definition: rdmtypes.h:27
@ CURSOR_AT_ROW
Definition: rdmtypes.h:208
@ RDM_RTREE_CONTAINS
Definition: rdmtypes.h:82
@ RDM_TRUE
Definition: psptypes.h:60
The TFS class This class provides the TFS implementation.
Definition: cpp-tfs.h:64
Header for the Transactional File Server (TFS) API.
#define RDM_STARTUP_EXAMPLE(name)
Definition: rdmstartuptypes.h:73
Db Open(const char *name, RDM_OPEN_MODE mode, const char *const catalog) const
Open the database.
RDM_BOOL_T
Definition: psptypes.h:58
#define RDM_UNREF(a)
Definition: psptypes.h:45
virtual const char * GetEnum() const
Header for the C++ transaction API.
@ RDM_RTREE_OVERLAP
Definition: rdmtypes.h:81
Db AllocDatabase(const char *opts=NULL)
Instantiate a database.
the rdm_exception class This class implements the exception thrown by the RDM CPP API
Definition: cpp-exception.h:46
virtual const char * GetDescription() const
method to get a text description of the error causing the exception to be thrown
#define RDM_LEN(x)
Definition: psptypes.h:78
The RDM C++ Namespace.
Definition: cpp-cursor.h:27
static TFS Alloc(RDM_TFS tfs)
Return TFS object using the specified RDM_TFS.
Internal RDM Startup API used by startup macros.