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