1
/******************************************************************************
4
* Project: libLAS - http://liblas.org - A BSD library for LAS format data.
5
* Purpose: Reader implementation for C++ libLAS
6
* Author: Mateusz Loskot, mateusz@loskot.net
8
******************************************************************************
9
* Copyright (c) 2008, Mateusz Loskot
11
* All rights reserved.
13
* Redistribution and use in source and binary forms, with or without
14
* modification, are permitted provided that the following
17
* * Redistributions of source code must retain the above copyright
18
* notice, this list of conditions and the following disclaimer.
19
* * Redistributions in binary form must reproduce the above copyright
20
* notice, this list of conditions and the following disclaimer in
21
* the documentation and/or other materials provided
22
* with the distribution.
23
* * Neither the name of the Martin Isenburg or Iowa Department
24
* of Natural Resources nor the names of its contributors may be
25
* used to endorse or promote products derived from this software
26
* without specific prior written permission.
28
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
35
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
36
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
37
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
38
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
40
****************************************************************************/
42
#include <liblas/detail/reader.hpp>
43
#include <liblas/detail/reader10.hpp>
44
#include <liblas/detail/reader11.hpp>
45
#include <liblas/detail/reader12.hpp>
46
#include <liblas/lasheader.hpp>
47
#include <liblas/laspoint.hpp>
50
// #ifdef HAVE_LIBGEOTIFF
51
// #include <geotiff.h>
52
// #include <geo_simpletags.h>
53
// #include "geo_normalize.h"
54
// #include "geo_simpletags.h"
55
// #include "geovalues.h"
56
// #endif // HAVE_LIBGEOTIFF
59
#include <ogr_srs_api.h>
65
#include <cstdlib> // std::size_t
68
namespace liblas { namespace detail {
70
Reader::Reader(std::istream& ifs) :
71
m_ifs(ifs), m_size(0), m_current(0),
72
m_transform(0), m_in_ref(0), m_out_ref(0)
81
OCTDestroyCoordinateTransformation(m_transform);
85
OSRDestroySpatialReference(m_in_ref);
89
OSRDestroySpatialReference(m_out_ref);
95
std::istream& Reader::GetStream() const
100
void Reader::FillPoint(PointRecord& record, LASPoint& point)
103
point.SetX(record.x);
104
point.SetY(record.y);
105
point.SetZ(record.z);
112
point.SetIntensity(record.intensity);
113
point.SetScanFlags(record.flags);
114
point.SetClassification(record.classification);
115
point.SetScanAngleRank(record.scan_angle_rank);
116
point.SetUserData(record.user_data);
117
point.SetPointSourceID(record.point_source_id);
120
bool Reader::ReadVLR(LASHeader& header)
122
VLRHeader vlrh = { 0 };
124
m_ifs.seekg(header.GetHeaderSize(), std::ios::beg);
125
uint32_t count = header.GetRecordsCount();
126
header.SetRecordsCount(0);
127
for (uint32_t i = 0; i < count; ++i)
129
read_n(vlrh, m_ifs, sizeof(VLRHeader));
131
uint16_t length = vlrh.recordLengthAfterHeader;
134
throw std::domain_error("VLR record length must be at least 1 byte long");
136
std::vector<uint8_t> data;
139
read_n(data.front(), m_ifs, length);
141
LASVariableRecord vlr;
142
vlr.SetReserved(vlrh.reserved);
143
vlr.SetUserId(std::string(vlrh.userId));
144
vlr.SetDescription(std::string(vlrh.description));
145
vlr.SetRecordLength(vlrh.recordLengthAfterHeader);
146
vlr.SetRecordId(vlrh.recordId);
154
bool Reader::ReadGeoreference(LASHeader& header)
156
std::vector<LASVariableRecord> vlrs;
157
for (uint16_t i = 0; i < header.GetRecordsCount(); ++i)
159
LASVariableRecord record = header.GetVLR(i);
160
vlrs.push_back(record);
163
LASSpatialReference srs(vlrs);
166
// keep a copy on the reader in case we're going to reproject data
173
void Reader::Reset(LASHeader const& header)
178
// Reset sizes and set internal cursor to the beginning of file.
180
m_size = header.GetPointRecordsCount();
183
void Reader::SetSRS(const LASSpatialReference& srs)
187
m_in_ref = OSRNewSpatialReference(0);
188
m_out_ref = OSRNewSpatialReference(0);
190
int result = OSRSetFromUserInput(m_in_ref, m_in_srs.GetWKT().c_str());
191
if (result != OGRERR_NONE)
193
std::ostringstream msg;
194
msg << "Could not import input spatial reference for Reader::" << CPLGetLastErrorMsg() << result;
195
std::string message(msg.str());
196
throw std::runtime_error(message);
199
result = OSRSetFromUserInput(m_out_ref, m_out_srs.GetWKT().c_str());
200
if (result != OGRERR_NONE)
202
std::ostringstream msg;
203
msg << "Could not import output spatial reference for Reader::" << CPLGetLastErrorMsg() << result;
204
std::string message(msg.str());
205
throw std::runtime_error(message);
208
m_transform = OCTNewCoordinateTransformation( m_in_ref, m_out_ref);
213
void Reader::Project(LASPoint& point)
218
double x = point.GetX();
219
double y = point.GetY();
220
double z = point.GetZ();
222
ret = OCTTransform(m_transform, 1, &x, &y, &z);
225
std::ostringstream msg;
226
msg << "Could not project point for Reader::" << CPLGetLastErrorMsg() << ret;
227
std::string message(msg.str());
228
throw std::runtime_error(message);
235
UNREFERENCED_PARAMETER(point);
239
Reader* ReaderFactory::Create(std::istream& ifs)
243
throw std::runtime_error("input stream state is invalid");
246
// Determine version of given LAS file and
247
// instantiate appropriate reader.
248
uint8_t verMajor = 0;
249
uint8_t verMinor = 0;
250
ifs.seekg(24, std::ios::beg);
251
detail::read_n(verMajor, ifs, 1);
252
detail::read_n(verMinor, ifs, 1);
254
if (1 == verMajor && 0 == verMinor)
256
return new v10::ReaderImpl(ifs);
258
else if (1 == verMajor && 1 == verMinor)
260
return new v11::ReaderImpl(ifs);
262
else if (1 == verMajor && 2 == verMinor)
264
return new v12::ReaderImpl(ifs);
266
else if (2 == verMajor && 0 == verMinor )
268
// TODO: LAS 2.0 read/write support
269
throw std::runtime_error("LAS 2.0+ file detected but unsupported");
272
throw std::runtime_error("LAS file of unknown version");
276
void ReaderFactory::Destroy(Reader* p)
282
}} // namespace liblas::detail