~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to frmts/pcidsk/sdk/segment/cpcidskrpcmodel.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
87
87
 
88
88
CPCIDSKRPCModelSegment::CPCIDSKRPCModelSegment(PCIDSKFile *file, int segment,const char *segment_pointer) :
89
89
    CPCIDSKSegment(file, segment, segment_pointer), pimpl_(new CPCIDSKRPCModelSegment::PCIDSKRPCInfo), 
90
 
    loaded_(false)
 
90
    loaded_(false),mbModified(false)
91
91
{
92
92
    Load();
93
93
}
108
108
    
109
109
    assert(data_size - 1024 == 7 * 512);
110
110
    
111
 
    pimpl_->seg_data.SetSize(data_size - 1024); // should be 7 * 512
 
111
    pimpl_->seg_data.SetSize((int) (data_size - 1024)); // should be 7 * 512
112
112
    
113
113
    ReadFromFile(pimpl_->seg_data.buffer, 0, data_size - 1024);
114
114
    
124
124
    // Bytes 30-35: 'SENSOR'
125
125
    // Bytes    36: Sensor Name (NULL terminated)
126
126
    
127
 
    if (std::strncmp(pimpl_->seg_data.buffer, "RFMODEL ", 8)) {
 
127
    if (std::strncmp(pimpl_->seg_data.buffer, "RFMODEL ", 8)) 
 
128
    {
 
129
        pimpl_->seg_data.Put("RFMODEL",0,8);
 
130
        pimpl_->userrpc = false;
 
131
        pimpl_->adjusted = false;
 
132
        pimpl_->seg_data.Put("DS",22,2);
 
133
        pimpl_->downsample = 1;
 
134
        pimpl_->seg_data.Put("SENSOR",30,6);
 
135
        pimpl_->num_coeffs = 20;
 
136
        loaded_ = true;
 
137
        return;
128
138
        // Something has gone terribly wrong!
129
 
        throw PCIDSKException("A segment that was previously identified as an RFMODEL "
 
139
        /*throw PCIDSKException("A segment that was previously identified as an RFMODEL "
130
140
            "segment does not contain the appropriate data. Found: [%s]", 
131
 
            std::string(pimpl_->seg_data.buffer, 8).c_str());
 
141
            std::string(pimpl_->seg_data.buffer, 8).c_str());*/
132
142
    }
133
143
    
134
144
    // Determine if this is user-provided
135
 
    pimpl_->userrpc = pimpl_->seg_data.buffer[8] == 0 ? true : false;
 
145
    pimpl_->userrpc = pimpl_->seg_data.buffer[8] == '1' ? true : false;
136
146
    
137
147
    // Check for the DS characters
138
148
    pimpl_->downsample = 1;
139
 
    if (!std::strncmp(&pimpl_->seg_data.buffer[22], "DS", 2)) {
 
149
    if (!std::strncmp(&pimpl_->seg_data.buffer[22], "DS", 2)) 
 
150
    {
140
151
        // Read the downsample factor
141
152
        pimpl_->downsample = pimpl_->seg_data.GetInt(24, 3);
142
153
    }
143
154
    
144
 
    // I don't know what 2ND means yet.
 
155
    //This is requiered if writting with PCIDSKIO 
 
156
    //and reading with GDBIO (probably because of legacy issue)
 
157
    // see Bugzilla 255 and 254.
 
158
    bool bSecond = false;
 
159
    if (!std::strncmp(&pimpl_->seg_data.buffer[27], "2ND", 3)) 
 
160
    {
 
161
        bSecond = true;
 
162
    }
145
163
    
146
164
    // Sensor name:
147
165
    if (!std::strncmp(&pimpl_->seg_data.buffer[30], "SENSOR", 6)) {
166
184
    // Bytes 222-243: line scale
167
185
    // Bytes 244-375: Adjusted X coefficients (5 * 22 bytes)
168
186
    // Bytes 376-507: Adjusted Y coefficients (5 * 22 bytes)
169
 
    
170
 
    pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 4);
171
 
    
172
 
    if (pimpl_->num_coeffs * 22 > 512) {
173
 
        // this segment is malformed. Throw an exception.
174
 
        throw PCIDSKException("RFMODEL segment coefficient count requires more "
175
 
            "than one block to store. There is an error in this segment. The "
176
 
            "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
177
 
    }
178
 
    
179
 
    pimpl_->lines = pimpl_->seg_data.GetInt(512 + 4, 10);
180
 
    pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 14, 10);
181
 
    pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 24, 22);
182
 
    pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 46, 22);
183
 
    pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 68, 22);
