Line data Source code
1 : /******************************************************************************
2 : *
3 : * Purpose: Implementation of the CPCIDSKPolyModelSegment class.
4 : *
5 : ******************************************************************************
6 : * Copyright (c) 2009
7 : * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada.
8 : *
9 : * Permission is hereby granted, free of charge, to any person obtaining a
10 : * copy of this software and associated documentation files (the "Software"),
11 : * to deal in the Software without restriction, including without limitation
12 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 : * and/or sell copies of the Software, and to permit persons to whom the
14 : * Software is furnished to do so, subject to the following conditions:
15 : *
16 : * The above copyright notice and this permission notice shall be included
17 : * in all copies or substantial portions of the Software.
18 : *
19 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 : * DEALINGS IN THE SOFTWARE.
26 : ****************************************************************************/
27 :
28 : #include "pcidsk_poly.h"
29 : #include "segment/cpcidsksegment.h"
30 : #include "core/pcidsk_utils.h"
31 : #include "pcidsk_exception.h"
32 : #include "segment/cpcidskpolymodel.h"
33 :
34 : #include <vector>
35 : #include <string>
36 : #include <cassert>
37 : #include <cstring>
38 :
39 : using namespace PCIDSK;
40 :
41 0 : CPCIDSKPolyModelSegment::CPCIDSKPolyModelSegment(PCIDSKFile *fileIn,
42 : int segmentIn,
43 0 : const char *segment_pointer) :
44 : CPCIDSKSegment(fileIn, segmentIn, segment_pointer),
45 0 : pimpl_(new CPCIDSKPolyModelSegment::PCIDSKPolyInfo),
46 0 : loaded_(false),mbModified(false)
47 : {
48 0 : Load();
49 0 : }
50 :
51 :
52 0 : CPCIDSKPolyModelSegment::~CPCIDSKPolyModelSegment()
53 : {
54 0 : delete pimpl_;
55 0 : }
56 :
57 : // Load the contents of the segment
58 0 : void CPCIDSKPolyModelSegment::Load()
59 : {
60 : // Check if we've already loaded the segment into memory
61 0 : if (loaded_) {
62 0 : return;
63 : }
64 :
65 0 : if (data_size - 1024 != 7 * 512)
66 0 : return ThrowPCIDSKException("Corrupted poly model?");
67 :
68 0 : pimpl_->seg_data.SetSize((int)(data_size - 1024)); // should be 7 * 512
69 :
70 0 : ReadFromFile(pimpl_->seg_data.buffer, 0, data_size - 1024);
71 :
72 : // The Polynomial Model Segment is defined as follows:
73 : // Polynomial Segment: 7 512-byte blocks
74 :
75 : // Block 1:
76 : // Bytes 0-7: 'POLYMDL '
77 0 : if (std::strncmp(pimpl_->seg_data.buffer, "POLYMDL ", 8))
78 : {
79 0 : pimpl_->seg_data.Put("POLYMDL ",0,8);
80 0 : return;
81 : // Something has gone terribly wrong!
82 : /*throw PCIDSKException("A segment that was previously identified as an RFMODEL "
83 : "segment does not contain the appropriate data. Found: [%s]",
84 : std::string(pimpl_->seg_data.buffer, 8).c_str());*/
85 : }
86 :
87 : // Block 2: number of coefficient and size
88 : // Bytes 0-21: number of coefficients
89 : // Bytes 22-41: number of pixels
90 : // Bytes 42-61: number of lines
91 0 : pimpl_->nNumCoeffs = pimpl_->seg_data.GetInt(512, 22);
92 0 : pimpl_->nPixels = pimpl_->seg_data.GetInt(512 + 22, 22);
93 0 : pimpl_->nLines = pimpl_->seg_data.GetInt(512 + 44, 22);
94 :
95 0 : int i=0;
96 : // Block 3: Forward Coefficients (Geo2Img)
97 : // Each coefficient take 22 Bytes
98 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
99 : {
100 0 : pimpl_->vdfX1.push_back(pimpl_->seg_data.GetDouble(2*512 + (i*22), 22));
101 : }
102 :
103 : // Block 4: Forward Coefficients (Geo2Img)
104 : // Each coefficient take 22 Bytes
105 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
106 : {
107 0 : pimpl_->vdfY1.push_back(pimpl_->seg_data.GetDouble(3*512 + (i*22), 22));
108 : }
109 :
110 : // Block 5: Backward Coefficients Img2Geo
111 : // Each coefficient take 22 Bytes
112 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
113 : {
114 0 : pimpl_->vdfX2.push_back(pimpl_->seg_data.GetDouble(4*512 + (i*22), 22));
115 : }
116 :
117 : // Block 6: Backward Coefficients Img2Geo
118 : // Each coefficient take 22 Bytes
119 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
120 : {
121 0 : pimpl_->vdfY2.push_back(pimpl_->seg_data.GetDouble(5*512 + (i*22), 22));
122 : }
123 :
124 : // Block 7: Required projection
125 : // Bytes 0-16: The map units
126 : // Bytes 17-511: the proj param info.
127 0 : pimpl_->oMapUnit = pimpl_->seg_data.Get(6*512,17);
128 0 : for(i=0 ; i < 19 ; i++)
129 : {
130 0 : pimpl_->oProjectionInfo.push_back(pimpl_->seg_data.GetDouble(6*512+17+i*26,26));
131 : }
132 :
133 : // We've now loaded the structure up with data. Mark it as being loaded
134 : // properly.
135 0 : loaded_ = true;
136 : }
137 :
138 0 : void CPCIDSKPolyModelSegment::Write(void)
139 : {
140 : //We are not writing if nothing was loaded.
141 0 : if (!loaded_) {
142 0 : return;
143 : }
144 :
145 : // Block 1:
146 : // Bytes 0-7: 'POLYMDL '
147 0 : pimpl_->seg_data.Put("POLYMDL ",0,8);
148 :
149 : // Block 2: number of coefficient and size
150 : // Bytes 0-21: number of coefficients
151 : // Bytes 22-41: number of pixels
152 : // Bytes 42-61: number of lines
153 0 : pimpl_->seg_data.Put(pimpl_->nNumCoeffs,512, 22);
154 0 : pimpl_->seg_data.Put(pimpl_->nPixels,512 + 22, 22);
155 0 : pimpl_->seg_data.Put(pimpl_->nLines,512 + 44, 22);
156 :
157 0 : int i=0;
158 0 : assert(pimpl_->vdfX1.size() == pimpl_->nNumCoeffs);
159 0 : assert(pimpl_->vdfX2.size() == pimpl_->nNumCoeffs);
160 0 : assert(pimpl_->vdfY1.size() == pimpl_->nNumCoeffs);
161 0 : assert(pimpl_->vdfY2.size() == pimpl_->nNumCoeffs);
162 : // Block 3: Forward Coefficients (Geo2Img)
163 : // Each coefficient take 22 Bytes
164 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
165 : {
166 0 : pimpl_->seg_data.Put(pimpl_->vdfX1[i],2*512 + (i*22), 22,"%20.14f");
167 : }
168 :
169 : // Block 4: Forward Coefficients (Geo2Img)
170 : // Each coefficient take 22 Bytes
171 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
172 : {
173 0 : pimpl_->seg_data.Put(pimpl_->vdfY1[i],3*512 + (i*22), 22,"%20.14f");
174 : }
175 :
176 : // Block 5: Forward Coefficients (Geo2Img)
177 : // Each coefficient take 22 Bytes
178 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
179 : {
180 0 : pimpl_->seg_data.Put(pimpl_->vdfX2[i],4*512 + (i*22), 22,"%20.14f");
181 : }
182 :
183 : // Block 6: Forward Coefficients (Geo2Img)
184 : // Each coefficient take 22 Bytes
185 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
186 : {
187 0 : pimpl_->seg_data.Put(pimpl_->vdfY2[i],5*512 + (i*22), 22,"%20.14f");
188 : }
189 :
190 0 : assert(pimpl_->oMapUnit.size() <= 17);
191 0 : assert(pimpl_->oProjectionInfo.size() <= 512-17-1);
192 : // Block 7: Required projection
193 : // Bytes 0-16: The map units
194 : // Bytes 17-511: the proj param info.
195 0 : pimpl_->seg_data.Put(" \0",6*512,17);
196 0 : pimpl_->seg_data.Put(pimpl_->oMapUnit.c_str(),6*512,(int)pimpl_->oMapUnit.size());
197 : //19 because (511-17)/26 = 19 (26 is the size of one value)
198 0 : for(i=0 ; i < 19 ; i++)
199 : {
200 0 : pimpl_->seg_data.Put(pimpl_->oProjectionInfo[i],6*512+17+(i*26),26,"%20.14f");
201 : }
202 :
203 0 : WriteToFile(pimpl_->seg_data.buffer,0,data_size-1024);
204 0 : mbModified = false;
205 : }
206 :
207 0 : std::vector<double> CPCIDSKPolyModelSegment::GetXForwardCoefficients() const
208 : {
209 0 : return pimpl_->vdfX1;
210 : }
211 :
212 0 : std::vector<double> CPCIDSKPolyModelSegment::GetYForwardCoefficients() const
213 : {
214 0 : return pimpl_->vdfY1;
215 : }
216 :
217 0 : std::vector<double> CPCIDSKPolyModelSegment::GetXBackwardCoefficients() const
218 : {
219 0 : return pimpl_->vdfX2;
220 : }
221 :
222 0 : std::vector<double> CPCIDSKPolyModelSegment::GetYBackwardCoefficients() const
223 : {
224 0 : return pimpl_->vdfY2;
225 : }
226 :
227 0 : void CPCIDSKPolyModelSegment::SetCoefficients(const std::vector<double>& oXForward,
228 : const std::vector<double>& oYForward,
229 : const std::vector<double>& oXBackward,
230 : const std::vector<double>& oYBackward)
231 : {
232 0 : assert(oXForward.size() == oYForward.size());
233 0 : assert(oYForward.size() == oXBackward.size());
234 0 : assert(oXBackward.size() == oYBackward.size());
235 0 : pimpl_->vdfX1 = oXForward;
236 0 : pimpl_->vdfY1 = oYForward;
237 0 : pimpl_->vdfX2 = oXBackward;
238 0 : pimpl_->vdfY2 = oYBackward;
239 0 : pimpl_->nNumCoeffs = (unsigned int)oXForward.size();
240 0 : }
241 :
242 0 : unsigned int CPCIDSKPolyModelSegment::GetPixels() const
243 : {
244 0 : return pimpl_->nPixels;
245 : }
246 :
247 0 : unsigned int CPCIDSKPolyModelSegment::GetLines() const
248 : {
249 0 : return pimpl_->nLines;
250 : }
251 :
252 0 : void CPCIDSKPolyModelSegment::SetRasterSize(unsigned int nLines,unsigned int nPixels)
253 : {
254 0 : pimpl_->nPixels = nPixels;
255 0 : pimpl_->nLines = nLines;
256 0 : }
257 :
258 0 : std::string CPCIDSKPolyModelSegment::GetGeosysString() const
259 : {
260 0 : return pimpl_->oMapUnit;
261 : }
262 :
263 0 : void CPCIDSKPolyModelSegment::SetGeosysString(const std::string& oGeosys)
264 : {
265 0 : pimpl_->oMapUnit = oGeosys;
266 0 : }
267 :
268 0 : std::vector<double> CPCIDSKPolyModelSegment::GetProjParamInfo() const
269 : {
270 0 : return pimpl_->oProjectionInfo;
271 : }
272 :
273 0 : void CPCIDSKPolyModelSegment::SetProjParamInfo(const std::vector<double>& oInfo)
274 : {
275 0 : pimpl_->oProjectionInfo = oInfo;
276 0 : while(pimpl_->oProjectionInfo.size() < 19)
277 : {
278 0 : pimpl_->oProjectionInfo.push_back(0.0);
279 : }
280 0 : }
281 :
282 0 : void CPCIDSKPolyModelSegment::Synchronize()
283 : {
284 0 : if(mbModified)
285 : {
286 0 : this->Write();
287 : }
288 0 : }
289 :
|