[Liblas-commits] r1302 - in trunk: apps include/liblas/index src/index

liblas-commits at liblas.org liblas-commits at liblas.org
Sat Jul 4 00:53:50 EDT 2009


Author: hobu
Date: Sat Jul  4 00:53:49 2009
New Revision: 1302
URL: http://liblas.org/changeset/1302

Log:
more indexing updates for point cloud creation.  almost working.

Modified:
   trunk/apps/Makefile.am
   trunk/apps/las2oci.cpp
   trunk/apps/lasindex.cpp
   trunk/include/liblas/index/index.hpp
   trunk/include/liblas/index/query.hpp
   trunk/src/index/index.cpp
   trunk/src/index/query.cpp

Modified: trunk/apps/Makefile.am
==============================================================================
--- trunk/apps/Makefile.am	(original)
+++ trunk/apps/Makefile.am	Sat Jul  4 00:53:49 2009
@@ -22,7 +22,7 @@
 BOOST_FLAGS = @BOOST_CPPFLAGS@ -DHAVE_BOOST=1
 endif
 
-AM_CPPFLAGS = -I../include/liblas/capi -I../include $(GEOTIFF_CPPFLAGS) $(GDAL_CPPFLAGS) $(SPATIALINDEX_CPPFLAGS) $(OCI_CPPFLAGS) $(ZLIB_CPPFLAGS) $(BOOST_FLAGS)
+AM_CPPFLAGS = -I../include/liblas/capi -I../include $(GDAL_CPPFLAGS) $(GEOTIFF_CPPFLAGS) $(SPATIALINDEX_CPPFLAGS) $(OCI_CPPFLAGS) $(ZLIB_CPPFLAGS) $(BOOST_FLAGS)
 
 lasinfo_SOURCES = lasinfo.c lascommon.c
 las2las_SOURCES = las2las.c lascommon.c

Modified: trunk/apps/las2oci.cpp
==============================================================================
--- trunk/apps/las2oci.cpp	(original)
+++ trunk/apps/las2oci.cpp	Sat Jul  4 00:53:49 2009
@@ -1,9 +1,60 @@
+
+// god-awful hack because of GDAL/GeoTIFF's shitty include structure
+#define CPL_SERV_H_INCLUDED
+
 #include "oci_wrapper.h"
+
+#include <liblas/cstdint.hpp>
+#include <liblas/detail/utility.hpp>
+
+#include <liblas/laspoint.hpp>
+#include <liblas/lasreader.hpp>
+#include <liblas/lasheader.hpp>
+#include <liblas/index/index.hpp>
+
 #include <string>
 #include <sstream>
 #include <iostream>
+#include <fstream>
+#include <exception>
+
+#ifdef HAVE_SPATIALINDEX
+#include <spatialindex/SpatialIndex.h>
+#endif
+
+#include <oci.h>
 
 using namespace std;
