[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