/usr/include/liblas/index.hpp is in liblas-dev 1.7.0+dfsg-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | /******************************************************************************
* $Id$
*
* Project: libLAS - http://liblas.org - A BSD library for LAS format data.
* Purpose: LAS index class
* Author: Gary Huber, gary@garyhuberart.com
*
******************************************************************************
* Copyright (c) 2010, Gary Huber, gary@garyhuberart.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the Martin Isenburg or Iowa Department
* of Natural Resources nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/
#ifndef LIBLAS_LASINDEX_HPP_INCLUDED
#define LIBLAS_LASINDEX_HPP_INCLUDED
#include <liblas/reader.hpp>
#include <liblas/header.hpp>
#include <liblas/bounds.hpp>
#include <liblas/variablerecord.hpp>
#include <liblas/detail/index/indexcell.hpp>
#include <liblas/export.hpp>
// std
#include <stdexcept> // std::out_of_range
#include <cstdio> // file io
#include <iostream> // file io
#include <cstdlib> // std::size_t
#include <vector> // std::vector
namespace liblas {
#define LIBLAS_INDEX_MAXMEMDEFAULT 10000000 // 10 megs default
#define LIBLAS_INDEX_MINMEMDEFAULT 1000000 // 1 meg at least has to be allowed
#define LIBLAS_INDEX_VERSIONMAJOR 1
#define LIBLAS_INDEX_VERSIONMINOR 2 // minor version 2 begins 11/15/10
#define LIBLAS_INDEX_MAXSTRLEN 512
#define LIBLAS_INDEX_MAXCELLS 250000
#define LIBLAS_INDEX_OPTPTSPERCELL 100
#define LIBLAS_INDEX_MAXPTSPERCELL 1000
#define LIBLAS_INDEX_RESERVEFILTERDEFAULT 1000000 // 1 million points will be reserved on large files for filter result
// define this in order to fix problem with last bytes of last VLR getting corrupted
// when saved and reloaded from index or las file.
#define LIBLAS_INDEX_PADLASTVLR
typedef std::vector<boost::uint8_t> IndexVLRData;
typedef std::vector<liblas::detail::IndexCell> IndexCellRow;
typedef std::vector<IndexCellRow> IndexCellDataBlock;
class LAS_DLL IndexData;
class LAS_DLL IndexIterator;
// Index class is the fundamental object for building and filtering a spatial index of points in an LAS file.
// An Index class doesn't do anything until it is configured with an IndexData object (see below).
// You instantiate an Index object first and then pass it an IndexData or you can construct the Index with an
// IndexData. Nothing happens until the Index is told what to do via the configuration with IndexData.
// For details on configuration options see IndexData below.
// Once an index exists and is configured, it can be used to filter the point set in the LAS file for which it
// was built. The points have to be what they were when the index was built. The index is not automatically
// updated if the point set is changed. The index becomes invalid if either the number of points is changed,
// the order of points is changed or the location of any points is changed. The Validate function is run to
// determine as best it can the validity of the stored index but it isn't perfect. It can only determine if
// the number of points has changed or the spatial extents of the file have changed.
// The user can constrain the memory used in building an index if that is believed to be an issue.
// The results will be the same but some efficiency may be lost in the index building process.
// Data stored in index header can be examined for determining suitability of index for desired purpose.
// 1) presence of z-dimensional cell structure is indicated by GetCellsZ() called on the Index.
// 2) Index author GetIndexAuthorStr() - provided by author at time of creation
// 3) Index comment GetIndexCommentStr() - provided by author at time of creation
// 4) Index creation date GetIndexDateStr() - provided by author at time of creation
// The latter fields are not validated in any way by the index building code and are just three fields
// which can be used as the user sees fit. Maximum length is LIBLAS_INDEX_MAXSTRLEN - 1.
// Obtaining a filtered set of points requires that a valid index exist (see above).
// The IndexData class is used again to pass the extents of the filter to the Index. By making any high/low
// bounds coordinate pair equal, that dimension is ignored for the purposes of filtering. Note that Z dimension
// discrimination is still available even if z-binning was not invoked during index creation. Filtering with
// the z dimension may be slower in that event but no less successful.
// A filter operation is invoked with the command:
// const std::vector<boost::uint32_t>& Filter(IndexData const& ParamSrc);
// The return value is a vector of point ID's. The points can be accessed from the LAS file in the standard way
// as the index in no way modifies them or their sequential order.
// Currently only one, two or three dimensional spatial window filters are supported. See IndexData below for
// more info on filtering.
class LAS_DLL Index
{
public:
Index();
Index(IndexData const& ParamSrc);
~Index();
// Blocked copying operations, declared but not defined.
/// Copy constructor.
Index(Index const& other);
/// Assignment operator.
Index& operator=(Index const& rhs);
private:
Reader *m_reader;
Reader *m_idxreader;
Header m_pointheader;
Header m_idxheader;
Bounds<double> m_bounds;
bool m_indexBuilt, m_tempFileStarted, m_readerCreated, m_readOnly, m_writestandaloneindex, m_forceNewIndex;
int m_debugOutputLevel;
boost::uint8_t m_versionMajor, m_versionMinor;
boost::uint32_t m_pointRecordsCount, m_maxMemoryUsage, m_cellsX, m_cellsY, m_cellsZ, m_totalCells,
m_DataVLR_ID;
liblas::detail::TempFileOffsetType m_tempFileWrittenBytes;
double m_rangeX, m_rangeY, m_rangeZ, m_cellSizeZ, m_cellSizeX, m_cellSizeY;
std::string m_tempFileName;
std::string m_indexAuthor;
std::string m_indexComment;
std::string m_indexDate;
std::vector<boost::uint32_t> m_filterResult;
std::ostream *m_ofs;
FILE *m_tempFile, *m_outputFile;
FILE *m_debugger;
void SetValues(void);
bool IndexInit(void);
void ClearOldIndex(void);
bool BuildIndex(void);
bool Validate(void);
boost::uint32_t GetDefaultReserve(void);
bool LoadIndexVLR(VariableRecord const& vlr);
void SetCellFilterBounds(IndexData & ParamSrc);
bool FilterOneVLR(VariableRecord const& vlr, boost::uint32_t& i, IndexData & ParamSrc, bool & VLRDone);
bool FilterPointSeries(boost::uint32_t & PointID, boost::uint32_t & PointsScanned,
boost::uint32_t const PointsToIgnore, boost::uint32_t const x, boost::uint32_t const y, boost::uint32_t const z,
liblas::detail::ConsecPtAccumulator const ConsecutivePts, IndexIterator *Iterator,
IndexData const& ParamSrc);
bool VLRInteresting(boost::int32_t MinCellX, boost::int32_t MinCellY, boost::int32_t MaxCellX, boost::int32_t MaxCellY,
IndexData const& ParamSrc);
bool CellInteresting(boost::int32_t x, boost::int32_t y, IndexData const& ParamSrc);
bool SubCellInteresting(boost::int32_t SubCellID, boost::int32_t XCellID, boost::int32_t YCellID, IndexData const& ParamSrc);
bool ZCellInteresting(boost::int32_t ZCellID, IndexData const& ParamSrc);
bool FilterOnePoint(boost::int32_t x, boost::int32_t y, boost::int32_t z, boost::int32_t PointID, boost::int32_t LastPointID, bool &LastPtRead,
IndexData const& ParamSrc);
// Determines what X/Y cell in the basic cell matrix a point falls in
bool IdentifyCell(Point const& CurPt, boost::uint32_t& CurCellX, boost::uint32_t& CurCellY) const;
// determines what Z cell a point falls in
bool IdentifyCellZ(Point const& CurPt, boost::uint32_t& CurCellZ) const;
// Determines what quadrant sub-cell a point falls in
bool IdentifySubCell(Point const& CurPt, boost::uint32_t x, boost::uint32_t y, boost::uint32_t& CurSubCell) const;
// Offloads binned cell data while building Index when cell data in memory exceeds maximum set by user
bool PurgePointsToTempFile(IndexCellDataBlock& CellBlock);
// Reloads and examines one cell of data from temp file
bool LoadCellFromTempFile(liblas::detail::IndexCell *CellBlock,
boost::uint32_t CurCellX, boost::uint32_t CurCellY);
// temp file is used to store sorted data while building index
FILE *OpenTempFile(void);
// closes and removes the temp file
void CloseTempFile(void);
// Creates a Writer from m_ofs and re-saves entire LAS input file with new index
// Current version does not save any data following the points
bool SaveIndexInLASFile(void);
// Creates a Writer from m_ofs and re-saves LAS header with new index, but not with data point records
bool SaveIndexInStandAloneFile(void);
// Calculate index bounds dimensions
void CalcRangeX(void) {m_rangeX = (m_bounds.max)(0) - (m_bounds.min)(0);}
void CalcRangeY(void) {m_rangeY = (m_bounds.max)(1) - (m_bounds.min)(1);}
void CalcRangeZ(void) {m_rangeZ = (m_bounds.max)(2) - (m_bounds.min)(2);}
// error messages
bool FileError(const char *Reporter);
bool InputFileError(const char *Reporter) const;
bool OutputFileError(const char *Reporter) const;
bool DebugOutputError(const char *Reporter) const;
bool PointCountError(const char *Reporter) const;
bool PointBoundsError(const char *Reporter) const;
bool MemoryError(const char *Reporter) const;
bool InitError(const char *Reporter) const;
bool InputBoundsError(const char *Reporter) const;
// debugging
bool OutputCellStats(IndexCellDataBlock& CellBlock) const;
bool OutputCellGraph(std::vector<boost::uint32_t> CellPopulation, boost::uint32_t MaxPointsPerCell) const;
public:
// IndexFailed and IndexReady can be used to tell if an Index is ready for a filter operation
bool IndexFailed(void) const {return (! m_indexBuilt);}
bool IndexReady(void) const {return (m_indexBuilt);}
// Prep takes the input data and initializes Index values and then either builds or examines the Index
bool Prep(IndexData const& ParamSrc);
// Filter performs a point filter using the bounds in ParamSrc
const std::vector<boost::uint32_t>& Filter(IndexData & ParamSrc);
IndexIterator* Filter(IndexData const& ParamSrc, boost::uint32_t ChunkSize);
IndexIterator* Filter(double LowFilterX, double HighFilterX, double LowFilterY, double HighFilterY,
double LowFilterZ, double HighFilterZ, boost::uint32_t ChunkSize);
IndexIterator* Filter(Bounds<double> const& BoundsSrc, boost::uint32_t ChunkSize);
// Return the bounds of the current Index
double GetMinX(void) const {return (m_bounds.min)(0);}
double GetMaxX(void) const {return (m_bounds.max)(0);}
double GetMinY(void) const {return (m_bounds.min)(1);}
double GetMaxY(void) const {return (m_bounds.max)(1);}
double GetMinZ(void) const {return (m_bounds.min)(2);}
double GetMaxZ(void) const {return (m_bounds.max)(2);}
// Ranges are updated when an index is built or the index header VLR read
double GetRangeX(void) const {return m_rangeX;}
double GetRangeY(void) const {return m_rangeY;}
double GetRangeZ(void) const {return m_rangeZ;}
Bounds<double> const& GetBounds(void) const {return m_bounds;}
// Return the number of points used to build the Index
boost::uint32_t GetPointRecordsCount(void) const {return m_pointRecordsCount;}
// Return the number of cells in the Index
boost::uint32_t GetCellsX(void) const {return m_cellsX;}
boost::uint32_t GetCellsY(void) const {return m_cellsY;}
// Return the number of Z-dimension cells in the Index. Value is 1 if no Z-cells were created during Index building
boost::uint32_t GetCellsZ(void) const {return m_cellsZ;}
// 42 is the ID for the Index header VLR and 43 is the normal ID for the Index data VLR's
// For future expansion, multiple indexes could assign data VLR ID's of their own choosing
boost::uint32_t GetDataVLR_ID(void) const {return m_DataVLR_ID;}
// Since the user can define a Z cell size it is useful to examine that for an existing index
double GetCellSizeZ(void) const {return m_cellSizeZ;}
// Return values used in building or examining index
FILE *GetDebugger(void) const {return m_debugger;}
bool GetReadOnly(void) const {return m_readOnly;}
bool GetStandaloneIndex(void) const {return m_writestandaloneindex;}
bool GetForceNewIndex(void) const {return m_forceNewIndex;}
boost::uint32_t GetMaxMemoryUsage(void) const {return m_maxMemoryUsage;}
int GetDebugOutputLevel(void) const {return m_debugOutputLevel;}
// Not sure if these are more useful than dangerous
Header *GetPointHeader(void) {return &m_pointheader;}
Header *GetIndexHeader(void) {return &m_idxheader;}
Reader *GetReader(void) const {return m_reader;}
Reader *GetIndexReader(void) const {return m_idxreader;}
const char *GetTempFileName(void) const {return m_tempFileName.c_str();}
// Returns the strings set in the index when built
const char *GetIndexAuthorStr(void) const;
const char *GetIndexCommentStr(void) const;
const char *GetIndexDateStr(void) const;
boost::uint8_t GetVersionMajor(void) const {return m_versionMajor;}
boost::uint8_t GetVersionMinor(void) const {return m_versionMinor;}
// Methods for setting values used when reading index from file to facilitate moving reading function into
// separate IndexInput object at a future time to provide symmetry with IndexOutput
void SetDataVLR_ID(boost::uint32_t DataVLR_ID) {m_DataVLR_ID = DataVLR_ID;}
void SetIndexAuthorStr(const char *ias) {m_indexAuthor = ias;}
void SetIndexCommentStr(const char *ics) {m_indexComment = ics;}
void SetIndexDateStr(const char *ids) {m_indexDate = ids;}
void SetMinX(double minX) {(m_bounds.min)(0, minX);}
void SetMaxX(double maxX) {(m_bounds.max)(0, maxX);}
void SetMinY(double minY) {(m_bounds.min)(1, minY);}
void SetMaxY(double maxY) {(m_bounds.max)(1, maxY);}
void SetMinZ(double minZ) {(m_bounds.min)(2, minZ);}
void SetMaxZ(double maxZ) {(m_bounds.max)(2, maxZ);}
void SetPointRecordsCount(boost::uint32_t prc) {m_pointRecordsCount = prc;}
void SetCellsX(boost::uint32_t cellsX) {m_cellsX = cellsX;}
void SetCellsY(boost::uint32_t cellsY) {m_cellsY = cellsY;}
void SetCellsZ(boost::uint32_t cellsZ) {m_cellsZ = cellsZ;}
};
// IndexData is used to pass attributes to and from the Index itself.
// How it is initialized determines what action is taken when an Index object is instantiated with the IndexData.
// The choices are:
// a) Build an index for an las file
// 1) std::ostream *ofs must be supplied as well as std::istream *ifs or Reader *reader and a full file path
// for writing a temp file, const char *tmpfilenme.
// b) Examine an index for an las file
// 1) std::istream *ifs or Reader *reader must be supplied for the LAS file containing the point data
// 2) if the index to be read is in a standalone file then Reader *idxreader must also be supplied
// Options for building are
// a) build a new index even if an old one exists, overwriting the old one
// 1) forcenewindex must be true
// 2) std::ostream *ofs must be a valid ostream where there is storage space for the desired output
// b) only build an index if none exists
// 1) forcenewindex must be false
// 2) std::ostream *ofs must be a valid ostream where there is storage space for the desired output
// c) do not build a new index under any circumstances
// 1) readonly must be true
// Location of the index can be specified
// a) build the index within the las file VLR structure
// 1) writestandaloneindex must be false
// 2) std::ostream *ofs must be a valid ostream where there is storage space for a full copy
// of the LAS file plus the new index which is typically less than 5% of the original file size
// b) build a stand-alone index outside the las file
// 1) writestandaloneindex must be true
// 2) std::ostream *ofs must be a valid ostream where there is storage space for the new index
// which is typically less than 5% of the original file size
// How the index is built is determined also by members of the IndexData class object.
// Options include:
// a) control the maximum memory used during the build process
// 1) pass a value for maxmem in bytes greater than 0. 0 resolves to default LIBLAS_INDEX_MAXMEMDEFAULT.
// b) debug messages generated during index creation or filtering. The higher the number, the more messages.
// 0) no debug reports
// 1) general info messages
// 2) status messages
// 3) cell statistics
// 4) progress status
// c) where debug messages are sent
// 1) default is stderr
// d) control the creation of z-dimensional cells and what z cell size to use
// 1) to turn on z-dimensional binning, use a value larger than 0 for zbinht
// e) data can be stored in index header for later use in recognizing the index.
// 1) Index author indexauthor - provided by author at time of creation
// 2) Index comment indexcomment - provided by author at time of creation
// 3) Index creation date indexdate - provided by author at time of creation
// The fields are not validated in any way by the index building code and are just three fields
// which can be used as the user sees fit. Maximum length is LIBLAS_INDEX_MAXSTRLEN - 1.
// Once an index is built, or if an index already exists, the IndexData can be configured
// to define the bounds of a filter operation. Any dimension whose bounds pair are equal will
// be disregarded for the purpose of filtering. Filtering on the Z axis can still be performed even if the
// index was not built with Z cell sorting. Bounds must be defined in the same units and coordinate
// system that a liblas::Header returns with the commands GetMin{X|Y|Z} and a liblas::Point returns with
// Get{X|Y|Z}
class LAS_DLL IndexData
{
friend class Index;
friend class IndexIterator;
public:
IndexData(void);
IndexData(Index const& index);
// use one of these methods to configure the IndexData with the values needed for specific tasks
// one comprehensive method to set all the values used in index initialization
bool SetInitialValues(std::istream *ifs = 0, Reader *reader = 0, std::ostream *ofs = 0, Reader *idxreader = 0,
const char *tmpfilenme = 0, const char *indexauthor = 0,
const char *indexcomment = 0, const char *indexdate = 0, double zbinht = 0.0,
boost::uint32_t maxmem = LIBLAS_INDEX_MAXMEMDEFAULT, int debugoutputlevel = 0, bool readonly = 0,
bool writestandaloneindex = 0, bool forcenewindex = 0, FILE *debugger = 0);
// set the values needed for building an index embedded in existing las file, overriding any existing index
bool SetBuildEmbedValues(Reader *reader, std::ostream *ofs, const char *tmpfilenme, const char *indexauthor = 0,
const char *indexcomment = 0, const char *indexdate = 0, double zbinht = 0.0,
boost::uint32_t maxmem = LIBLAS_INDEX_MAXMEMDEFAULT, int debugoutputlevel = 0, FILE *debugger = 0);
// set the values needed for building an index in a standalone file, overriding any existing index
bool SetBuildAloneValues(Reader *reader, std::ostream *ofs, const char *tmpfilenme, const char *indexauthor = 0,
const char *indexcomment = 0, const char *indexdate = 0, double zbinht = 0.0,
boost::uint32_t maxmem = LIBLAS_INDEX_MAXMEMDEFAULT, int debugoutputlevel = 0, FILE *debugger = 0);
// set the values needed for filtering with an existing index in an las file
bool SetReadEmbedValues(Reader *reader, int debugoutputlevel = 0, FILE *debugger = 0);
// set the values needed for filtering with an existing index in a standalone file
bool SetReadAloneValues(Reader *reader, Reader *idxreader, int debugoutputlevel = 0, FILE *debugger = 0);
// set the values needed for building an index embedded in existing las file only if no index already exists
// otherwise, prepare the existing index for filtering
bool SetReadOrBuildEmbedValues(Reader *reader, std::ostream *ofs, const char *tmpfilenme, const char *indexauthor = 0,
const char *indexcomment = 0, const char *indexdate = 0, double zbinht = 0.0,
boost::uint32_t maxmem = LIBLAS_INDEX_MAXMEMDEFAULT, int debugoutputlevel = 0, FILE *debugger = 0);
// set the values needed for building an index in a standalone file only if no index already exists in the las file
// otherwise, prepare the existing index for filtering
bool SetReadOrBuildAloneValues(Reader *reader, std::ostream *ofs, const char *tmpfilenme, const char *indexauthor = 0,
const char *indexcomment = 0, const char *indexdate = 0, double zbinht = 0.0,
boost::uint32_t maxmem = LIBLAS_INDEX_MAXMEMDEFAULT, int debugoutputlevel = 0, FILE *debugger = 0);
// set the bounds for use in filtering
bool SetFilterValues(double LowFilterX, double HighFilterX, double LowFilterY, double HighFilterY, double LowFilterZ, double HighFilterZ,
Index const& index);
bool SetFilterValues(Bounds<double> const& src, Index const& index);
/// Copy constructor.
IndexData(IndexData const& other);
/// Assignment operator.
IndexData& operator=(IndexData const& rhs);
private:
void SetValues(void);
bool CalcFilterEnablers(void);
void Copy(IndexData const& other);
protected:
Reader *m_reader;
Reader *m_idxreader;
IndexIterator *m_iterator;
Bounds<double> m_filter;
std::istream *m_ifs;
std::ostream *m_ofs;
const char *m_tempFileName;
const char *m_indexAuthor;
const char *m_indexComment;
const char *m_indexDate;
double m_cellSizeZ;
double m_LowXBorderPartCell, m_HighXBorderPartCell, m_LowYBorderPartCell, m_HighYBorderPartCell;
boost::int32_t m_LowXCellCompletelyIn, m_HighXCellCompletelyIn, m_LowYCellCompletelyIn, m_HighYCellCompletelyIn,
m_LowZCellCompletelyIn, m_HighZCellCompletelyIn;
boost::int32_t m_LowXBorderCell, m_HighXBorderCell, m_LowYBorderCell, m_HighYBorderCell,
m_LowZBorderCell, m_HighZBorderCell;
boost::uint32_t m_maxMemoryUsage;
int m_debugOutputLevel;
bool m_noFilterX, m_noFilterY, m_noFilterZ, m_readOnly, m_writestandaloneindex, m_forceNewIndex, m_indexValid;
FILE *m_debugger;
void SetIterator(IndexIterator *setIt) {m_iterator = setIt;}
IndexIterator *GetIterator(void) {return(m_iterator);}
public:
double GetCellSizeZ(void) const {return m_cellSizeZ;}
FILE *GetDebugger(void) const {return m_debugger;}
bool GetReadOnly(void) const {return m_readOnly;}
bool GetStandaloneIndex(void) const {return m_writestandaloneindex;}
bool GetForceNewIndex(void) const {return m_forceNewIndex;}
boost::uint32_t GetMaxMemoryUsage(void) const {return m_maxMemoryUsage;}
Reader *GetReader(void) const {return m_reader;}
int GetDebugOutputLevel(void) const {return m_debugOutputLevel;}
const char *GetTempFileName(void) const {return m_tempFileName;}
const char *GetIndexAuthorStr(void) const;
const char *GetIndexCommentStr(void) const;
const char *GetIndexDateStr(void) const;
double GetMinFilterX(void) const {return (m_filter.min)(0);}
double GetMaxFilterX(void) const {return (m_filter.max)(0);}
double GetMinFilterY(void) const {return (m_filter.min)(1);}
double GetMaxFilterY(void) const {return (m_filter.max)(1);}
double GetMinFilterZ(void) const {return (m_filter.min)(2);}
double GetMaxFilterZ(void) const {return (m_filter.max)(2);}
void ClampFilterBounds(Bounds<double> const& m_bounds);
void SetReader(Reader *reader) {m_reader = reader;}
void SetIStream(std::istream *ifs) {m_ifs = ifs;}
void SetOStream(std::ostream *ofs) {m_ofs = ofs;}
void SetTmpFileName(const char *tmpfilenme) {m_tempFileName = tmpfilenme;}
void SetIndexAuthor(const char *indexauthor) {m_indexAuthor = indexauthor;}
void SetIndexComment(const char *indexcomment) {m_indexComment = indexcomment;}
void SetIndexDate(const char *indexdate) {m_indexDate = indexdate;}
void SetCellSizeZ(double cellsizez) {m_cellSizeZ = cellsizez;}
void SetMaxMem(boost::uint32_t maxmem) {m_maxMemoryUsage = maxmem;}
void SetDebugOutputLevel(int debugoutputlevel) {m_debugOutputLevel = debugoutputlevel;}
void SetReadOnly(bool readonly) {m_readOnly = readonly;}
void SetStandaloneIndex(bool writestandaloneindex) {m_writestandaloneindex = writestandaloneindex;}
void SetDebugger(FILE *debugger) {m_debugger = debugger;}
};
class LAS_DLL IndexIterator
{
friend class Index;
protected:
IndexData m_indexData;
Index *m_index;
boost::uint32_t m_chunkSize, m_advance;
boost::uint32_t m_curVLR, m_curCellStartPos, m_curCellX, m_curCellY, m_totalPointsScanned, m_ptsScannedCurCell,
m_ptsScannedCurVLR;
boost::uint32_t m_conformingPtsFound;
public:
IndexIterator(Index *IndexSrc, double LowFilterX, double HighFilterX, double LowFilterY, double HighFilterY,
double LowFilterZ, double HighFilterZ, boost::uint32_t ChunkSize);
IndexIterator(Index *IndexSrc, IndexData const& IndexDataSrc, boost::uint32_t ChunkSize);
IndexIterator(Index *IndexSrc, Bounds<double> const& BoundsSrc, boost::uint32_t ChunkSize);
/// Copy constructor.
IndexIterator(IndexIterator const& other);
/// Assignment operator.
IndexIterator& operator=(IndexIterator const& rhs);
private:
void Copy(IndexIterator const& other);
void ResetPosition(void);
boost::uint8_t MinMajorVersion(void) {return(1);}
boost::uint8_t MinMinorVersion(void) {return(2);}
public:
/// n=0 or n=1 gives next sequence with no gap, n>1 skips n-1 filter-compliant points, n<0 jumps backwards n compliant points
const std::vector<boost::uint32_t>& advance(boost::int32_t n);
/// returns filter-compliant points as though the first point returned is element n in a zero-based array
const std::vector<boost::uint32_t>& operator()(boost::int32_t n);
/// returns next set of filter-compliant points with no skipped points
inline const std::vector<boost::uint32_t>& operator++() {return (advance(1));}
/// returns next set of filter-compliant points with no skipped points
inline const std::vector<boost::uint32_t>& operator++(int) {return (advance(1));}
/// returns set of filter-compliant points skipping backwards 1 from the end of the last set
inline const std::vector<boost::uint32_t>& operator--() {return (advance(-1));}
/// returns set of filter-compliant points skipping backwards 1 from the end of the last set
inline const std::vector<boost::uint32_t>& operator--(int) {return (advance(-1));}
/// returns next set of filter-compliant points with n-1 skipped points, for n<0 acts like -=()
inline const std::vector<boost::uint32_t>& operator+=(boost::int32_t n) {return (advance(n));}
/// returns next set of filter-compliant points with n-1 skipped points, for n<0 acts like -()
inline const std::vector<boost::uint32_t>& operator+(boost::int32_t n) {return (advance(n));}
/// returns set of filter-compliant points beginning n points backwards from the end of the last set, for n<0 acts like +=()
inline const std::vector<boost::uint32_t>& operator-=(boost::int32_t n) {return (advance(-n));}
/// returns set of filter-compliant points beginning n points backwards from the end of the last set, for n<0 acts like +()
inline const std::vector<boost::uint32_t>& operator-(boost::int32_t n) {return (advance(-n));}
/// returns filter-compliant points as though the first point returned is element n in a zero-based array
inline const std::vector<boost::uint32_t>& operator[](boost::int32_t n) {return ((*this)(n));}
/// tests viability of index for filtering with iterator
bool ValidateIndexVersion(boost::uint8_t VersionMajor, boost::uint8_t VersionMinor) {return (VersionMajor > MinMajorVersion() || (VersionMajor == MinMajorVersion() && VersionMinor >= MinMinorVersion()));}
};
template <typename T, typename Q>
inline void ReadVLRData_n(T& dest, IndexVLRData const& src, Q& pos)
{
// error if reading past array end
if (static_cast<size_t>(pos) + sizeof(T) > src.size())
throw std::out_of_range("liblas::detail::ReadVLRData_n: array index out of range");
// copy sizeof(T) bytes to destination
memcpy(&dest, &src[pos], sizeof(T));
// Fix little-endian
LIBLAS_SWAP_BYTES_N(dest, sizeof(T));
// increment the write position to end of written data
pos = pos + static_cast<Q>(sizeof(T));
}
template <typename T, typename Q>
inline void ReadVLRDataNoInc_n(T& dest, IndexVLRData const& src, Q const& pos)
{
// error if reading past array end
if (static_cast<size_t>(pos) + sizeof(T) > src.size())
throw std::out_of_range("liblas::detail::ReadVLRDataNoInc_n: array index out of range");
// copy sizeof(T) bytes to destination
memcpy(&dest, &src[pos], sizeof(T));
// Fix little-endian
LIBLAS_SWAP_BYTES_N(dest, sizeof(T));
}
template <typename T, typename Q>
inline void ReadeVLRData_str(char * dest, IndexVLRData const& src, T const srclen, Q& pos)
{
// error if reading past array end
if (static_cast<size_t>(pos) + static_cast<size_t>(srclen) > src.size())
throw std::out_of_range("liblas::detail::ReadeVLRData_str: array index out of range");
// copy srclen bytes to destination
memcpy(dest, &src[pos], srclen);
// increment the write position to end of written data
pos = pos + static_cast<Q>(srclen);
}
template <typename T, typename Q>
inline void ReadVLRDataNoInc_str(char * dest, IndexVLRData const& src, T const srclen, Q pos)
{
// error if reading past array end
if (static_cast<size_t>(pos) + static_cast<size_t>(srclen) > src.size())
throw std::out_of_range("liblas::detail::ReadVLRDataNoInc_str: array index out of range");
// copy srclen bytes to destination
std::memcpy(dest, &src[pos], srclen);
}
} // namespace liblas
#endif // LIBLAS_LASINDEX_HPP_INCLUDED
|