184
 
    pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 90, 22);
185
 
    pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 112, 22);
186
 
    pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 134, 22);
187
 
    pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 156, 22);
188
 
    pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 178, 22);
189
 
    pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 200, 22);
190
 
    pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 222, 22);
191
 
    
192
 
    // Read in adjusted X coefficients
193
 
    for (unsigned int i = 0; i <= 5; i++) {
194
 
        double tmp = pimpl_->seg_data.GetDouble(512 + 244 + (i * 22), 22);
195
 
        pimpl_->x_adj.push_back(tmp);
196
 
    }
197
 
    
198
 
    // Read in adjusted Y coefficients
199
 
    for (unsigned int i = 0; i <= 5; i++) {
200
 
        double tmp = pimpl_->seg_data.GetDouble(512 + 376 + (i * 22), 22);
201
 
        pimpl_->y_adj.push_back(tmp);
 
187
    // if bSecond is false, then the coefficient are stored
 
188
    // at others positions
 
189
    // every value takes 22 bytes.
 
190
    
 
191
    if(bSecond)
 
192
    {
 
193
        pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 4);
 
194
 
 
195
        if (pimpl_->num_coeffs * 22 > 512) {
 
196
            // this segment is malformed. Throw an exception.
 
197
            throw PCIDSKException("RFMODEL segment coefficient count requires more "
 
198
                "than one block to store. There is an error in this segment. The "
 
199
                "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
 
200
        }
 
201
 
 
202
        pimpl_->lines = pimpl_->seg_data.GetInt(512 + 4, 10);
 
203
        pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 14, 10);
 
204
        pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 24, 22);
 
205
        pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 46, 22);
 
206
        pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 68, 22);
 
207
        pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 90, 22);
 
208
        pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 112, 22);
 
209
        pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 134, 22);
 
210
        pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 156, 22);
 
211
        pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 178, 22);
 
212
        pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 200, 22);
 
213
        pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 222, 22);
 
214
 
 
215
        pimpl_->adjusted = false;
 
216
        // Read in adjusted X coefficients
 
217
        for (unsigned int i = 0; i <= 5; i++) 
 
218
        {
 
219
            double tmp = pimpl_->seg_data.GetDouble(512 + 244 + (i * 22), 22);
 
220
            pimpl_->x_adj.push_back(tmp);
 
221
            if (0.0 != tmp)
 
222
            {
 
223
                pimpl_->adjusted = true;
 
224
            }
 
225
        }
 
226
 
 
227
        // Read in adjusted Y coefficients
 
228
        for (unsigned int i = 0; i <= 5; i++) 
 
229
        {
 
230
            double tmp = pimpl_->seg_data.GetDouble(512 + 376 + (i * 22), 22);
 
231
            pimpl_->y_adj.push_back(tmp);
 
232
            if (0.0 != tmp)
 
233
            {
 
234
                pimpl_->adjusted = true;
 
235
            }
 
236
        }
 
237
    }
 
238
    else
 
239
    {
 
240
        pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 22);
 
241
 
 
242
        if (pimpl_->num_coeffs * 22 > 512) {
 
243
            // this segment is malformed. Throw an exception.
 
244
            throw PCIDSKException("RFMODEL segment coefficient count requires more "
 
245
                "than one block to store. There is an error in this segment. The "
 
246
                "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
 
247
        }
 
248
 
 
249
        pimpl_->lines = pimpl_->seg_data.GetInt(512 + 22, 22);
 
250
        pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 2*22,22);
 
251
        pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 3*22, 22);
 
252
        pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 4*22, 22);
 
253
        pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 5*22, 22);
 
