[Liblas-commits] r1242 - in trunk: apps include/liblas src
liblas-commits at liblas.org
liblas-commits at liblas.org
Mon Apr 20 13:14:31 EDT 2009
Author: hobu
Date: Mon Apr 20 13:14:30 2009
New Revision: 1242
URL: http://liblas.org/changeset/1242
Log:
indexing prototype
Added:
trunk/apps/lasindex.cpp
Modified:
trunk/apps/ (props changed)
trunk/apps/Makefile.am
trunk/include/liblas/lasindex.hpp
trunk/include/liblas/lasreader.hpp
trunk/src/Makefile.am
trunk/src/lasindex.cpp
trunk/src/lasreader.cpp
Modified: trunk/apps/Makefile.am
==============================================================================
--- trunk/apps/Makefile.am (original)
+++ trunk/apps/Makefile.am Mon Apr 20 13:14:30 2009
@@ -6,7 +6,11 @@
GEOTIFF_CPPFLAGS = @GEOTIFF_INC@ -DHAVE_LIBGEOTIFF=1
endif
-AM_CPPFLAGS = $(GEOTIFF_CPPFLAGS) $(GDAL_CPPFLAGS) -I../include/liblas/capi -I../include
+if SPATIALINDEX_IS_CONFIG
+SPATIALINDEX_CPPFLAGS = @SPATIALINDEX_INC@/spatialindex @SPATIALINDEX_INC@ -DHAVE_SPATIALINDEX=1
+endif
+
+AM_CPPFLAGS = $(GEOTIFF_CPPFLAGS) $(GDAL_CPPFLAGS) $(SPATIALINDEX_CPPFLAGS) -I../include/liblas/capi -I../include
lasinfo_SOURCES = lasinfo.c lascommon.c
las2las_SOURCES = las2las.c lascommon.c
@@ -14,9 +18,10 @@
las2txt_SOURCES = las2txt.c lascommon.c
txt2las_SOURCES = txt2las.c
ts2las_SOURCES = ts2las.cpp
+lasindex_SOURCES = lasindex.cpp
-bin_PROGRAMS = lasinfo las2las lasmerge las2txt txt2las ts2las
+bin_PROGRAMS = lasinfo las2las lasmerge las2txt txt2las ts2las lasindex
bin_SCRIPTS = liblas-config
Added: trunk/apps/lasindex.cpp
==============================================================================
--- (empty file)
+++ trunk/apps/lasindex.cpp Mon Apr 20 13:14:30 2009
@@ -0,0 +1,121 @@
+#include <liblas/cstdint.hpp>
+#include <liblas/detail/utility.hpp>
+
+#include <liblas/laswriter.hpp>
+#include <liblas/laspoint.hpp>
+#include <liblas/lascolor.hpp>
+#include <liblas/lasreader.hpp>
+#include <liblas/lasheader.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+#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;
+}
+
+void usage() {}
+
+using namespace liblas;
+
+int main(int argc, char* argv[])
+{
+ int rc = 0;
+
+ std::string input;
+ std::string output;
+
+ for (int i = 1; i < argc; i++)
+ {
+ if ( strcmp(argv[i],"-h") == 0 ||
+ strcmp(argv[i],"--help") == 0
+ )
+ {
+ usage();
+ exit(0);
+ }
+ else if ( strcmp(argv[i],"--input") == 0 ||
+ strcmp(argv[i],"-input") == 0 ||
+ strcmp(argv[i],"-i") == 0 ||
+ strcmp(argv[i],"-in") == 0
+ )
+ {
+ 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
+ )
+ {
+ i++;
+ output = std::string(argv[i]);
+ }
+ else if (i == argc - 2 && output.empty() && input.empty())
+ {
+ input = std::string(argv[i]);
+ }
+ else if (i == argc - 1 && output.empty() && input.empty())
+ {
+ input = std::string(argv[i]);
+ }
+ else if (i == argc - 1 && output.empty() && input.empty())
+ {
+ output = std::string(argv[i]);
+ }
+ else
+ {
+ usage();
+ exit(1);
+ }
+ }
+
+ std::cout << "input: " << input<< " output: " <<output<<std::endl;
+
+ std::istream* istrm = OpenInput(input);
+ LASReader* reader = new LASReader(*istrm);
+ reader->Index(input);
+
+ LASHeader header = reader->GetHeader();
+ std::cout << "number of points: " << header.GetPointRecordsCount() << std::endl;
+
+ for (int i=0; i< 23; i++) {
+ bool read = reader->ReadPointAt(i);
+ LASPoint p = reader->GetPoint();
+ std::cout.precision(2);
+ std::cout.setf(std::ios_base::fixed);
+ // std::cout << "x: " << p.GetX() << " y: " << p.GetY() << std::endl;
+ }
+
+ LASIndex* idx = reader->GetIndex();
+
+ std::vector<liblas::uint32_t>* ids = idx->intersects(289815.12,4320979.06, 289818.01,4320982.59);
+
+ std::cout << "Vec length" << ids->size() << std::endl;
+}
Modified: trunk/include/liblas/lasindex.hpp
==============================================================================
--- trunk/include/liblas/lasindex.hpp (original)
+++ trunk/include/liblas/lasindex.hpp Mon Apr 20 13:14:30 2009
@@ -42,10 +42,20 @@
#ifndef LIBLAS_LASINDEX_HPP_INCLUDED
#define LIBLAS_LASINDEX_HPP_INCLUDED
+#include <liblas/lasvariablerecord.hpp>
+#include <liblas/laspoint.hpp>
+
+#ifdef HAVE_SPATIALINDEX
+#include <spatialindex/SpatialIndex.h>
+
+#endif
+
//std
#include <string>
#include <vector>
+#include <stack>
+#include <sys/stat.h>
namespace liblas {
@@ -56,7 +66,7 @@
LASIndex();
-
+ LASIndex(std::string& filename);
/// Copy constructor.
LASIndex(LASIndex const& other);
@@ -64,12 +74,113 @@
LASIndex& operator=(LASIndex const& rhs);
/// Comparison operator.
- bool operator==(const LASIndex& other) const;
+ bool operator==(const LASIndex& other) const;
+
+ SpatialIndex::ISpatialIndex& index() {return *m_rtree;}
+
+ void insert(LASPoint& p, int64_t id);
+ std::vector<uint32_t>* intersects(double minx, double miny, double maxx, double maxy);
private:
+
+ SpatialIndex::IStorageManager* m_storage;
+ SpatialIndex::StorageManager::IBuffer* m_buffer;
+ SpatialIndex::ISpatialIndex* m_rtree;
+ std::string m_indexname;
+
+ void Init();
};
+class LASVisitor : public SpatialIndex::IVisitor
+{
+public:
+ // size_t m_indexIO;
+ // size_t m_leafIO;
+
+ std::vector<uint32_t>* m_vector;
+
+
+public:
+ LASVisitor(std::vector<uint32_t>* vect){m_vector = vect;}
+
+ void visitNode(const SpatialIndex::INode& n)
+ {
+ // std::cout << "visitNode" << std::endl;
+ // if (n.isLeaf()) m_leafIO++;
+ // else m_indexIO++;
+ }
+
+ void visitData(const SpatialIndex::IData& d)
+ {
+ SpatialIndex::IShape* pS;
+ d.getShape(&pS);
+ // do something.
+ delete pS;
+
+ // data should be an array of characters representing a Region as a string.
+ uint8_t* pData = 0;
+ size_t cLen = 0;
+ d.getData(cLen, &pData);
+ // do something.
+ //string s = reinterpret_cast<char*>(pData);
+ //cout << s << endl;
+ delete[] pData;
+
+ // std::cout << d.getIdentifier() << std::endl;
+ m_vector->push_back(d.getIdentifier());
+ // the ID of this data entry is an answer to the query. I will just print it to stdout.
+ }
+
+ void visitData(std::vector<const SpatialIndex::IData*>& v)
+ {
+ std::cout << v[0]->getIdentifier() << " " << v[1]->getIdentifier() << std::endl;
+ }
+};
+
} // namespace liblas
+namespace SpatialIndex
+{
+
+
+ namespace StorageManager
+ {
+ extern IStorageManager* returnLASStorageManager(Tools::PropertySet& in);
+ extern IStorageManager* createNewLASStorageManager();
+
+ class LASStorageManager : public SpatialIndex::IStorageManager
+ {
+ public:
+ LASStorageManager(Tools::PropertySet&);
+
+ virtual ~LASStorageManager();
+
+ virtual void loadByteArray(const id_type id, size_t& len, uint8_t** data);
+ virtual void storeByteArray(id_type& id, const size_t len, const uint8_t* const data);
+ virtual void deleteByteArray(const id_type id);
+
+ private:
+ class Entry
+ {
+ public:
+ byte* m_pData;
+ size_t m_length;
+
+ Entry(size_t l, const uint8_t* const d) : m_pData(0), m_length(l)
+ {
+ m_pData = new uint8_t[m_length];
+ memcpy(m_pData, d, m_length);
+ }
+
+ ~Entry() { delete[] m_pData; }
+ }; // Entry
+
+ std::vector<Entry*> m_buffer;
+ std::stack<id_type> m_emptyPages;
+ }; // MemoryStorageManager
+ }
+}
+
+
#endif // LIBLAS_LASINDEX_HPP_INCLUDED
Modified: trunk/include/liblas/lasreader.hpp
==============================================================================
--- trunk/include/liblas/lasreader.hpp (original)
+++ trunk/include/liblas/lasreader.hpp Mon Apr 20 13:14:30 2009
@@ -47,6 +47,7 @@
#include <liblas/laspoint.hpp>
#include <liblas/lasvariablerecord.hpp>
#include <liblas/lasspatialreference.hpp>
+#include <liblas/lasindex.hpp>
#include <liblas/detail/fwd.hpp>
// std
#include <iosfwd>
@@ -83,6 +84,11 @@
/// The operator is not const because it updates file stream position.
LASPoint const& operator[](std::size_t n);
+
+ void Index(std::string& filename);
+ void Index();
+
+ LASIndex* GetIndex();
private:
@@ -96,6 +102,9 @@
LASHeader m_header;
LASPoint m_point;
std::vector<LASVariableRecord> m_vlrs;
+
+ LASIndex* m_index;
+ bool m_doindex;
};
} // namespace liblas
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Mon Apr 20 13:14:30 2009
@@ -10,7 +10,7 @@
endif
if SPATIALINDEX_IS_CONFIG
-SPATIALINDEX_CPPFLAGS = @SPATIALINDEX_INC@ -DHAVE_SPATIALINDEX=1
+SPATIALINDEX_CPPFLAGS = @SPATIALINDEX_INC@/spatialindex @SPATIALINDEX_INC@ -DHAVE_SPATIALINDEX=1
endif
AM_CPPFLAGS = $(GEOTIFF_CPPFLAGS) $(GDAL_CPPFLAGS) $(SPATIALINDEX_CPPFLAGS) -I../include -I../include/detail
Modified: trunk/src/lasindex.cpp
==============================================================================
--- trunk/src/lasindex.cpp (original)
+++ trunk/src/lasindex.cpp Mon Apr 20 13:14:30 2009
@@ -57,17 +57,65 @@
namespace liblas
{
+
LASIndex::LASIndex()
{
+ m_storage = SpatialIndex::StorageManager::createNewLASStorageManager();
+ Init();
+ // m_storage = SpatialIndex::StorageManager::createNewMemoryStorageManager();
+}
+
+void LASIndex::Init()
+{
+ uint16_t capacity = 10;
+ bool writeThrough = false;
+ m_buffer = SpatialIndex::StorageManager::createNewRandomEvictionsBuffer(*m_storage, capacity, writeThrough);
+
+ // R-Tree parameters
+ double fillFactor = 0.7;
+ uint32_t indexCapacity = 10;
+ uint32_t leafCapacity = 10;
+ uint32_t dimension = 2;
+ SpatialIndex::RTree::RTreeVariant variant = SpatialIndex::RTree::RV_RSTAR;
+
+ // create R-tree
+ SpatialIndex::id_type indexId=1;
+ m_rtree = SpatialIndex::RTree::createNewRTree(*m_buffer, fillFactor, indexCapacity,
+ leafCapacity, dimension, variant, indexId);
+
+
}
+LASIndex::LASIndex(std::string& filename)
+{
+ struct stat stats;
+ std::ostringstream os;
+ os << filename << ".dat";
+ std::cout << "index name: " << os.str() << std::endl;
+
+ std::string indexname = os.str();
+ int ret = stat(indexname.c_str(),&stats);
+ if (!ret) {
+ std::cout << "loading existing index " << indexname << std::endl;
+ m_storage = SpatialIndex::StorageManager::loadDiskStorageManager(filename);
+ }
+ else
+ {
+ std::cout << "Creating new index ... " << std::endl;
+ m_storage = SpatialIndex::StorageManager::createNewDiskStorageManager(filename, 24);
+ }
+
+ Init();
+}
LASIndex::LASIndex(LASIndex const& other)
{
+ std::cout << "Index copy called" << std::endl;
}
LASIndex& LASIndex::operator=(LASIndex const& rhs)
{
+ std::cout << "Index assignment called" << std::endl;
if (&rhs != this)
{
}
@@ -81,7 +129,141 @@
return true;
}
+void LASIndex::insert(LASPoint& p, int64_t id)
+{
+ double min[2];
+ double max[2];
+
+ min[0] = p.GetX(); min[1] = p.GetY();
+ max[0] = p.GetX(); max[1] = p.GetY();
+ index().insertData(0, 0, SpatialIndex::Region(min, max, 2), id);
+}
+
+std::vector<uint32_t>* LASIndex::intersects(double minx, double miny, double maxx, double maxy)
+{
+ double min[2];
+ double max[2];
+
+ min[0] = minx; min[1] = miny;
+ max[0] = maxx; max[1] = maxy;
+
+ std::cout.setf(std::ios_base::fixed);
+
+ std::cout << "minx: " << min[0] << " miny: "<<min[1] << " maxx: " <<max[0] << " maxy: " << max[1] << std::endl;
+ if (min[0] > max[0] || min[1] > max[1]) {std::cout << "epic fail!" << std::endl;};
+ std::vector<uint32_t>* vect = new std::vector<uint32_t>;
+ LASVisitor* visitor = new LASVisitor(vect);
+
+ const SpatialIndex::Region *region = new SpatialIndex::Region(min, max, 2);
+ std::cout << *region << std::endl;
+ index().intersectsWithQuery(*region, *visitor);
+
+ return vect;
+
+}
} // namespace liblas
+
+#include <stdexcept>
+
+
+using namespace SpatialIndex;
+using namespace SpatialIndex::StorageManager;
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::returnLASStorageManager(Tools::PropertySet& ps)
+{
+ IStorageManager* sm = new LASStorageManager(ps);
+ return sm;
+}
+
+SpatialIndex::IStorageManager* SpatialIndex::StorageManager::createNewLASStorageManager()
+{
+ Tools::PropertySet ps;
+ return returnLASStorageManager(ps);
+}
+
+LASStorageManager::LASStorageManager(Tools::PropertySet& ps)
+{
+}
+
+LASStorageManager::~LASStorageManager()
+{
+ for (std::vector<Entry*>::iterator it = m_buffer.begin(); it != m_buffer.end(); it++) delete *it;
+}
+
+void LASStorageManager::loadByteArray(const id_type id, size_t& len, uint8_t** data)
+{
+ Entry* e;
+ try
+ {
+ e = m_buffer.at(id);
+ if (e == 0) throw Tools::InvalidPageException(id);
+ }
+ catch (std::out_of_range)
+ {
+ throw Tools::InvalidPageException(id);
+ }
+
+ len = e->m_length;
+ *data = new uint8_t[len];
+
+ memcpy(*data, e->m_pData, len);
+}
+
+void LASStorageManager::storeByteArray(id_type& id, const size_t len, const uint8_t* const data)
+{
+ if (id == NewPage)
+ {
+ Entry* e = new Entry(len, data);
+
+ if (m_emptyPages.empty())
+ {
+ m_buffer.push_back(e);
+ id = m_buffer.size() - 1;
+ }
+ else
+ {
+ id = m_emptyPages.top(); m_emptyPages.pop();
+ m_buffer[id] = e;
+ }
+ }
+ else
+ {
+ Entry* e_old;
+ try
+ {
+ e_old = m_buffer.at(id);
+ if (e_old == 0) throw Tools::InvalidPageException(id);
+ }
+ catch (std::out_of_range)
+ {
+ throw Tools::InvalidPageException(id);
+ }
+
+ Entry* e = new Entry(len, data);
+
+ delete e_old;
+ m_buffer[id] = e;
+ }
+}
+
+void LASStorageManager::deleteByteArray(const id_type id)
+{
+ Entry* e;
+ try
+ {
+ e = m_buffer.at(id);
+ if (e == 0) throw Tools::InvalidPageException(id);
+ }
+ catch (std::out_of_range)
+ {
+ throw Tools::InvalidPageException(id);
+ }
+
+ m_buffer[id] = 0;
+ m_emptyPages.push(id);
+
+ delete e;
+}
\ No newline at end of file
Modified: trunk/src/lasreader.cpp
==============================================================================
--- trunk/src/lasreader.cpp (original)
+++ trunk/src/lasreader.cpp Mon Apr 20 13:14:30 2009
@@ -50,6 +50,7 @@
#include <cassert>
#include <iostream>
+
namespace liblas
{
@@ -57,6 +58,7 @@
m_pimpl(detail::ReaderFactory::Create(ifs))
{
//MakePIMPL(ifs);
+ m_doindex = false;
Init();
}
@@ -90,6 +92,7 @@
bool LASReader::ReadPointAt(std::size_t n)
{
bool ret = m_pimpl->ReadPointAt(n, m_point, m_header);
+ if (m_doindex) m_index->insert(m_point, n);
return ret;
}
@@ -121,6 +124,7 @@
m_pimpl->ReadGeoreference(m_header);
m_pimpl->Reset(m_header);
+
}
std::istream& LASReader::GetStream() const
@@ -144,6 +148,23 @@
return true;
}
+void LASReader::Index()
+{
+ m_doindex = true;
+ m_index = new LASIndex();
+}
+
+void LASReader::Index(std::string& filename)
+{
+ m_doindex = true;
+ m_index = new LASIndex(filename);
+
+}
+
+LASIndex* LASReader::GetIndex()
+{
+ return m_index;
+}
} // namespace liblas
More information about the Liblas-commits
mailing list