PageRenderTime 86ms CodeModel.GetById 15ms app.highlight 62ms RepoModel.GetById 1ms app.codeStats 1ms

/Utilities/otbliblas/apps/lasindex_test.cpp

https://bitbucket.org/olahlou/otb
C++ | 711 lines | 520 code | 49 blank | 142 comment | 104 complexity | 1501c9463dacc1840ffc4a166f981bb6 MD5 | raw file
  1// lasindex_test.cpp : Defines the entry point for the console application.
  2//
  3
  4#include <boost/cstdint.hpp>
  5
  6#include <iosfwd>
  7#include <iostream>
  8#include <cstdio>
  9#include <bitset>
 10#include <exception>
 11#include <fstream>
 12#include <iostream>
 13#include <map>
 14#include <sstream> // std::stringstream
 15#include <string>
 16#include <stack>
 17#include <typeinfo>
 18#include <vector>
 19
 20#include <liblas/lasindex.hpp>
 21
 22using namespace liblas;
 23using namespace boost;
 24
 25#ifdef _WIN32
 26#define compare_no_case(a,b,n)  _strnicmp( (a), (b), (n) )
 27#else
 28#define compare_no_case(a,b,n)  strncasecmp( (a), (b), (n) )
 29#endif
 30
 31#define lasindex_test_version	"1.0"
 32#define SAMPLE_AUTHOR	"Gary Huber"
 33#define SAMPLE_COMMENT	"This is a test of the LAS file index system in LibLAS"
 34#define SAMPLE_DATE	"7/22/10"
 35void usage(FILE *debugger)
 36{
 37    fprintf(debugger,"----------------------------------------------------------\n");
 38    fprintf(debugger,"    lasindex_test (version %s) usage:\n", lasindex_test_version);
 39    fprintf(debugger,"----------------------------------------------------------\n");
 40    fprintf(debugger,"\n");
 41
 42    fprintf(debugger,"Create index for in file, resave to out file, temporary storage file, max memory usage, sort with Z bin interval:\n");
 43    fprintf(debugger,"  lasindex_test -i in.las -o out.las -t tempfile -z interval -m maxmemory\n");
 44    fprintf(debugger,"\n");
 45    
 46    fprintf(debugger,"-i or --infile (required):\n");
 47    fprintf(debugger,"  complete input file name and path\n");
 48    fprintf(debugger,"\n");
 49    
 50    fprintf(debugger,"-o or --outfile (required unless readonly):\n");
 51    fprintf(debugger,"  complete output file name and path\n");
 52    fprintf(debugger,"\n");
 53    
 54    fprintf(debugger,"-n or --indexfile (required for reading standalone index):\n");
 55    fprintf(debugger,"  complete output file name and path\n");
 56    fprintf(debugger,"\n");
 57    
 58    fprintf(debugger,"-t or --tempfile (required):\n");
 59    fprintf(debugger,"  complete temporary file name and path used during index building\n");
 60    fprintf(debugger,"\n");
 61    
 62    fprintf(debugger,"-b or --zbinheight (optional):\n");
 63    fprintf(debugger,"  elevation sorting bin height, no z sorting if omitted\n");
 64    fprintf(debugger,"\n");
 65    
 66    fprintf(debugger,"-m or --maxmem (optional):\n");
 67    fprintf(debugger,"  maximum memory to use for index building, defaults to no limit if omitted\n");
 68    fprintf(debugger,"\n");
 69    
 70    fprintf(debugger,"-a or --author (optional):\n");
 71    fprintf(debugger,"  author field for index file record header, 512 max length\n");
 72    fprintf(debugger,"\n");
 73    
 74    fprintf(debugger,"-c or --comment (optional):\n");
 75    fprintf(debugger,"  comment field for index file record header, 512 max length\n");
 76    fprintf(debugger,"\n");
 77    
 78    fprintf(debugger,"-d or --date (optional):\n");
 79    fprintf(debugger,"  date of index creation for index file record header, 512 max length\n");
 80    fprintf(debugger,"\n");
 81    
 82    fprintf(debugger,"-r or --readonly (optional):\n");
 83    fprintf(debugger,"  if set, index is to be read only, not created\n");
 84    fprintf(debugger,"\n");
 85    
 86    fprintf(debugger,"-s or --standalone (optional):\n");
 87    fprintf(debugger,"  if set, index is to be saved in separate index file, not in las file\n");
 88    fprintf(debugger,"\n");
 89    
 90    fprintf(debugger,"-x (at least one dimension required for filter):\n");
 91    fprintf(debugger,"  follow with low and high values for X filter\n");
 92    fprintf(debugger,"\n");
 93    
 94    fprintf(debugger,"-y (at least one dimension required for filter):\n");
 95    fprintf(debugger,"  follow with low and high values for Y filter\n");
 96    fprintf(debugger,"\n");
 97    
 98    fprintf(debugger,"-z (at least one dimension required for filter):\n");
 99    fprintf(debugger,"  follow with low and high values for Z filter\n");
100    fprintf(debugger,"\n");
101    
102    fprintf(debugger,"-it (use iterator for filtering):\n");
103    fprintf(debugger,"  follow with number of points to be returned in each iteration\n");
104    fprintf(debugger,"\n");
105    
106    fprintf(debugger, "\nFor more information, see the full documentation for lasindex_test at:\n"
107                    " http://liblas.org/browser/trunk/doc/lasindex_test.txt\n");
108    fprintf(debugger,"----------------------------------------------------------\n");
109
110}
111
112std::istream* OpenInput(std::string filename) 
113{
114    std::ios::openmode const mode = std::ios::in | std::ios::binary;
115    std::istream* istrm = 0;
116    if (compare_no_case(filename.c_str(),"STDIN",5) == 0)
117    {
118        istrm = &std::cin;
119    }
120    else 
121    {
122        istrm = new std::ifstream(filename.c_str(), mode);
123    }
124    
125    if (!istrm->good())
126    {
127        delete istrm;
128        istrm = 0;
129        throw std::runtime_error("Reading stream was not able to be created.");
130    }
131    return istrm;
132}
133
134std::ostream* OpenOutput(std::string filename) 
135{
136    std::ios::openmode const mode = std::ios::out | std::ios::binary;
137    std::ostream* ostrm = 0;
138    if (compare_no_case(filename.c_str(),"STDOUT",5) == 0)
139    {
140        ostrm = &std::cout;
141    }
142    else 
143    {
144        ostrm = new std::ofstream(filename.c_str(), mode);
145    }
146    
147    if (!ostrm->good())
148    {
149        delete ostrm;
150        ostrm = 0;
151        throw std::runtime_error("Writing stream was not able to be created.");
152    }
153    return ostrm;
154}
155
156void IndexInitError(FILE *debugger)
157{
158    fprintf(debugger, "Unable to initialize index.\n");
159}
160
161void IndexFilterNoPoints(FILE *debugger)
162{
163    fprintf(debugger, "No points found in search area.\n");
164}
165
166void IndexFilterInitError(FILE *debugger)
167{
168    fprintf(debugger, "Unable to initialize index filter. Invalid values.\n");
169}
170
171bool ReportIteratorResults(FILE *debugger, uint32_t resultSize, uint32_t pointCount, uint32_t step)
172{
173	if (resultSize)
174	{
175		// do something with the list of points
176		#ifdef VISUAL_8
177		fprintf(debugger, "Points within filter area %d of %d, step %d, %s\n", resultSize, 
178			pointCount, step, "Using iterator");
179		#else // VISUAL_8
180		fprintf(debugger, "Points within filter area %d of %d, step %d, %s\n", resultSize, 
181			pointCount, step, "Using iterator");
182		#endif // VISUAL_8
183		return true;
184	}
185	else
186	{
187		IndexFilterNoPoints(debugger);
188		return false;
189	} // else
190} // ReportIteratorResults
191
192int main(int argc, char* argv[])
193{
194	char *tmpfilenme = 0;
195	char *lasinfilenme = 0;
196	char *lasoutfilenme = 0;
197	char *idxinfilenme = 0;
198	char *authorname = 0;
199	char *commentfield = 0;
200	char *datefield = 0;
201	double zbinheight = 0.0;
202	double oLowFilterX = 0.0, oHighFilterX = 0.0, oLowFilterY = 0.0, oHighFilterY = 0.0, oLowFilterZ = 0.0, oHighFilterZ = 0.0;
203	boost::uint32_t maxmem = 0;
204	boost::uint32_t chunkSize = 100;
205	int debuglevel = 3;
206	bool readonly = 0;
207	bool forcenewindex = 0;
208	bool boundssetbyuser = 0;
209	bool writestandaloneindex = 0;
210	bool useiterator = 0;
211	FILE *debugger = stderr;
212	
213	// temporary until argv[] starts to work
214	// uncomment only one of these blocks
215	/*------------------------------N1440375----------------------------------*/
216	/*------------------------build embedded index------------------------------
217	const char* arggv[] = {"foo", "-t", "C:\\LibLAS\\Samples\\N1440375.tmp",
218		 "-i", "C:\\LibLAS\\Samples\\N1440375.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
219		 "-o", "C:\\LibLAS\\Samples\\N1440375_idx.las"};
220	argc = 13;
221	*/
222	/*-----------------build index in standalone file---------------------------
223	const char* arggv[] = {"foo", "-t", "C:\\LibLAS\\Samples\\N1440375.tmp",
224		 "-i", "C:\\LibLAS\\Samples\\N1440375.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
225		 "-o", "C:\\LibLAS\\Samples\\N1440375_idx.ldx", "-s"};
226	argc = 14;
227	*/
228	/*------------------filter with embedded index------------------------------
229	const char* arggv[] = {"foo",
230		 "-i", "C:\\LibLAS\\Samples\\N1440375_idx.las", "-r"};
231	argc = 4;
232	*/
233	/*-------------------filter from standalone file----------------------------
234	const char* arggv[] = {"foo", "-i", "C:\\LibLAS\\Samples\\N1440375.las",
235		 "-n", "C:\\LibLAS\\Samples\\N1440375_idx.ldx", "-r"};
236	argc = 6;
237	*/
238	/*-----------------build embedded index, filter with user bounds------------ */
239	const char* arggv[] = {"foo", "-t", "C:\\LibLAS\\Samples\\N1440375.tmp",
240		 "-i", "C:\\LibLAS\\Samples\\N1440375.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
241		 "-o", "C:\\LibLAS\\Samples\\N1440375_idx.las",
242		 "-x", "1443000.00", "1444000.00", "-y", "376000.02", "379000.00", "-z", "850.00", "950.00"};
243	argc = 22;
244
245	/*------------filter with embedded index using iterator---------------------
246	const char* arggv[] = {"foo",
247		 "-i", "C:\\LibLAS\\Samples\\N1440375_idx.las", "-r", "-it", "20000"};
248	argc = 6;
249	*/
250	/*---------------------Serpent Mound Model LAS Data-----------------------*/
251	/*----------------------------build index-----------------------------------
252	const char* arggv[] = {"foo", "-t", "C:\\LibLAS\\Samples\\Serpent Mound Model LAS Data.tmp",
253		 "-i", "C:\\LibLAS\\Samples\\Serpent Mound Model LAS Data.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
254		 "-o", "C:\\LibLAS\\Samples\\Serpent Mound Model LAS Data_idx.las"};
255	argc = 13;
256	*/
257	/*------------------filter with embedded index------------------------------
258	const char* arggv[] = {"foo",
259		 "-i", "C:\\LibLAS\\Samples\\Serpent Mound Model LAS Data_idx.las", "-r"};
260	argc = 4;
261	*/
262	/*---------------------Mount St Helens Oct 4 2004-------------------------*/
263	/*----------------------------build index-----------------------------------
264	const char* arggv[] = {"foo", "-t", "C:\\LibLAS\\Mount St Helens Oct 4 2004.tmp",
265		 "-i", "C:\\LibLAS\\Samples\\Mount St Helens Oct 4 2004.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
266		 "-o", "C:\\LibLAS\\Samples\\Mount St Helens Oct 4 2004_idx.las", "-b", "100"};
267	argc = 15;
268	*/
269	/*------------------filter with embedded index------------------------------
270	const char* arggv[] = {"foo",
271		 "-i", "C:\\LibLAS\\Samples\\Mount St Helens Oct 4 2004_idx.las", "-r"};
272	argc = 4;
273	*/
274	/*----------------------------Lincoln-------------------------------------*/
275	/*--------------------------build index-------------------------------------
276	const char* arggv[] = {"foo", "-t", "C:\\LibLAS\\Samples\\Lincoln.tmp",
277		 "-i", "C:\\LibLAS\\Samples\\Lincoln.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
278		 "-o", "C:\\LibLAS\\Samples\\Lincoln_idx.las"};
279	argc = 13;
280	*/
281	/*------------------filter with embedded index------------------------------
282	const char* arggv[] = {"foo",
283		 "-i", "C:\\LibLAS\\Samples\\Lincoln_idx.las", "-r"};
284	argc = 4;
285	*/
286	/*------------------------------flatDataset-------------------------------*/
287	/*------------------------------build index---------------------------------
288	const char* arggv[] = {"foo", "-t", "C:\\LibLAS\\flatDataset.tmp",
289		 "-i", "C:\\LibLAS\\Samples\\flatDataset.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
290		 "-o", "C:\\LibLAS\\Samples\\flatDataset_idx.las"};
291	argc = 13;
292	*/
293	/*------------------filter with embedded index------------------------------
294	const char* arggv[] = {"foo",
295		 "-i", "C:\\LibLAS\\Samples\\flatDataset_idx.las", "-r"};
296	argc = 4;
297	*/
298	/*------------filter with embedded index using iterator---------------------
299	const char* arggv[] = {"foo",
300		 "-i", "C:\\LibLAS\\Samples\\flatDataset_idx.las", "-r", "-it", "25"};
301	argc = 6;
302	*/
303	/*---------------------------billion_points-------------------------------*/
304	/*-----------------build index in standalone file---------------------------
305	const char* arggv[] = {"foo", "-t", "K:\\FME\\billion_points.tmp",
306		 "-i", "D:\\Zips\\FME\\billion_points.las", "-a", SAMPLE_AUTHOR, "-c", SAMPLE_COMMENT, "-d", SAMPLE_DATE,
307		 "-o", "K:\\FME\\billion_points_idx.ldx", "-s", "-it", "5000000"};
308	argc = 16;
309	*/
310	/*-------------------filter from standalone file using iterator---------------
311	const char* arggv[] = {"foo", "-i", "D:\\Zips\\FME\\billion_points.las",
312		 "-n", "K:\\FME\\billion_points_idx.ldx", "-r", "-it", "5000000"};
313	argc = 8;
314	*/
315	
316	for (int i = 1; i < argc; i++)
317    {
318        if (    strcmp((const char *)arggv[i],"-h") == 0 ||
319                strcmp((const char *)arggv[i],"--help") == 0
320            )
321        {
322            usage(debugger);
323            exit(0);
324        }
325        else if (   strcmp((const char *)arggv[i],"-t") == 0 ||
326                    strcmp((const char *)arggv[i],"--tempfile") == 0
327            )
328        {
329            i++;
330            tmpfilenme = (char *)arggv[i];
331        }
332        else if (   strcmp((const char *)arggv[i],"-i") == 0 ||
333                    strcmp((const char *)arggv[i],"--infile") == 0
334            )
335        {
336            i++;
337            lasinfilenme = (char *)arggv[i];
338        }
339        else if (   strcmp((const char *)arggv[i],"-o") == 0 ||
340                    strcmp((const char *)arggv[i],"--outfile") == 0
341            )
342        {
343            i++;
344            lasoutfilenme = (char *)arggv[i];
345        }
346        else if (   strcmp((const char *)arggv[i],"-n") == 0 ||
347                    strcmp((const char *)arggv[i],"--indexfile") == 0
348            )
349        {
350            i++;
351            idxinfilenme = (char *)arggv[i];
352        }
353        else if (   strcmp((const char *)arggv[i],"-b") == 0 ||
354                    strcmp((const char *)arggv[i],"--zbinheight") == 0
355            )
356        {
357            i++;
358            zbinheight = atof((const char *)arggv[i]);
359        }
360        else if (   strcmp((const char *)arggv[i],"-m") == 0 ||
361                    strcmp((const char *)arggv[i],"--maxmem") == 0
362            )
363        {
364            i++;
365            maxmem = atoi((const char *)arggv[i]);
366        }
367        else if (   strcmp((const char *)arggv[i],"-a") == 0 ||
368                    strcmp((const char *)arggv[i],"--author") == 0
369            )
370        {
371            i++;
372            authorname = (char *)arggv[i];
373        }
374        else if (   strcmp((const char *)arggv[i],"-c") == 0 ||
375                    strcmp((const char *)arggv[i],"--comment") == 0
376            )
377        {
378            i++;
379            commentfield = (char *)arggv[i];
380        }
381        else if (   strcmp((const char *)arggv[i],"-d") == 0 ||
382                    strcmp((const char *)arggv[i],"--date") == 0
383            )
384        {
385            i++;
386            datefield = (char *)arggv[i];
387        }
388        else if (   strcmp((const char *)arggv[i],"-r") == 0 ||
389                    strcmp((const char *)arggv[i],"--readonly") == 0
390            )
391        {
392            readonly = true;
393        }
394        else if (   strcmp((const char *)arggv[i],"-s") == 0 ||
395                    strcmp((const char *)arggv[i],"--standalone") == 0
396            )
397        {
398            writestandaloneindex = true;
399        }
400        else if (   strcmp((const char *)arggv[i],"-x") == 0
401            )
402        {
403            i++;
404            oLowFilterX = atof((const char *)arggv[i]);
405            i++;
406            oHighFilterX = atof((const char *)arggv[i]);
407            boundssetbyuser = true;
408        }
409        else if (   strcmp((const char *)arggv[i],"-y") == 0
410            )
411        {
412            i++;
413            oLowFilterY = atof((const char *)arggv[i]);
414            i++;
415            oHighFilterY = atof((const char *)arggv[i]);
416            boundssetbyuser = true;
417        }
418        else if (   strcmp((const char *)arggv[i],"-z") == 0
419            )
420        {
421            i++;
422            oLowFilterZ = atof((const char *)arggv[i]);
423            i++;
424            oHighFilterZ = atof((const char *)arggv[i]);
425            boundssetbyuser = true;
426        }
427        else if (   strcmp((const char *)arggv[i],"-it") == 0
428            )
429        {
430            i++;
431            chunkSize = atoi((const char *)arggv[i]);
432            useiterator = true;
433        }
434	} // for
435
436	fprintf(debugger, "%s\n", lasinfilenme);
437	
438	IndexData ParamSrc;
439	IndexData ParamSrc2;
440	
441	if (lasinfilenme)
442	{
443		// open the las file for reading
444		if (std::istream* istrm = OpenInput(std::string(lasinfilenme)))
445		{
446			if (Reader *reader = new Reader(*istrm))
447			{
448				Reader *idxreader = NULL;
449				std::istream* idxstrm = NULL;
450				if (idxinfilenme)
451				{
452					idxstrm = OpenInput(std::string(idxinfilenme));
453					if (idxstrm)
454					{
455						idxreader = new Reader(*idxstrm);
456					} // if
457				} // if
458				if (idxreader || ! idxinfilenme)
459				{
460					// open the output stream here whether for embedded index or standalone
461					std::ostream* ostrm = ! readonly ? OpenOutput(std::string(lasoutfilenme)): 0;
462					if (ostrm || readonly)
463					{
464						// there are many versions of this method tailored to specific index tasks. Look for them
465						// together in lasindex.hpp. This is version the most generic
466						if (ParamSrc.SetInitialValues(0, reader, ostrm, idxreader, tmpfilenme, authorname, commentfield, datefield,
467							zbinheight, maxmem, debuglevel, readonly, writestandaloneindex, forcenewindex, debugger))
468						{
469							// Another way to initiate an index would be to
470							// create a simple index with Index() and then initialize it with the Prep command.
471							// It would look like this:
472							// Index index();  if (index.Prep(ParamSrc)) {}
473							// Prep returns true only if an index is ready to use for filtering
474							// But here's the other way to do it in which the constructor does the heavy lifting
475							Index index(ParamSrc);
476							if (index.IndexReady())
477							{
478								// for testing filter bounds set by user
479								if (useiterator)
480								{
481									ParamSrc = IndexData(index);
482									ParamSrc2 = IndexData(index);
483									if (ParamSrc.SetFilterValues(index.GetBounds(), index)
484										&& ParamSrc2.SetFilterValues((index.GetMinX() + index.GetMaxX()) * .5, index.GetMaxX(), 
485										(index.GetMinY() + index.GetMaxY()) * .5, index.GetMaxY(), index.GetMinZ(), index.GetMaxZ(), index))
486									{
487										// two iterators with different filter bounds
488										IndexIterator *indexIt = index.Filter(ParamSrc, chunkSize);
489										IndexIterator *indexIt2 = index.Filter(ParamSrc2, chunkSize);
490										if (indexIt && indexIt2)
491										{
492											for (boost::uint32_t step = 0; step < 1000; ++step)
493											{
494												// use any of these to begin the vector with the next point that fits the filter criteria 
495												// that hasn't been scanned yet.
496												// ex: indexIt->advance(1) starts the vector on the first point that fits the criteria if no points have 
497												// been scanned previously. If there have been previous points scanned then the vector returned
498												// will start with the next point that fits the criteria beyond those previously scanned.
499												// ex: indexIt->advance(5) starts the vector on the fifth point that fits the criteria if no points have 
500												// been scanned previously. If there have been previous points scanned then the vector returned
501												// will start with the fifth point that fits the criteria beyond those previously scanned.
502												// The following three methods may be used to advance by any positive number X.
503												//const std::vector<boost::uint32_t>& FilterResult = indexIt->advance(X);
504												//const std::vector<boost::uint32_t>& FilterResult = (*indexIt)+=X;
505												//const std::vector<boost::uint32_t>& FilterResult = (*indexIt)+X;
506												// The following two methods may be used to advance as though X were 1.
507												// There is no functional difference between pre and post increment;
508												//const std::vector<boost::uint32_t>& FilterResult = ++(*indexIt);
509												//const std::vector<boost::uint32_t>& FilterResult = (*indexIt)++;
510												// Random access to any number point in the file that fits the filter criteria is 
511												// provided with the overloaded [] operator or () operator.
512												// ex: (*indexIt)[32] would start the array at the 32nd point in the file that fits the criteria
513												// Any number of non-conforming points may have been skipped to get to the start point
514												//const std::vector<boost::uint32_t>& FilterResult = (*indexIt)[32];
515												//const std::vector<boost::uint32_t>& FilterResult = (*indexIt)(0);
516												
517												// get first or next consecutive range on first iterator
518												const std::vector<boost::uint32_t>& FilterResult = (*indexIt)++;
519												if (!ReportIteratorResults(debugger, FilterResult.size(), index.GetPointRecordsCount(), step))
520													break;
521
522												// get first or next consecutive range on 2nd iterator
523												const std::vector<boost::uint32_t>& FilterResult2 = (*indexIt2)++;
524												if (!ReportIteratorResults(debugger, FilterResult2.size(), index.GetPointRecordsCount(), step))
525													break;
526
527												// get next range on first iterator
528												const std::vector<boost::uint32_t>& FilterResult3 = (*indexIt)++;
529												if (!ReportIteratorResults(debugger, FilterResult3.size(), index.GetPointRecordsCount(), step))
530													break;
531												
532												// get a range beginning with the 5th compliant point on 2nd iterator
533												const std::vector<boost::uint32_t>& FilterResult4 = (*indexIt2)[5];
534												if (!ReportIteratorResults(debugger, FilterResult4.size(), index.GetPointRecordsCount(), step))
535													break;
536
537												// get a range on first iterator beginning 6 compliant pts beyond last range (skipping 5)
538												const std::vector<boost::uint32_t>& FilterResult5 = (*indexIt)+6;
539												if (!ReportIteratorResults(debugger, FilterResult5.size(), index.GetPointRecordsCount(), step))
540													break;
541											
542											} // for
543										} // if
544										else
545											IndexFilterInitError(debugger);
546										delete indexIt;
547										delete indexIt2;
548									}
549									else
550										IndexFilterInitError(debugger);
551								} // if useiterator
552								else if (boundssetbyuser)
553								{
554									Bounds<double> filterBounds(oLowFilterX, oLowFilterY, oLowFilterZ,
555										oHighFilterX, oHighFilterY, oHighFilterZ);
556									if (ParamSrc.SetFilterValues(filterBounds, index))
557									{
558										const std::vector<uint32_t>& FilterResult = index.Filter(ParamSrc);
559										if (FilterResult.size())
560										{
561											// do something with the list of points
562											std::ostringstream oss;
563											oss << "Points within filter area " << FilterResult.size() 
564												<< " of " << index.GetPointRecordsCount()
565												<< ",\nUser-defined filter bounds" << std::endl;
566											fprintf(debugger, "%s", oss.str().c_str());
567										}
568										else
569											IndexFilterNoPoints(debugger);
570									}
571									else
572										IndexFilterInitError(debugger);
573								} // if
574								else
575								{
576									// run 6 programmed filter tests of stored data
577									double RangeZ, RangeY, RangeX;
578									const char *CovgStr;
579									Bounds<double> indexBounds = index.GetBounds();
580									Bounds<double> filterBounds;
581									RangeX = index.GetRangeX();
582									RangeY = index.GetRangeY();
583									RangeZ = index.GetRangeZ();
584									for (int loopct = 0; loopct < 6; ++loopct)
585									{
586										switch (loopct)
587										{
588											case 0:
589											{
590												CovgStr = "entire range, all 3 axes";
591												filterBounds = indexBounds;
592												break;
593											} // 0
594											case 1:
595											{
596												CovgStr = "middle half of all 3 axes";
597												filterBounds = Bounds<double>
598													(indexBounds.min(0) + .25 * RangeX,
599													indexBounds.min(1) + .25 * RangeY,
600													indexBounds.min(2) + .25 * RangeZ,
601													indexBounds.max(0) - .25 * RangeX,
602													indexBounds.max(1) - .25 * RangeY,
603													indexBounds.max(2) - .25 * RangeZ);
604												break;
605											} // 1
606											case 2:
607											{
608												CovgStr = "upper left, all Z range";
609												filterBounds = Bounds<double>
610													(indexBounds.min(0),
611													indexBounds.min(1) + .5 * RangeY,
612													indexBounds.min(2),
613													indexBounds.min(0) + .5 * RangeX,
614													indexBounds.max(1),
615													indexBounds.max(2));
616												break;
617											} // 2
618											case 3:
619											{
620												CovgStr = "upper right, all Z range";
621												filterBounds = Bounds<double>
622													(indexBounds.min(0) + .5 * RangeX,
623													indexBounds.min(1) + .5 * RangeY,
624													indexBounds.min(2),
625													indexBounds.max(0),
626													indexBounds.max(1),
627													indexBounds.max(2));
628												break;
629											} // 3
630											case 4:
631											{
632												CovgStr = "lower left, all Z range";
633												filterBounds = Bounds<double>
634													(indexBounds.min(0),
635													indexBounds.min(1),
636													indexBounds.min(2),
637													indexBounds.min(0) + .5 * RangeX,
638													indexBounds.min(1) + .5 * RangeY,
639													indexBounds.max(2));
640												break;
641											} // 4
642											case 5:
643											{
644												CovgStr = "lower right, all Z range";
645												filterBounds = Bounds<double>
646													(indexBounds.min(0)+ .5 * RangeX,
647													indexBounds.min(1),
648													indexBounds.min(2),
649													indexBounds.max(0),
650													indexBounds.min(1) + .5 * RangeY,
651													indexBounds.max(2));
652												break;
653											} // 5
654                                            default:
655                                            {
656                                                CovgStr = "";
657                                                break;
658                                            }
659										} // switch
660
661										if (ParamSrc.SetFilterValues(filterBounds, index))
662										{
663											const std::vector<uint32_t>& FilterResult = index.Filter(ParamSrc);
664											if (FilterResult.size())
665											{
666												// do something with the list of points
667												std::ostringstream oss;
668												oss << "Points within filter area " << FilterResult.size() 
669													<< " of " << index.GetPointRecordsCount() 
670													<< ", " << CovgStr << std::endl;
671												fprintf(debugger, "%s", oss.str().c_str());
672											}
673											else
674												IndexFilterNoPoints(debugger);
675										}
676										else
677											IndexFilterInitError(debugger);
678									} // for
679								} // else
680							} // if
681							else
682								IndexInitError(debugger);
683						} // if
684						else
685							IndexInitError(debugger);
686						if (ostrm)
687						{
688							if (static_cast<std::ofstream&>(*ostrm))
689								static_cast<std::ofstream&>(*ostrm).close();
690						} // if
691					} // if
692				} // if
693				if (idxstrm)
694				{
695					if (static_cast<std::ifstream&>(*idxstrm))
696						static_cast<std::ifstream&>(*idxstrm).close();
697				} // if
698
699				delete idxreader;
700				delete reader;
701			} // if reader
702		
703        if (static_cast<std::ifstream&>(*istrm))
704            static_cast<std::ifstream&>(*istrm).close();
705        delete istrm;
706		} // if istrm
707	} // if input file name
708	return 0;
709}
710
711// } // namespace liblas