254
        pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 6*22, 22);
 
255
        pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 7*22, 22);
 
256
        pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 8*22, 22);
 
257
        pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 9*22, 22);
 
258
        pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 10*22, 22);
 
259
        pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 11*22, 22);
 
260
        pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 12*22, 22);
 
261
 
 
262
        pimpl_->adjusted = false;
 
263
        // Read in adjusted X coefficients
 
264
        for (unsigned int i = 0; i <= 3; i++) 
 
265
        {
 
266
            double tmp = pimpl_->seg_data.GetDouble(512 + 12*22 + (i * 22), 22);
 
267
            pimpl_->x_adj.push_back(tmp);
 
268
            if (0.0 != tmp)
 
269
            {
 
270
                pimpl_->adjusted = true;
 
271
            }
 
272
        }
 
273
        pimpl_->x_adj.push_back(0.0);
 
274
        pimpl_->x_adj.push_back(0.0);
 
275
        pimpl_->x_adj.push_back(0.0);
 
276
 
 
277
        // Read in adjusted Y coefficients
 
278
        for (unsigned int i = 0; i <= 3; i++) 
 
279
        {
 
280
            double tmp = pimpl_->seg_data.GetDouble(512 + 16*22 + (i * 22), 22);
 
281
            pimpl_->y_adj.push_back(tmp);
 
282
            if (0.0 != tmp)
 
283
            {
 
284
                pimpl_->adjusted = true;
 
285
            }
 
286
        }
 
287
        pimpl_->y_adj.push_back(0.0);
 
288
        pimpl_->y_adj.push_back(0.0);
 
289
        pimpl_->y_adj.push_back(0.0);
202
290
    }
203
291
    
204
292
    // Block 3:
242
330
 
