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

« back to all changes in this revision

Viewing changes to src/detail/reader/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:  LAS 1.0 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/liblas.hpp>
 
43
#include <liblas/detail/reader/reader.hpp>
 
44
#include <liblas/detail/private_utility.hpp>
 
45
// boost
 
46
#include <boost/cstdint.hpp>
 
47
// std
 
48
#include <fstream>
 
49
#include <istream>
 
50
#include <iostream>
 
51
#include <stdexcept>
 
52
#include <cstddef> // std::size_t
 
53
#include <cstdlib> // std::free
 
54
#include <cassert>
 
55
 
 
56
using namespace boost;
 
57
 
 
58
namespace liblas { namespace detail { 
 
59
 
 
60
ReaderImpl::ReaderImpl(std::istream& ifs)
 
61
    : m_ifs(ifs)
 
62
    , m_size(0)
 
63
    , m_current(0)
 
64
    // , m_point_reader(PointReaderPtr())
 
65
    , m_header_reader(new reader::Header(m_ifs))
 
66
    , m_header(HeaderPtr())
 
67
    , m_point(PointPtr(new liblas::Point()))
 
68
    , m_filters(0)
 
69
    , m_transforms(0)
 
70
    , bNeedHeaderCheck(false)
 
71
{
 
72
 
 
73
}
 
74
 
 
75
ReaderImpl::~ReaderImpl()
 
76
{
 
77
}
 
78
 
 
79
void ReaderImpl::Reset()
 
80
{
 
81
    m_ifs.clear();
 
82
    m_ifs.seekg(0);
 
83
 
 
84
    // Reset sizes and set internal cursor to the beginning of file.
 
85
    m_current = 0;
 
86
    m_size = m_header->GetPointRecordsCount();
 
87
 
 
88
    m_record_size = m_header->GetSchema().GetByteSize();
 
89
}
 
90
 
 
91
void ReaderImpl::TransformPoint(liblas::Point& p)
 
92
{    
 
93
 
 
94
    // Apply the transforms to each point
 
95
    std::vector<liblas::TransformPtr>::const_iterator ti;
 
96
 
 
97
    for (ti = m_transforms.begin(); ti != m_transforms.end(); ++ti)
 
98
    {
 
99
        liblas::TransformPtr transform = *ti;
 
100
        transform->transform(p);
 
101
    }            
 
102
}
 
103
 
 
104
 
 
105
bool ReaderImpl::FilterPoint(liblas::Point const& p)
 
106
{    
 
107
    // If there's no filters on this reader, we keep 
 
108
    // the point no matter what.
 
109
    if (m_filters.empty() ) {
 
110
        return true;
 
111
    }
 
112
 
 
113
    std::vector<liblas::FilterPtr>::const_iterator fi;
 
114
    for (fi = m_filters.begin(); fi != m_filters.end(); ++fi)
 
115
    {
 
116
        liblas::FilterPtr filter = *fi;
 
117
        if (!filter->filter(p))
 
118
        {
 
119
            return false;
 
120
        }
 
121
    }
 
122
    return true;
 
123
}
 
124
 
 
125
 
 
126
    
 
127
void ReaderImpl::ReadHeader()
 
128
{
 
129
    // If we're eof, we need to reset the state
 
130
    if (m_ifs.eof())
 
131
        m_ifs.clear();
 
132
    
 
133
    m_header_reader->ReadHeader();
 
134
    m_header = m_header_reader->GetHeader();
 
135
    
 
136
    if (m_header->Compressed())
 
137
        throw std::runtime_error("Internal error: uncompressed reader encountered compressed header"); 
 
138
        
 
139
    m_point->SetHeader(m_header.get());
 
140
 
 
141
 
 
142
    Reset();
 
143
}
 
144
 
 
145
void ReaderImpl::SetHeader(liblas::Header const& header) 
 
146
{
 
147
    m_header = HeaderPtr(new liblas::Header(header));
 
148
    m_point->SetHeader(m_header.get());
 
149
}
 
150
    
 
151
void ReaderImpl::ReadNextPoint()
 
152
{
 
153
    if (0 == m_current)
 
154
    {
 
155
        m_ifs.clear();
 
156
        m_ifs.seekg(m_header->GetDataOffset(), std::ios::beg);
 
157
    }
 
158
 
 
159
    if (m_current >= m_size ){
 
160
        throw std::out_of_range("ReadNextPoint: file has no more points to read, end of file reached");
 
161
    } 
 
162
 
 
163
    if (bNeedHeaderCheck) 
 
164
    {
 
165
        if (!(m_point->GetHeader() == m_header.get()))
 
166
            m_point->SetHeader(m_header.get());
 
167
    }
 
168
    
 
169
    try
 
170
    {
 
171
        detail::read_n(m_point->GetData().front(), m_ifs, m_record_size);
 
172
        ++m_current;
 
173
        
 
174
    } catch (std::runtime_error&)
 
175
    {
 
176
        // If the stream is no good anymore, we're done reading points
 
177
        throw std::out_of_range("ReadNextPoint: file has no more points to read, end of file reached");
 
178
 
 
179
    }
 
180
 
 
181
    // Filter the points and continue reading until we either find 
 
182
    // one to keep or throw an exception.
 
183
 
 
184
    bool bLastPoint = false;
 
185
    
 
186
    if (!m_filters.empty())
 
187
    {
 
188
        if (!FilterPoint(*m_point))
 
189
        {
 
190
 
 
191
            try
 
192
            {
 
193
                detail::read_n(m_point->GetData().front(), m_ifs, m_record_size);
 
194
                ++m_current;
 
195
        
 
196
            } catch (std::runtime_error&)
 
197
            {
 
198
                // If the stream is no good anymore, we're done reading points
 
199
                throw std::out_of_range("ReadNextPoint: file has no more points to read, end of file reached");
 
200
            }
 
201
 
 
202
            while (!FilterPoint(*m_point))
 
203
            {
 
204
 
 
205
                try
 
206
                {
 
207
                    detail::read_n(m_point->GetData().front(), m_ifs, m_record_size);
 
208
                    ++m_current;
 
209
        
 
210
                } catch (std::runtime_error&)
 
211
                {
 
212
                    // If the stream is no good anymore, we're done reading points
 
213
                    throw std::out_of_range("ReadNextPoint: file has no more points to read, end of file reached");
 
214
                }
 
215
                if (m_current == m_size) 
 
216
                {
 
217
                    bLastPoint = true;
 
218
                    break;
 
219
                }
 
220
            }
 
221
        }
 
222
    }
 
223
 
 
224
 
 
225
    if (!m_transforms.empty())
 
226
    {
 
227
        TransformPoint(*m_point);
 
228
    }
 
229
 
 
230
    if (bLastPoint)
 
231
        throw std::out_of_range("ReadNextPoint: file has no more points to read, end of file reached");
 
232
 
 
233
 
 
234
}
 
235
 
 
236
liblas::Point const& ReaderImpl::ReadPointAt(std::size_t n)
 
237
{
 
238
    if (m_size == n) {
 
239
        throw std::out_of_range("file has no more points to read, end of file reached");
 
240
    } else if (m_size < n) {
 
241
        std::ostringstream msg;
 
242
        msg << "ReadPointAt:: Inputted value: " << n << " is greater than the number of points: " << m_size;
 
243
        throw std::runtime_error(msg.str());
 
244
    } 
 
245
 
 
246
    std::streamsize const pos = (static_cast<std::streamsize>(n) * m_header->GetDataRecordLength()) + m_header->GetDataOffset();    
 
247
 
 
248
    m_ifs.clear();
 
249
    m_ifs.seekg(pos, std::ios::beg);
 
250
 
 
251
    if (bNeedHeaderCheck) 
 
252
    {
 
253
        if (!(m_point->GetHeader() == m_header.get()))
 
254
            m_point->SetHeader(m_header.get());
 
255
    }
 
256
    
 
257
    detail::read_n(m_point->GetData().front(), m_ifs, m_record_size);
 
258
 
 
259
    if (!m_transforms.empty())
 
260
    {
 
261
        TransformPoint(*m_point);
 
262
    }
 
263
    return *m_point;
 
264
}
 
265
 
 
266
void ReaderImpl::Seek(std::size_t n)
 
267
{
 
268
    if (m_size == n) {
 
269
        throw std::out_of_range("file has no more points to read, end of file reached");
 
270
    } else if (m_size < n) {
 
271
        std::ostringstream msg;
 
272
        msg << "Seek:: Inputted value: " << n << " is greater than the number of points: " << m_size;
 
273
        throw std::runtime_error(msg.str());
 
274
    } 
 
275
 
 
276
    std::streamsize pos = (static_cast<std::streamsize>(n) * m_header->GetDataRecordLength()) + m_header->GetDataOffset();    
 
277
 
 
278
    m_ifs.clear();
 
279
    m_ifs.seekg(pos, std::ios::beg);
 
280
    
 
281
    m_current = n;
 
282
}
 
283
 
 
284
void ReaderImpl::SetFilters(std::vector<liblas::FilterPtr> const& filters)
 
285
{
 
286
    m_filters = filters;
 
287
}
 
288
 
 
289
std::vector<liblas::FilterPtr>  ReaderImpl::GetFilters() const
 
290
{
 
291
    return m_filters;
 
292
}
 
293
 
 
294
void ReaderImpl::SetTransforms(std::vector<liblas::TransformPtr> const& transforms)
 
295
{
 
296
    m_transforms = transforms;
 
297
    
 
298
    // Transforms are allowed to change the point, including moving the 
 
299
    // point's HeaderPtr.  We need to check if we need to set that 
 
300
    // back on any subsequent reads.
 
301
    if (m_transforms.size() > 0)
 
302
    {
 
303
        for (std::vector<liblas::TransformPtr>::const_iterator i = transforms.begin(); i != transforms.end(); i++)
 
304
        {
 
305
            if (i->get()->ModifiesHeader())
 
306
                bNeedHeaderCheck = true;
 
307
        }
 
308
    }
 
309
}
 
310
 
 
311
std::vector<liblas::TransformPtr>  ReaderImpl::GetTransforms() const
 
312
{
 
313
    return m_transforms;
 
314
}
 
315
 
 
316
}} // namespace liblas::detail
 
317