LCOV - code coverage report
Current view: directory - frmts/dted - dted_create.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 119 104 87.4 %
Date: 2010-01-09 Functions: 3 3 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: dted_create.c 12223 2007-09-21 23:46:17Z rouault $
       3                 :  *
       4                 :  * Project:  DTED Translator
       5                 :  * Purpose:  Implementation of DTEDCreate() portion of DTED API.
       6                 :  * Author:   Frank Warmerdam, warmerdamm@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2001, Frank Warmerdam
      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 "dted_api.h"
      31                 : #include <assert.h>
      32                 : 
      33                 : CPL_CVSID("$Id: dted_create.c 12223 2007-09-21 23:46:17Z rouault $");
      34                 : 
      35                 : #define DTED_ABS_VERT_ACC "NA  "
      36                 : #define DTED_SECURITY     "U"
      37                 : #define DTED_EDITION      1
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                           DTEDFormatDMS()                            */
      41                 : /************************************************************************/
      42                 : 
      43             168 : static void DTEDFormatDMS( unsigned char *achField, double dfAngle, 
      44                 :                            const char *pszLatLong, const char *pszFormat )
      45                 : 
      46                 : {
      47                 :     char        chHemisphere;
      48                 :     char        szWork[128];
      49                 :     int         nDegrees, nMinutes, nSeconds;
      50                 :     double      dfRemainder;
      51                 :     
      52             168 :     if( pszFormat == NULL )
      53              84 :         pszFormat = "%03d%02d%02d%c";
      54                 : 
      55             168 :     assert( EQUAL(pszLatLong,"LAT") || EQUAL(pszLatLong,"LONG") );
      56                 :     
      57             168 :     if( EQUAL(pszLatLong,"LAT") )
      58                 :     {
      59              84 :         if( dfAngle < 0.0 )
      60               0 :             chHemisphere = 'S';
      61                 :         else
      62              84 :             chHemisphere = 'N';
      63                 :     }
      64                 :     else
      65                 :     {
      66              84 :         if( dfAngle < 0.0 )
      67              18 :             chHemisphere = 'W';
      68                 :         else
      69              66 :             chHemisphere = 'E';
      70                 :     }
      71                 : 
      72             168 :     dfAngle = ABS(dfAngle);
      73                 : 
      74             168 :     nDegrees = (int) floor(dfAngle + 0.5/3600.0);
      75             168 :     dfRemainder = dfAngle - nDegrees;
      76             168 :     nMinutes = (int) floor(dfRemainder*60.0 + 0.5/60.0);
      77             168 :     dfRemainder = dfRemainder - nMinutes / 60.0;
      78             168 :     nSeconds = (int) floor(dfRemainder * 3600.0 + 0.5);
      79                 : 
      80             168 :     sprintf( szWork, pszFormat,
      81                 :              nDegrees, nMinutes, nSeconds, chHemisphere );
      82                 : 
      83             168 :     strncpy( (char *) achField, szWork, strlen(szWork) );
      84             168 : }
      85                 : 
      86                 : /************************************************************************/
      87                 : /*                             DTEDFormat()                             */
      88                 : /************************************************************************/
      89                 : 
      90             490 : static void DTEDFormat( unsigned char *pszTarget, const char *pszFormat, ... )
      91                 : 
      92                 : {
      93                 :     va_list args;
      94                 :     char    szWork[512];
      95                 : 
      96             490 :     va_start(args, pszFormat);
      97             490 :     vsprintf( szWork, pszFormat, args );
      98             490 :     va_end(args);
      99                 : 
     100             490 :     strncpy( (char *) pszTarget, szWork, strlen(szWork) );
     101             490 : }
     102                 : 
     103                 : /************************************************************************/
     104                 : /*                             DTEDCreate()                             */
     105                 : /************************************************************************/
     106                 : 
     107              14 : const char *DTEDCreate( const char *pszFilename, int nLevel, 
     108                 :                         int nLLOriginLat, int nLLOriginLong )
     109                 : 
     110                 : {
     111                 :     FILE        *fp;
     112                 :     unsigned char achRecord[3601*2 + 12];
     113                 :     int         nXSize, nYSize, iProfile;
     114                 :     static char szError[512];
     115                 : 
     116                 : /* -------------------------------------------------------------------- */
     117                 : /*      Establish resolution.                                           */
     118                 : /* -------------------------------------------------------------------- */
     119              14 :     if( nLevel == 0 )
     120                 :     {
     121               2 :         nXSize = 121;
     122               2 :         nYSize = 121;
     123                 :     }
     124              12 :     else if( nLevel == 1 )
     125                 :     {
     126              12 :         nXSize = 1201;
     127              12 :         nYSize = 1201;
     128                 :     } 
     129               0 :     else if( nLevel == 2 )
     130                 :     {
     131               0 :         nXSize = 3601;
     132               0 :         nYSize = 3601;
     133                 :     }
     134                 :     else
     135                 :     {
     136               0 :         sprintf( szError, "Illegal DTED Level value %d, only 0-2 allowed.",
     137                 :                  nLevel );
     138               0 :         return szError;
     139                 :     }
     140                 : 
     141              14 :     if( ABS(nLLOriginLat) >= 80 )
     142               0 :         nXSize = (nXSize - 1) / 6 + 1;
     143              14 :     else if( ABS(nLLOriginLat) >= 75 )
     144               0 :         nXSize = (nXSize - 1) / 4 + 1;
     145              14 :     else if( ABS(nLLOriginLat) >= 70 )
     146               0 :         nXSize = (nXSize - 1) / 3 + 1;
     147              14 :     else if( ABS(nLLOriginLat) >= 50 )
     148               1 :         nXSize = (nXSize - 1) / 2 + 1;
     149                 : 
     150                 : /* -------------------------------------------------------------------- */
     151                 : /*      Open the file.                                                  */
     152                 : /* -------------------------------------------------------------------- */
     153              14 :     fp = VSIFOpenL( pszFilename, "wb" );
     154                 : 
     155              14 :     if( fp == NULL )
     156                 :     {
     157               0 :         sprintf( szError, "Unable to create file `%s'.", pszFilename );
     158               0 :         return szError;
     159                 :     }
     160                 : 
     161                 : /* -------------------------------------------------------------------- */
     162                 : /*      Format and write the UHL record.                                */
     163                 : /* -------------------------------------------------------------------- */
     164              14 :     memset( achRecord, ' ', DTED_UHL_SIZE );
     165                 : 
     166              14 :     DTEDFormat( achRecord + 0, "UHL1" );
     167                 :     
     168              14 :     DTEDFormatDMS( achRecord + 4, nLLOriginLong, "LONG", NULL );
     169              14 :     DTEDFormatDMS( achRecord + 12, nLLOriginLat, "LAT", NULL );
     170                 : 
     171              14 :     DTEDFormat( achRecord + 20, "%04d", (3600 / (nXSize-1)) * 10 );
     172              14 :     DTEDFormat( achRecord + 24, "%04d", (3600 / (nYSize-1)) * 10 );
     173                 : 
     174              14 :     DTEDFormat( achRecord + 28, "%4s", DTED_ABS_VERT_ACC );
     175              14 :     DTEDFormat( achRecord + 32, "%-3s", DTED_SECURITY );
     176              14 :     DTEDFormat( achRecord + 47, "%04d", nXSize );
     177              14 :     DTEDFormat( achRecord + 51, "%04d", nYSize );
     178              14 :     DTEDFormat( achRecord + 55, "%c", '0' );
     179                 : 
     180              14 :     if( VSIFWriteL( achRecord, DTED_UHL_SIZE, 1, fp ) != 1 )
     181               0 :         return "UHL record write failed.";
     182                 : 
     183                 : /* -------------------------------------------------------------------- */
     184                 : /*      Format and write the DSI record.                                */
     185                 : /* -------------------------------------------------------------------- */
     186              14 :     memset( achRecord, ' ', DTED_DSI_SIZE );
     187                 : 
     188              14 :     DTEDFormat( achRecord + 0, "DSI" );
     189              14 :     DTEDFormat( achRecord + 3, "%1s", DTED_SECURITY );
     190                 : 
     191              14 :     DTEDFormat( achRecord + 59, "DTED%d", nLevel );
     192              14 :     DTEDFormat( achRecord + 64, "%015d", 0 );
     193              14 :     DTEDFormat( achRecord + 87, "%02d", DTED_EDITION );
     194              14 :     DTEDFormat( achRecord + 89, "%c", 'A' );
     195              14 :     DTEDFormat( achRecord + 90, "%04d", 0 );
     196              14 :     DTEDFormat( achRecord + 94, "%04d", 0 );
     197              14 :     DTEDFormat( achRecord + 98, "%04d", 0 );
     198              14 :     DTEDFormat( achRecord + 126, "PRF89020B");
     199              14 :     DTEDFormat( achRecord + 135, "00");
     200              14 :     DTEDFormat( achRecord + 137, "0005");
     201              14 :     DTEDFormat( achRecord + 141, "MSL" );
     202              14 :     DTEDFormat( achRecord + 144, "WGS84" );
     203                 : 
     204                 :     /* origin */
     205              14 :     DTEDFormatDMS( achRecord + 185, nLLOriginLat, "LAT", 
     206                 :                    "%02d%02d%02d.0%c" );
     207              14 :     DTEDFormatDMS( achRecord + 194, nLLOriginLong, "LONG", 
     208                 :                    "%03d%02d%02d.0%c" );
     209                 : 
     210                 :     /* SW */
     211              14 :     DTEDFormatDMS( achRecord + 204, nLLOriginLat, "LAT", "%02d%02d%02d%c" );
     212              14 :     DTEDFormatDMS( achRecord + 211, nLLOriginLong, "LONG", NULL );
     213                 : 
     214                 :     /* NW */
     215              14 :     DTEDFormatDMS( achRecord + 219, nLLOriginLat+1, "LAT", "%02d%02d%02d%c" );
     216              14 :     DTEDFormatDMS( achRecord + 226, nLLOriginLong, "LONG", NULL );
     217                 : 
     218                 :     /* NE */
     219              14 :     DTEDFormatDMS( achRecord + 234, nLLOriginLat+1, "LAT", "%02d%02d%02d%c" );
     220              14 :     DTEDFormatDMS( achRecord + 241, nLLOriginLong+1, "LONG", NULL );
     221                 : 
     222                 :     /* SE */
     223              14 :     DTEDFormatDMS( achRecord + 249, nLLOriginLat, "LAT", "%02d%02d%02d%c" );
     224              14 :     DTEDFormatDMS( achRecord + 256, nLLOriginLong+1, "LONG", NULL );
     225                 : 
     226              14 :     DTEDFormat( achRecord + 264, "0000000.0" );
     227              14 :     DTEDFormat( achRecord + 264, "0000000.0" );
     228                 : 
     229              14 :     DTEDFormat( achRecord + 273, "%04d", (3600 / (nYSize-1)) * 10 );
     230              14 :     DTEDFormat( achRecord + 277, "%04d", (3600 / (nXSize-1)) * 10 );
     231                 : 
     232              14 :     DTEDFormat( achRecord + 281, "%04d", nYSize );
     233              14 :     DTEDFormat( achRecord + 285, "%04d", nXSize );
     234              14 :     DTEDFormat( achRecord + 289, "%02d", 0 );
     235                 : 
     236              14 :     if( VSIFWriteL( achRecord, DTED_DSI_SIZE, 1, fp ) != 1 )
     237               0 :         return "DSI record write failed.";
     238                 : 
     239                 : /* -------------------------------------------------------------------- */
     240                 : /*      Create and write ACC record.                                    */
     241                 : /* -------------------------------------------------------------------- */
     242              14 :     memset( achRecord, ' ', DTED_ACC_SIZE );
     243                 : 
     244              14 :     DTEDFormat( achRecord + 0, "ACC" );
     245                 : 
     246              14 :     DTEDFormat( achRecord + 3, "NA" );
     247              14 :     DTEDFormat( achRecord + 7, "NA" );
     248              14 :     DTEDFormat( achRecord + 11, "NA" );
     249              14 :     DTEDFormat( achRecord + 15, "NA" );
     250                 : 
     251              14 :     DTEDFormat( achRecord + 55, "00" );
     252                 :     
     253              14 :     if( VSIFWriteL( achRecord, DTED_ACC_SIZE, 1, fp ) != 1 )
     254               0 :         return "ACC record write failed.";
     255                 : 
     256                 : /* -------------------------------------------------------------------- */
     257                 : /*      Write blank template profile data records.                      */
     258                 : /* -------------------------------------------------------------------- */
     259              14 :     memset( achRecord, 0, nYSize*2 + 12 );
     260              14 :     memset( achRecord + 8, 0xff, nYSize*2 );
     261                 : 
     262              14 :     achRecord[0] = 0252;
     263                 :     
     264           14068 :     for( iProfile = 0; iProfile < nXSize; iProfile++ )
     265                 :     {
     266           14054 :         achRecord[1] = 0;
     267           14054 :         achRecord[2] = (GByte) (iProfile / 256);
     268           14054 :         achRecord[3] = (GByte) (iProfile % 256);
     269                 :         
     270           14054 :         achRecord[4] = (GByte) (iProfile / 256);
     271           14054 :         achRecord[5] = (GByte) (iProfile % 256);
     272                 : 
     273           14054 :         if( VSIFWriteL( achRecord, nYSize*2 + 12, 1, fp ) != 1 )
     274               0 :             return "Data record write failed.";
     275                 :     }
     276                 : 
     277              14 :     VSIFCloseL( fp );
     278                 : 
     279              14 :     return NULL;
     280                 : }

Generated by: LCOV version 1.7