243
331
void CPCIDSKRPCModelSegment::Write(void)
244
332
{
245
 
    
 
333
    //We are not writing if nothing was loaded.
 
334
    if (!loaded_) {
 
335
        return;
 
336
    }
 
337
      
 
338
    // The RPC Model Segment is defined as follows:
 
339
    // RFMODEL Segment: 7 512-byte blocks
 
340
    
 
341
    // Block 1:
 
342
    // Bytes   0-7: 'RFMODEL '
 
343
    // Byte      8: User Provided RPC (1: user-provided, 0: computed from GCPs)
 
344
    // Bytes 22-23: 'DS' 
 
345
    // Bytes 24-26: Downsample factor used during Epipolar Generation
 
346
    // Bytes 27-29: '2ND' -- no clue what this means
 
347
    // Bytes 30-35: 'SENSOR'
 
348
    // Bytes    36: Sensor Name (NULL terminated)
 
349
    pimpl_->seg_data.Put("RFMODEL",0,8);
 
350
    
 
351
    // Determine if this is user-provided
 
352
    pimpl_->seg_data.buffer[8] = pimpl_->userrpc ? '1' : '0';
 
353
    
 
354
    // Check for the DS characters
 
355
    pimpl_->seg_data.Put("DS",22,2);
 
356
    pimpl_->seg_data.Put(pimpl_->downsample,24,3);
 
357
 
 
358
    //This is requiered if writting with PCIDSKIO 
 
359
    //and reading with GDBIO (probably because of legacy issue)
 
360
    // see Bugzilla 255 and 254.
 
361
    pimpl_->seg_data.Put("2ND",27,3);
 
362
 
 
363
    // Sensor name:
 
364
    pimpl_->seg_data.Put("SENSOR",30,6);
 
365
    pimpl_->seg_data.Put(pimpl_->sensor_name.c_str(),36,pimpl_->sensor_name.size());
 
366
  
 
367
    // Block 2:
 
368
    // Bytes     0-3: Number of coefficients
 
369
    // Bytes    4-13: Number of pixels
 
370
    // Bytes   14-23: Number of lines
 
371
    // Bytes   24-45: Longitude offset
 
372
    // Bytes   46-67: Longitude scale
 
373
    // Bytes   68-89: Latitude Offset
 
374
    // Bytes  90-111: Latitude Scale
 
375
    // Bytes 112-133: Height offset
 
376
    // Bytes 134-155: Height scale
 
377
    // Bytes 156-177: Sample offset
 
378
    // Bytes 178-199: Sample scale
 
379
    // Bytes 200-221: Line offset
 
380
    // Bytes 222-243: line scale
 
381
    // Bytes 244-375: Adjusted X coefficients (5 * 22 bytes)
 
382
    // Bytes 376-507: Adjusted Y coefficients (5 * 22 bytes)
 
383
 
 
384
    if (pimpl_->num_coeffs * 22 > 512) {
 
385
        // this segment is malformed. Throw an exception.
 
386
        throw PCIDSKException("RFMODEL segment coefficient count requires more "
 
387
            "than one block to store. There is an error in this segment. The "
 
388
            "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
 
389
    }
 
390
    
 
391
    pimpl_->seg_data.Put(pimpl_->num_coeffs,512, 4);
 
392
    
 
393
    pimpl_->seg_data.Put(pimpl_->lines,512 + 4, 10);
 
394
    pimpl_->seg_data.Put(pimpl_->pixels,512 + 14, 10);
 
395
    pimpl_->seg_data.Put(pimpl_->x_off,512 + 24, 22,"%22.14f");
 
396
    pimpl_->seg_data.Put(pimpl_->x_scale,512 + 46, 22,"%22.14f");
 
397
    pimpl_->seg_data.Put(pimpl_->y_off,512 + 68, 22,"%22.14f");
 
398
    pimpl_->seg_data.Put(pimpl_->y_scale,512 + 90, 22,"%22.14f");
 
399
    pimpl_->seg_data.Put(pimpl_->z_off,512 + 112, 22,"%22.14f");
 
400
    pimpl_->seg_data.Put(pimpl_->z_scale,512 + 134, 22,"%22.14f");
 
401
    pimpl_->seg_data.Put(pimpl_->pix_off,512 + 156, 22,"%22.14f");
 
402
    pimpl_->seg_data.Put(pimpl_->pix_scale,512 + 178, 22,"%22.14f");
 
403
    pimpl_->seg_data.Put(pimpl_->line_off,512 + 200, 22,"%22.14f");
 
404
    pimpl_->seg_data.Put(pimpl_->line_scale,512 + 222, 22,"%22.14f");
 
405
    
 
406
    // Read in adjusted X coefficients
 
407
    for (unsigned int i = 0; i <= 5; i++) 
 
408
    {
 
409
        pimpl_->seg_data.Put(pimpl_->x_adj[i],512 + 244 + (i * 22), 22,"%22.14f");
 
410
        if(pimpl_->x_adj[i] != 0.0)
 
411
        {
 
412
            pimpl_->adjusted = true;
 
413
        }
 
414
    }
 
415
    
 
416
    // Read in adjusted Y coefficients
 
417
    for (unsigned int i = 0; i <= 5; i++) 
 
418
    {
 
419
        pimpl_->seg_data.Put(pimpl_->y_adj[i],512 + 376 + (i * 22), 22,"%22.14f");
 
420
        if(pimpl_->y_adj[i] != 0.0)
 
421
        {
 
422
            pimpl_->adjusted = true;
 
423
        }
 
424
    }
 
425
    
 
426
    // Block 3:
 
427
    // Block 3 contains the numerator coefficients for the pixel rational polynomial
 
428
    // Number of Coefficients * 22 bytes
 
429
    for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
 
430
    {
 
431
        pimpl_->seg_data.Put(pimpl_->pixel_num[i],2 * 512 + (i * 22), 22,"%22.14f");
 
432
    }
 
433
    
 
434
    // Block 4:
 
435
    // Block 4 contains the denominator coefficients for the pixel rational polynomial
 
436
    // Number of Coefficients * 22 bytes
 
437
    for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
 
438
    {
 
439
        pimpl_->seg_data.Put(pimpl_->pixel_denom[i],3 * 512 + (i * 22), 22,"%22.14f");
 
440
    }
 
441
    
 
442
    // Block 5:
 
443
    // Block 5 contains the numerator coefficients for the line rational polynomial
 
444
    // Number of Coefficients * 22 bytes
 
445
    for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
 
446
    {
 
447
        pimpl_->seg_data.Put(pimpl_->line_num[i],4 * 512 + (i * 22), 22,"%22.14f");
 
448
    }
 
449
    
 
450
    // Block 6:
 
451
    // Block 6 contains the denominator coefficients for the line rational polynomial
 
452
    // Number of Coefficients * 22 bytes
 
453
    for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
 
454
    {
 
455
        pimpl_->seg_data.Put(pimpl_->line_denom[i],5 * 512 + (i * 22), 22,"%22.14f");
 
456
    }
 
457
    
 
458
    // Block 7:
 
459
    // Bytes    0-15: MapUnits string
 
460
    // Bytes 256-511: ProjInfo_t, serialized
 
461
    pimpl_->seg_data.Put(pimpl_->map_units.c_str(),6 * 512, 16);
 
462
   
 
463
    WriteToFile(pimpl_->seg_data.buffer,0,data_size-1024);
 
464
    mbModified = false;
246
465
}
247
466
 
248
467
std::vector<double> CPCIDSKRPCModelSegment::GetXNumerator(void) const
280
499
    pimpl_->pixel_denom = xdenom;   
281
500
    pimpl_->line_num = ynum;
282
501
    pimpl_->line_denom = ydenom;
 
502
    mbModified = true;
283
503
}
284
504
    
