/*========================================================================= Program: Visualization Toolkit Module: vtkGDALRasterReader.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkLASReader.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include vtkStandardNewMacro(vtkLASReader) //---------------------------------------------------------------------------- vtkLASReader::vtkLASReader() { this->FileName = NULL; this->SetNumberOfInputPorts(0); this->SetNumberOfOutputPorts(1); } //---------------------------------------------------------------------------- vtkLASReader::~vtkLASReader() { if ( ! this->FileName ) delete[] this->FileName; } //---------------------------------------------------------------------------- int vtkLASReader::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** vtkNotUsed(request), vtkInformationVector* outputVector) { // Get the info object vtkInformation* outInfo = outputVector->GetInformationObject(0); // Get the ouptut vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); // Open LAS File for reading std::ifstream ifs; ifs.open(this->FileName, std::ios_base::binary | std::ios_base::in); if ( ! ifs.is_open() ) { vtkErrorMacro (<< "Unable to open file for reading: " << this->FileName ); return VTK_ERROR; } // Read header data liblas::ReaderFactory readerFactory; liblas::Reader reader = readerFactory.CreateWithStream(ifs); vtkNew pointsPolyData; this->ReadPointRecordData(reader, pointsPolyData); ifs.close(); // Convert points to verts in output polydata vtkNew vertexFilter; vertexFilter->SetInputData(pointsPolyData); vertexFilter->Update(); output->ShallowCopy(vertexFilter->GetOutput()); return VTK_OK; } //---------------------------------------------------------------------------- void vtkLASReader::ReadPointRecordData(liblas::Reader &reader, vtkPolyData* pointsPolyData) { vtkNew points; // scalars associated with points vtkNew color; color->SetName("color"); color->SetNumberOfComponents(3); vtkNew classification; classification->SetName("classification"); classification->SetNumberOfComponents(1); vtkNew intensity; intensity->SetName("intensity"); intensity->SetNumberOfComponents(1); liblas::Header header = liblas::Header(reader.GetHeader()); std::valarray scale = { header.GetScaleX(), header.GetScaleY(), header.GetScaleZ() }; std::valarray offset = { header.GetOffsetX(), header.GetOffsetY(), header.GetOffsetZ() }; liblas::PointFormatName pointFormat = header.GetDataFormatId(); int pointRecordsCount = header.GetPointRecordsCount(); for ( int i= 0; i < pointRecordsCount && reader.ReadNextPoint(); i++) { liblas::Point const& p = reader.GetPoint(); std::valarray lasPoint = { p.GetX(), p.GetY(), p.GetZ() }; points->InsertNextPoint(&lasPoint[0]); //std::valarray point = lasPoint * scale + offset; // We have seen a file where the scaled points were much smaller than the offset // So, all points ended up in the same place. std::valarray point = lasPoint * scale; switch(pointFormat) { case liblas::ePointFormat2: case liblas::ePointFormat3: case liblas::ePointFormat5: { unsigned short c[3]; c[0] = p.GetColor().GetRed(); c[1] = p.GetColor().GetGreen(); c[2] = p.GetColor().GetBlue(); color->InsertNextTypedTuple(c); intensity->InsertNextValue(p.GetIntensity()); } break; case liblas::ePointFormat0: case liblas::ePointFormat1: classification->InsertNextValue(p.GetClassification().GetClass()); intensity->InsertNextValue(p.GetIntensity()); break; case liblas::ePointFormatUnknown: default: intensity->InsertNextValue(p.GetIntensity()); break; } } pointsPolyData->SetPoints(points); pointsPolyData->GetPointData()->AddArray(intensity); switch(pointFormat) { case liblas::ePointFormat2: case liblas::ePointFormat3: case liblas::ePointFormat5: pointsPolyData->GetPointData()->AddArray(color); break; case liblas::ePointFormat0: case liblas::ePointFormat1: pointsPolyData->GetPointData()->AddArray(classification); break; case liblas::ePointFormatUnknown: default: break; } } //---------------------------------------------------------------------------- void vtkLASReader::PrintSelf(ostream &os, vtkIndent indent) { Superclass::PrintSelf(os, indent); os << "vtkLASReader" << std::endl; os << "Filename: " << this->FileName << std::endl; }