LCOV - code coverage report
Current view: directory - frmts/gtiff - gt_citation.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 232 107 46.1 %
Date: 2010-01-09 Functions: 6 5 83.3 %

       1                 : /******************************************************************************
       2                 :  * $Id$
       3                 :  *
       4                 :  * Project:  GeoTIFF Driver
       5                 :  * Purpose:  Implements special parsing of Imagine citation strings, and
       6                 :  *           to encode PE String info in citation fields as needed.
       7                 :  * Author:   Xiuguang Zhou (ESRI)
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2008, Xiuguang Zhou (ESRI)
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : #include "cpl_port.h"
      32                 : #include "cpl_string.h"
      33                 : 
      34                 : #include "geo_normalize.h"
      35                 : #include "geovalues.h"
      36                 : #include "ogr_spatialref.h"
      37                 : 
      38                 : CPL_CVSID("$Id$");
      39                 : 
      40                 : #define nCitationNameTypes 9
      41                 : typedef enum 
      42                 : {
      43                 :   CitCsName = 0,
      44                 :   CitPcsName = 1,
      45                 :   CitProjectionName = 2,
      46                 :   CitLUnitsName = 3,
      47                 :   CitGcsName = 4,
      48                 :   CitDatumName = 5,
      49                 :   CitEllipsoidName = 6,
      50                 :   CitPrimemName = 7,
      51                 :   CitAUnitsName = 8
      52                 : } CitationNameType;
      53                 : 
      54                 : char* ImagineCitationTranslation(const char* psCitation, geokey_t keyID);
      55                 : char** CitationStringParse(const char* psCitation);
      56                 : void SetLinearUnitCitation(GTIF* psGTIF, char* pszLinearUOMName);
      57                 : void SetGeogCSCitation(GTIF * psGTIF, OGRSpatialReference *poSRS, char* angUnitName, int nDatum, short nSpheroid);
      58                 : OGRBoolean SetCitationToSRS(GTIF* hGTIF, char* szCTString, int nCTStringLen,
      59                 :                             geokey_t geoKey,  OGRSpatialReference* poSRS, OGRBoolean* linearUnitIsSet);
      60                 : void GetGeogCSFromCitation(char* szGCSName, int nGCSName,
      61                 :                            geokey_t geoKey, 
      62                 :                           char  **ppszGeogName,
      63                 :                           char  **ppszDatumName,
      64                 :                           char  **ppszPMName,
      65                 :                           char  **ppszSpheroidName,
      66                 :                           char  **ppszAngularUnits);
      67                 : 
      68                 : /************************************************************************/
      69                 : /*                     ImagineCitationTranslation()                     */
      70                 : /*                                                                      */
      71                 : /*      Translate ERDAS Imagine GeoTif citation                         */
      72                 : /************************************************************************/
      73              13 : char* ImagineCitationTranslation(const char* psCitation, geokey_t keyID)
      74                 : {
      75              13 :     char* ret = NULL;
      76              13 :     if(!psCitation)
      77               0 :         return ret;
      78              13 :     if(EQUALN(psCitation, "IMAGINE GeoTIFF Support", strlen("IMAGINE GeoTIFF Support")))
      79                 :     {
      80               0 :         CPLString osName;
      81                 : 
      82                 :         // this is a handle IMAGING style citation
      83               0 :         const char* p = NULL;
      84               0 :         p = strchr(psCitation, '$');
      85               0 :         if(p)
      86               0 :             p = strchr(p, '\n');
      87               0 :         if(p)
      88               0 :             p++;
      89               0 :         const char* p1 = NULL;
      90               0 :         if(p)
      91               0 :             p1 = strchr(p, '\n');
      92               0 :         if(p && p1)
      93                 :         {
      94               0 :             switch (keyID)
      95                 :             {
      96                 :               case PCSCitationGeoKey:
      97               0 :                 osName = "PCS Name = ";
      98               0 :                 break;
      99                 :               case GTCitationGeoKey:
     100               0 :                 osName = "CS Name = ";
     101               0 :                 break;
     102                 :               case GeogCitationGeoKey:
     103               0 :                 if(!strstr(p, "Unable to"))
     104               0 :                     osName = "GCS Name = ";
     105                 :                 break;
     106                 :               default:
     107                 :                 break;
     108                 :             }
     109               0 :             if(strlen(osName)>0)
     110                 :             {
     111               0 :                 osName.append(p, p1-p);
     112               0 :                 osName += "|";
     113                 :             }
     114                 :         }
     115               0 :         p = strstr(psCitation, "Projection Name = ");
     116               0 :         if(p)
     117                 :         {
     118               0 :             p += strlen("Projection Name = ");
     119               0 :             p1 = strchr(p, '\n');
     120               0 :             if(!p1)
     121               0 :                 p1 = strchr(p, '\0');
     122                 :         }
     123               0 :         if(p && p1)
     124                 :         {
     125               0 :             osName.append(p, p1-p);
     126               0 :             osName += "|";
     127                 :         }
     128               0 :         p = strstr(psCitation, "Datum = ");
     129               0 :         if(p)
     130                 :         {
     131               0 :             p += strlen("Datum = ");
     132               0 :             p1 = strchr(p, '\n');
     133               0 :             if(!p1)
     134               0 :                 p1 = strchr(p, '\0');
     135                 :         }
     136               0 :         if(p && p1)
     137                 :         {
     138               0 :             osName += "Datum = ";
     139               0 :             osName.append(p, p1-p);
     140               0 :             osName += "|";
     141                 :         }
     142               0 :         p = strstr(psCitation, "Ellipsoid = ");
     143               0 :         if(p)
     144                 :         {
     145               0 :             p += strlen("Ellipsoid = ");
     146               0 :             p1 = strchr(p, '\n');
     147               0 :             if(!p1)
     148               0 :                 p1 = strchr(p, '\0');
     149                 :         }
     150               0 :         if(p && p1)
     151                 :         {
     152               0 :             osName += "Ellipsoid = ";
     153               0 :             osName.append(p, p1-p);
     154               0 :             osName += "|";
     155                 :         }
     156               0 :         p = strstr(psCitation, "Units = ");
     157               0 :         if(p)
     158                 :         {
     159               0 :             p += strlen("Units = ");
     160               0 :             p1 = strchr(p, '\n');
     161               0 :             if(!p1)
     162               0 :                 p1 = strchr(p, '\0');
     163                 :         }
     164               0 :         if(p && p1)
     165                 :         {
     166               0 :             osName += "LUnits = ";
     167               0 :             osName.append(p, p1-p);
     168               0 :             osName += "|";
     169                 :         }
     170               0 :         if(strlen(osName) > 0)
     171                 :         {
     172               0 :             ret = CPLStrdup(osName);
     173               0 :         }
     174                 :     }
     175              13 :     return ret;
     176                 : }
     177                 : 
     178                 : /************************************************************************/
     179                 : /*                        CitationStringParse()                         */
     180                 : /*                                                                      */
     181                 : /*      Parse a Citation string                                         */
     182                 : /************************************************************************/
     183              13 : char** CitationStringParse(const char* psCitation)
     184                 : {
     185              13 :     char ** ret = NULL;
     186              13 :     if(!psCitation)
     187               0 :         return ret;
     188                 : 
     189              13 :     ret = (char **) CPLCalloc(sizeof(char*), nCitationNameTypes); 
     190              13 :     const char* pDelimit = NULL;
     191              13 :     const char* pStr = psCitation;
     192              13 :     CPLString osName;
     193              13 :     int nCitationLen = strlen(psCitation);
     194              13 :     OGRBoolean nameFound = FALSE;
     195              48 :     while((pStr-psCitation+1)< nCitationLen)
     196                 :     {
     197              22 :         if( (pDelimit = strstr(pStr, "|")) )
     198                 :         {
     199              18 :             osName = "";
     200              18 :             osName.append(pStr, pDelimit-pStr);
     201              18 :             pStr = pDelimit+1;
     202                 :         }
     203                 :         else
     204                 :         {
     205               4 :             osName = pStr;
     206               4 :             pStr += strlen(pStr);
     207                 :         }
     208              22 :         const char* name = osName.c_str();
     209              22 :         if( strstr(name, "PCS Name = ") )
     210                 :         {
     211               0 :             if (!ret[CitPcsName])
     212               0 :                 ret[CitPcsName] = CPLStrdup(name+strlen("PCS Name = "));
     213               0 :             nameFound = TRUE;
     214                 :         }
     215              22 :         if(strstr(name, "Projection Name = "))
     216                 :         {
     217               0 :             if (!ret[CitProjectionName])
     218               0 :                 ret[CitProjectionName] = CPLStrdup(name+strlen("Projection Name = "));
     219               0 :             nameFound = TRUE;
     220                 :         }
     221              22 :         if(strstr(name, "LUnits = "))
     222                 :         {
     223               0 :             if (!ret[CitLUnitsName])
     224               0 :                 ret[CitLUnitsName] = CPLStrdup(name+strlen("LUnits = "));
     225               0 :             nameFound = TRUE;
     226                 :         }
     227              22 :         if(strstr(name, "GCS Name = "))
     228                 :         {
     229               3 :             if (!ret[CitGcsName])
     230               3 :                 ret[CitGcsName] = CPLStrdup(name+strlen("GCS Name = "));
     231               3 :             nameFound = TRUE;
     232                 :         }
     233              22 :         if(strstr(name, "Datum = "))
     234                 :         {
     235               3 :             if (!ret[CitDatumName])
     236               3 :                 ret[CitDatumName] = CPLStrdup(name+strlen("Datum = "));
     237               3 :             nameFound = TRUE;
     238                 :         }
     239              22 :         if(strstr(name, "Ellipsoid = "))
     240                 :         {
     241               3 :             if (!ret[CitEllipsoidName])
     242               3 :                 ret[CitEllipsoidName] = CPLStrdup(name+strlen("Ellipsoid = "));
     243               3 :             nameFound = TRUE;
     244                 :         }
     245              22 :         if(strstr(name, "Primem = "))
     246                 :         {
     247               3 :             if (!ret[CitPrimemName])
     248               3 :                 ret[CitPrimemName] = CPLStrdup(name+strlen("Primem = "));
     249               3 :             nameFound = TRUE;
     250                 :         }
     251              22 :         if(strstr(name, "AUnits = "))
     252                 :         {
     253               0 :             if (!ret[CitAUnitsName])
     254               0 :                 ret[CitAUnitsName] = CPLStrdup(name+strlen("AUnits = "));
     255               0 :             nameFound = TRUE;
     256                 :         }
     257                 :     }
     258              13 :     if(!nameFound)
     259                 :     {
     260              10 :         CPLFree( ret );
     261              10 :         ret = (char**)NULL;
     262                 :     }
     263              13 :     return ret;
     264                 : }
     265                 : 
     266                 : /************************************************************************/
     267                 : /*                       SetLinearUnitCitation()                        */
     268                 : /*                                                                      */
     269                 : /*      Set linear unit Citation string                                 */
     270                 : /************************************************************************/
     271               0 : void SetLinearUnitCitation(GTIF* psGTIF, char* pszLinearUOMName)
     272                 : {
     273                 :     char szName[512];
     274               0 :     CPLString osCitation;
     275               0 :     int n = 0;
     276               0 :     if( GTIFKeyGet( psGTIF, PCSCitationGeoKey, szName, 0, sizeof(szName) ) )
     277               0 :         n = strlen(szName);
     278               0 :     if(n>0)
     279                 :     {
     280               0 :         osCitation = szName;
     281               0 :         if(osCitation[n-1] != '|')
     282               0 :             osCitation += "|";
     283               0 :         osCitation += "LUnits = ";
     284               0 :         osCitation += pszLinearUOMName;
     285               0 :         osCitation += "|";
     286                 :     }
     287                 :     else
     288                 :     {
     289               0 :         osCitation = "LUnits = ";
     290               0 :         osCitation += pszLinearUOMName;
     291                 :     }
     292               0 :     GTIFKeySet( psGTIF, PCSCitationGeoKey, TYPE_ASCII, 0, osCitation.c_str() );
     293               0 :     return;
     294                 : }
     295                 : 
     296                 : /************************************************************************/
     297                 : /*                         SetGeogCSCitation()                          */
     298                 : /*                                                                      */
     299                 : /*      Set geogcs Citation string                                      */
     300                 : /************************************************************************/
     301               8 : void SetGeogCSCitation(GTIF * psGTIF, OGRSpatialReference *poSRS, char* angUnitName, int nDatum, short nSpheroid)
     302                 : {
     303               8 :     int bRewriteGeogCitation = FALSE;
     304                 :     char szName[256];
     305               8 :     CPLString osCitation;
     306               8 :     size_t n = 0;
     307               8 :     if( GTIFKeyGet( psGTIF, GeogCitationGeoKey, szName, 0, sizeof(szName) ) )
     308               8 :         n = strlen(szName);
     309               8 :     if (n == 0)
     310                 :         return;
     311                 : 
     312               8 :     if(!EQUALN(szName, "GCS Name = ", strlen("GCS Name = ")))
     313                 :     {
     314               8 :         osCitation = "GCS Name = ";
     315               8 :         osCitation += szName;
     316                 :     }
     317                 :     else
     318                 :     {
     319               0 :         osCitation = szName;
     320                 :     }
     321                 : 
     322               8 :     if(nDatum == KvUserDefined )
     323                 :     {
     324               6 :         const char* datumName = poSRS->GetAttrValue( "DATUM" );
     325               6 :         if(datumName && strlen(datumName) > 0)
     326                 :         {
     327               6 :             osCitation += "|Datum = ";
     328               6 :             osCitation += datumName;
     329               6 :             bRewriteGeogCitation = TRUE;
     330                 :         }
     331                 :     }
     332               8 :     if(nSpheroid == KvUserDefined )
     333                 :     {
     334               8 :         const char* spheroidName = poSRS->GetAttrValue( "SPHEROID" );
     335               8 :         if(spheroidName && strlen(spheroidName) > 0)
     336                 :         {
     337               6 :             osCitation += "|Ellipsoid = ";
     338               6 :             osCitation += spheroidName;
     339               6 :             bRewriteGeogCitation = TRUE;
     340                 :         }
     341                 :     }
     342                 : 
     343               8 :     const char* primemName = poSRS->GetAttrValue( "PRIMEM" );
     344               8 :     if(primemName && strlen(primemName) > 0)
     345                 :     {
     346               6 :         osCitation += "|Primem = ";
     347               6 :         osCitation += primemName;
     348               6 :         bRewriteGeogCitation = TRUE;
     349                 : 
     350               6 :         double primemValue = poSRS->GetPrimeMeridian(NULL);
     351               6 :         if(angUnitName && !EQUAL(angUnitName, "Degree"))
     352                 :         {
     353               0 :             double aUnit = poSRS->GetAngularUnits(NULL);
     354               0 :             primemValue *= aUnit;
     355                 :         }
     356                 :         GTIFKeySet( psGTIF, GeogPrimeMeridianLongGeoKey, TYPE_DOUBLE, 1, 
     357               6 :                     primemValue );
     358                 :     } 
     359               8 :     if(angUnitName && strlen(angUnitName) > 0 && !EQUAL(angUnitName, "Degree"))
     360                 :     {
     361               0 :         osCitation += "|AUnits = ";
     362               0 :         osCitation += angUnitName;
     363               0 :         bRewriteGeogCitation = TRUE;
     364                 :     }
     365                 : 
     366               8 :     if (osCitation[strlen(osCitation) - 1] != '|')
     367               8 :         osCitation += "|";
     368                 : 
     369               8 :     if (bRewriteGeogCitation)
     370               6 :         GTIFKeySet( psGTIF, GeogCitationGeoKey, TYPE_ASCII, 0, osCitation.c_str() );
     371                 : 
     372               0 :     return;
     373                 : }
     374                 : 
     375                 : /************************************************************************/
     376                 : /*                          SetCitationToSRS()                          */
     377                 : /*                                                                      */
     378                 : /*      Parse and set Citation string to SRS                            */
     379                 : /************************************************************************/
     380               8 : OGRBoolean SetCitationToSRS(GTIF* hGTIF, char* szCTString, int nCTStringLen,
     381                 :                             geokey_t geoKey,  OGRSpatialReference*  poSRS, OGRBoolean* linearUnitIsSet)
     382                 : {
     383               8 :     OGRBoolean ret = FALSE;
     384               8 :     *linearUnitIsSet = FALSE;
     385               8 :     char* imgCTName = ImagineCitationTranslation(szCTString, geoKey);
     386               8 :     if(imgCTName)
     387                 :     {
     388               0 :         strncpy(szCTString, imgCTName, nCTStringLen);
     389               0 :         szCTString[nCTStringLen-1] = '\0';
     390               0 :         CPLFree( imgCTName );
     391                 :     }
     392               8 :     char** ctNames = CitationStringParse(szCTString);
     393               8 :     if(ctNames)
     394                 :     {
     395               0 :         if( poSRS->GetRoot() == NULL)
     396               0 :             poSRS->SetNode( "PROJCS", "unnamed" );
     397               0 :         if(ctNames[CitPcsName])
     398                 :         {
     399               0 :             poSRS->SetNode( "PROJCS", ctNames[CitPcsName] );
     400               0 :             ret = TRUE;
     401                 :         }
     402               0 :         else if(geoKey != GTCitationGeoKey) 
     403                 :         {
     404                 :             char    szPCSName[128];
     405               0 :             if( GTIFKeyGet( hGTIF, GTCitationGeoKey, szPCSName, 0, sizeof(szPCSName) ) )
     406                 :             {
     407               0 :                 poSRS->SetNode( "PROJCS", szPCSName );
     408               0 :                 ret = TRUE;
     409                 :             }
     410                 :         }
     411                 :     
     412               0 :         if(ctNames[CitProjectionName])
     413               0 :             poSRS->SetProjection( ctNames[CitProjectionName] );
     414                 : 
     415               0 :         if(ctNames[CitLUnitsName])
     416                 :         {
     417                 :             double unitSize;
     418               0 :             if (GTIFKeyGet(hGTIF, ProjLinearUnitSizeGeoKey, &unitSize, 0,
     419                 :                            sizeof(unitSize) ))
     420                 :             {
     421               0 :                 poSRS->SetLinearUnits( ctNames[CitLUnitsName], unitSize);
     422               0 :                 *linearUnitIsSet = TRUE;
     423                 :             }
     424                 :         }
     425               0 :         for(int i= 0; i<nCitationNameTypes; i++) 
     426               0 :             CPLFree( ctNames[i] );
     427               0 :         CPLFree( ctNames );
     428                 :     }
     429               8 :     return ret;
     430                 : }
     431                 : 
     432                 : /************************************************************************/
     433                 : /*                       GetGeogCSFromCitation()                        */
     434                 : /*                                                                      */
     435                 : /*      Parse and get geogcs names from a Citation string               */
     436                 : /************************************************************************/
     437               5 : void GetGeogCSFromCitation(char* szGCSName, int nGCSName,
     438                 :                            geokey_t geoKey, 
     439                 :                            char **ppszGeogName,
     440                 :                            char **ppszDatumName,
     441                 :                            char **ppszPMName,
     442                 :                            char **ppszSpheroidName,
     443                 :                            char **ppszAngularUnits)
     444                 : {
     445                 :     *ppszGeogName = *ppszDatumName = *ppszPMName = 
     446               5 :         *ppszSpheroidName = *ppszAngularUnits = NULL;
     447                 : 
     448               5 :     char* imgCTName = ImagineCitationTranslation(szGCSName, geoKey);
     449               5 :     if(imgCTName)
     450                 :     {
     451               0 :         strncpy(szGCSName, imgCTName, nGCSName);
     452               0 :         szGCSName[nGCSName-1] = '\0';
     453               0 :         CPLFree( imgCTName );
     454                 :     }
     455               5 :     char** ctNames = CitationStringParse(szGCSName);
     456               5 :     if(ctNames)
     457                 :     {
     458               3 :         if(ctNames[CitGcsName])
     459               3 :             *ppszGeogName = CPLStrdup( ctNames[CitGcsName] );
     460                 : 
     461               3 :         if(ctNames[CitDatumName])
     462               3 :             *ppszDatumName = CPLStrdup( ctNames[CitDatumName] );
     463                 : 
     464               3 :         if(ctNames[CitEllipsoidName])
     465               3 :             *ppszSpheroidName = CPLStrdup( ctNames[CitEllipsoidName] );
     466                 : 
     467               3 :         if(ctNames[CitPrimemName])
     468               3 :             *ppszPMName = CPLStrdup( ctNames[CitPrimemName] );
     469                 : 
     470               3 :         if(ctNames[CitAUnitsName])
     471               0 :             *ppszAngularUnits = CPLStrdup( ctNames[CitAUnitsName] );
     472                 : 
     473              30 :         for(int i= 0; i<nCitationNameTypes; i++)
     474              27 :             CPLFree( ctNames[i] );
     475               3 :         CPLFree( ctNames );
     476                 :     }
     477                 :     return;
     478                 : }
     479                 : 
     480                 : 

Generated by: LCOV version 1.7