~ubuntu-branches/ubuntu/trusty/liblas/trusty-proposed

« back to all changes in this revision

Viewing changes to src/detail/reader.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2014-01-05 17:00:29 UTC
  • mfrom: (7.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140105170029-ddtp0j63x5jvck2u
Tags: 1.7.0+dfsg-2
Fixed missing linking of system boost component.
(closes: #733282)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************************************
2
 
 * $Id$
3
 
 *
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
7
 
 *
8
 
 ******************************************************************************
9
 
 * Copyright (c) 2008, Mateusz Loskot
10
 
 *
11
 
 * All rights reserved.
12
 
 * 
13
 
 * Redistribution and use in source and binary forms, with or without 
14
 
 * modification, are permitted provided that the following 
15
 
 * conditions are met:
16
 
 * 
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.
27
 
 * 
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 
39
 
 * OF SUCH DAMAGE.
40
 
 ****************************************************************************/
41
 
 
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>
48
 
// 
49
 
// // GeoTIFF
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
57
 
 
58
 
#ifdef HAVE_GDAL
59
 
#include <ogr_srs_api.h>
60
 
#endif
61
 
 
62
 
// std
63
 
#include <fstream>
64
 
#include <cassert>
65
 
#include <cstdlib> // std::size_t
66
 
#include <stdexcept>
67
 
 
68
 
namespace liblas { namespace detail {
69
 
 
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)
73
 
{
74
 
}
75
 
 
76
 
Reader::~Reader()
77
 
{
78
 
#ifdef HAVE_GDAL
79
 
    if (m_transform)
80
 
    {
81
 
        OCTDestroyCoordinateTransformation(m_transform);
82
 
    }
83
 
    if (m_in_ref)
84
 
    {
85
 
        OSRDestroySpatialReference(m_in_ref);
86
 
    }
87
 
    if (m_out_ref)
88
 
    {
89
 
        OSRDestroySpatialReference(m_out_ref);
90
 
    }
91
 
 
92
 
#endif
93
 
}
94
 
 
95
 
std::istream& Reader::GetStream() const
96
 
{
97
 
    return m_ifs;
98
 
}
99
 
 
100
 
void Reader::FillPoint(PointRecord& record, LASPoint& point) 
101
 
{
102
 
    
103
 
    point.SetX(record.x);
104
 
    point.SetY(record.y);
105
 
    point.SetZ(record.z);
106
 
    
107
 
    if (m_transform)
108
 
    {
109
 
        Project(point);
110
 
    }
111
 
 
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);
118
 
}
119
 
 
120
 
bool Reader::ReadVLR(LASHeader& header)
121
 
{
122
 
    VLRHeader vlrh = { 0 };
123
 
 
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)
128
 
    {
129
 
        read_n(vlrh, m_ifs, sizeof(VLRHeader));
130
 
 
131
 
        uint16_t length = vlrh.recordLengthAfterHeader;
132
 
        if (length < 1)
133
 
        {
134
 
            throw std::domain_error("VLR record length must be at least 1 byte long");
135
 
        } 
136
 
        std::vector<uint8_t> data;
137
 
        data.resize(length);
138
 
 
139
 
        read_n(data.front(), m_ifs, length);
140
 
         
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);
147
 
        vlr.SetData(data);
148
 
 
149
 
        header.AddVLR(vlr);
150
 
    }
151
 
    return true;
152
 
}
153
 
 
154
 
bool Reader::ReadGeoreference(LASHeader& header)
155
 
{
156
 
    std::vector<LASVariableRecord> vlrs;
157
 
    for (uint16_t i = 0; i < header.GetRecordsCount(); ++i)
158
 
    {
159
 
        LASVariableRecord record = header.GetVLR(i);
160
 
        vlrs.push_back(record);
161
 
    }
162
 
 
163
 
    LASSpatialReference srs(vlrs);    
164
 
    header.SetSRS(srs);
165
 
 
166
 
    // keep a copy on the reader in case we're going to reproject data 
167
 
    // on the way out.
168
 
    m_in_srs = srs;
169
 
 
170
 
    return true;
171
 
}
172
 
 
173
 
void Reader::Reset(LASHeader const& header)
174
 
{
175
 
    m_ifs.clear();
176
 
    m_ifs.seekg(0);
177
 
 
178
 
    // Reset sizes and set internal cursor to the beginning of file.
179
 
    m_current = 0;
180
 
    m_size = header.GetPointRecordsCount();
181
 
}
182
 
 
183
 
void Reader::SetSRS(const LASSpatialReference& srs)
184
 
{
185
 
    m_out_srs = srs;
186
 
#ifdef HAVE_GDAL
187
 
    m_in_ref = OSRNewSpatialReference(0);
188
 
    m_out_ref = OSRNewSpatialReference(0);
189
 
 
190
 
    int result = OSRSetFromUserInput(m_in_ref, m_in_srs.GetWKT().c_str());
191
 
    if (result != OGRERR_NONE) 
192
 
    {
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);
197
 
    }
198
 
    
199
 
    result = OSRSetFromUserInput(m_out_ref, m_out_srs.GetWKT().c_str());
200
 
    if (result != OGRERR_NONE) 
201
 
    {
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);
206
 
    }
207
 
 
208
 
    m_transform = OCTNewCoordinateTransformation( m_in_ref, m_out_ref);
209
 
    
210
 
#endif
211
 
}
212
 
 
213
 
void Reader::Project(LASPoint& point)
214
 
{
215
 
#ifdef HAVE_GDAL
216
 
    
217
 
    int ret = 0;
218
 
    double x = point.GetX();
219
 
    double y = point.GetY();
220
 
    double z = point.GetZ();
221
 
    
222
 
    ret = OCTTransform(m_transform, 1, &x, &y, &z);    
223
 
    if (!ret)
224
 
    {
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);
229
 
    }
230
 
 
231
 
    point.SetX(x);
232
 
    point.SetY(y);
233
 
    point.SetZ(z);
234
 
#else
235
 
    UNREFERENCED_PARAMETER(point);
236
 
#endif
237
 
}
238
 
 
239
 
Reader* ReaderFactory::Create(std::istream& ifs)
240
 
{
241
 
    if (!ifs)
242
 
    {
243
 
        throw std::runtime_error("input stream state is invalid");
244
 
    }
245
 
 
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);
253
 
 
254
 
    if (1 == verMajor && 0 == verMinor)
255
 
    {
256
 
        return new v10::ReaderImpl(ifs);
257
 
    }
258
 
    else if (1 == verMajor && 1 == verMinor)
259
 
    {
260
 
        return new v11::ReaderImpl(ifs);
261
 
    }
262
 
    else if (1 == verMajor && 2 == verMinor)
263
 
    {
264
 
        return new v12::ReaderImpl(ifs);
265
 
    }
266
 
    else if (2 == verMajor && 0 == verMinor )
267
 
    {
268
 
        // TODO: LAS 2.0 read/write support
269
 
        throw std::runtime_error("LAS 2.0+ file detected but unsupported");
270
 
    }
271
 
 
272
 
    throw std::runtime_error("LAS file of unknown version");
273
 
}
274
 
 
275
 
 
276
 
void ReaderFactory::Destroy(Reader* p) 
277
 
{
278
 
    delete p;
279
 
    p = 0;
280
 
}
281
 
 
282
 
}} // namespace liblas::detail