[Liblas-commits] libpc: basic block insertion working
liblas-commits at liblas.org
liblas-commits at liblas.org
Sat Mar 12 10:20:57 EST 2011
details: http://hg.liblas.orglibpc/rev/ead0797d4b32
changeset: 223:ead0797d4b32
user: Howard Butler <hobu.inc at gmail.com>
date: Sat Mar 12 09:20:52 2011 -0600
description:
basic block insertion working
diffstat:
src/drivers/oci/writer.cpp | 292 ++++++++++++++++++++++++++++++++++++++++++--
src/drivers/oci/writer.hpp | 19 ++-
2 files changed, 294 insertions(+), 17 deletions(-)
diffs (truncated from 436 to 300 lines):
diff -r cad506ee8458 -r ead0797d4b32 src/drivers/oci/writer.cpp
--- a/src/drivers/oci/writer.cpp Sat Mar 12 08:09:18 2011 -0600
+++ b/src/drivers/oci/writer.cpp Sat Mar 12 09:20:52 2011 -0600
@@ -65,7 +65,7 @@
m_tree.put("connection", std::string(""));
m_tree.put("block_table_name", std::string("output"));
m_tree.put("block_table_partition_column", std::string(""));
- m_tree.put("block_table_partition_value", std::string(""));
+ m_tree.put("block_table_partition_value", 0);
m_tree.put("base_table_name", std::string("hobu"));
m_tree.put("cloud_column_name", std::string("cloud"));
m_tree.put("header_blob_column_name", std::string("header"));
@@ -75,6 +75,7 @@
m_tree.put("pre_sql", std::string(""));
m_tree.put("post_block_sql", std::string(""));
m_tree.put("base_table_bounds", libpc::Bounds<double>());
+ m_tree.put("cloud_id", boost::uint32_t(0));
}
@@ -92,6 +93,20 @@
return debug;
}
+bool Options::IsSolid() const
+{
+ bool solid = false;
+ try
+ {
+ solid = m_tree.get<bool>("solid");
+ }
+ catch (liblas::property_tree::ptree_bad_path const& e) {
+ ::boost::ignore_unused_variable_warning(e);
+
+ }
+ return solid;
+}
+
bool Options::Is3d() const
{
bool is3d = false;
@@ -146,6 +161,8 @@
Writer::~Writer()
{
+ m_connection->Commit();
+
return;
}
@@ -513,12 +530,9 @@
}
-long Writer::CreatePCEntry(std::vector<boost::uint8_t> const* header_data)
+void Writer::CreatePCEntry(std::vector<boost::uint8_t> const* header_data)
{
-
-
-
- boost::property_tree::ptree tree = m_options.GetPTree();
+ boost::property_tree::ptree& tree = m_options.GetPTree();
std::string block_table_name = to_upper(tree.get<std::string>("block_table_name"));
std::string base_table_name = to_upper(tree.get<std::string>("base_table_name"));
@@ -647,7 +661,7 @@
}
output = pc_id;
- return output;
+ tree.put("cloud_id", pc_id);
}
void Writer::writeBegin()
@@ -685,16 +699,26 @@
return;
}
-bool Writer::FillOraclePointData(PointData const& buffer, std::vector<boost::uint8_t>& point_data)
+bool Writer::FillOraclePointData(PointData const& buffer,
+ std::vector<boost::uint8_t>& point_data,
+ chipper::Block const& block,
+ boost::uint32_t block_id)
{
libpc::Schema const& schema = buffer.getSchema();
+ std::vector<boost::uint32_t> ids = block.GetIDs();
bool hasTimeData = schema.hasDimension(Dimension::Field_Time);
boost::uint64_t count = buffer.getNumPoints();
+ point_data.clear(); // wipe whatever was there
+ boost::uint32_t oracle_record_size = 8+8+8+8+8+4+4;
+ // point_data.resize(count*oracle_record_size);
+
+ // assert(count*oracle_record_size == point_data.size());
+
const int indexX = schema.getDimensionIndex(Dimension::Field_X);
const int indexY = schema.getDimensionIndex(Dimension::Field_Y);
const int indexZ = schema.getDimensionIndex(Dimension::Field_Z);
@@ -714,24 +738,262 @@
double zoffset = dimZ.getNumericOffset();
boost::uint32_t counter = 0;
+ std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
+ std::cout.precision(6);
+
while (counter < count)
{
- const double x = (buffer.getField<boost::int32_t>(counter, indexX) * xscale) + xoffset;
- const double y = (buffer.getField<boost::int32_t>(counter, indexY) * yscale) + yoffset;
- const double z = (buffer.getField<boost::int32_t>(counter, indexZ) * zscale) + zoffset;
+ double x = (buffer.getField<boost::int32_t>(counter, indexX) * xscale) + xoffset;
+ double y = (buffer.getField<boost::int32_t>(counter, indexY) * yscale) + yoffset;
+ double z = (buffer.getField<boost::int32_t>(counter, indexZ) * zscale) + zoffset;
+ boost::uint8_t classification = buffer.getField<boost::uint8_t>(counter, indexClassification);
+ double c = static_cast<double>(classification);
+ boost::uint32_t id = ids[counter];
+ std::cout << x <<" "<< y <<" "<< z << " "<< id << " " << c <<std::endl;
double t = 0.0;
- if (indexTime != -1)
+ if (hasTimeData)
t = buffer.getField<double>(counter, indexTime);
+
+ boost::uint8_t* x_b = reinterpret_cast<boost::uint8_t*>(&x);
+ boost::uint8_t* y_b = reinterpret_cast<boost::uint8_t*>(&y);
+ boost::uint8_t* z_b = reinterpret_cast<boost::uint8_t*>(&z);
+ boost::uint8_t* t_b = reinterpret_cast<boost::uint8_t*>(&t);
+ boost::uint8_t* c_b = reinterpret_cast<boost::uint8_t*>(&c);
+
+ // big-endian
+ for (int i = sizeof(double) - 1; i >= 0; i--) {
+ point_data.push_back(x_b[i]);
+ }
+
+ for (int i = sizeof(double) - 1; i >= 0; i--) {
+ point_data.push_back(y_b[i]);
+ }
+
+ for (int i = sizeof(double) - 1; i >= 0; i--) {
+ point_data.push_back(z_b[i]);
+ }
+
+
+ for (int i = sizeof(double) - 1; i >= 0; i--) {
+ point_data.push_back(t_b[i]);
+ }
+
+ // Classification is only a single byte, but
+ // we need to store it in an 8 byte big-endian
+ // double to satisfy OPC
+ for (int i = sizeof(double) - 1; i >= 0; i--) {
+ point_data.push_back(c_b[i]);
+ }
+
+ boost::uint8_t* id_b = reinterpret_cast<boost::uint8_t*>(&id);
+ boost::uint8_t* block_b = reinterpret_cast<boost::uint8_t*>(&block_id);
+ // 4-byte big-endian integer for the BLK_ID value
+ for (int i = sizeof(boost::uint32_t) - 1; i >= 0; i--) {
+ point_data.push_back(block_b[i]);
+ }
+ // 4-byte big-endian integer for the PT_ID value
+ for (int i = sizeof(boost::uint32_t) - 1; i >= 0; i--) {
+ point_data.push_back(id_b[i]);
+ }
+
counter++;
}
+
+ assert(count*oracle_record_size == point_data.size());
return true;
}
+void Writer::SetElements( Statement statement,
+ OCIArray* elem_info)
+{
+
+
+ statement->AddElement(elem_info, 1);
+ bool bUseSolidGeometry = m_options.IsSolid();
+ if (bUseSolidGeometry == true) {
+ //"(1,1007,3)";
+ statement->AddElement(elem_info, 1007);
+ } else {
+ //"(1,1003,3)";
+ statement->AddElement(elem_info, 1003);
+ }
+
+ statement->AddElement(elem_info, 3);
+
+}
+
+void Writer::SetOrdinates(Statement statement,
+ OCIArray* ordinates,
+ libpc::Bounds<double> const& extent)
+{
+
+ statement->AddElement(ordinates, extent.getMinimum(0));
+ statement->AddElement(ordinates, extent.getMaximum(1));
+ if (extent.dimensions().size() > 2)
+ statement->AddElement(ordinates, extent.getMinimum(2));
+
+ statement->AddElement(ordinates, extent.getMaximum(0));
+ statement->AddElement(ordinates, extent.getMaximum(1));
+ if (extent.dimensions().size() > 2)
+ statement->AddElement(ordinates, extent.getMaximum(2));
+
+
+}
+
+bool Writer::WriteBlock(PointData const& buffer,
+ std::vector<boost::uint8_t>& point_data,
+ chipper::Block const& block,
+ boost::uint32_t block_id)
+{
+
+ boost::property_tree::ptree& tree = m_options.GetPTree();
+
+ std::string block_table_name = to_upper(tree.get<std::string>("block_table_name"));
+ std::string block_table_partition_column = to_upper(tree.get<std::string>("block_table_partition_column"));
+ boost::int32_t block_table_partition_value = tree.get<boost::uint32_t>("block_table_partition_value");
+ boost::uint32_t srid = tree.get<boost::uint32_t>("srid");
+
+ bool bUsePartition = block_table_partition_column.size() != 0;
+
+ std::vector<boost::uint32_t> ids = block.GetIDs();
+
+
+
+ std::ostringstream oss;
+ std::ostringstream partition;
+
+ if (bUsePartition)
+ {
+ partition << "," << block_table_partition_column;
+ }
+
+
+
+ // EnableTracing(connection);
+
+ long gtype = GetGType();
+
+
+ oss << "INSERT INTO "<< block_table_name <<
+ "(OBJ_ID, BLK_ID, NUM_POINTS, POINTS, "
+ "PCBLK_MIN_RES, BLK_EXTENT, PCBLK_MAX_RES, NUM_UNSORTED_POINTS, PT_SORT_DIM";
+ if (bUsePartition)
+ oss << partition.str();
+ oss << ") "
+ "VALUES ( :1, :2, :3, :4, 1, mdsys.sdo_geometry(:5, :6, null,:7, :8)"
+ ", 1, 0, 1";
+ if (bUsePartition)
+ oss << ", :9";
+
+ oss <<")";
+
+ // TODO: If gotdata == false below, this memory probably leaks --mloskot
+ OCILobLocator** locator =(OCILobLocator**) VSIMalloc( sizeof(OCILobLocator*) * 1 );
+
+ Statement statement = Statement(m_connection->CreateStatement(oss.str().c_str()));
+
+
+ long pc_id = tree.get<boost::int32_t>("cloud_id");
+ long* p_pc_id = (long*) malloc( 1 * sizeof(long));
+ p_pc_id[0] = pc_id;
+
+ long* p_result_id = (long*) malloc( 1 * sizeof(long));
+ p_result_id[0] = (long)block_id;
+
+ long* p_num_points = (long*) malloc (1 * sizeof(long));
+ p_num_points[0] = (long)ids.size();
+
+
+ // :1
+ statement->Bind( p_pc_id );
+
+ // :2
+ statement->Bind( p_result_id );
+
+ // :3
+ statement->Bind( p_num_points );
+
+ // :4
+ statement->Define( locator, 1 );
+
+
+ // std::vector<liblas::uint8_t> data;
+ // bool gotdata = GetResultData(result, reader, data, 3);
+ // if (! gotdata) throw std::runtime_error("unable to fetch point data byte array");
+
+ statement->Bind((char*)&(point_data[0]),(long)point_data.size());
+
More information about the Liblas-commits
mailing list