/*========================================================================= 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 #include vtkStandardNewMacro(vtkLASReader); //------------------------------------------------------------------------------ vtkLASReader::vtkLASReader() { this->FileName = nullptr; this->SetNumberOfInputPorts(0); this->SetNumberOfOutputPorts(1); } //------------------------------------------------------------------------------ vtkLASReader::~vtkLASReader() { 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 output vtkPolyData* output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); // Open LAS File for reading vtksys::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; }