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

« back to all changes in this revision

Viewing changes to src/detail/writer.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 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/writer.hpp>
43
 
#include <liblas/detail/writer10.hpp>
44
 
#include <liblas/detail/writer11.hpp>
45
 
#include <liblas/detail/writer12.hpp>
46
 
#include <liblas/lasheader.hpp>
47
 
#include <liblas/laspoint.hpp>
48
 
#include <liblas/lasspatialreference.hpp>
49
 
 
50
 
#ifdef HAVE_GDAL
51
 
#include <ogr_srs_api.h>
52
 
#endif
53
 
 
54
 
 
55
 
// std
56
 
#include <fstream>
57
 
#include <cassert>
58
 
#include <cstdlib> // std::size_t
59
 
#include <stdexcept>
60
 
 
61
 
namespace liblas { namespace detail {
62
 
 
63
 
Writer::Writer(std::ostream& ofs) : m_ofs(ofs), m_transform(0), m_in_ref(0), m_out_ref(0)
64
 
{
65
 
}
66
 
 
67
 
Writer::~Writer()
68
 
{
69
 
#ifdef HAVE_GDAL
70
 
    if (m_transform) {
71
 
        OCTDestroyCoordinateTransformation(m_transform);
72
 
    }
73
 
    if (m_in_ref) {
74
 
        OSRDestroySpatialReference(m_in_ref);
75
 
    }
76
 
    if (m_out_ref) {
77
 
        OSRDestroySpatialReference(m_out_ref);
78
 
    }
79
 
#endif
80
 
}
81
 
 
82
 
std::ostream& Writer::GetStream() const
83
 
{
84
 
    return m_ofs;
85
 
}
86
 
 
87
 
 
88
 
void Writer::FillPointRecord(PointRecord& record, const LASPoint& point, const LASHeader& header) 
89
 
{
90
 
    if (m_transform) {
91
 
        // let's just copy the point for now.
92
 
        LASPoint p = LASPoint(point);
93
 
        Project(p);
94
 
        record.x = static_cast<int32_t>((p.GetX() - header.GetOffsetX()) / header.GetScaleX());
95
 
        record.y = static_cast<int32_t>((p.GetY() - header.GetOffsetY()) / header.GetScaleY());
96
 
        record.z = static_cast<int32_t>((p.GetZ() - header.GetOffsetZ()) / header.GetScaleZ());
97
 
    } else {
98
 
        record.x = static_cast<int32_t>((point.GetX() - header.GetOffsetX()) / header.GetScaleX());
99
 
        record.y = static_cast<int32_t>((point.GetY() - header.GetOffsetY()) / header.GetScaleY());
100
 
        record.z = static_cast<int32_t>((point.GetZ() - header.GetOffsetZ()) / header.GetScaleZ());
101
 
    }
102
 
 
103
 
    record.intensity = point.GetIntensity();
104
 
    record.flags = point.GetScanFlags();
105
 
    record.classification = point.GetClassification();
106
 
    record.scan_angle_rank = point.GetScanAngleRank();
107
 
    record.user_data = point.GetUserData();
108
 
    record.point_source_id = point.GetPointSourceID();
109
 
}
110
 
 
111
 
uint32_t Writer::WriteVLR(LASHeader const& header) 
112
 
{
113
 
    // If this function returns a value, it is the size that the header's 
114
 
    // data offset must be increased by in order for the VLRs to fit in 
115
 
    // the header.  
116
 
    m_ofs.seekp(header.GetHeaderSize(), std::ios::beg);
117
 
 
118
 
    // if the VLRs won't fit because the data offset is too 
119
 
    // small, we need to throw an error.
120
 
    uint32_t vlr_total_size = 0;
121
 
        
122
 
    // Calculate a new data offset size
123
 
    for (uint32_t i = 0; i < header.GetRecordsCount(); ++i)
124
 
    {
125
 
        LASVariableRecord vlr = header.GetVLR(i);
126
 
        vlr_total_size += vlr.GetTotalSize();
127
 
    }
128
 
    
129
 
    int32_t difference = header.GetDataOffset() - (vlr_total_size + header.GetHeaderSize());
130
 
 
131
 
    if (difference < 0) 
132
 
    {
133
 
        return difference;
134
 
    }
135
 
    
136
 
    for (uint32_t i = 0; i < header.GetRecordsCount(); ++i)
137
 
    {
138
 
        LASVariableRecord vlr = header.GetVLR(i);
139
 
 
140
 
        detail::write_n(m_ofs, vlr.GetReserved(), sizeof(uint16_t));
141
 
        detail::write_n(m_ofs, vlr.GetUserId(true).c_str(), 16);
142
 
        detail::write_n(m_ofs, vlr.GetRecordId(), sizeof(uint16_t));
143
 
        detail::write_n(m_ofs, vlr.GetRecordLength(), sizeof(uint16_t));
144
 
        detail::write_n(m_ofs, vlr.GetDescription(true).c_str(), 32);
145
 
        std::vector<uint8_t> const& data = vlr.GetData();
146
 
        std::streamsize const size = static_cast<std::streamsize>(data.size());
147
 
        detail::write_n(m_ofs, data.front(), size);
148
 
    }
149
 
    
150
 
    // if we had more room than we need for the VLRs, we need to pad that with 
151
 
    // 0's.  We must also not forget to add the 1.0 pad bytes to the end of this
152
 
    // but the impl should be the one doing that, not us.
153
 
    if (difference > 0) {
154
 
        detail::write_n(m_ofs, "\0", difference);
155
 
    }
156
 
    return 0;
157
 
}
158
 
 
159
 
 
160
 
void Writer::SetSRS(const LASSpatialReference& srs )
161
 
{
162
 
    m_out_srs = srs;
163
 
#ifdef HAVE_GDAL
164
 
    m_in_ref = OSRNewSpatialReference(0);
165
 
    m_out_ref = OSRNewSpatialReference(0);
166
 
 
167
 
    int result = OSRSetFromUserInput(m_in_ref, m_in_srs.GetWKT().c_str());
168
 
    if (result != OGRERR_NONE) 
169
 
    {
170
 
        std::ostringstream msg; 
171
 
        msg << "Could not import input spatial reference for Writer::" << CPLGetLastErrorMsg() << result;
172
 
        std::string message(msg.str());
173
 
        throw std::runtime_error(message);
174
 
    }
175
 
    
176
 
    result = OSRSetFromUserInput(m_out_ref, m_out_srs.GetWKT().c_str());
177
 
    if (result != OGRERR_NONE) 
178
 
    {
179
 
        std::ostringstream msg; 
180
 
        msg << "Could not import output spatial reference for Writer::" << CPLGetLastErrorMsg() << result;
181
 
        std::string message(msg.str());
182
 
        throw std::runtime_error(message);
183
 
    }
184
 
 
185
 
    m_transform = OCTNewCoordinateTransformation( m_in_ref, m_out_ref);
186
 
    
187
 
#endif
188
 
}
189
 
 
190
 
void Writer::Project(LASPoint& p)
191
 
{
192
 
#ifdef HAVE_GDAL
193
 
    
194
 
    int ret = 0;
195
 
    double x = p.GetX();
196
 
    double y = p.GetY();
197
 
    double z = p.GetZ();
198
 
    
199
 
    ret = OCTTransform(m_transform, 1, &x, &y, &z);
200
 
    
201
 
    if (!ret) {
202
 
        std::ostringstream msg; 
203
 
        msg << "Could not project point for Writer::" << CPLGetLastErrorMsg() << ret;
204
 
        std::string message(msg.str());
205
 
        throw std::runtime_error(message);
206
 
    }
207
 
    
208
 
    p.SetX(x);
209
 
    p.SetY(y);
210
 
    p.SetZ(z);
211
 
#else
212
 
    UNREFERENCED_PARAMETER(p);
213
 
#endif
214
 
}
215
 
Writer* WriterFactory::Create(std::ostream& ofs, LASHeader const& header)
216
 
{
217
 
    if (!ofs)
218
 
    {
219
 
        throw std::runtime_error("output stream state is invalid");
220
 
    }
221
 
 
222
 
    // Select writer implementation based on requested LAS version.
223
 
    uint8_t major = header.GetVersionMajor();
224
 
    uint8_t minor = header.GetVersionMinor();
225
 
    
226
 
    if (1 == major && 0 == minor)
227
 
    {
228
 
        return new v10::WriterImpl(ofs);
229
 
    }
230
 
    if (1 == major && 1 == minor)
231
 
    {
232
 
        return new v11::WriterImpl(ofs);
233
 
    }
234
 
    if (1 == major && 2 == minor)
235
 
    {
236
 
        return new v12::WriterImpl(ofs);
237
 
    }
238
 
    else if (2 == major && 0 == minor)
239
 
    {
240
 
        // TODO: LAS 2.0 read/write support
241
 
        throw std::runtime_error("LAS 2.0 file detected but unsupported");
242
 
    }
243
 
 
244
 
    throw std::runtime_error("LAS file of unknown version");
245
 
}
246
 
 
247
 
void WriterFactory::Destroy(Writer* p) 
248
 
{
249
 
    delete p;
250
 
    p = 0;
251
 
}
252
 
 
253
 
}} // namespace liblas::detail