+using namespace liblas;
+
+#ifdef _WIN32
+#define compare_no_case(a,b,n)  _strnicmp( (a), (b), (n) )
+#else
+#define compare_no_case(a,b,n)  strncasecmp( (a), (b), (n) )
+#endif
+
+
+std::istream* OpenInput(std::string filename) 
+{
+    std::ios::openmode const mode = std::ios::in | std::ios::binary;
+    std::istream* istrm;
+    if (compare_no_case(filename.c_str(),"STDIN",5) == 0)
+    {
+        istrm = &std::cin;
+    }
+    else 
+    {
+        istrm = new std::ifstream(filename.c_str(), mode);
+    }
+    
+    if (!istrm->good())
+    {
+        delete istrm;
+        throw std::runtime_error("Reading stream was not able to be created");
+        exit(1);
+    }
+    return istrm;
+}
 
 OWStatement* Run(OWConnection* connection, ostringstream& command) 
 {
@@ -70,23 +121,227 @@
     ostringstream oss;
     OWStatement* statement = 0;
     
-    oss << "CREATE TABLE "<< tableName <<" (ID VARCHAR2(24), VAL_D1 NUMBER, VAL_D2 NUMBER, VAL_D3 NUMBER)";
+    oss << "CREATE TABLE "<< tableName <<" (OBJ_ID NUMBER, BLK_ID NUMBER, "
+                                         " BLK_EXTENT MDSYS.SDO_GEOMETRY, BLK_DOMAIN MDSYS.SDO_ORGSCL_TYPE,"
+                                         " PCBLK_MIN_RES NUMBER, PCBLK_MAX_RES NUMBER, NUM_POINTS NUMBER, "
+                                         " NUM_UNSORTED_POINTS NUMBER, PT_SORT_DIM NUMBER, POINTS BLOB)";
+    statement = Run(connection, oss);
+    if (statement != 0) delete statement; else return false;
+    oss.str("");
+
+    return true;
+
+}
+
+bool DeleteTable(OWConnection* connection, const char* tableName)
+{
+    ostringstream oss;
+    OWStatement* statement = 0;
+    
+    oss << "DROP TABLE "<< tableName ;
     statement = Run(connection, oss);
     if (statement != 0) delete statement; else return false;
     oss.str("");
     
     return true;
+
+}
+std::vector<liblas::uint8_t>* GetPointData(LASPoint const& p, bool bTime)
+{
+    // This function returns an array of bytes describing the 
+    // x,y,z and optionally time values for the point.  The caller owns 
+    // the array.
+    std::vector<liblas::uint8_t>* data = new std::vector<liblas::uint8_t>;
+    data->resize(24);
+    if (bTime) data->resize(data->size()+8); // Add the time bytes too
+
+    double x = p.GetX();
+    double y = p.GetY();
+    double z = p.GetZ();
+    double t = p.GetTime();
+
+    liblas::uint8_t* x_b =  reinterpret_cast<liblas::uint8_t*>(&x);
+    liblas::uint8_t* y_b =  reinterpret_cast<liblas::uint8_t*>(&y);
+    liblas::uint8_t* z_b =  reinterpret_cast<liblas::uint8_t*>(&z);
+
+    liblas::uint8_t* t_b =  reinterpret_cast<liblas::uint8_t*>(&t);
+
+    // doubles are 8 bytes long.  For each double, push back the 
+    // byte.  We do this for all four values (x,y,z,t)
+    for (int i=0; i<8; i++) {
+        data->push_back(x_b[i]);
+    }
+    for (int i=0; i<8; i++) {
+        data->push_back(y_b[i]);
+    }
+    for (int i=0; i<8; i++) {
+        data->push_back(z_b[i]);
+    }
+    
+    if (bTime)
+    {
+        for (int i=0; i<8; i++) {
+            data->push_back(t_b[i]);
+        }
+    }
+    return data;
+}
+std::vector<liblas::uint8_t>* GetResultData(const LASQueryResult& result, LASReader* reader, int nDimension)
+{
+    list<SpatialIndex::id_type> const& ids = result.GetIDs();
     
+    // calculate the vector size
+    // d 8-byte IEEE doubles, where d is the PC_TOT_DIMENSIONS value
+    // 4-byte big-endian integer for the BLK_ID value
+    // 4-byte big-endian integer for the PT_ID value
+    
+    bool bTime = false;
+    liblas::uint32_t record_size;
+    if (nDimension == 3)
+        record_size = ids.size() * (8*3+4+4);
+    else if (nDimension == 4)
+    {
+        record_size = ids.size() * (8*4+4+4);
+        bTime = true;
+    }
+    else
+        // throw a big error
+        throw std::runtime_error("Dimension must be 3 or 4");
+
+    vector<liblas::uint8_t>* output = new vector<liblas::uint8_t>;
+    output->resize(record_size);
+    
+    list<SpatialIndex::id_type>::const_iterator i;
+    vector<liblas::uint8_t>::iterator pi;
+    
+    
+    liblas::uint32_t block_id = result.GetID();
+    
+    for (i=ids.begin(); i!=ids.end(); i++) 
+    {
+        SpatialIndex::id_type id = *i;
+
+        bool doRead = reader->ReadPointAt(id);
+        if (doRead) {
+            LASPoint const& p = reader->GetPoint();
+            std::vector<liblas::uint8_t> *point_data = GetPointData(p, bTime);
+            
+            std::vector<liblas::uint8_t>::const_iterator d;
+            for (d = point_data->begin(); d!=point_data->end(); d++) {
+                output->push_back(*d);
+            }
+            // pi = std::copy(point_data->begin(), point_data->end(), pi);
+            delete point_data;
+            liblas::uint8_t* id_b = reinterpret_cast<liblas::uint8_t*>(&id);
+            liblas::uint8_t* block_b = reinterpret_cast<liblas::uint8_t*>(&block_id);
+            
+            // add 4-byte big endian integers
+            output->push_back(id_b[3]);
+            output->push_back(id_b[2]);
+            output->push_back(id_b[1]);
+            output->push_back(id_b[0]);
+            
+            output->push_back(block_b[3]);
+            output->push_back(block_b[2]);
+            output->push_back(block_b[1]);
+            output->push_back(block_b[0]);
+
+        }
+    }
+    return output;
+}
+
+bool InsertBlock(OWConnection* connection, const LASQueryResult& result, int srid, LASReader* reader, const char* tableName)
+{
+    ostringstream oss;
+
+    list<SpatialIndex::id_type> const& ids = result.GetIDs();
+    const SpatialIndex::Region* b = result.GetBounds();
+    liblas::uint32_t num_points =ids.size();
+    ostringstream oss_geom;
+    
+    oss_geom.setf(std::ios_base::fixed, std::ios_base::floatfield);
+    oss_geom.precision(2);
+    oss_geom << "mdsys.sdo_geometry(2003,"<<srid<<", null,"
+              "mdsys.sdo_elem_info_array(1,1003,3),"
+              "mdsys.sdo_ordinate_array("<< b->getLow(0) <<","<<b->getLow(1)<<","<<b->getHigh(0) <<","<<b->getHigh(1)<<"))";
+    oss << "INSERT INTO "<< tableName << "(OBJ_ID, NUM_POINTS, BLK_EXTENT, POINTS) VALUES ( " 
+                         << result.GetID() <<"," << num_points << ", " << oss_geom.str() <<", EMPTY_BLOB())";
+
+    OWStatement* statement = 0;
+    statement = connection->CreateStatement(oss.str().c_str());
+
+    if (statement->Execute() == false) {
+        delete statement;
+        return false;
+    }
+    
+    delete statement; statement = 0;
+    oss.str("");
+    
+    oss << "SELECT POINTS FROM " << tableName << " WHERE OBJ_ID=" << result.GetID() << " FOR UPDATE";
+    
+    // we only expect one blob to come back
+    OCILobLocator** locator =(OCILobLocator**) VSIMalloc( sizeof(OCILobLocator*) * 1 );
+    
+
+    statement = connection->CreateStatement(oss.str().c_str());
+    statement->Define( locator, 1 ); // fetch one blob
+    
+
+    if( statement->Execute() == false )
+    {
+        std::cout << "Unable to execute statement!" << std::endl;
+        delete statement;
+        return false;
+    }
+
+    if( statement->Fetch( 1 ) == false )
+    {
+        std::cout << "Unable to fetch POINTS blob!" << std::endl;
+        delete statement;
+        return false;
+    }
+    
+
+    liblas::uint32_t num_bytes = 0;
+    std::vector<liblas::uint8_t>* data = GetResultData(result, reader, 3);
+    std::cout << "Data size: " << data->size() << std::endl;
+    // liblas::uint8_t *bytes = (liblas::uint8_t*) new liblas::uint8_t[data->size()];
+    // memcpy( (void*)&(bytes[0]), (void*)data[0], data->size() );
+    // liblas::uint8_t *bytes;
+    int anumber = data->size();
+
+    // liblas::uint8_t *bytes2 = (liblas::uint8_t*) new liblas::uint8_t[data.size()];
+    // memset( bytes2, 0, data.size());
+
+//         int nBytesRead = statement->ReadBlob( locator[0],
+//                                             (void*)data,
+//                                             anumber );
+
+
+// this could be writing junk
+liblas::uint32_t num_bytes_written = statement->WriteBlob( locator[0],
+                                         data,
+                                        anumber );
+
+    delete statement;
+    // OWStatement::Free(locator, 1);
+    // exit(0);
+    return true;
 
 }
 void usage() {}
 
 int main(int argc, char* argv[])
 {
-    int rc = 0;
 
     std::string input;
     std::string output;
+    bool bDropTable = false;
+    liblas::uint32_t nCapacity = 10000;
+    double dFillFactor = 1.0;
+    int srid = 8307;
     
     for (int i = 1; i < argc; i++)
     {
@@ -106,27 +361,43 @@
             i++;
             input = std::string(argv[i]);
         }
-        else if (   strcmp(argv[i],"--output") == 0  ||
-                    strcmp(argv[i],"--out") == 0     ||
-                    strcmp(argv[i],"-out") == 0     ||
-                    strcmp(argv[i],"-o") == 0       
+        else if (   strcmp(argv[i],"--overwrite") == 0  ||
+                    strcmp(argv[i],"-drop") == 0   ||
+                    strcmp(argv[i],"-d") == 0 
                 )
         {
             i++;
-            output = std::string(argv[i]);
+            bDropTable=true;
         }
-        else if (i == argc - 2 && output.empty() && input.empty())
+        else if (   strcmp(argv[i],"--blk_capacity") == 0  ||
+                    strcmp(argv[i],"--capacity") == 0   ||
+                    strcmp(argv[i],"-c") == 0 
+                )
         {
-            input = std::string(argv[i]);
+            i++;
+            nCapacity=atoi(argv[i]);
         }
-        else if (i == argc - 1 && output.empty() && input.empty())
+        else if (   strcmp(argv[i],"--fill") == 0  ||
+                    strcmp(argv[i],"-fill") == 0   ||
+                    strcmp(argv[i],"-f") == 0 
+                )
         {
-            input = std::string(argv[i]);
+            i++;
+            dFillFactor=atof(argv[i]);
+        }
+        else if (   strcmp(argv[i],"--srid") == 0  ||
+                    strcmp(argv[i],"-srid") == 0   ||
+                    strcmp(argv[i],"-s") == 0 
+                )
+        {
+            i++;
+            srid=atoi(argv[i]);
         }
-        else if (i == argc - 1 && output.empty() && input.empty())
+        else if (input.empty())
         {
-            output = std::string(argv[i]);
+            input = std::string(argv[i]);
         }
+
         else 
         {
             usage();
@@ -135,10 +406,59 @@
     }
     
     OWConnection* con = new OWConnection("lidar","lidar","ubuntu/crrel.local");
-    if (con->Succeeded()) printf("succeded");
+    if (con->Succeeded()) std::cout <<"Oracle Connection succeded" << std::endl;
+
+
+    std::istream* istrm;
+    try {
+            istrm = OpenInput(input);
+    } catch (std::exception const& e)
+    {
+        std::cout << e.what() << std::endl;
+        std::cout << "exiting..." << std::endl;
+        exit(-1);
+    }
+
+    
+    
+    // change filename foo.las -> foo for an appropriate
+    // tablename for oracle
+    string::size_type dot_pos = input.find_first_of(".");
+    string table_name = input.substr(0,dot_pos);
+    
+    if (bDropTable) DeleteTable(con, table_name.c_str());
+    CreateTable(con, table_name.c_str());
+
+    LASReader* reader = new LASReader(*istrm);
+    LASIndexDataStream* idxstrm = new LASIndexDataStream(reader);
+    // reader->Reset();
+
+    LASIndex* idx = new LASIndex(input);
+    idx->SetType(LASIndex::eExternalIndex);
+    idx->SetLeafCapacity(nCapacity);
+    idx->SetFillFactor(1.0);
+    idx->Initialize(*idxstrm);
+
+    LASQuery* query = new LASQuery;
+    idx->Query(*query);    
+
+    if (idx != 0) delete idx;
+    if (reader != 0) delete reader;
+    if (istrm != 0 ) delete istrm;
+    
+    std::list<LASQueryResult>& results = query->GetResults();
+    
+    std::list<LASQueryResult>::const_iterator i;
+    
+    std::istream* istrm2;
+    istrm2 = OpenInput(input);
+    LASReader* reader2 = new LASReader(*istrm2);
+    for (i=results.begin(); i!=results.end(); i++)
+    {
+        bool inserted = InsertBlock(con, *i, srid, reader2, table_name.c_str());
+    }
     
-    Cleanup(con, "base");
-    CreateTable(con, "inptab");
+//    Cleanup(con, "base");
 
  // int   iCol = 0;
  //    char  szField[OWNAME];

Modified: trunk/apps/lasindex.cpp
==============================================================================
--- trunk/apps/lasindex.cpp	(original)
+++ trunk/apps/lasindex.cpp	Sat Jul  4 00:53:49 2009
@@ -9,16 +9,16 @@
 #include <liblas/lasvariablerecord.hpp>
 #include <liblas/index/index.hpp>
 
-#ifdef HAVE_BOOST
-#include <boost/iostreams/filter/zlib.hpp>
-#include <boost/iostreams/filtering_streambuf.hpp>
-#include <boost/iostreams/filtering_stream.hpp>
-#include <boost/iostreams/device/array.hpp>
-#include <boost/iostreams/device/back_inserter.hpp>
-#include <boost/iostreams/copy.hpp> 
-#include <boost/range/iterator_range.hpp>
-#include <boost/format.hpp> 
-#endif
+// #ifdef HAVE_BOOST
+// #include <boost/iostreams/filter/zlib.hpp>
+// #include <boost/iostreams/filtering_streambuf.hpp>
+// #include <boost/iostreams/filtering_stream.hpp>
+// #include <boost/iostreams/device/array.hpp>
+// #include <boost/iostreams/device/back_inserter.hpp>
+// #include <boost/iostreams/copy.hpp> 
+// #include <boost/range/iterator_range.hpp>
+// #include <boost/format.hpp> 
+// #endif
 
 #ifdef HAVE_SPATIALINDEX
 #include <spatialindex/SpatialIndex.h>
@@ -165,9 +165,19 @@
 
     
     std::string nothing = std::string("");
-    LASIndex* idx = new LASIndex(nothing);
-    idx->SetType(LASIndex::eMemoryIndex);
+    LASIndex* idx = new LASIndex(input);
+    idx->SetType(LASIndex::eExternalIndex);
+    idx->SetLeafCapacity(10000);
+    idx->SetFillFactor(1.0);
     idx->Initialize(*idxstrm);
+
+    if (idx != 0) delete idx;
+    idx = 0;
+
+    idx = new LASIndex(input);
+    idx->SetType(LASIndex::eExternalIndex);
+    idx->Initialize(*idxstrm);
+    
     std::vector<liblas::uint32_t>* ids = 0;
 
     try{
@@ -191,52 +201,60 @@
         std::cout << ids->at(i) <<",";
     }
     std::cout << std::endl;
+    
+    LASQuery* query = new LASQuery;
+    idx->Query(*query);
+
+    if (ids != 0) delete ids;
+    if (idx != 0) delete idx;
+    if (query != 0 ) delete query;
+
     // 
     // if (ids != 0) delete ids;
     // if (idx != 0) delete idx;
     // idx = 0;
     // 
-    namespace io = boost::iostreams;
-
-    // io::filtering_ostream ofilter;
-    // std::stringstream  junk;
-
-    // std::vector<liblas::uint8_t> compressed;
-    
-    std::string compressed;
-    io::filtering_streambuf<io::output> ofilter; 
-    ofilter.push(io::zlib_compressor());
-    ofilter.push(back_inserter(compressed));
-    
-    LASVariableRecord *vlr = idx->GetVLR();
-
-    std::string data("some junkdsfasdfasdfqwerasdfasdfasdfasdfasdfweradsfasdfasdfasdfasdfasdqwerasdfasdfasdfasdfqwerasdfasdfv");
-    // std::string data(vlr->GetData());
-    std::cout << "uncompressed size " << data.size() << std::endl;
-    
-    io::copy(boost::make_iterator_range(data),ofilter);
- 
-    // std::vector<liblas::uint8_t>&  d= *(vlr->GetData());
-    // io::copy(boost::make_iterator_range(d.begin(), d.end()),ofilter);
-
-    std::cout << "compressed size " << compressed.size() << std::endl;
+    // namespace io = boost::iostreams;
     // 
+    // // io::filtering_ostream ofilter;
+    // // std::stringstream  junk;
+    // 
+    // // std::vector<liblas::uint8_t> compressed;
+    // 
+    // std::string compressed;
+    // io::filtering_streambuf<io::output> ofilter; 
     // ofilter.push(io::zlib_compressor());
     // ofilter.push(back_inserter(compressed));
     // 
     // LASVariableRecord *vlr = idx->GetVLR();
-    // std::cout << "VLR length: " << vlr->GetRecordLength() << std::endl;
-    // 
-    // ofilter << "some junkdsfasdfasdfqwerasdfv";
     // 
-    // // ofilter << *vlr;
-    // std::cout << "stream size: " << ofilter.size() << std::endl;
+    // std::string data("some junkdsfasdfasdfqwerasdfasdfasdfasdfasdfweradsfasdfasdfasdfasdfasdqwerasdfasdfasdfasdfqwerasdfasdfv");
+    // // std::string data(vlr->GetData());
+    // std::cout << "uncompressed size " << data.size() << std::endl;
     // 
-    // ofilter.flush();
-    // 
-    // std::cout << "compressed size: " << compressed.size() << std::endl;
+    // io::copy(boost::make_iterator_range(data),ofilter);
     //  
+    // // std::vector<liblas::uint8_t>&  d= *(vlr->GetData());
+    // // io::copy(boost::make_iterator_range(d.begin(), d.end()),ofilter);
     // 
-    // 
+    // std::cout << "compressed size " << compressed.size() << std::endl;
+    // // 
+    // // ofilter.push(io::zlib_compressor());
+    // // ofilter.push(back_inserter(compressed));
+    // // 
+    // // LASVariableRecord *vlr = idx->GetVLR();
+    // // std::cout << "VLR length: " << vlr->GetRecordLength() << std::endl;
+    // // 
+    // // ofilter << "some junkdsfasdfasdfqwerasdfv";
+    // // 
+    // // // ofilter << *vlr;
+    // // std::cout << "stream size: " << ofilter.size() << std::endl;
+    // // 
+    // // ofilter.flush();
+    // // 
+    // // std::cout << "compressed size: " << compressed.size() << std::endl;
+    // //  
+    // // 
+    // // 
     
 }

Modified: trunk/include/liblas/index/index.hpp
==============================================================================
--- trunk/include/liblas/index/index.hpp	(original)
+++ trunk/include/liblas/index/index.hpp	Sat Jul  4 00:53:49 2009
@@ -54,7 +54,7 @@
 #include <liblas/index/datastream.hpp>
 #include <liblas/index/storage.hpp>
 #include <liblas/index/visitor.hpp>
-
+#include <liblas/index/query.hpp>
 
 //std
 #include <string>
@@ -114,7 +114,31 @@
     /// Get index page size for indexes that are stored externally
     /// \return index page size.
     uint32_t GetPageSize() { return m_Pagesize; }
-    
+
+    /// Sets the index leaf capacity
+    /// \param v - leaf capacity value.  Defaults to 1000.
+    void SetLeafCapacity(uint32_t v) { m_idxLeafCap = v; }
+
+    /// Get index leaf capacity 
+    /// \return index leaf capacity value.
+    uint32_t GetLeafCapacity() { return m_idxLeafCap; }
+
+    /// Sets the index capacity
+    /// \param v - capacity value.  Defaults to 100.
+    void SetIndexCapacity(uint32_t v) { m_idxCapacity = v; }
+
+    /// Get index capacity 
+    /// \return index capacity value.
+    uint32_t GetIndexCapacity() { return m_idxCapacity; }
+
+    /// Sets the fill factor
+    /// \param v - fill factor value.  Defaults to 0.7.
+    void SetFillFactor(double v) { m_idxFillFactor = v; }
+
+    /// Get the index fill factor
+    /// \return index fill factor.
+    double GetFillFactor() { return m_idxFillFactor; }
+                        
     /// Sets the index type
     /// \param v - index type.  Defaults to eExternalIndex.
     void SetType(IndexType v) { m_idxType = v; }
@@ -125,6 +149,7 @@
     
     LASVariableRecord* GetVLR();
     
+    void Query(LASQuery& query);
 private:
 
     SpatialIndex::IStorageManager* m_storage;

Modified: trunk/include/liblas/index/query.hpp
==============================================================================
--- trunk/include/liblas/index/query.hpp	(original)
+++ trunk/include/liblas/index/query.hpp	Sat Jul  4 00:53:49 2009
@@ -39,8 +39,8 @@
  * OF SUCH DAMAGE.
  ****************************************************************************/
 
-#ifndef LIBLAS_INDEX_VISITOR_HPP_INCLUDED
-#define LIBLAS_INDEX_VISITOR_HPP_INCLUDED
+#ifndef LIBLAS_INDEX_QUERY_HPP_INCLUDED
+#define LIBLAS_INDEX_QUERY_HPP_INCLUDED
 
 
 #ifndef _MSC_VER
@@ -53,25 +53,55 @@
 #include <string>
 #include <vector>
 #include <stack>
+#include <queue>
 #include <sys/stat.h>
 
 namespace liblas {
 
+class LASQueryResult 
+{
+private:
+    std::list<SpatialIndex::id_type> ids;
+    SpatialIndex::Region* bounds;
+    uint32_t m_id;
+    LASQueryResult();
+public:
+    LASQueryResult(uint32_t id) : bounds(0), m_id(id){};
+    ~LASQueryResult() {if (bounds!=0) delete bounds;};
+
+    /// Copy constructor.
+    LASQueryResult(LASQueryResult const& other);
+
+    /// Assignment operator.
+    LASQueryResult& operator=(LASQueryResult const& rhs);
+        
+    std::list<SpatialIndex::id_type> const& GetIDs() const;
+    void SetIDs(std::list<SpatialIndex::id_type>& v);
+    const SpatialIndex::Region* GetBounds() const;
+    void SetBounds(const SpatialIndex::Region*  b);
+    uint32_t GetID() const {return m_id;}
+    void SetID(uint32_t v) {m_id = v;}
+};
 
 class LASQuery : public SpatialIndex::IQueryStrategy
 {
 private:
-
+    std::queue<SpatialIndex::id_type> m_ids;
+    uint32_t m_count;
+    std::list<LASQueryResult> m_results;
 public:
 
     LASQuery();
-
+    ~LASQuery() {
+        std::cout << "child count was" << m_count << std::endl;
+        std::cout << "results count was" << m_results.size() << std::endl;};
     void getNextEntry(const SpatialIndex::IEntry& entry, SpatialIndex::id_type& nextEntry, bool& hasNext);
-
+    
+    std::list<LASQueryResult>& GetResults() {return m_results;}
 };
 
 
 
 }
 
-#endif // LIBLAS_INDEX_VISITOR_HPP_INCLUDED
+#endif // LIBLAS_INDEX_QUERY_HPP_INCLUDED

Modified: trunk/src/index/index.cpp
==============================================================================
--- trunk/src/index/index.cpp	(original)
+++ trunk/src/index/index.cpp	Sat Jul  4 00:53:49 2009
@@ -67,7 +67,7 @@
     m_idxId = 1;
     
     m_idxCapacity = 100;
-    m_idxLeafCap = 100;
+    m_idxLeafCap = 1000;
     m_idxDimension = 3;
     
     m_idxFillFactor = 0.7;
@@ -159,6 +159,7 @@
     else
         return new LASVariableRecord();
 }
