LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/segment - cpcidskrpcmodel.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 275 0.0 %
Date: 2024-11-21 22:18:42 Functions: 0 31 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Purpose:  Implementation of the CPCIDSKRPCModelSegment 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_rpc.h"
      13             : #include "segment/cpcidsksegment.h"
      14             : #include "core/pcidsk_utils.h"
      15             : #include "pcidsk_exception.h"
      16             : #include "segment/cpcidskrpcmodel.h"
      17             : 
      18             : #include <vector>
      19             : #include <string>
      20             : #include <cassert>
      21             : #include <cstring>
      22             : 
      23             : using namespace PCIDSK;
      24             : 
      25           0 : CPCIDSKRPCModelSegment::CPCIDSKRPCModelSegment(PCIDSKFile *fileIn, int segmentIn,const char *segment_pointer) :
      26           0 :     CPCIDSKSegment(fileIn, segmentIn, segment_pointer), pimpl_(new CPCIDSKRPCModelSegment::PCIDSKRPCInfo),
      27           0 :     loaded_(false),mbModified(false),mbEmpty(false)
      28             : {
      29             :     try
      30             :     {
      31           0 :         Load();
      32             :     }
      33           0 :     catch( const PCIDSKException& )
      34             :     {
      35           0 :         delete pimpl_;
      36           0 :         pimpl_ = nullptr;
      37           0 :         throw;
      38             :     }
      39           0 : }
      40             : 
      41             : 
      42           0 : CPCIDSKRPCModelSegment::~CPCIDSKRPCModelSegment()
      43             : {
      44           0 :     delete pimpl_;
      45           0 : }
      46             : 
      47             : // Load the contents of the segment
      48           0 : void CPCIDSKRPCModelSegment::Load()
      49             : {
      50             :     // Check if we've already loaded the segment into memory
      51           0 :     if (loaded_) {
      52           0 :         return;
      53             :     }
      54             : 
      55           0 :     if(data_size == 1024)
      56             :     {
      57           0 :         mbEmpty = true;
      58           0 :         return;
      59             :     }
      60             : 
      61           0 :     mbEmpty = false;
      62             : 
      63           0 :     if( data_size != 1024 + 7 * 512 )
      64             :     {
      65           0 :         return ThrowPCIDSKException("Wrong data_size in CPCIDSKRPCModelSegment");
      66             :     }
      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 RPC Model Segment is defined as follows:
      73             :     // RFMODEL Segment: 7 512-byte blocks
      74             : 
      75             :     // Block 1:
      76             :     // Bytes   0-7: 'RFMODEL '
      77             :     // Byte      8: User Provided RPC (1: user-provided, 0: computed from GCPs)
      78             :     // Bytes 22-23: 'DS'
      79             :     // Bytes 24-26: Downsample factor used during Epipolar Generation
      80             :     // Bytes 27-29: '2ND' -- no clue what this means
      81             :     // Bytes 30-35: 'SENSOR'
      82             :     // Bytes    36: Sensor Name (NULL terminated)
      83             : 
      84           0 :     if (!STARTS_WITH(pimpl_->seg_data.buffer, "RFMODEL "))
      85             :     {
      86           0 :         pimpl_->seg_data.Put("RFMODEL",0,8);
      87           0 :         pimpl_->userrpc = false;
      88           0 :         pimpl_->adjusted = false;
      89           0 :         pimpl_->seg_data.Put("DS",22,2);
      90           0 :         pimpl_->downsample = 1;
      91           0 :         pimpl_->seg_data.Put("SENSOR",30,6);
      92           0 :         pimpl_->num_coeffs = 20;
      93           0 :         loaded_ = true;
      94           0 :         return;
      95             :         // Something has gone terribly wrong!
      96             :         /*throw PCIDSKException("A segment that was previously identified as an RFMODEL "
      97             :             "segment does not contain the appropriate data. Found: [%s]",
      98             :             std::string(pimpl_->seg_data.buffer, 8).c_str());*/
      99             :     }
     100             : 
     101             :     // Determine if this is user-provided
     102           0 :     pimpl_->userrpc = pimpl_->seg_data.buffer[8] == '1' ? true : false;
     103             : 
     104             :     // Check for the DS characters
     105           0 :     pimpl_->downsample = 1;
     106           0 :     if (STARTS_WITH(&pimpl_->seg_data.buffer[22], "DS"))
     107             :     {
     108             :         // Read the downsample factor
     109           0 :         pimpl_->downsample = pimpl_->seg_data.GetInt(24, 3);
     110             :     }
     111             : 
     112             :     //This is required if writing with PCIDSKIO
     113             :     //and reading with GDBIO (probably because of legacy issue)
     114             :     // see Bugzilla 255 and 254.
     115           0 :     bool bSecond = false;
     116           0 :     if (STARTS_WITH(&pimpl_->seg_data.buffer[27], "2ND"))
     117             :     {
     118           0 :         bSecond = true;
     119             :     }
     120             : 
     121             :     // Sensor name:
     122           0 :     if (STARTS_WITH(&pimpl_->seg_data.buffer[30], "SENSOR")) {
     123           0 :         pimpl_->sensor_name = std::string(&pimpl_->seg_data.buffer[36]);
     124             :     } else {
     125           0 :         pimpl_->sensor_name = "";
     126             :     }
     127             : 
     128             :     // Block 2:
     129             :     // Bytes     0-3: Number of coefficients
     130             :     // Bytes    4-13: Number of pixels
     131             :     // Bytes   14-23: Number of lines
     132             :     // Bytes   24-45: Longitude offset
     133             :     // Bytes   46-67: Longitude scale
     134             :     // Bytes   68-89: Latitude Offset
     135             :     // Bytes  90-111: Latitude Scale
     136             :     // Bytes 112-133: Height offset
     137             :     // Bytes 134-155: Height scale
     138             :     // Bytes 156-177: Sample offset
     139             :     // Bytes 178-199: Sample scale
     140             :     // Bytes 200-221: Line offset
     141             :     // Bytes 222-243: line scale
     142             :     // Bytes 244-375: Adjusted X coefficients (5 * 22 bytes)
     143             :     // Bytes 376-507: Adjusted Y coefficients (5 * 22 bytes)
     144             :     // if bSecond is false, then the coefficient are stored
     145             :     // at others positions
     146             :     // every value takes 22 bytes.
     147             : 
     148           0 :     if(bSecond)
     149             :     {
     150           0 :         pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 4);
     151             : 
     152           0 :         if (pimpl_->num_coeffs * 22 > 512) {
     153             :             // this segment is malformed. Throw an exception.
     154           0 :             return ThrowPCIDSKException("RFMODEL segment coefficient count requires more "
     155             :                 "than one block to store. There is an error in this segment. The "
     156           0 :                 "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
     157             :         }
     158             : 
     159           0 :         pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 4, 10);
     160           0 :         pimpl_->lines = pimpl_->seg_data.GetInt(512 + 14, 10);
     161           0 :         pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 24, 22);
     162           0 :         pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 46, 22);
     163           0 :         pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 68, 22);
     164           0 :         pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 90, 22);
     165           0 :         pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 112, 22);
     166           0 :         pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 134, 22);
     167           0 :         pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 156, 22);
     168           0 :         pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 178, 22);
     169           0 :         pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 200, 22);
     170           0 :         pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 222, 22);
     171             : 
     172           0 :         pimpl_->adjusted = false;
     173             :         // Read in adjusted X coefficients
     174           0 :         for (unsigned int i = 0; i <= 5; i++)
     175             :         {
     176           0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 244 + (i * 22), 22);
     177           0 :             pimpl_->x_adj.push_back(tmp);
     178           0 :             if (0.0 != tmp)
     179             :             {
     180           0 :                 pimpl_->adjusted = true;
     181             :             }
     182             :         }
     183             : 
     184             :         // Read in adjusted Y coefficients
     185           0 :         for (unsigned int i = 0; i <= 5; i++)
     186             :         {
     187           0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 376 + (i * 22), 22);
     188           0 :             pimpl_->y_adj.push_back(tmp);
     189           0 :             if (0.0 != tmp)
     190             :             {
     191           0 :                 pimpl_->adjusted = true;
     192             :             }
     193             :         }
     194             :     }
     195             :     else
     196             :     {
     197           0 :         pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 22);
     198             : 
     199           0 :         if (pimpl_->num_coeffs * 22 > 512) {
     200             :             // this segment is malformed. Throw an exception.
     201           0 :             return ThrowPCIDSKException("RFMODEL segment coefficient count requires more "
     202             :                 "than one block to store. There is an error in this segment. The "
     203           0 :                 "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
     204             :         }
     205             : 
     206           0 :         pimpl_->lines = pimpl_->seg_data.GetInt(512 + 22, 22);
     207           0 :         pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 2*22,22);
     208           0 :         pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 3*22, 22);
     209           0 :         pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 4*22, 22);
     210           0 :         pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 5*22, 22);
     211           0 :         pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 6*22, 22);
     212           0 :         pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 7*22, 22);
     213           0 :         pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 8*22, 22);
     214           0 :         pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 9*22, 22);
     215           0 :         pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 10*22, 22);
     216           0 :         pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 11*22, 22);
     217           0 :         pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 12*22, 22);
     218             : 
     219           0 :         pimpl_->adjusted = false;
     220             :         // Read in adjusted X coefficients
     221           0 :         for (unsigned int i = 0; i <= 3; i++)
     222             :         {
     223           0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 12*22 + (i * 22), 22);
     224           0 :             pimpl_->x_adj.push_back(tmp);
     225           0 :             if (0.0 != tmp)
     226             :             {
     227           0 :                 pimpl_->adjusted = true;
     228             :             }
     229             :         }
     230           0 :         pimpl_->x_adj.push_back(0.0);
     231           0 :         pimpl_->x_adj.push_back(0.0);
     232           0 :         pimpl_->x_adj.push_back(0.0);
     233             : 
     234             :         // Read in adjusted Y coefficients
     235           0 :         for (unsigned int i = 0; i <= 3; i++)
     236             :         {
     237           0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 16*22 + (i * 22), 22);
     238           0 :             pimpl_->y_adj.push_back(tmp);
     239           0 :             if (0.0 != tmp)
     240             :             {
     241           0 :                 pimpl_->adjusted = true;
     242             :             }
     243             :         }
     244           0 :         pimpl_->y_adj.push_back(0.0);
     245           0 :         pimpl_->y_adj.push_back(0.0);
     246           0 :         pimpl_->y_adj.push_back(0.0);
     247             :     }
     248             : 
     249             :     // Block 3:
     250             :     // Block 3 contains the numerator coefficients for the pixel rational polynomial
     251             :     // Number of Coefficients * 22 bytes
     252           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     253           0 :         pimpl_->pixel_num.push_back(pimpl_->seg_data.GetDouble(2 * 512 + (i * 22), 22));
     254             :     }
     255             : 
     256             :     // Block 4:
     257             :     // Block 4 contains the denominator coefficients for the pixel rational polynomial
     258             :     // Number of Coefficients * 22 bytes
     259           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     260           0 :         pimpl_->pixel_denom.push_back(pimpl_->seg_data.GetDouble(3 * 512 + (i * 22), 22));
     261             :     }
     262             : 
     263             :     // Block 5:
     264             :     // Block 5 contains the numerator coefficients for the line rational polynomial
     265             :     // Number of Coefficients * 22 bytes
     266           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     267           0 :         pimpl_->line_num.push_back(pimpl_->seg_data.GetDouble(4 * 512 + (i * 22), 22));
     268             :     }
     269             : 
     270             :     // Block 6:
     271             :     // Block 6 contains the denominator coefficients for the line rational polynomial
     272             :     // Number of Coefficients * 22 bytes
     273           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     274           0 :         pimpl_->line_denom.push_back(pimpl_->seg_data.GetDouble(5 * 512 + (i * 22), 22));
     275             :     }
     276             : 
     277             :     // Pad coefficients up to 20
     278           0 :     for (unsigned int i = pimpl_->num_coeffs; i < 20; ++i)
     279             :     {
     280           0 :         pimpl_->pixel_num.push_back(0.0);
     281           0 :         pimpl_->pixel_denom.push_back(0.0);
     282           0 :         pimpl_->line_num.push_back(0.0);
     283           0 :         pimpl_->line_denom.push_back(0.0);
     284             :     }
     285             : 
     286             :     // Block 7:
     287             :     // Bytes    0-15: MapUnits string
     288             :     // Bytes 256-511: ProjInfo_t, serialized
     289           0 :     pimpl_->map_units = std::string(&pimpl_->seg_data.buffer[6 * 512], 16);
     290           0 :     pimpl_->proj_parms = std::string(&pimpl_->seg_data.buffer[6 * 512 + 256], 256);
     291             : 
     292             :     // We've now loaded the structure up with data. Mark it as being loaded
     293             :     // properly.
     294           0 :     loaded_ = true;
     295             : }
     296             : 
     297           0 : void CPCIDSKRPCModelSegment::Write(void)
     298             : {
     299             :     //We are not writing if nothing was loaded.
     300           0 :     if (!loaded_) {
     301           0 :         return;
     302             :     }
     303             : 
     304             :     // The RPC Model Segment is defined as follows:
     305             :     // RFMODEL Segment: 7 512-byte blocks
     306             : 
     307             :     // Block 1:
     308             :     // Bytes   0-7: 'RFMODEL '
     309             :     // Byte      8: User Provided RPC (1: user-provided, 0: computed from GCPs)
     310             :     // Bytes 22-23: 'DS'
     311             :     // Bytes 24-26: Downsample factor used during Epipolar Generation
     312             :     // Bytes 27-29: '2ND' -- no clue what this means
     313             :     // Bytes 30-35: 'SENSOR'
     314             :     // Bytes    36: Sensor Name (NULL terminated)
     315           0 :     pimpl_->seg_data.Put("RFMODEL",0,8);
     316             : 
     317             :     // Determine if this is user-provided
     318           0 :     pimpl_->seg_data.buffer[8] = pimpl_->userrpc ? '1' : '0';
     319             : 
     320             :     // Check for the DS characters
     321           0 :     pimpl_->seg_data.Put("DS",22,2);
     322           0 :     pimpl_->seg_data.Put(pimpl_->downsample,24,3);
     323             : 
     324             :     //This is required if writing with PCIDSKIO
     325             :     //and reading with GDBIO (probably because of legacy issue)
     326             :     // see Bugzilla 255 and 254.
     327           0 :     pimpl_->seg_data.Put("2ND",27,3);
     328             : 
     329             :     // Sensor name:
     330           0 :     pimpl_->seg_data.Put("SENSOR",30,6);
     331           0 :     pimpl_->seg_data.Put(pimpl_->sensor_name.c_str(), 36, static_cast<int>(pimpl_->sensor_name.size()), true);
     332             : 
     333             :     // Block 2:
     334             :     // Bytes     0-3: Number of coefficients
     335             :     // Bytes    4-13: Number of pixels
     336             :     // Bytes   14-23: Number of lines
     337             :     // Bytes   24-45: Longitude offset
     338             :     // Bytes   46-67: Longitude scale
     339             :     // Bytes   68-89: Latitude Offset
     340             :     // Bytes  90-111: Latitude Scale
     341             :     // Bytes 112-133: Height offset
     342             :     // Bytes 134-155: Height scale
     343             :     // Bytes 156-177: Sample offset
     344             :     // Bytes 178-199: Sample scale
     345             :     // Bytes 200-221: Line offset
     346             :     // Bytes 222-243: line scale
     347             :     // Bytes 244-375: Adjusted X coefficients (5 * 22 bytes)
     348             :     // Bytes 376-507: Adjusted Y coefficients (5 * 22 bytes)
     349             : 
     350           0 :     if (pimpl_->num_coeffs * 22 > 512) {
     351             :         // this segment is malformed. Throw an exception.
     352           0 :         return ThrowPCIDSKException("RFMODEL segment coefficient count requires more "
     353             :             "than one block to store. There is an error in this segment. The "
     354           0 :             "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
     355             :     }
     356             : 
     357           0 :     pimpl_->seg_data.Put(pimpl_->num_coeffs,512, 4);
     358             : 
     359           0 :     pimpl_->seg_data.Put(pimpl_->pixels,512 + 4, 10);
     360           0 :     pimpl_->seg_data.Put(pimpl_->lines,512 + 14, 10);
     361           0 :     pimpl_->seg_data.Put(pimpl_->x_off,512 + 24, 22,"%22.14f");
     362           0 :     pimpl_->seg_data.Put(pimpl_->x_scale,512 + 46, 22,"%22.14f");
     363           0 :     pimpl_->seg_data.Put(pimpl_->y_off,512 + 68, 22,"%22.14f");
     364           0 :     pimpl_->seg_data.Put(pimpl_->y_scale,512 + 90, 22,"%22.14f");
     365           0 :     pimpl_->seg_data.Put(pimpl_->z_off,512 + 112, 22,"%22.14f");
     366           0 :     pimpl_->seg_data.Put(pimpl_->z_scale,512 + 134, 22,"%22.14f");
     367           0 :     pimpl_->seg_data.Put(pimpl_->pix_off,512 + 156, 22,"%22.14f");
     368           0 :     pimpl_->seg_data.Put(pimpl_->pix_scale,512 + 178, 22,"%22.14f");
     369           0 :     pimpl_->seg_data.Put(pimpl_->line_off,512 + 200, 22,"%22.14f");
     370           0 :     pimpl_->seg_data.Put(pimpl_->line_scale,512 + 222, 22,"%22.14f");
     371             : 
     372             :     // Read in adjusted X coefficients
     373           0 :     for (unsigned int i = 0; i <= 5; i++)
     374             :     {
     375           0 :         pimpl_->seg_data.Put(pimpl_->x_adj[i],512 + 244 + (i * 22), 22,"%22.14f");
     376           0 :         if(pimpl_->x_adj[i] != 0.0)
     377             :         {
     378           0 :             pimpl_->adjusted = true;
     379             :         }
     380             :     }
     381             : 
     382             :     // Read in adjusted Y coefficients
     383           0 :     for (unsigned int i = 0; i <= 5; i++)
     384             :     {
     385           0 :         pimpl_->seg_data.Put(pimpl_->y_adj[i],512 + 376 + (i * 22), 22,"%22.14f");
     386           0 :         if(pimpl_->y_adj[i] != 0.0)
     387             :         {
     388           0 :             pimpl_->adjusted = true;
     389             :         }
     390             :     }
     391             : 
     392             :     // Block 3:
     393             :     // Block 3 contains the numerator coefficients for the pixel rational polynomial
     394             :     // Number of Coefficients * 22 bytes
     395           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++)
     396             :     {
     397           0 :         pimpl_->seg_data.Put(pimpl_->pixel_num[i],2 * 512 + (i * 22), 22,"%22.14f");
     398             :     }
     399             : 
     400             :     // Block 4:
     401             :     // Block 4 contains the denominator coefficients for the pixel rational polynomial
     402             :     // Number of Coefficients * 22 bytes
     403           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++)
     404             :     {
     405           0 :         pimpl_->seg_data.Put(pimpl_->pixel_denom[i],3 * 512 + (i * 22), 22,"%22.14f");
     406             :     }
     407             : 
     408             :     // Block 5:
     409             :     // Block 5 contains the numerator coefficients for the line rational polynomial
     410             :     // Number of Coefficients * 22 bytes
     411           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++)
     412             :     {
     413           0 :         pimpl_->seg_data.Put(pimpl_->line_num[i],4 * 512 + (i * 22), 22,"%22.14f");
     414             :     }
     415             : 
     416             :     // Block 6:
     417             :     // Block 6 contains the denominator coefficients for the line rational polynomial
     418             :     // Number of Coefficients * 22 bytes
     419           0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++)
     420             :     {
     421           0 :         pimpl_->seg_data.Put(pimpl_->line_denom[i],5 * 512 + (i * 22), 22,"%22.14f");
     422             :     }
     423             : 
     424             :     // Block 7:
     425             :     // Bytes    0-15: MapUnits string
     426             :     // Bytes 256-511: ProjInfo_t, serialized
     427           0 :     pimpl_->seg_data.Put(pimpl_->map_units.c_str(),6 * 512, 16);
     428           0 :     pimpl_->seg_data.Put(pimpl_->proj_parms.c_str(), 6 * 512 + 256, 256);
     429             : 
     430           0 :     WriteToFile(pimpl_->seg_data.buffer,0,data_size-1024);
     431           0 :     mbModified = false;
     432           0 :     mbEmpty = false;
     433             : }
     434             : 
     435           0 : std::vector<double> CPCIDSKRPCModelSegment::GetXNumerator(void) const
     436             : {
     437           0 :     return pimpl_->pixel_num;
     438             : }
     439             : 
     440           0 : std::vector<double> CPCIDSKRPCModelSegment::GetXDenominator(void) const
     441             : {
     442           0 :     return pimpl_->pixel_denom;
     443             : }
     444             : 
     445           0 : std::vector<double> CPCIDSKRPCModelSegment::GetYNumerator(void) const
     446             : {
     447           0 :     return pimpl_->line_num;
     448             : }
     449             : 
     450           0 : std::vector<double> CPCIDSKRPCModelSegment::GetYDenominator(void) const
     451             : {
     452           0 :     return pimpl_->line_denom;
     453             : }
     454             : 
     455             : // Set the RPC Coefficients
     456           0 : void CPCIDSKRPCModelSegment::SetCoefficients(
     457             :     const std::vector<double>& xnum, const std::vector<double>& xdenom,
     458             :     const std::vector<double>& ynum, const std::vector<double>& ydenom)
     459             : {
     460           0 :     if (xnum.size() != xdenom.size() || ynum.size() != ydenom.size() ||
     461           0 :         xnum.size() != ynum.size() || xdenom.size() != ydenom.size()) {
     462           0 :         return ThrowPCIDSKException("All RPC coefficient vectors must be the "
     463           0 :             "same size.");
     464             :     }
     465             : 
     466           0 :     pimpl_->pixel_num = xnum;
     467           0 :     pimpl_->pixel_denom = xdenom;
     468           0 :     pimpl_->line_num = ynum;
     469           0 :     pimpl_->line_denom = ydenom;
     470           0 :     mbModified = true;
     471             : }
     472             : 
     473             : // Get the RPC offset/scale Coefficients
     474           0 : void CPCIDSKRPCModelSegment::GetRPCTranslationCoeffs(double& xoffset, double& xscale,
     475             :     double& yoffset, double& yscale, double& zoffset, double& zscale,
     476             :     double& pixoffset, double& pixscale, double& lineoffset, double& linescale) const
     477             : {
     478           0 :     xoffset = pimpl_->x_off;
     479           0 :     xscale = pimpl_->x_scale;
     480             : 
     481           0 :     yoffset = pimpl_->y_off;
     482           0 :     yscale = pimpl_->y_scale;
     483             : 
     484           0 :     zoffset = pimpl_->z_off;
     485           0 :     zscale = pimpl_->z_scale;
     486             : 
     487           0 :     pixoffset = pimpl_->pix_off;
     488           0 :     pixscale = pimpl_->pix_scale;
     489             : 
     490           0 :     lineoffset = pimpl_->line_off;
     491           0 :     linescale = pimpl_->line_scale;
     492           0 : }
     493             : 
     494             : // Set the RPC offset/scale Coefficients
     495           0 : void CPCIDSKRPCModelSegment::SetRPCTranslationCoeffs(
     496             :     const double xoffset, const double xscale,
     497             :     const double yoffset, const double yscale,
     498             :     const double zoffset, const double zscale,
     499             :     const double pixoffset, const double pixscale,
     500             :     const double lineoffset, const double linescale)
     501             : {
     502           0 :     pimpl_->x_off = xoffset;
     503           0 :     pimpl_->x_scale = xscale;
     504             : 
     505           0 :     pimpl_->y_off = yoffset;
     506           0 :     pimpl_->y_scale = yscale;
     507             : 
     508           0 :     pimpl_->z_off = zoffset;
     509           0 :     pimpl_->z_scale = zscale;
     510             : 
     511           0 :     pimpl_->pix_off = pixoffset;
     512           0 :     pimpl_->pix_scale = pixscale;
     513             : 
     514           0 :     pimpl_->line_off = lineoffset;
     515           0 :     pimpl_->line_scale = linescale;
     516             : 
     517           0 :     mbModified = true;
     518           0 : }
     519             : 
     520             : // Get the adjusted X values
     521           0 : std::vector<double> CPCIDSKRPCModelSegment::GetAdjXValues(void) const
     522             : {
     523           0 :     return pimpl_->x_adj;
     524             : }
     525             : 
     526             : // Get the adjusted Y values
     527           0 : std::vector<double> CPCIDSKRPCModelSegment::GetAdjYValues(void) const
     528             : {
     529           0 :     return pimpl_->y_adj;
     530             : }
     531             : 
     532             : // Set the adjusted X/Y values
     533           0 : void CPCIDSKRPCModelSegment::SetAdjCoordValues(const std::vector<double>& xcoord,
     534             :     const std::vector<double>& ycoord)
     535             : {
     536           0 :     if (xcoord.size() != 6 || ycoord.size() != 6) {
     537           0 :         return ThrowPCIDSKException("X and Y adjusted coordinates must have "
     538           0 :             "length 6.");
     539             :     }
     540             : 
     541           0 :     pimpl_->x_adj = xcoord;
     542           0 :     pimpl_->y_adj = ycoord;
     543             : 
     544           0 :     mbModified = true;
     545             : }
     546             : 
     547             : // Get whether or not this is a user-generated RPC model
     548           0 : bool CPCIDSKRPCModelSegment::IsUserGenerated(void) const
     549             : {
     550           0 :     return pimpl_->userrpc;
     551             : }
     552             : 
     553             : // Set whether or not this is a user-generated RPC model
     554           0 : void CPCIDSKRPCModelSegment::SetUserGenerated(bool usergen)
     555             : {
     556           0 :     pimpl_->userrpc = usergen;
     557           0 :     mbModified = true;
     558           0 : }
     559             : 
     560             : // Get whether the model has been adjusted
     561           0 : bool CPCIDSKRPCModelSegment::IsNominalModel(void) const
     562             : {
     563           0 :     return !pimpl_->adjusted;
     564             : }
     565             : 
     566             : // Set whether the model has been adjusted
     567           0 : void CPCIDSKRPCModelSegment::SetIsNominalModel(bool nominal)
     568             : {
     569           0 :     pimpl_->adjusted = !nominal;
     570           0 :     mbModified = true;
     571           0 : }
     572             : 
     573             : // Get sensor name
     574           0 : std::string CPCIDSKRPCModelSegment::GetSensorName(void) const
     575             : {
     576           0 :     return pimpl_->sensor_name;
     577             : }
     578             : 
     579             : // Set sensor name
     580           0 : void CPCIDSKRPCModelSegment::SetSensorName(const std::string& name)
     581             : {
     582           0 :     pimpl_->sensor_name = name;
     583           0 :     mbModified = true;
     584           0 : }
     585             : 
     586             : /******************************************************************************/
     587             : /*      GetMapUnits()                                                         */
     588             : /******************************************************************************/
     589             : /**
     590             :  * Get output projection information of the RPC math model.
     591             :  *
     592             :  * @param[out] map_units PCI mapunits string
     593             :  * @param[out] proj_parms Additional projection parameters, encoded as a
     594             :  *      string.
     595             :  *
     596             :  * @remarks If false == IsUserGenerated(), then this projection represents
     597             :  *      the projection that is utilized by the RPC's ground-to-image
     598             :  *      coefficients, i.e., the projection that must be used when performing
     599             :  *      ground-to-image or image-to-ground projections with the model.
     600             :  * @remarks If true == IsUserGenerated(), then the RPC math model's projection
     601             :  *      is Geographic WGS84 and the values returned here are just nominal
     602             :  *      values that may be used to generate output products with this model.
     603             :  */
     604             : void
     605           0 : CPCIDSKRPCModelSegment::GetMapUnits(std::string& map_units,
     606             :                                     std::string& proj_parms) const
     607             : {
     608           0 :     map_units = pimpl_->map_units;
     609           0 :     proj_parms = pimpl_->proj_parms;
     610           0 :     return;
     611             : }// GetMapUnits
     612             : 
     613             : 
     614             : /******************************************************************************/
     615             : /*      SetMapUnits()                                                         */
     616             : /******************************************************************************/
     617             : /**
     618             :  * Set output projection information of the RPC math model.
     619             :  *
     620             :  * @param[in] map_units PCI mapunits string
     621             :  * @param[in] proj_parms Additional projection parameters, encoded as a
     622             :  *      string.
     623             :  *
     624             :  * @remarks If false == IsUserGenerated(), then this projection represents
     625             :  *      the projection that is utilized by the RPC's ground-to-image
     626             :  *      coefficients, i.e., the projection that must be used when performing
     627             :  *      ground-to-image or image-to-ground projections with the model.
     628             :  * @remarks If true == IsUserGenerated(), then the RPC math model's projection
     629             :  *      is Geographic WGS84 and the values returned here are just nominal
     630             :  *      values that may be used to generate output products with this model.
     631             :  */
     632             : void
     633           0 : CPCIDSKRPCModelSegment::SetMapUnits(std::string const& map_units,
     634             :                                     std::string const& proj_parms)
     635             : {
     636           0 :     if (map_units.size() > 16)
     637             :     {
     638           0 :         return ThrowPCIDSKException("GeoSys/MapUnits string must be no more than "
     639           0 :             "16 characters to be valid.");
     640             :     }
     641           0 :     if (proj_parms.size() > 256)
     642             :     {
     643           0 :         return ThrowPCIDSKException("GeoSys/Projection parameters string must be no more than "
     644           0 :             "256 characters to be valid.");
     645             :     }
     646           0 :     pimpl_->map_units = map_units;
     647           0 :     pimpl_->proj_parms = proj_parms;
     648           0 :     mbModified = true;
     649             : }
     650             : 
     651             : // Get number of lines
     652           0 : unsigned int CPCIDSKRPCModelSegment::GetLines(void) const
     653             : {
     654           0 :     return pimpl_->lines;
     655             : }
     656             : 
     657           0 : unsigned int CPCIDSKRPCModelSegment::GetPixels(void) const
     658             : {
     659           0 :     return pimpl_->pixels;
     660             : }
     661             : 
     662           0 : void CPCIDSKRPCModelSegment::SetRasterSize(const unsigned int lines, const unsigned int pixels)
     663             : {
     664           0 :     if (lines == 0 || pixels == 0) {
     665           0 :         return ThrowPCIDSKException("Nonsensical raster dimensions provided: %ux%u",
     666           0 :                               lines, pixels);
     667             :     }
     668             : 
     669           0 :     pimpl_->lines = lines;
     670           0 :     pimpl_->pixels = pixels;
     671           0 :     mbModified = true;
     672             : }
     673             : 
     674           0 : void CPCIDSKRPCModelSegment::SetDownsample(const unsigned int downsample)
     675             : {
     676           0 :     if (downsample == 0) {
     677           0 :         return ThrowPCIDSKException("Invalid downsample factor provided: %u", downsample);
     678             :     }
     679             : 
     680           0 :     pimpl_->downsample = downsample;
     681           0 :     mbModified = true;
     682             : }
     683             : 
     684           0 : unsigned int CPCIDSKRPCModelSegment::GetDownsample(void) const
     685             : {
     686           0 :     return pimpl_->downsample;
     687             : }
     688             : 
     689           0 : void CPCIDSKRPCModelSegment::Synchronize()
     690             : {
     691           0 :     if(mbModified)
     692             :     {
     693           0 :         this->Write();
     694             :     }
     695           0 : }

Generated by: LCOV version 1.14