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

Generated by: LCOV version 1.14