+
 SpatialIndex::ISpatialIndex* LASIndex::CreateIndex(LASIndexDataStream& strm) 
 {
     using namespace SpatialIndex;
@@ -213,10 +214,9 @@
 {
     using namespace SpatialIndex::StorageManager;
     
-    std::cout << "index type:" << m_idxType << std::endl;
     SpatialIndex::IStorageManager* storage = 0;
     if (m_idxType == eExternalIndex) {
-
+        std::cout << "index type was eExternalIndex" << std::endl;
         if (ExternalIndexExists(filename) && !filename.empty()) {
             std::cout << "loading existing DiskStorage " << filename << std::endl;
             try{
@@ -241,6 +241,7 @@
             }         
         }
     } else if (m_idxType == eMemoryIndex) {
+        std::cout << "index type was eMemoryIndex" << std::endl;
 
         try{
             std::cout << "creating new createNewVLRStorageManager " << filename << std::endl;            
@@ -377,8 +378,10 @@
     
 }
 
-
-
+void LASIndex::Query(LASQuery& query)
+{
+    m_rtree->queryStrategy(query);
+}
 
 
 } // namespace liblas
\ No newline at end of file

Modified: trunk/src/index/query.cpp
==============================================================================
--- trunk/src/index/query.cpp	(original)
+++ trunk/src/index/query.cpp	Sat Jul  4 00:53:49 2009
@@ -49,21 +49,108 @@
 #include <vector>
 #include <stdexcept>
 
+
 namespace liblas
 {
 
-LASQuery::LASQuery() {}
+    LASQuery::LASQuery() :m_count(0){}
 
 void LASQuery::getNextEntry(const SpatialIndex::IEntry& entry, SpatialIndex::id_type& nextEntry, bool& hasNext) {
-	// the first time we are called, entry points to the root.
+    // the first time we are called, entry points to the root.
+    const SpatialIndex::INode* n = dynamic_cast<const SpatialIndex::INode*>(&entry);
+    
+    // if (n !=0 ) {
+    //     for (size_t i = 0; i < n->getChildrenCount(); i++) 
+    //     {
+    //         m_ids.push(n->getChildIdentifier(i));
+    //     }
+    // }
+
+		// traverse only index nodes at levels 2 and higher.
+		if (n != 0 && n->getLevel() > 0)
+		{
+            m_count +=n->getChildrenCount();
+			for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+			{
+				m_ids.push(n->getChildIdentifier(cChild));
+			}
+		}
+		
+		if (n->isLeaf()) {
+
+            SpatialIndex::IShape* ps;
+		    entry.getShape(&ps);
+		    SpatialIndex::Region* pr = dynamic_cast<SpatialIndex::Region*>(ps);
+            std::list<SpatialIndex::id_type> ids;
+			for (size_t cChild = 0; cChild < n->getChildrenCount(); cChild++)
+			{
+				ids.push_back(n->getChildIdentifier(cChild));
+			}
+            LASQueryResult result(n->getIdentifier());
+            result.SetIDs(ids);
+            result.SetBounds(pr);
+            m_results.push_back(result);
+		}
+		    
+    if (! m_ids.empty())
+    {
+        nextEntry = m_ids.front(); m_ids.pop();
+        hasNext = true;
+    }
+    else
+    {
+        hasNext = false;
+    }    
+    
+    // // stop after the root.
+    // hasNext = false;
+    // 
+    // SpatialIndex::IShape* ps;
+    // entry.getShape(&ps);
+    //     // ps->getMBR(m_indexedSpace);
+    // delete ps;
+}
+
 
-	// stop after the root.
-	hasNext = false;
+std::list<SpatialIndex::id_type> const& LASQueryResult::GetIDs() const
+{
+    return ids;
+}
 
-	SpatialIndex::IShape* ps;
-	entry.getShape(&ps);
-    // ps->getMBR(m_indexedSpace);
-	delete ps;
+void LASQueryResult::SetIDs(std::list<SpatialIndex::id_type>& v) 
+{
+    ids.resize(v.size());
+    std::copy(v.begin(), v.end(), ids.begin());
+}
+const SpatialIndex::Region*  LASQueryResult::GetBounds() const
+{
+    return bounds;
+}
+
+void LASQueryResult::SetBounds(const SpatialIndex::Region*  b) 
+{
+    bounds = new SpatialIndex::Region(*b);
+}
+
+LASQueryResult::LASQueryResult(LASQueryResult const& other)
+{
+    ids.resize(other.ids.size());
+    std::copy(other.ids.begin(), other.ids.end(), ids.begin());
+    m_id = other.m_id;
+    
+    bounds = other.bounds->clone();
+}
+
+LASQueryResult& LASQueryResult::operator=(LASQueryResult const& rhs)
+{
+    if (&rhs != this)
+    {
+        ids.resize(rhs.ids.size());
+        std::copy(rhs.ids.begin(), rhs.ids.end(), ids.begin());
+        m_id = rhs.m_id;
+        bounds = rhs.bounds->clone();
+    }
+    return *this;
 }
 
 


More information about the Liblas-commits mailing list