LCOV - code coverage report
Current view: directory - frmts/msgn - msg_basic_types.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 96 0 0.0 %
Date: 2010-01-09 Functions: 12 0 0.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: msg_basic_types.cpp 17686 2009-09-25 13:35:11Z dron $
       3                 :  *
       4                 :  * Project:  MSG Native Reader
       5                 :  * Purpose:  Basic types implementation.
       6                 :  * Author:   Frans van den Bergh, fvdbergh@csir.co.za
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2005, Frans van den Bergh <fvdbergh@csir.co.za>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "msg_basic_types.h"
      31                 : #include "cpl_port.h"
      32                 : 
      33                 : CPL_CVSID("$Id: msg_basic_types.cpp 17686 2009-09-25 13:35:11Z dron $");
      34                 : 
      35                 : #include <stdio.h>
      36                 : 
      37                 : namespace msg_native_format {
      38                 : 
      39                 : #ifndef SQR 
      40                 : #define SQR(x) ((x)*(x))
      41                 : #endif
      42                 : 
      43                 : // endian conversion routines
      44               0 : void to_native(GP_PK_HEADER& h) {
      45               0 :     h.sourceSUId    = CPL_MSBWORD32(h.sourceSUId);
      46               0 :     h.sequenceCount = CPL_MSBWORD16(h.sequenceCount);
      47               0 :     h.packetLength  = CPL_MSBWORD32(h.packetLength);
      48               0 : }
      49                 : 
      50               0 : void to_native(GP_PK_SH1& h) {
      51               0 :     h.spacecraftId  = CPL_MSBWORD16(h.spacecraftId);
      52               0 : }
      53                 : 
      54               0 : void to_native(SUB_VISIRLINE& v) {
      55               0 :     v.satelliteId   = CPL_MSBWORD16(v.satelliteId);
      56               0 :     v.lineNumberInVisirGrid = CPL_MSBWORD32(v.lineNumberInVisirGrid);
      57               0 : }
      58                 : 
      59               0 : static void swap_64_bits(unsigned char* b) {
      60               0 :     for (int i=0; i < 4; i++) {
      61               0 :         unsigned char t = b[i];
      62               0 :         b[i] = b[7-i];
      63               0 :         b[7-i] = t;
      64                 :     }
      65               0 : }
      66                 : 
      67               0 : void to_native(RADIOMETRIC_PROCCESSING_RECORD& r) {
      68               0 :     for (int i=0; i < 12; i++) {
      69               0 :         swap_64_bits((unsigned char*)&r.level1_5ImageCalibration[i].cal_slope);
      70               0 :         swap_64_bits((unsigned char*)&r.level1_5ImageCalibration[i].cal_offset);
      71                 :     }
      72               0 : }
      73                 : 
      74               0 : void to_native(IMAGE_DESCRIPTION_RECORD& r) {
      75               0 :     r.referencegrid_visir.numberOfLines = CPL_MSBWORD32(r.referencegrid_visir.numberOfLines);
      76               0 :     r.referencegrid_visir.numberOfColumns = CPL_MSBWORD32(r.referencegrid_visir.numberOfColumns);
      77                 :     // should floats be swapped too?
      78                 :     unsigned int t;
      79                 :     
      80                 :     // convert float using CPL_MSBWORD32
      81               0 :     t = *(unsigned int *)&r.referencegrid_visir.lineDirGridStep;
      82               0 :     t = CPL_MSBWORD32(t);
      83               0 :     r.referencegrid_visir.lineDirGridStep = *(float *)&t;
      84                 :     
      85                 :     // convert float using CPL_MSBWORD32
      86               0 :     t = *(unsigned int *)&r.referencegrid_visir.columnDirGridStep;
      87               0 :     t = CPL_MSBWORD32(t);
      88               0 :     r.referencegrid_visir.columnDirGridStep = *(float *)&t;
      89               0 : }
      90                 : 
      91               0 : void to_string(PH_DATA& d) {
      92               0 :     d.name[29] = 0;
      93               0 :     d.value[49] = 0;
      94               0 : }
      95                 : 
      96                 : // unit tests on structures
      97               0 : bool perform_type_size_check(void) {
      98               0 :     bool success = true;
      99                 :     if (sizeof(MAIN_PROD_HEADER) != 3674) {
     100                 :         fprintf(stderr, "MAIN_PROD_HEADER size not 3674 (%lu)\n", (unsigned long)sizeof(MAIN_PROD_HEADER));
     101                 :         success = false;
     102                 :     }
     103                 :     if (sizeof(SECONDARY_PROD_HEADER) != 1120) {
     104                 :         fprintf(stderr, "SECONDARY_PROD_HEADER size not 1120 (%lu)\n", (unsigned long)sizeof(SECONDARY_PROD_HEADER));
     105                 :         success = false;
     106                 :     }
     107                 :     if (sizeof(SUB_VISIRLINE) != 27) {
     108                 :         fprintf(stderr, "SUB_VISIRLINE size not 17 (%lu)\n", (unsigned long)sizeof(SUB_VISIRLINE));
     109                 :         success = false;
     110                 :     }
     111                 :     if (sizeof(GP_PK_HEADER) != 22) {
     112                 :         fprintf(stderr, "GP_PK_HEADER size not 22 (%lu)\n", (unsigned long)sizeof(GP_PK_HEADER));
     113                 :         success = false;
     114                 :     }
     115                 :     if (sizeof(GP_PK_SH1) != 16) {
     116                 :         fprintf(stderr, "GP_PK_SH1 size not 16 (%lu)\n", (unsigned long)sizeof(GP_PK_SH1));
     117                 :         success = false;
     118                 :     }
     119               0 :     return success;
     120                 : }
     121                 : 
     122                 : const double Conversions::altitude      =   42164;          // from origin
     123                 : const double Conversions::req           =   6378.1690;       // earthequatorial radius
     124                 : const double Conversions::rpol          =   6356.5838;       // earth polar radius
     125                 : const double Conversions::oblate        =   1.0/298.257;    // oblateness of earth
     126                 : const double Conversions::deg_to_rad    =   M_PI/180.0; 
     127                 : const double Conversions::rad_to_deg    =   180.0/M_PI; 
     128                 : const double Conversions::nlines        =   3712;           // number of lines in an image
     129                 : const double Conversions::step          =   17.83/nlines;    // pixel / line step in degrees
     130                 : 
     131                 : const int Conversions::CFAC    = -781648343;
     132                 : const int Conversions::LFAC    = -781648343;
     133                 : const int Conversions::COFF    = 1856;
     134                 : const int Conversions::LOFF    = 1856;
     135                 : 
     136                 : #define SQR(x) ((x)*(x))
     137                 : 
     138               0 : void Conversions::convert_pixel_to_geo(double line, double column, double&longitude, double& latitude) {
     139               0 :     double x = (column - COFF - 0.0) / double(CFAC >> 16);
     140               0 :     double y = (line - LOFF - 0.0) / double(LFAC >> 16);
     141                 :     
     142               0 :     double sd = sqrt(SQR(altitude*cos(x)*cos(y)) - (SQR(cos(y)) + 1.006803*SQR(sin(y)))*1737121856); 
     143               0 :     double sn = (altitude*cos(x)*cos(y) - sd)/(SQR(cos(y)) + 1.006803*SQR(sin(y)));
     144               0 :     double s1 = altitude - sn*cos(x)*cos(y);
     145               0 :     double s2 = sn*sin(x)*cos(y);
     146               0 :     double s3 = -sn*sin(y);
     147               0 :     double sxy = sqrt(s1*s1 + s2*s2);
     148                 :     
     149               0 :     longitude = atan(s2/s1);
     150               0 :     latitude  = atan(1.006803*s3/sxy);
     151                 :     
     152               0 :     longitude = longitude / M_PI * 180.0;
     153               0 :     latitude  = latitude  / M_PI * 180.0;
     154               0 : }
     155                 : 
     156               0 : void Conversions::compute_pixel_xyz(double line, double column, double& x,double& y, double& z) {
     157               0 :     double asamp = -(column - (nlines/2.0 + 0.5)) * step;
     158               0 :     double aline = (line - (nlines/2.0 + 0.5)) * step;
     159                 :     
     160               0 :     asamp *= deg_to_rad;
     161               0 :     aline *= deg_to_rad;
     162                 :     
     163               0 :     double tanal = tan(aline);
     164               0 :     double tanas = tan(asamp);
     165                 :     
     166               0 :     double p = -1;
     167               0 :     double q = tanas;
     168               0 :     double r = tanal * sqrt(1 + q*q);
     169                 :     
     170               0 :    double a = q*q + (r*req/rpol)*(r*req/rpol) + p*p;
     171               0 :     double b = 2 * altitude * p;
     172               0 :     double c = altitude * altitude  - req*req;
     173                 :     
     174               0 :     double det = b*b - 4*a*c;
     175                 :      
     176               0 :     if (det > 0) {
     177               0 :         double k = (-b - sqrt(det))/(2*a);
     178               0 :         x = altitude + k*p;
     179               0 :         y = k * q;
     180               0 :         z = k * r;
     181                 :         
     182                 :     } else {
     183               0 :         fprintf(stderr, "Warning: pixel not visible\n");
     184                 :     }
     185               0 : }
     186                 : 
     187               0 : double Conversions::compute_pixel_area_sqkm(double line, double column) {
     188                 :     double x1, x2;
     189                 :     double y1, y2;
     190                 :     double z1, z2;
     191                 : 
     192               0 :     compute_pixel_xyz(line-0.5, column-0.5, x1, y1, z1);
     193               0 :     compute_pixel_xyz(line+0.5, column-0.5, x2, y2, z2);
     194                 :     
     195               0 :     double xlen = sqrt(SQR(x1 - x2) + SQR(y1 - y2) + SQR(z1 - z2));
     196                 :     
     197               0 :     compute_pixel_xyz(line-0.5, column+0.5, x2, y2, z2);
     198                 :     
     199               0 :     double ylen = sqrt(SQR(x1 - x2) + SQR(y1 - y2) + SQR(z1 - z2));
     200                 :     
     201               0 :     return xlen*ylen;
     202                 : }
     203                 : 
     204               0 : void Conversions::convert_geo_to_pixel(double longitude, double latitude,unsigned int& line, unsigned int& column) {
     205                 : 
     206               0 :     latitude = latitude / 180.0 * M_PI;
     207               0 :     longitude = longitude / 180.8 * M_PI;
     208                 : 
     209               0 :     double c_lat = atan(0.993243 * tan(latitude));
     210               0 :     double r_l = rpol / sqrt(1 - 0.00675701*cos(c_lat)*cos(c_lat));
     211               0 :     double r1 = altitude - r_l*cos(c_lat)*cos(longitude);
     212               0 :     double r2 = -r_l*cos(c_lat)*sin(longitude);
     213               0 :     double r3 = r_l*sin(c_lat);
     214               0 :     double rn = sqrt(r1*r1 + r2*r2 + r3*r3);
     215                 :     
     216               0 :     double x = atan(-r2/r1) * (CFAC >> 16) + COFF;
     217               0 :     double y = asin(-r3/rn) * (LFAC >> 16) + LOFF;
     218                 :     
     219               0 :     line = (unsigned int)floor(x + 0.5);
     220               0 :     column = (unsigned int)floor(y + 0.5);
     221               0 : }
     222                 : 
     223                 : } // namespace msg_native_format
     224                 : 
     225                 : 

Generated by: LCOV version 1.7