LCOV - code coverage report
Current view: directory - frmts/pcidsk/sdk/segment - cpcidskrpcmodel.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 249 0 0.0 %
Date: 2012-04-28 Functions: 33 0 0.0 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Implementation of the CPCIDSKRPCModelSegment class.
       4                 :  * 
       5                 :  ******************************************************************************
       6                 :  * Copyright (c) 2009
       7                 :  * PCI Geomatics, 50 West Wilmot Street, Richmond Hill, Ont, Canada
       8                 :  *
       9                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      10                 :  * copy of this software and associated documentation files (the "Software"),
      11                 :  * to deal in the Software without restriction, including without limitation
      12                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      13                 :  * and/or sell copies of the Software, and to permit persons to whom the
      14                 :  * Software is furnished to do so, subject to the following conditions:
      15                 :  *
      16                 :  * The above copyright notice and this permission notice shall be included
      17                 :  * in all copies or substantial portions of the Software.
      18                 :  *
      19                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      20                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      22                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      24                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      25                 :  * DEALINGS IN THE SOFTWARE.
      26                 :  ****************************************************************************/
      27                 : 
      28                 : #include "pcidsk_rpc.h"
      29                 : #include "segment/cpcidsksegment.h"
      30                 : #include "core/pcidsk_utils.h"
      31                 : #include "pcidsk_exception.h"
      32                 : #include "segment/cpcidskrpcmodel.h"
      33                 : 
      34                 : #include <vector>
      35                 : #include <string>
      36                 : #include <cassert>
      37                 : #include <cstring>
      38                 : 
      39                 : using namespace PCIDSK;
      40                 : 
      41                 : // Struct to store details of the RPC model
      42                 : struct CPCIDSKRPCModelSegment::PCIDSKRPCInfo
      43               0 : {
      44                 :     bool userrpc; // whether or not the RPC was generated from GCPs
      45                 :     bool adjusted; // Whether or not the RPC has been adjusted
      46                 :     int downsample; // Epipolar Downsample factor
      47                 :     
      48                 :     unsigned int pixels; // pixels in the image
      49                 :     unsigned int lines; // lines in the image
      50                 :     
      51                 :     unsigned int num_coeffs; // number of coefficientsg
      52                 :     
      53                 :     std::vector<double> pixel_num; // numerator, pixel direction
      54                 :     std::vector<double> pixel_denom; // denominator, pixel direction
      55                 :     std::vector<double> line_num; // numerator, line direction
      56                 :     std::vector<double> line_denom; // denominator, line direction
      57                 :     
      58                 :     // Scale/offset coefficients in the ground domain
      59                 :     double x_off;
      60                 :     double x_scale;
      61                 :     
      62                 :     double y_off;
      63                 :     double y_scale;
      64                 :     
      65                 :     double z_off;
      66                 :     double z_scale;
      67                 :     
      68                 :     // Scale/offset coefficients in the raster domain
      69                 :     double pix_off;
      70                 :     double pix_scale;
      71                 :     
      72                 :     double line_off;
      73                 :     double line_scale;
      74                 :     
      75                 :     std::vector<double> x_adj; // adjusted X values
      76                 :     std::vector<double> y_adj; // adjusted Y values
      77                 :     
      78                 :     std::string sensor_name; // the name of the sensor
      79                 :     
      80                 :     std::string map_units; // the map units string
      81                 :     
      82                 :     // TODO: Projection Info
      83                 :     
      84                 :     // The raw segment data
      85                 :     PCIDSKBuffer seg_data;
      86                 : };
      87                 : 
      88               0 : CPCIDSKRPCModelSegment::CPCIDSKRPCModelSegment(PCIDSKFile *file, int segment,const char *segment_pointer) :
      89                 :     CPCIDSKSegment(file, segment, segment_pointer), pimpl_(new CPCIDSKRPCModelSegment::PCIDSKRPCInfo), 
      90               0 :     loaded_(false),mbModified(false)
      91                 : {
      92               0 :     Load();
      93               0 : }
      94                 : 
      95                 : 
      96               0 : CPCIDSKRPCModelSegment::~CPCIDSKRPCModelSegment()
      97                 : {
      98               0 :     delete pimpl_;
      99               0 : }
     100                 : 
     101                 : // Load the contents of the segment
     102               0 : void CPCIDSKRPCModelSegment::Load()
     103                 : {
     104                 :     // Check if we've already loaded the segment into memory
     105               0 :     if (loaded_) {
     106               0 :         return;
     107                 :     }
     108                 :     
     109               0 :     assert(data_size - 1024 == 7 * 512);
     110                 :     
     111               0 :     pimpl_->seg_data.SetSize((int) (data_size - 1024)); // should be 7 * 512
     112                 :     
     113               0 :     ReadFromFile(pimpl_->seg_data.buffer, 0, data_size - 1024);
     114                 :     
     115                 :     // The RPC Model Segment is defined as follows:
     116                 :     // RFMODEL Segment: 7 512-byte blocks
     117                 :     
     118                 :     // Block 1:
     119                 :     // Bytes   0-7: 'RFMODEL '
     120                 :     // Byte      8: User Provided RPC (1: user-provided, 0: computed from GCPs)
     121                 :     // Bytes 22-23: 'DS' 
     122                 :     // Bytes 24-26: Downsample factor used during Epipolar Generation
     123                 :     // Bytes 27-29: '2ND' -- no clue what this means
     124                 :     // Bytes 30-35: 'SENSOR'
     125                 :     // Bytes    36: Sensor Name (NULL terminated)
     126                 :     
     127               0 :     if (std::strncmp(pimpl_->seg_data.buffer, "RFMODEL ", 8)) 
     128                 :     {
     129               0 :         pimpl_->seg_data.Put("RFMODEL",0,8);
     130               0 :         pimpl_->userrpc = false;
     131               0 :         pimpl_->adjusted = false;
     132               0 :         pimpl_->seg_data.Put("DS",22,2);
     133               0 :         pimpl_->downsample = 1;
     134               0 :         pimpl_->seg_data.Put("SENSOR",30,6);
     135               0 :         pimpl_->num_coeffs = 20;
     136               0 :         loaded_ = true;
     137               0 :         return;
     138                 :         // Something has gone terribly wrong!
     139                 :         /*throw PCIDSKException("A segment that was previously identified as an RFMODEL "
     140                 :             "segment does not contain the appropriate data. Found: [%s]", 
     141                 :             std::string(pimpl_->seg_data.buffer, 8).c_str());*/
     142                 :     }
     143                 :     
     144                 :     // Determine if this is user-provided
     145               0 :     pimpl_->userrpc = pimpl_->seg_data.buffer[8] == '1' ? true : false;
     146                 :     
     147                 :     // Check for the DS characters
     148               0 :     pimpl_->downsample = 1;
     149               0 :     if (!std::strncmp(&pimpl_->seg_data.buffer[22], "DS", 2)) 
     150                 :     {
     151                 :         // Read the downsample factor
     152               0 :         pimpl_->downsample = pimpl_->seg_data.GetInt(24, 3);
     153                 :     }
     154                 :     
     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               0 :     bool bSecond = false;
     159               0 :     if (!std::strncmp(&pimpl_->seg_data.buffer[27], "2ND", 3)) 
     160                 :     {
     161               0 :         bSecond = true;
     162                 :     }
     163                 :     
     164                 :     // Sensor name:
     165               0 :     if (!std::strncmp(&pimpl_->seg_data.buffer[30], "SENSOR", 6)) {
     166               0 :         pimpl_->sensor_name = std::string(&pimpl_->seg_data.buffer[36]);
     167                 :     } else {
     168               0 :         pimpl_->sensor_name = "";
     169                 :     }
     170                 :     
     171                 :     // Block 2:
     172                 :     // Bytes     0-3: Number of coefficients
     173                 :     // Bytes    4-13: Number of pixels
     174                 :     // Bytes   14-23: Number of lines
     175                 :     // Bytes   24-45: Longitude offset
     176                 :     // Bytes   46-67: Longitude scale
     177                 :     // Bytes   68-89: Latitude Offset
     178                 :     // Bytes  90-111: Latitude Scale
     179                 :     // Bytes 112-133: Height offset
     180                 :     // Bytes 134-155: Height scale
     181                 :     // Bytes 156-177: Sample offset
     182                 :     // Bytes 178-199: Sample scale
     183                 :     // Bytes 200-221: Line offset
     184                 :     // Bytes 222-243: line scale
     185                 :     // Bytes 244-375: Adjusted X coefficients (5 * 22 bytes)
     186                 :     // Bytes 376-507: Adjusted Y coefficients (5 * 22 bytes)
     187                 :     // if bSecond is false, then the coefficient are stored
     188                 :     // at others positions
     189                 :     // every value takes 22 bytes.
     190                 :     
     191               0 :     if(bSecond)
     192                 :     {
     193               0 :         pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 4);
     194                 : 
     195               0 :         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               0 :                 "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
     200                 :         }
     201                 : 
     202               0 :         pimpl_->lines = pimpl_->seg_data.GetInt(512 + 4, 10);
     203               0 :         pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 14, 10);
     204               0 :         pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 24, 22);
     205               0 :         pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 46, 22);
     206               0 :         pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 68, 22);
     207               0 :         pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 90, 22);
     208               0 :         pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 112, 22);
     209               0 :         pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 134, 22);
     210               0 :         pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 156, 22);
     211               0 :         pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 178, 22);
     212               0 :         pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 200, 22);
     213               0 :         pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 222, 22);
     214                 : 
     215               0 :         pimpl_->adjusted = false;
     216                 :         // Read in adjusted X coefficients
     217               0 :         for (unsigned int i = 0; i <= 5; i++) 
     218                 :         {
     219               0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 244 + (i * 22), 22);
     220               0 :             pimpl_->x_adj.push_back(tmp);
     221               0 :             if (0.0 != tmp)
     222                 :             {
     223               0 :                 pimpl_->adjusted = true;
     224                 :             }
     225                 :         }
     226                 : 
     227                 :         // Read in adjusted Y coefficients
     228               0 :         for (unsigned int i = 0; i <= 5; i++) 
     229                 :         {
     230               0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 376 + (i * 22), 22);
     231               0 :             pimpl_->y_adj.push_back(tmp);
     232               0 :             if (0.0 != tmp)
     233                 :             {
     234               0 :                 pimpl_->adjusted = true;
     235                 :             }
     236                 :         }
     237                 :     }
     238                 :     else
     239                 :     {
     240               0 :         pimpl_->num_coeffs = pimpl_->seg_data.GetInt(512, 22);
     241                 : 
     242               0 :         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               0 :                 "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
     247                 :         }
     248                 : 
     249               0 :         pimpl_->lines = pimpl_->seg_data.GetInt(512 + 22, 22);
     250               0 :         pimpl_->pixels = pimpl_->seg_data.GetInt(512 + 2*22,22);
     251               0 :         pimpl_->x_off = pimpl_->seg_data.GetDouble(512 + 3*22, 22);
     252               0 :         pimpl_->x_scale = pimpl_->seg_data.GetDouble(512 + 4*22, 22);
     253               0 :         pimpl_->y_off = pimpl_->seg_data.GetDouble(512 + 5*22, 22);
     254               0 :         pimpl_->y_scale = pimpl_->seg_data.GetDouble(512 + 6*22, 22);
     255               0 :         pimpl_->z_off = pimpl_->seg_data.GetDouble(512 + 7*22, 22);
     256               0 :         pimpl_->z_scale = pimpl_->seg_data.GetDouble(512 + 8*22, 22);
     257               0 :         pimpl_->pix_off = pimpl_->seg_data.GetDouble(512 + 9*22, 22);
     258               0 :         pimpl_->pix_scale = pimpl_->seg_data.GetDouble(512 + 10*22, 22);
     259               0 :         pimpl_->line_off = pimpl_->seg_data.GetDouble(512 + 11*22, 22);
     260               0 :         pimpl_->line_scale = pimpl_->seg_data.GetDouble(512 + 12*22, 22);
     261                 : 
     262               0 :         pimpl_->adjusted = false;
     263                 :         // Read in adjusted X coefficients
     264               0 :         for (unsigned int i = 0; i <= 3; i++) 
     265                 :         {
     266               0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 12*22 + (i * 22), 22);
     267               0 :             pimpl_->x_adj.push_back(tmp);
     268               0 :             if (0.0 != tmp)
     269                 :             {
     270               0 :                 pimpl_->adjusted = true;
     271                 :             }
     272                 :         }
     273               0 :         pimpl_->x_adj.push_back(0.0);
     274               0 :         pimpl_->x_adj.push_back(0.0);
     275               0 :         pimpl_->x_adj.push_back(0.0);
     276                 : 
     277                 :         // Read in adjusted Y coefficients
     278               0 :         for (unsigned int i = 0; i <= 3; i++) 
     279                 :         {
     280               0 :             double tmp = pimpl_->seg_data.GetDouble(512 + 16*22 + (i * 22), 22);
     281               0 :             pimpl_->y_adj.push_back(tmp);
     282               0 :             if (0.0 != tmp)
     283                 :             {
     284               0 :                 pimpl_->adjusted = true;
     285                 :             }
     286                 :         }
     287               0 :         pimpl_->y_adj.push_back(0.0);
     288               0 :         pimpl_->y_adj.push_back(0.0);
     289               0 :         pimpl_->y_adj.push_back(0.0);
     290                 :     }
     291                 :     
     292                 :     // Block 3:
     293                 :     // Block 3 contains the numerator coefficients for the pixel rational polynomial
     294                 :     // Number of Coefficients * 22 bytes
     295               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     296               0 :         pimpl_->pixel_num.push_back(pimpl_->seg_data.GetDouble(2 * 512 + (i * 22), 22));
     297                 :     }
     298                 :     
     299                 :     // Block 4:
     300                 :     // Block 4 contains the denominator coefficients for the pixel rational polynomial
     301                 :     // Number of Coefficients * 22 bytes
     302               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     303               0 :         pimpl_->pixel_denom.push_back(pimpl_->seg_data.GetDouble(3 * 512 + (i * 22), 22));
     304                 :     }
     305                 :     
     306                 :     // Block 5:
     307                 :     // Block 5 contains the numerator coefficients for the line rational polynomial
     308                 :     // Number of Coefficients * 22 bytes
     309               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     310               0 :         pimpl_->line_num.push_back(pimpl_->seg_data.GetDouble(4 * 512 + (i * 22), 22));
     311                 :     }
     312                 :     
     313                 :     // Block 6:
     314                 :     // Block 6 contains the denominator coefficients for the line rational polynomial
     315                 :     // Number of Coefficients * 22 bytes
     316               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) {
     317               0 :         pimpl_->line_denom.push_back(pimpl_->seg_data.GetDouble(5 * 512 + (i * 22), 22));
     318                 :     }
     319                 :     
     320                 :     // Block 7:
     321                 :     // Bytes    0-15: MapUnits string
     322                 :     // Bytes 256-511: ProjInfo_t, serialized
     323               0 :     pimpl_->map_units = std::string(&pimpl_->seg_data.buffer[6 * 512], 16);
     324                 :     
     325                 :     // We've now loaded the structure up with data. Mark it as being loaded 
     326                 :     // properly.
     327               0 :     loaded_ = true;
     328                 :     
     329                 : }
     330                 : 
     331               0 : void CPCIDSKRPCModelSegment::Write(void)
     332                 : {
     333                 :     //We are not writing if nothing was loaded.
     334               0 :     if (!loaded_) {
     335               0 :         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               0 :     pimpl_->seg_data.Put("RFMODEL",0,8);
     350                 :     
     351                 :     // Determine if this is user-provided
     352               0 :     pimpl_->seg_data.buffer[8] = pimpl_->userrpc ? '1' : '0';
     353                 :     
     354                 :     // Check for the DS characters
     355               0 :     pimpl_->seg_data.Put("DS",22,2);
     356               0 :     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               0 :     pimpl_->seg_data.Put("2ND",27,3);
     362                 : 
     363                 :     // Sensor name:
     364               0 :     pimpl_->seg_data.Put("SENSOR",30,6);
     365               0 :     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               0 :     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               0 :             "number of coefficients according to the segment is %d.", pimpl_->num_coeffs);
     389                 :     }
     390                 :     
     391               0 :     pimpl_->seg_data.Put(pimpl_->num_coeffs,512, 4);
     392                 :     
     393               0 :     pimpl_->seg_data.Put(pimpl_->lines,512 + 4, 10);
     394               0 :     pimpl_->seg_data.Put(pimpl_->pixels,512 + 14, 10);
     395               0 :     pimpl_->seg_data.Put(pimpl_->x_off,512 + 24, 22,"%22.14f");
     396               0 :     pimpl_->seg_data.Put(pimpl_->x_scale,512 + 46, 22,"%22.14f");
     397               0 :     pimpl_->seg_data.Put(pimpl_->y_off,512 + 68, 22,"%22.14f");
     398               0 :     pimpl_->seg_data.Put(pimpl_->y_scale,512 + 90, 22,"%22.14f");
     399               0 :     pimpl_->seg_data.Put(pimpl_->z_off,512 + 112, 22,"%22.14f");
     400               0 :     pimpl_->seg_data.Put(pimpl_->z_scale,512 + 134, 22,"%22.14f");
     401               0 :     pimpl_->seg_data.Put(pimpl_->pix_off,512 + 156, 22,"%22.14f");
     402               0 :     pimpl_->seg_data.Put(pimpl_->pix_scale,512 + 178, 22,"%22.14f");
     403               0 :     pimpl_->seg_data.Put(pimpl_->line_off,512 + 200, 22,"%22.14f");
     404               0 :     pimpl_->seg_data.Put(pimpl_->line_scale,512 + 222, 22,"%22.14f");
     405                 :     
     406                 :     // Read in adjusted X coefficients
     407               0 :     for (unsigned int i = 0; i <= 5; i++) 
     408                 :     {
     409               0 :         pimpl_->seg_data.Put(pimpl_->x_adj[i],512 + 244 + (i * 22), 22,"%22.14f");
     410               0 :         if(pimpl_->x_adj[i] != 0.0)
     411                 :         {
     412               0 :             pimpl_->adjusted = true;
     413                 :         }
     414                 :     }
     415                 :     
     416                 :     // Read in adjusted Y coefficients
     417               0 :     for (unsigned int i = 0; i <= 5; i++) 
     418                 :     {
     419               0 :         pimpl_->seg_data.Put(pimpl_->y_adj[i],512 + 376 + (i * 22), 22,"%22.14f");
     420               0 :         if(pimpl_->y_adj[i] != 0.0)
     421                 :         {
     422               0 :             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               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
     430                 :     {
     431               0 :         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               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
     438                 :     {
     439               0 :         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               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
     446                 :     {
     447               0 :         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               0 :     for (unsigned int i = 0; i < pimpl_->num_coeffs; i++) 
     454                 :     {
     455               0 :         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               0 :     pimpl_->seg_data.Put(pimpl_->map_units.c_str(),6 * 512, 16);
     462                 :    
     463               0 :     WriteToFile(pimpl_->seg_data.buffer,0,data_size-1024);
     464               0 :     mbModified = false;
     465                 : }
     466                 : 
     467               0 : std::vector<double> CPCIDSKRPCModelSegment::GetXNumerator(void) const
     468                 : {
     469               0 :     return pimpl_->pixel_num;
     470                 : }
     471                 : 
     472               0 : std::vector<double> CPCIDSKRPCModelSegment::GetXDenominator(void) const
     473                 : {
     474               0 :     return pimpl_->pixel_denom;
     475                 : }
     476                 : 
     477               0 : std::vector<double> CPCIDSKRPCModelSegment::GetYNumerator(void) const
     478                 : {
     479               0 :     return pimpl_->line_num;
     480                 : }
     481                 : 
     482               0 : std::vector<double> CPCIDSKRPCModelSegment::GetYDenominator(void) const
     483                 : {
     484               0 :     return pimpl_->line_denom;
     485                 : }
     486                 : 
     487                 : // Set the RPC Coefficients
     488               0 : void CPCIDSKRPCModelSegment::SetCoefficients(
     489                 :     const std::vector<double>& xnum, const std::vector<double>& xdenom,
     490                 :     const std::vector<double>& ynum, const std::vector<double>& ydenom)
     491                 : {
     492               0 :     if (xnum.size() != xdenom.size() || ynum.size() != ydenom.size() ||
     493                 :         xnum.size() != ynum.size() || xdenom.size() != ydenom.size()) {
     494                 :         throw PCIDSKException("All RPC coefficient vectors must be the "
     495               0 :             "same size.");
     496                 :     }
     497                 :     
     498               0 :     pimpl_->pixel_num = xnum;
     499               0 :     pimpl_->pixel_denom = xdenom;   
     500               0 :     pimpl_->line_num = ynum;
     501               0 :     pimpl_->line_denom = ydenom;
     502               0 :     mbModified = true;
     503               0 : }
     504                 :     
     505                 : // Get the RPC offset/scale Coefficients
     506               0 : void CPCIDSKRPCModelSegment::GetRPCTranslationCoeffs(double& xoffset, double& xscale,
     507                 :     double& yoffset, double& yscale, double& zoffset, double& zscale,
     508                 :     double& pixoffset, double& pixscale, double& lineoffset, double& linescale) const
     509                 : {
     510               0 :     xoffset = pimpl_->x_off;
     511               0 :     xscale = pimpl_->x_scale;
     512                 : 
     513               0 :     yoffset = pimpl_->y_off;
     514               0 :     yscale = pimpl_->y_scale;
     515                 :     
     516               0 :     zoffset = pimpl_->z_off;
     517               0 :     zscale = pimpl_->z_scale;
     518                 :     
     519               0 :     pixoffset = pimpl_->pix_off;
     520               0 :     pixscale = pimpl_->pix_scale;
     521                 :     
     522               0 :     lineoffset = pimpl_->line_off;
     523               0 :     linescale = pimpl_->line_scale;
     524               0 : }
     525                 :     
     526                 : // Set the RPC offset/scale Coefficients
     527               0 : void CPCIDSKRPCModelSegment::SetRPCTranslationCoeffs(
     528                 :     const double xoffset, const double xscale,
     529                 :     const double yoffset, const double yscale, 
     530                 :     const double zoffset, const double zscale,
     531                 :     const double pixoffset, const double pixscale, 
     532                 :     const double lineoffset, const double linescale)
     533                 : {
     534               0 :     pimpl_->x_off = xoffset;
     535               0 :     pimpl_->x_scale = xscale;
     536                 :     
     537               0 :     pimpl_->y_off = yoffset;
     538               0 :     pimpl_->y_scale = yscale;
     539                 : 
     540               0 :     pimpl_->z_off = zoffset;
     541               0 :     pimpl_->z_scale = zscale;
     542                 : 
     543               0 :     pimpl_->pix_off = pixoffset;
     544               0 :     pimpl_->pix_scale = pixscale;
     545                 : 
     546               0 :     pimpl_->line_off = lineoffset;
     547               0 :     pimpl_->line_scale = linescale;
     548                 : 
     549               0 :     mbModified = true;
     550               0 : }
     551                 : 
     552                 : // Get the adjusted X values
     553               0 : std::vector<double> CPCIDSKRPCModelSegment::GetAdjXValues(void) const
     554                 : {
     555               0 :     return pimpl_->x_adj;
     556                 : }
     557                 : 
     558                 : // Get the adjusted Y values
     559               0 : std::vector<double> CPCIDSKRPCModelSegment::GetAdjYValues(void) const
     560                 : {
     561               0 :     return pimpl_->y_adj;
     562                 : }
     563                 : 
     564                 : // Set the adjusted X/Y values
     565               0 : void CPCIDSKRPCModelSegment::SetAdjCoordValues(const std::vector<double>& xcoord,
     566                 :     const std::vector<double>& ycoord)
     567                 : {
     568               0 :     if (xcoord.size() != 6 || ycoord.size() != 6) {
     569                 :         throw PCIDSKException("X and Y adjusted coordinates must have "
     570               0 :             "length 6.");
     571                 :     }
     572                 :     
     573               0 :     pimpl_->x_adj = xcoord;
     574               0 :     pimpl_->y_adj = ycoord;
     575                 : 
     576               0 :     mbModified = true;
     577               0 : }
     578                 : 
     579                 : // Get whether or not this is a user-generated RPC model
     580               0 : bool CPCIDSKRPCModelSegment::IsUserGenerated(void) const
     581                 : {
     582               0 :     return pimpl_->userrpc;
     583                 : }
     584                 : 
     585                 : // Set whether or not this is a user-generated RPC model
     586               0 : void CPCIDSKRPCModelSegment::SetUserGenerated(bool usergen)
     587                 : {
     588               0 :     pimpl_->userrpc = usergen;
     589               0 :     mbModified = true;
     590               0 : }
     591                 : 
     592                 : // Get whether the model has been adjusted
     593               0 : bool CPCIDSKRPCModelSegment::IsNominalModel(void) const
     594                 : {
     595               0 :     return !pimpl_->adjusted;
     596                 : }
     597                 : 
     598                 : // Set whether the model has been adjusted
     599               0 : void CPCIDSKRPCModelSegment::SetIsNominalModel(bool nominal)
     600                 : {
     601               0 :     pimpl_->adjusted = !nominal;
     602               0 :     mbModified = true;
     603               0 : }
     604                 : 
     605                 : // Get sensor name
     606               0 : std::string CPCIDSKRPCModelSegment::GetSensorName(void) const
     607                 : {
     608               0 :     return pimpl_->sensor_name;
     609                 : }
     610                 : 
     611                 : // Set sensor name
     612               0 : void CPCIDSKRPCModelSegment::SetSensorName(const std::string& name)
     613                 : {
     614               0 :     pimpl_->sensor_name = name;
     615               0 :     mbModified = true;
     616               0 : }
     617                 : 
     618                 : // Output projection information of RPC Model
     619                 : // Get the Geosys String
     620               0 : std::string CPCIDSKRPCModelSegment::GetGeosysString(void) const
     621                 : {
     622               0 :     return pimpl_->map_units;
     623                 : }
     624                 : 
     625                 : // Set the Geosys string
     626               0 : void CPCIDSKRPCModelSegment::SetGeosysString(const std::string& geosys)
     627                 : {
     628               0 :     if (geosys.size() > 16) {
     629                 :         throw PCIDSKException("GeoSys/MapUnits string must be no more than "
     630               0 :             "16 characters to be valid.");
     631                 :     }
     632               0 :     pimpl_->map_units = geosys;
     633               0 :     mbModified = true;
     634               0 : }
     635                 : 
     636                 : // Get number of lines
     637               0 : unsigned int CPCIDSKRPCModelSegment::GetLines(void) const 
     638                 : {
     639               0 :     return pimpl_->lines;
     640                 : }
     641                 : 
     642               0 : unsigned int CPCIDSKRPCModelSegment::GetPixels(void) const
     643                 : {
     644               0 :     return pimpl_->pixels;
     645                 : }
     646                 : 
     647               0 : void CPCIDSKRPCModelSegment::SetRasterSize(const unsigned int lines, const unsigned int pixels)
     648                 : {
     649               0 :     if (lines == 0 || pixels == 0) {
     650               0 :         throw PCIDSKException("Non-sensical raster dimensions provided: %ux%u", lines, pixels);
     651                 :     }
     652                 :     
     653               0 :     pimpl_->lines = lines;
     654               0 :     pimpl_->pixels = pixels;
     655               0 :     mbModified = true;
     656               0 : }
     657                 : 
     658               0 : void CPCIDSKRPCModelSegment::SetDownsample(const unsigned int downsample)
     659                 : {
     660               0 :     if (downsample == 0) {
     661               0 :         throw PCIDSKException("Invalid downsample factor provided: %u", downsample);
     662                 :     }
     663                 :     
     664               0 :     pimpl_->downsample = downsample;
     665               0 :     mbModified = true;
     666               0 : }
     667                 : 
     668               0 : unsigned int CPCIDSKRPCModelSegment::GetDownsample(void) const
     669                 : {
     670               0 :     return pimpl_->downsample;
     671                 : }
     672                 : 
     673               0 : void CPCIDSKRPCModelSegment::Synchronize()
     674                 : {
     675               0 :     if(mbModified)
     676                 :     {
     677               0 :         this->Write();
     678                 :     }
     679               0 : }
     680                 : 

Generated by: LCOV version 1.7