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

« back to all changes in this revision

Viewing changes to src/detail/reader11.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.1 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/reader11.hpp>
43
 
#include <liblas/detail/utility.hpp>
44
 
#include <liblas/liblas.hpp>
45
 
#include <liblas/lasheader.hpp>
46
 
#include <liblas/laspoint.hpp>
47
 
#include <liblas/lasvariablerecord.hpp>
48
 
 
49
 
// std
50
 
#include <fstream>
51
 
#include <iostream>
52
 
#include <stdexcept>
53
 
#include <cstdlib> // std::size_t
54
 
#include <cassert>
55
 
 
56
 
namespace liblas { namespace detail { namespace v11 {
57
 
 
58
 
ReaderImpl::ReaderImpl(std::istream& ifs) : Base(ifs)
59
 
{
60
 
}
61
 
 
62
 
std::size_t ReaderImpl::GetVersion() const
63
 
{
64
 
    return eLASVersion11;
65
 
}
66
 
 
67
 
bool ReaderImpl::ReadHeader(LASHeader& header)
68
 
{
69
 
    using detail::read_n;
70
 
 
71
 
    // Helper variables
72
 
    uint8_t n1 = 0;
73
 
    uint16_t n2 = 0;
74
 
    uint32_t n4 = 0;
75
 
    double x1 = 0;
76
 
    double y1 = 0;
77
 
    double z1 = 0;
78
 
    double x2 = 0;
79
 
    double y2 = 0;
80
 
    double z2 = 0;
81
 
    std::string buf;
82
 
    std::string fsig;
83
 
 
84
 
    m_ifs.seekg(0);
85
 
 
86
 
    // 1. File Signature
87
 
    read_n(fsig, m_ifs, 4);
88
 
    header.SetFileSignature(fsig);
89
 
 
90
 
    // 2. File Source ID
91
 
    read_n(n2, m_ifs, sizeof(n2));
92
 
    header.SetFileSourceId(n2);
93
 
 
94
 
    // 3. Reserved
95
 
    // This data must always contain Zeros.
96
 
    read_n(n2, m_ifs, sizeof(n2));
97
 
 
98
 
    // 4-7. Project ID
99
 
    uint32_t d1 = 0;
100
 
    uint16_t d2 = 0;
101
 
    uint16_t d3 = 0;
102
 
    uint8_t d4[8] = { 0 };
103
 
    read_n(d1, m_ifs, sizeof(d1));
104
 
    read_n(d2, m_ifs, sizeof(d2));
105
 
    read_n(d3, m_ifs, sizeof(d3));
106
 
    read_n(d4, m_ifs, sizeof(d4));
107
 
    liblas::guid g(d1, d2, d3, d4);
108
 
    header.SetProjectId(g);
109
 
 
110
 
    // 8. Version major
111
 
    read_n(n1, m_ifs, sizeof(n1));
112
 
    header.SetVersionMajor(n1);
113
 
 
114
 
    // 9. Version minor
115
 
    read_n(n1, m_ifs, sizeof(n1));
116
 
    header.SetVersionMinor(n1);
117
 
 
118
 
    // 10. System ID
119
 
    read_n(buf, m_ifs, 32);
120
 
    header.SetSystemId(buf);
121
 
 
122
 
    // 11. Generating Software ID
123
 
    read_n(buf, m_ifs, 32);
124
 
    header.SetSoftwareId(buf);
125
 
 
126
 
    // 12. File Creation Day of Year
127
 
    read_n(n2, m_ifs, sizeof(n2));
128
 
    header.SetCreationDOY(n2);
129
 
 
130
 
    // 13. File Creation Year
131
 
    read_n(n2, m_ifs, sizeof(n2));
132
 
    header.SetCreationYear(n2);
133
 
 
134
 
    // 14. Header Size
135
 
    // NOTE: Size of the stanard header block must always be 227 bytes
136
 
    read_n(n2, m_ifs, sizeof(n2));
137
 
 
138
 
    // 15. Offset to data
139
 
    read_n(n4, m_ifs, sizeof(n4));
140
 
    if (n4 < header.GetHeaderSize())
141
 
    {
142
 
        // TODO: Move this test to LASHeader::Validate()
143
 
        throw std::domain_error("offset to point data smaller than header size");
144
 
    }
145
 
    header.SetDataOffset(n4);
146
 
 
147
 
    // 16. Number of variable length records
148
 
    read_n(n4, m_ifs, sizeof(n4));
149
 
    header.SetRecordsCount(n4);
150
 
 
151
 
    // 17. Point Data Format ID
152
 
    read_n(n1, m_ifs, sizeof(n1));
153
 
    if (n1 == LASHeader::ePointFormat0) {
154
 
        header.SetDataFormatId(LASHeader::ePointFormat0);
155
 
    } 
156
 
    else if (n1 == LASHeader::ePointFormat1) {
157
 
        header.SetDataFormatId(LASHeader::ePointFormat1);
158
 
    }
159
 
    else if (n1 == LASHeader::ePointFormat2) {
160
 
        header.SetDataFormatId(LASHeader::ePointFormat2);
161
 
    }
162
 
    else if (n1 == LASHeader::ePointFormat3) {
163
 
        header.SetDataFormatId(LASHeader::ePointFormat3);
164
 
    }
165
 
    else {
166
 
        throw std::domain_error("invalid point data format");
167
 
    }
168
 
    
169
 
    // 18. Point Data Record Length
170
 
    // NOTE: No need to set record length because it's
171
 
    // determined on basis of point data format.
172
 
    read_n(n2, m_ifs, sizeof(n2));
173
 
 
174
 
    // 19. Number of point records
175
 
    read_n(n4, m_ifs, sizeof(n4));
176
 
    header.SetPointRecordsCount(n4);
177
 
 
178
 
    // 20. Number of points by return
179
 
    std::vector<uint32_t>::size_type const srbyr = 5;
180
 
    uint32_t rbyr[srbyr] = { 0 };
181
 
    read_n(rbyr, m_ifs, sizeof(rbyr));
182
 
    for (std::size_t i = 0; i < srbyr; ++i)
183
 
    {
184
 
        header.SetPointRecordsByReturnCount(i, rbyr[i]);
185
 
    }
186
 
 
187
 
    // 21-23. Scale factors
188
 
    read_n(x1, m_ifs, sizeof(x1));
189
 
    read_n(y1, m_ifs, sizeof(y1));
190
 
    read_n(z1, m_ifs, sizeof(z1));
191
 
    header.SetScale(x1, y1, z1);
192
 
 
193
 
    // 24-26. Offsets
194
 
    read_n(x1, m_ifs, sizeof(x1));
195
 
    read_n(y1, m_ifs, sizeof(y1));
196
 
    read_n(z1, m_ifs, sizeof(z1));
197
 
    header.SetOffset(x1, y1, z1);
198
 
 
199
 
    // 27-28. Max/Min X
200
 
    read_n(x1, m_ifs, sizeof(x1));
201
 
    read_n(x2, m_ifs, sizeof(x2));
202
 
 
203
 
    // 29-30. Max/Min Y
204
 
    read_n(y1, m_ifs, sizeof(y1));
205
 
    read_n(y2, m_ifs, sizeof(y2));
206
 
 
207
 
    // 31-32. Max/Min Z
208
 
    read_n(z1, m_ifs, sizeof(z1));
209
 
    read_n(z2, m_ifs, sizeof(z2));
210
 
 
211
 
    header.SetMax(x1, y1, z1);
212
 
    header.SetMin(x2, y2, z2);
213
 
 
214
 
    m_ifs.seekg(header.GetDataOffset(), std::ios::beg);
215
 
 
216
 
    Reset(header);
217
 
 
218
 
    return true;
219
 
}
220
 
 
221
 
bool ReaderImpl::ReadNextPoint(LASPoint& point, const LASHeader& header)
222
 
{
223
 
    // Read point data record format 0
224
 
 
225
 
    // TODO: Replace with compile-time assert
226
 
 
227
 
    double t = 0;
228
 
    detail::PointRecord record;
229
 
    assert(LASHeader::ePointSize0 == sizeof(record));
230
 
 
231
 
    if (0 == m_current)
232
 
    {
233
 
        m_ifs.clear();
234
 
        m_ifs.seekg(header.GetDataOffset(), std::ios::beg);
235
 
    }
236
 
 
237
 
    if (m_current < m_size)
238
 
    {
239
 
        try
240
 
        {
241
 
            detail::read_n(record, m_ifs, sizeof(PointRecord));
242
 
            ++m_current;    
243
 
        }        
244
 
        catch (std::out_of_range const& e) // we reached the end of the file
245
 
        {
246
 
            std::cerr << e.what() << std::endl;
247
 
            return false;
248
 
        }
249
 
 
250
 
        Reader::FillPoint(record, point);
251
 
        point.SetCoordinates(header, point.GetX(), point.GetY(), point.GetZ());
252
 
    
253
 
        if (header.GetDataFormatId() == LASHeader::ePointFormat1) {
254
 
            detail::read_n(t, m_ifs, sizeof(double));
255
 
            point.SetTime(t);
256
 
        }
257
 
        return true;
258
 
    }
259
 
 
260
 
    return false;
261
 
}
262
 
 
263
 
 
264
 
bool ReaderImpl::ReadPointAt(std::size_t n, LASPoint& point, const LASHeader& header)
265
 
{
266
 
    // Read point data record format 0
267
 
 
268
 
    // TODO: Replace with compile-time assert
269
 
 
270
 
    double t = 0;
271
 
    detail::PointRecord record;
272
 
    assert(LASHeader::ePointSize0 == sizeof(record));
273
 
 
274
 
    if (m_size <= n)
275
 
        return false;
276
 
 
277
 
    std::streamsize pos = (static_cast<std::streamsize>(n) * header.GetDataRecordLength()) + header.GetDataOffset();
278
 
 
279
 
    m_ifs.clear();
280
 
    m_ifs.seekg(pos, std::ios::beg);
281
 
    detail::read_n(record, m_ifs, sizeof(record));
282
 
 
283
 
    Reader::FillPoint(record, point);
284
 
    point.SetCoordinates(header, point.GetX(), point.GetY(), point.GetZ());
285
 
    
286
 
    if (header.GetDataFormatId() == LASHeader::ePointFormat1) {
287
 
        detail::read_n(t, m_ifs, sizeof(double));
288
 
        point.SetTime(t);
289
 
    }
290
 
    return true;
291
 
}
292
 
 
293
 
 
294
 
}}} // namespace liblas::detail::v11
295