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 : * SPDX-License-Identifier: MIT
10 : ****************************************************************************/
11 :
12 : #include "pcidsk_poly.h"
13 : #include "segment/cpcidsksegment.h"
14 : #include "core/pcidsk_utils.h"
15 : #include "pcidsk_exception.h"
16 : #include "segment/cpcidskpolymodel.h"
17 :
18 : #include <vector>
19 : #include <string>
20 : #include <cassert>
21 : #include <cstring>
22 :
23 : using namespace PCIDSK;
24 :
25 0 : CPCIDSKPolyModelSegment::CPCIDSKPolyModelSegment(PCIDSKFile *fileIn,
26 : int segmentIn,
27 0 : const char *segment_pointer) :
28 : CPCIDSKSegment(fileIn, segmentIn, segment_pointer),
29 0 : pimpl_(new CPCIDSKPolyModelSegment::PCIDSKPolyInfo),
30 0 : loaded_(false),mbModified(false)
31 : {
32 0 : Load();
33 0 : }
34 :
35 :
36 0 : CPCIDSKPolyModelSegment::~CPCIDSKPolyModelSegment()
37 : {
38 0 : delete pimpl_;
39 0 : }
40 :
41 : // Load the contents of the segment
42 0 : void CPCIDSKPolyModelSegment::Load()
43 : {
44 : // Check if we've already loaded the segment into memory
45 0 : if (loaded_) {
46 0 : return;
47 : }
48 :
49 0 : if (data_size - 1024 != 7 * 512)
50 0 : return ThrowPCIDSKException("Corrupted poly model?");
51 :
52 0 : pimpl_->seg_data.SetSize((int)(data_size - 1024)); // should be 7 * 512
53 :
54 0 : ReadFromFile(pimpl_->seg_data.buffer, 0, data_size - 1024);
55 :
56 : // The Polynomial Model Segment is defined as follows:
57 : // Polynomial Segment: 7 512-byte blocks
58 :
59 : // Block 1:
60 : // Bytes 0-7: 'POLYMDL '
61 0 : if (std::strncmp(pimpl_->seg_data.buffer, "POLYMDL ", 8))
62 : {
63 0 : pimpl_->seg_data.Put("POLYMDL ",0,8);
64 0 : return;
65 : // Something has gone terribly wrong!
66 : /*throw PCIDSKException("A segment that was previously identified as an RFMODEL "
67 : "segment does not contain the appropriate data. Found: [%s]",
68 : std::string(pimpl_->seg_data.buffer, 8).c_str());*/
69 : }
70 :
71 : // Block 2: number of coefficient and size
72 : // Bytes 0-21: number of coefficients
73 : // Bytes 22-41: number of pixels
74 : // Bytes 42-61: number of lines
75 0 : pimpl_->nNumCoeffs = pimpl_->seg_data.GetInt(512, 22);
76 0 : pimpl_->nPixels = pimpl_->seg_data.GetInt(512 + 22, 22);
77 0 : pimpl_->nLines = pimpl_->seg_data.GetInt(512 + 44, 22);
78 :
79 0 : int i=0;
80 : // Block 3: Forward Coefficients (Geo2Img)
81 : // Each coefficient take 22 Bytes
82 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
83 : {
84 0 : pimpl_->vdfX1.push_back(pimpl_->seg_data.GetDouble(2*512 + (i*22), 22));
85 : }
86 :
87 : // Block 4: Forward Coefficients (Geo2Img)
88 : // Each coefficient take 22 Bytes
89 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
90 : {
91 0 : pimpl_->vdfY1.push_back(pimpl_->seg_data.GetDouble(3*512 + (i*22), 22));
92 : }
93 :
94 : // Block 5: Backward Coefficients Img2Geo
95 : // Each coefficient take 22 Bytes
96 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
97 : {
98 0 : pimpl_->vdfX2.push_back(pimpl_->seg_data.GetDouble(4*512 + (i*22), 22));
99 : }
100 :
101 : // Block 6: Backward Coefficients Img2Geo
102 : // Each coefficient take 22 Bytes
103 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
104 : {
105 0 : pimpl_->vdfY2.push_back(pimpl_->seg_data.GetDouble(5*512 + (i*22), 22));
106 : }
107 :
108 : // Block 7: Required projection
109 : // Bytes 0-16: The map units
110 : // Bytes 17-511: the proj param info.
111 0 : pimpl_->oMapUnit = pimpl_->seg_data.Get(6*512,17);
112 0 : for(i=0 ; i < 19 ; i++)
113 : {
114 0 : pimpl_->oProjectionInfo.push_back(pimpl_->seg_data.GetDouble(6*512+17+i*26,26));
115 : }
116 :
117 : // We've now loaded the structure up with data. Mark it as being loaded
118 : // properly.
119 0 : loaded_ = true;
120 : }
121 :
122 0 : void CPCIDSKPolyModelSegment::Write(void)
123 : {
124 : //We are not writing if nothing was loaded.
125 0 : if (!loaded_) {
126 0 : return;
127 : }
128 :
129 : // Block 1:
130 : // Bytes 0-7: 'POLYMDL '
131 0 : pimpl_->seg_data.Put("POLYMDL ",0,8);
132 :
133 : // Block 2: number of coefficient and size
134 : // Bytes 0-21: number of coefficients
135 : // Bytes 22-41: number of pixels
136 : // Bytes 42-61: number of lines
137 0 : pimpl_->seg_data.Put(pimpl_->nNumCoeffs,512, 22);
138 0 : pimpl_->seg_data.Put(pimpl_->nPixels,512 + 22, 22);
139 0 : pimpl_->seg_data.Put(pimpl_->nLines,512 + 44, 22);
140 :
141 0 : int i=0;
142 0 : assert(pimpl_->vdfX1.size() == pimpl_->nNumCoeffs);
143 0 : assert(pimpl_->vdfX2.size() == pimpl_->nNumCoeffs);
144 0 : assert(pimpl_->vdfY1.size() == pimpl_->nNumCoeffs);
145 0 : assert(pimpl_->vdfY2.size() == pimpl_->nNumCoeffs);
146 : // Block 3: Forward Coefficients (Geo2Img)
147 : // Each coefficient take 22 Bytes
148 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
149 : {
150 0 : pimpl_->seg_data.Put(pimpl_->vdfX1[i],2*512 + (i*22), 22,"%20.14f");
151 : }
152 :
153 : // Block 4: Forward Coefficients (Geo2Img)
154 : // Each coefficient take 22 Bytes
155 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
156 : {
157 0 : pimpl_->seg_data.Put(pimpl_->vdfY1[i],3*512 + (i*22), 22,"%20.14f");
158 : }
159 :
160 : // Block 5: Forward Coefficients (Geo2Img)
161 : // Each coefficient take 22 Bytes
162 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
163 : {
164 0 : pimpl_->seg_data.Put(pimpl_->vdfX2[i],4*512 + (i*22), 22,"%20.14f");
165 : }
166 :
167 : // Block 6: Forward Coefficients (Geo2Img)
168 : // Each coefficient take 22 Bytes
169 0 : for(i=0 ; i < (int)pimpl_->nNumCoeffs ; i++)
170 : {
171 0 : pimpl_->seg_data.Put(pimpl_->vdfY2[i],5*512 + (i*22), 22,"%20.14f");
172 : }
173 :
174 0 : assert(pimpl_->oMapUnit.size() <= 17);
175 0 : assert(pimpl_->oProjectionInfo.size() <= 512-17-1);
176 : // Block 7: Required projection
177 : // Bytes 0-16: The map units
178 : // Bytes 17-511: the proj param info.
179 0 : pimpl_->seg_data.Put(" \0",6*512,17);
180 0 : pimpl_->seg_data.Put(pimpl_->oMapUnit.c_str(),6*512,(int)pimpl_->oMapUnit.size());
181 : //19 because (511-17)/26 = 19 (26 is the size of one value)
182 0 : for(i=0 ; i < 19 ; i++)
183 : {
184 0 : pimpl_->seg_data.Put(pimpl_->oProjectionInfo[i],6*512+17+(i*26),26,"%20.14f");
185 : }
186 :
187 0 : WriteToFile(pimpl_->seg_data.buffer,0,data_size-1024);
188 0 : mbModified = false;
189 : }
190 :
191 0 : std::vector<double> CPCIDSKPolyModelSegment::GetXForwardCoefficients() const
192 : {
193 0 : return pimpl_->vdfX1;
194 : }
195 :
196 0 : std::vector<double> CPCIDSKPolyModelSegment::GetYForwardCoefficients() const
197 : {
198 0 : return pimpl_->vdfY1;
199 : }
200 :
201 0 : std::vector<double> CPCIDSKPolyModelSegment::GetXBackwardCoefficients() const
202 : {
203 0 : return pimpl_->vdfX2;
204 : }
205 :
206 0 : std::vector<double> CPCIDSKPolyModelSegment::GetYBackwardCoefficients() const
207 : {
208 0 : return pimpl_->vdfY2;
209 : }
210 :
211 0 : void CPCIDSKPolyModelSegment::SetCoefficients(const std::vector<double>& oXForward,
212 : const std::vector<double>& oYForward,
213 : const std::vector<double>& oXBackward,
214 : const std::vector<double>& oYBackward)
215 : {
216 0 : assert(oXForward.size() == oYForward.size());
217 0 : assert(oYForward.size() == oXBackward.size());
218 0 : assert(oXBackward.size() == oYBackward.size());
219 0 : pimpl_->vdfX1 = oXForward;
220 0 : pimpl_->vdfY1 = oYForward;
221 0 : pimpl_->vdfX2 = oXBackward;
222 0 : pimpl_->vdfY2 = oYBackward;
223 0 : pimpl_->nNumCoeffs = (unsigned int)oXForward.size();
224 0 : }
225 :
226 0 : unsigned int CPCIDSKPolyModelSegment::GetPixels() const
227 : {
228 0 : return pimpl_->nPixels;
229 : }
230 :
231 0 : unsigned int CPCIDSKPolyModelSegment::GetLines() const
232 : {
233 0 : return pimpl_->nLines;
234 : }
235 :
236 0 : void CPCIDSKPolyModelSegment::SetRasterSize(unsigned int nLines,unsigned int nPixels)
237 : {
238 0 : pimpl_->nPixels = nPixels;
239 0 : pimpl_->nLines = nLines;
240 0 : }
241 :
242 0 : std::string CPCIDSKPolyModelSegment::GetGeosysString() const
243 : {
244 0 : return pimpl_->oMapUnit;
245 : }
246 :
247 0 : void CPCIDSKPolyModelSegment::SetGeosysString(const std::string& oGeosys)
248 : {
249 0 : pimpl_->oMapUnit = oGeosys;
250 0 : }
251 :
252 0 : std::vector<double> CPCIDSKPolyModelSegment::GetProjParamInfo() const
253 : {
254 0 : return pimpl_->oProjectionInfo;
255 : }
256 :
257 0 : void CPCIDSKPolyModelSegment::SetProjParamInfo(const std::vector<double>& oInfo)
258 : {
259 0 : pimpl_->oProjectionInfo = oInfo;
260 0 : while(pimpl_->oProjectionInfo.size() < 19)
261 : {
262 0 : pimpl_->oProjectionInfo.push_back(0.0);
263 : }
264 0 : }
265 :
266 0 : void CPCIDSKPolyModelSegment::Synchronize()
267 : {
268 0 : if(mbModified)
269 : {
270 0 : this->Write();
271 : }
272 0 : }
273 :
|