285
505
// Get the RPC offset/scale Coefficients
326
546
    pimpl_->line_off = lineoffset;
327
547
    pimpl_->line_scale = linescale;
328
548
 
 
549
    mbModified = true;
329
550
}
330
551
 
331
552
// Get the adjusted X values
346
567
{
347
568
    if (xcoord.size() != 6 || ycoord.size() != 6) {
348
569
        throw PCIDSKException("X and Y adjusted coordinates must have "
349
 
            "length 5.");
 
570
            "length 6.");
350
571
    }
351
572
    
352
573
    pimpl_->x_adj = xcoord;
353
574
    pimpl_->y_adj = ycoord;
 
575
 
 
576
    mbModified = true;
354
577
}
355
578
 
356
579
// Get whether or not this is a user-generated RPC model
363
586
void CPCIDSKRPCModelSegment::SetUserGenerated(bool usergen)
364
587
{
365
588
    pimpl_->userrpc = usergen;
 
589
    mbModified = true;
366
590
}
367
591
 
368
592
// Get whether the model has been adjusted
375
599
void CPCIDSKRPCModelSegment::SetIsNominalModel(bool nominal)
376
600
{
377
601
    pimpl_->adjusted = !nominal;
 
602
    mbModified = true;
378
603
}
379
604
 
380
605
// Get sensor name
387
612
void CPCIDSKRPCModelSegment::SetSensorName(const std::string& name)
388
613
{
389
614
    pimpl_->sensor_name = name;
 
615
    mbModified = true;
390
616
}
391
617
 
392
618
// Output projection information of RPC Model
404
630
            "16 characters to be valid.");
405
631
    }
406
632
    pimpl_->map_units = geosys;
 
633
    mbModified = true;
407
634
}
408
635
 
409
636
// Get number of lines
425
652
    
426
653
    pimpl_->lines = lines;
427
654
    pimpl_->pixels = pixels;
428
 
}
 
655
    mbModified = true;
 
656
}
 
657
 
 
658
void CPCIDSKRPCModelSegment::SetDownsample(const unsigned int downsample)
 
659
{
 
660
    if (downsample == 0) {
 
661
        throw PCIDSKException("Invalid downsample factor provided: %u", downsample);
 
662
    }
 
663
    
 
664
    pimpl_->downsample = downsample;
 
665
    mbModified = true;
 
666
}
 
667
 
 
668
unsigned int CPCIDSKRPCModelSegment::GetDownsample(void) const
 
669
{
 
670
    return pimpl_->downsample;
 
671
}
 
672
 
 
673
void CPCIDSKRPCModelSegment::Synchronize()
 
674
{
 
675
    if(mbModified)
 
676
    {
 
677
        this->Write();
 
678
    }
 
679
}
 
680