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

« back to all changes in this revision

Viewing changes to src/detail/writer11.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 writer 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/writer11.hpp>
43
 
#include <liblas/detail/utility.hpp>
44
 
#include <liblas/lasheader.hpp>
45
 
#include <liblas/laspoint.hpp>
46
 
#include <liblas/liblas.hpp>
47
 
// std
48
 
#include <vector>
49
 
#include <fstream>
50
 
#include <stdexcept>
51
 
#include <cstdlib> // std::size_t
52
 
#include <cassert>
53
 
 
54
 
namespace liblas { namespace detail { namespace v11 {
55
 
 
56
 
WriterImpl::WriterImpl(std::ostream& ofs) :
57
 
    Base(ofs), m_pointCount(0)
58
 
{
59
 
}
60
 
 
61
 
std::size_t WriterImpl::GetVersion() const
62
 
{
63
 
    return eLASVersion11;
64
 
}
65
 
 
66
 
void WriterImpl::WriteHeader(LASHeader& header)
67
 
{
68
 
    uint8_t n1 = 0;
69
 
    uint16_t n2 = 0;
70
 
    uint32_t n4 = 0;
71
 
 
72
 
    // Rewrite the georeference VLR entries if they exist
73
 
    header.SetGeoreference();
74
 
 
75
 
    // Seek to the beginning
76
 
    m_ofs.seekp(0, std::ios::beg);
77
 
    std::ios::pos_type beginning = m_ofs.tellp();
78
 
 
79
 
    // Seek to the end
80
 
    m_ofs.seekp(0, std::ios::end);
81
 
    std::ios::pos_type end = m_ofs.tellp();
82
 
    
83
 
    // Figure out how many points we already have.  Each point record 
84
 
    // should be 20 bytes long, and header.GetDataOffset tells
85
 
    // us the location to start counting points from.  
86
 
    
87
 
    // This test should only be true if we were opened in both 
88
 
    // std::ios::in *and* std::ios::out, otherwise it should return false 
89
 
    // and we won't adjust the point count.
90
 
    
91
 
    if (beginning != end) {
92
 
        m_pointCount = ((uint32_t) end - header.GetDataOffset())/header.GetDataRecordLength();
93
 
 
94
 
        // Position to the beginning of the file to start writing the header
95
 
        m_ofs.seekp(0, std::ios::beg);
96
 
    }
97
 
    
98
 
    // 1. File Signature
99
 
    std::string const filesig(header.GetFileSignature());
100
 
    assert(filesig.size() == 4);
101
 
    detail::write_n(m_ofs, filesig, 4);
102
 
    
103
 
    // 2. File Source ID
104
 
    n2 = header.GetFileSourceId();
105
 
    detail::write_n(m_ofs, n2, sizeof(n2));
106
 
 
107
 
    // 3. Reserved
108
 
    n2 = header.GetReserved();
109
 
    detail::write_n(m_ofs, n2, sizeof(n2));
110
 
 
111
 
    // 4-7. GUID data
112
 
    uint32_t d1 = 0;
113
 
    uint16_t d2 = 0;
114
 
    uint16_t d3 = 0;
115
 
    uint8_t d4[8] = { 0 };
116
 
    liblas::guid g = header.GetProjectId();
117
 
    g.output_data(d1, d2, d3, d4);
118
 
    detail::write_n(m_ofs, d1, sizeof(d1));
119
 
    detail::write_n(m_ofs, d2, sizeof(d2));
120
 
    detail::write_n(m_ofs, d3, sizeof(d3));
121
 
    detail::write_n(m_ofs, d4, sizeof(d4));
122
 
    
123
 
    // 8. Version major
124
 
    n1 = header.GetVersionMajor();
125
 
    assert(1 == n1);
126
 
    detail::write_n(m_ofs, n1, sizeof(n1));
127
 
    
128
 
    // 9. Version minor
129
 
    n1 = header.GetVersionMinor();
130
 
    assert(1 == n1);
131
 
    detail::write_n(m_ofs, n1, sizeof(n1));
132
 
 
133
 
    // 10. System ID
134
 
    std::string const sysid(header.GetSystemId(true));
135
 
    assert(sysid.size() == 32);
136
 
    detail::write_n(m_ofs, sysid, 32);
137
 
    
138
 
    // 11. Generating Software ID
139
 
    std::string const softid(header.GetSoftwareId(true));
140
 
    assert(softid.size() == 32);
141
 
    detail::write_n(m_ofs, softid, 32);
142
 
 
143
 
    // 12. File Creation Day of Year
144
 
    n2 = header.GetCreationDOY();
145
 
    detail::write_n(m_ofs, n2, sizeof(n2));
146
 
 
147
 
    // 13. File Creation Year
148
 
    n2 = header.GetCreationYear();
149
 
    detail::write_n(m_ofs, n2, sizeof(n2));
150
 
 
151
 
    // 14. Header Size
152
 
    n2 = header.GetHeaderSize();
153
 
    assert(227 <= n2);
154
 
    detail::write_n(m_ofs, n2, sizeof(n2));
155
 
 
156
 
    // 15. Offset to data
157
 
    // At this point, no variable length records are written,
158
 
    // so  data offset is equal to header size (227)
159
 
    // TODO: This value must be updated after new variable length record is added.
160
 
    n4 = header.GetDataOffset();
161
 
    detail::write_n(m_ofs, n4, sizeof(n4));
162
 
 
163
 
    // 16. Number of variable length records
164
 
    // TODO: This value must be updated after new variable length record is added.
165
 
    n4 = header.GetRecordsCount();
166
 
    detail::write_n(m_ofs, n4, sizeof(n4));
167
 
 
168
 
    // 17. Point Data Format ID
169
 
    n1 = static_cast<uint8_t>(header.GetDataFormatId());
170
 
    detail::write_n(m_ofs, n1, sizeof(n1));
171
 
 
172
 
    // 18. Point Data Record Length
173
 
    n2 = header.GetDataRecordLength();
174
 
    detail::write_n(m_ofs, n2, sizeof(n2));
175
 
 
176
 
    // 19. Number of point records
177
 
    // This value is updated if necessary, see UpdateHeader function.
178
 
    n4 = header.GetPointRecordsCount();
179
 
    detail::write_n(m_ofs, n4, sizeof(n4));
180
 
 
181
 
    // 20. Number of points by return
182
 
    std::vector<uint32_t>::size_type const srbyr = 5;
183
 
    std::vector<uint32_t> const& vpbr = header.GetPointRecordsByReturnCount();
184
 
    assert(vpbr.size() <= srbyr);
185
 
    uint32_t pbr[srbyr] = { 0 };
186
 
    std::copy(vpbr.begin(), vpbr.end(), pbr);
187
 
    detail::write_n(m_ofs, pbr, sizeof(pbr));
188
 
 
189
 
    // 21-23. Scale factors
190
 
    detail::write_n(m_ofs, header.GetScaleX(), sizeof(double));
191
 
    detail::write_n(m_ofs, header.GetScaleY(), sizeof(double));
192
 
    detail::write_n(m_ofs, header.GetScaleZ(), sizeof(double));
193
 
 
194
 
    // 24-26. Offsets
195
 
    detail::write_n(m_ofs, header.GetOffsetX(), sizeof(double));
196
 
    detail::write_n(m_ofs, header.GetOffsetY(), sizeof(double));
197
 
    detail::write_n(m_ofs, header.GetOffsetZ(), sizeof(double));
198
 
 
199
 
    // 27-28. Max/Min X
200
 
    detail::write_n(m_ofs, header.GetMaxX(), sizeof(double));
201
 
    detail::write_n(m_ofs, header.GetMinX(), sizeof(double));
202
 
 
203
 
    // 29-30. Max/Min Y
204
 
    detail::write_n(m_ofs, header.GetMaxY(), sizeof(double));
205
 
    detail::write_n(m_ofs, header.GetMinY(), sizeof(double));
206
 
 
207
 
    // 31-32. Max/Min Z
208
 
    detail::write_n(m_ofs, header.GetMaxZ(), sizeof(double));
209
 
    detail::write_n(m_ofs, header.GetMinZ(), sizeof(double));
210
 
    
211
 
    // If WriteVLR returns a value, it is because the header's 
212
 
    // offset is not large enough to contain the VLRs.  The value 
213
 
    // it returns is the number of bytes we must increase the header
214
 
    // by in order for it to contain the VLRs.
215
 
    int32_t difference = WriteVLR(header);
216
 
    if (difference < 0) {
217
 
        header.SetDataOffset(header.GetDataOffset() + abs(difference) );
218
 
        WriteVLR(header);
219
 
 
220
 
        // Make sure to rewrite the dataoffset in the header portion now that
221
 
        // we've changed it.
222
 
        std::streamsize const current_pos = m_ofs.tellp();
223
 
        std::streamsize const offset_pos = 96; 
224
 
        m_ofs.seekp(offset_pos, std::ios::beg);
225
 
        detail::write_n(m_ofs, header.GetDataOffset() , sizeof(header.GetDataOffset()));
226
 
        m_ofs.seekp(current_pos, std::ios::beg);        
227
 
    }
228
 
 
229
 
    // If we already have points, we're going to put it at the end of the file.  
230
 
    // If we don't have any points,  we're going to leave it where it is.
231
 
    if (m_pointCount != 0)
232
 
        m_ofs.seekp(0, std::ios::end);
233
 
}
234
 
 
235
 
void WriterImpl::UpdateHeader(LASHeader const& header)
236
 
{
237
 
    if (m_pointCount != header.GetPointRecordsCount())
238
 
    {
239
 
        // Skip to first byte of number of point records data member
240
 
        std::streamsize const dataPos = 107; 
241
 
        m_ofs.seekp(dataPos, std::ios::beg);
242
 
 
243
 
        detail::write_n(m_ofs, m_pointCount , sizeof(m_pointCount));
244
 
    }
245
 
}
246
 
 
247
 
void WriterImpl::WritePointRecord(LASPoint const& point, const LASHeader& header)
248
 
{
249
 
    // TODO: Static assert would be better
250
 
    
251
 
    double t = 0;
252
 
    assert(LASHeader::ePointSize0 == sizeof(m_record));
253
 
    Writer::FillPointRecord(m_record, point, header);
254
 
    detail::write_n(m_ofs, m_record, sizeof(m_record));
255
 
 
256
 
    if (header.GetDataFormatId() == LASHeader::ePointFormat1) {
257
 
        t = point.GetTime();
258
 
        detail::write_n(m_ofs, t, sizeof(double));
259
 
    }
260
 
    ++m_pointCount;
261
 
}
262
 
 
263
 
}}} // namespace liblas::detail::v11
264