LCOV - code coverage report
Current view: directory - frmts/gtiff - gt_citation.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 361 278 77.0 %
Date: 2012-04-28 Functions: 8 7 87.5 %

       1                 : /******************************************************************************
       2                 :  * $Id: gt_citation.cpp 23433 2011-11-27 19:49:54Z rouault $
       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 "geovalues.h"
      35                 : #include "gt_citation.h"
      36                 : 
      37                 : CPL_CVSID("$Id: gt_citation.cpp 23433 2011-11-27 19:49:54Z rouault $");
      38                 : 
      39                 : static const char *apszUnitMap[] = {
      40                 :     "meters", "1.0",
      41                 :     "meter", "1.0",
      42                 :     "m", "1.0",
      43                 :     "centimeters", "0.01",
      44                 :     "centimeter", "0.01",
      45                 :     "cm", "0.01", 
      46                 :     "millimeters", "0.001",
      47                 :     "millimeter", "0.001",
      48                 :     "mm", "0.001",
      49                 :     "kilometers", "1000.0",
      50                 :     "kilometer", "1000.0",
      51                 :     "km", "1000.0",
      52                 :     "us_survey_feet", "0.3048006096012192",
      53                 :     "us_survey_foot", "0.3048006096012192",
      54                 :     "feet", "0.3048006096012192", 
      55                 :     "foot", "0.3048006096012192",
      56                 :     "ft", "0.3048006096012192",
      57                 :     "international_feet", "0.3048",
      58                 :     "international_foot", "0.3048",
      59                 :     "inches", "0.0254000508001",
      60                 :     "inch", "0.0254000508001",
      61                 :     "in", "0.0254000508001",
      62                 :     "yards", "0.9144",
      63                 :     "yard", "0.9144",
      64                 :     "yd", "0.9144",
      65                 :     "miles", "1304.544",
      66                 :     "mile", "1304.544",
      67                 :     "mi", "1304.544",
      68                 :     "modified_american_feet", "0.3048122530",
      69                 :     "modified_american_foot", "0.3048122530",
      70                 :     "clarke_feet", "0.3047972651",
      71                 :     "clarke_foot", "0.3047972651",
      72                 :     "indian_feet", "0.3047995142",
      73                 :     "indian_foot", "0.3047995142",
      74                 :     "Yard_Indian", "0.9143985307444408", 
      75                 :     "Foot_Clarke", "0.304797265",
      76                 :     "Foot_Gold_Coast", "0.3047997101815088",
      77                 :     "Link_Clarke", "0.2011661949", 
      78                 :     "Yard_Sears", "0.9143984146160287", 
      79                 :     "50_Kilometers", "50000.0", 
      80                 :     "150_Kilometers", "150000.0", 
      81                 :     NULL, NULL
      82                 : };
      83                 : 
      84                 : /************************************************************************/
      85                 : /*                     ImagineCitationTranslation()                     */
      86                 : /*                                                                      */
      87                 : /*      Translate ERDAS Imagine GeoTif citation                         */
      88                 : /************************************************************************/
      89            1300 : char* ImagineCitationTranslation(char* psCitation, geokey_t keyID)
      90                 : {
      91                 :     static const char *keyNames[] = {
      92                 :         "NAD = ", "Datum = ", "Ellipsoid = ", "Units = ", NULL
      93                 :     };
      94                 : 
      95            1300 :     char* ret = NULL;
      96                 :     int i;
      97            1300 :     if(!psCitation)
      98               0 :         return ret;
      99            1300 :     if(EQUALN(psCitation, "IMAGINE GeoTIFF Support", strlen("IMAGINE GeoTIFF Support")))
     100                 :     {
     101                 :         // this is a handle IMAGING style citation
     102                 :         char name[256];
     103               2 :         name[0] = '\0';
     104               2 :         char* p = NULL;
     105               2 :         char* p1 = NULL;
     106                 : 
     107               2 :         p = strchr(psCitation, '$');
     108               2 :         if( p && strchr(p, '\n') )
     109               2 :             p = strchr(p, '\n') + 1;
     110               2 :         if(p)
     111                 :         {
     112               2 :             p1 = p + strlen(p);
     113               2 :             char *p2 = strchr(p, '\n');
     114               2 :             if(p2)
     115               2 :                 p1 = MIN(p1, p2);
     116               2 :             p2 = strchr(p, '\0');
     117               2 :             if(p2)
     118               2 :                 p1 = MIN(p1, p2);
     119              10 :             for(i=0; keyNames[i]!=NULL; i++)
     120                 :             {
     121               8 :                 p2 = strstr(p, keyNames[i]);
     122               8 :                 if(p2)
     123               2 :                     p1 = MIN(p1, p2);
     124                 :             }
     125                 :         }
     126                 : 
     127                 :         // PCS name, GCS name and PRJ name
     128               2 :         if(p && p1)
     129                 :         {
     130               2 :             switch (keyID)
     131                 :             {
     132                 :               case PCSCitationGeoKey:
     133               2 :                 if(strstr(psCitation, "Projection = "))
     134               0 :                     strcpy(name, "PRJ Name = ");
     135                 :                 else
     136               2 :                     strcpy(name, "PCS Name = ");
     137               2 :                 break;
     138                 :               case GTCitationGeoKey:
     139               0 :                 strcpy(name, "PCS Name = ");
     140               0 :                 break;
     141                 :               case GeogCitationGeoKey:
     142               0 :                 if(!strstr(p, "Unable to"))
     143               0 :                     strcpy(name, "GCS Name = ");
     144                 :                 break;
     145                 :               default:
     146                 :                 break;
     147                 :             }
     148               2 :             if(strlen(name)>0)
     149                 :             {
     150                 :                 char* p2;
     151               2 :                 if((p2 = strstr(psCitation, "Projection Name = ")) != 0)
     152               0 :                     p = p2 + strlen("Projection Name = ");
     153               2 :                 if((p2 = strstr(psCitation, "Projection = ")) != 0)
     154               0 :                     p = p2 + strlen("Projection = ");
     155               2 :                 if(p1[0] == '\0' || p1[0] == '\n' || p1[0] == ' ')
     156               2 :                     p1 --;
     157               2 :                 p2 = p1 - 1;
     158               4 :                 while( p2>0 && (p2[0] == ' ' || p2[0] == '\0' || p2[0] == '\n') )
     159               0 :                     p2--;
     160               2 :                 if(p2 != p1 - 1)
     161               0 :                     p1 = p2;
     162               2 :                 if(p1 >= p)
     163                 :                 {
     164               2 :                     strncat(name, p, p1-p+1);
     165               2 :                     strcat(name, "|");
     166               2 :                     name[strlen(name)] = '\0';
     167                 :                 }
     168                 :             }
     169                 :         }
     170                 : 
     171                 :         // All other parameters
     172              10 :         for(i=0; keyNames[i]!=NULL; i++)
     173                 :         {
     174               8 :             p = strstr(psCitation, keyNames[i]);
     175               8 :             if(p)
     176                 :             {
     177               2 :                 p += strlen(keyNames[i]);
     178               2 :                 p1 = p + strlen(p);
     179               2 :                 char *p2 = strchr(p, '\n');
     180               2 :                 if(p2)
     181               0 :                     p1 = MIN(p1, p2);
     182               2 :                 p2 = strchr(p, '\0');
     183               2 :                 if(p2)
     184               2 :                     p1 = MIN(p1, p2);
     185              10 :                 for(int j=0; keyNames[j]!=NULL; j++)
     186                 :                 {
     187               8 :                     p2 = strstr(p, keyNames[j]);
     188               8 :                     if(p2)
     189               0 :                         p1 = MIN(p1, p2);
     190                 :                 }
     191                 :             }
     192               8 :             if(p && p1 && p1>p)
     193                 :             {
     194               2 :                 if(EQUAL(keyNames[i], "Units = "))
     195               0 :                     strcat(name, "LUnits = ");
     196                 :                 else
     197               2 :                     strcat(name, keyNames[i]);
     198               2 :                 if(p1[0] == '\0' || p1[0] == '\n' || p1[0] == ' ')
     199               2 :                     p1 --;
     200               2 :                 char* p2 = p1 - 1;
     201               4 :                 while( p2>0 && (p2[0] == ' ' || p2[0] == '\0' || p2[0] == '\n') )
     202               0 :                     p2--;
     203               2 :                 if(p2 != p1 - 1)
     204               0 :                     p1 = p2;
     205               2 :                 if(p1 >= p)
     206                 :                 {
     207               2 :                     strncat(name, p, p1-p+1);
     208               2 :                     strcat(name, "|");
     209               2 :                     name[strlen(name)] = '\0';
     210                 :                 }
     211                 :             }
     212                 :         }
     213               2 :         if(strlen(name) > 0)
     214               2 :             ret = CPLStrdup(name);
     215                 :     }
     216            1300 :     return ret;
     217                 : 
     218                 : }
     219                 : 
     220                 : /************************************************************************/
     221                 : /*                        CitationStringParse()                         */
     222                 : /*                                                                      */
     223                 : /*      Parse a Citation string                                         */
     224                 : /************************************************************************/
     225                 : 
     226            1300 : char** CitationStringParse(char* psCitation, geokey_t keyID)
     227                 : {
     228            1300 :     char ** ret = NULL;
     229            1300 :     if(!psCitation)
     230               0 :         return ret;
     231                 : 
     232            1300 :     ret = (char **) CPLCalloc(sizeof(char*), nCitationNameTypes); 
     233            1300 :     char* pDelimit = NULL;
     234            1300 :     char* pStr = psCitation;
     235                 :     char name[512];
     236            1300 :     int nameSet = FALSE;
     237            1300 :     int nameLen = strlen(psCitation);
     238            1300 :     OGRBoolean nameFound = FALSE;
     239            4052 :     while((pStr-psCitation+1)< nameLen)
     240                 :     {
     241            1452 :         if( (pDelimit = strstr(pStr, "|")) != NULL )
     242                 :         {
     243             204 :             strncpy( name, pStr, pDelimit-pStr );
     244             204 :             name[pDelimit-pStr] = '\0';
     245             204 :             pStr = pDelimit+1;
     246             204 :             nameSet = TRUE;
     247                 :         }
     248                 :         else
     249                 :         {
     250            1248 :             strcpy (name, pStr);
     251            1248 :             pStr += strlen(pStr);
     252            1248 :             nameSet = TRUE;
     253                 :         }
     254            1452 :         if( strstr(name, "PCS Name = ") )
     255                 :         {
     256               2 :             ret[CitPcsName] = CPLStrdup(name+strlen("PCS Name = "));
     257               2 :             nameFound = TRUE;
     258                 :         }
     259            1452 :         if(strstr(name, "PRJ Name = "))
     260                 :         {
     261               0 :             ret[CitProjectionName] = CPLStrdup(name+strlen("PRJ Name = "));
     262               0 :             nameFound = TRUE;
     263                 :         }
     264            1452 :         if(strstr(name, "LUnits = "))
     265                 :         {
     266               6 :             ret[CitLUnitsName] = CPLStrdup(name+strlen("LUnits = "));
     267               6 :             nameFound = TRUE;
     268                 :         }
     269            1452 :         if(strstr(name, "GCS Name = "))
     270                 :         {
     271              50 :             ret[CitGcsName] = CPLStrdup(name+strlen("GCS Name = "));
     272              50 :             nameFound = TRUE;
     273                 :         }
     274            1452 :         if(strstr(name, "Datum = "))
     275                 :         {
     276              50 :             ret[CitDatumName] = CPLStrdup(name+strlen("Datum = "));
     277              50 :             nameFound = TRUE;
     278                 :         }
     279            1452 :         if(strstr(name, "Ellipsoid = "))
     280                 :         {
     281              50 :             ret[CitEllipsoidName] = CPLStrdup(name+strlen("Ellipsoid = "));
     282              50 :             nameFound = TRUE;
     283                 :         }
     284            1452 :         if(strstr(name, "Primem = "))
     285                 :         {
     286              50 :             ret[CitPrimemName] = CPLStrdup(name+strlen("Primem = "));    
     287              50 :             nameFound = TRUE;
     288                 :         }
     289            1452 :         if(strstr(name, "AUnits = "))
     290                 :         {
     291               0 :             ret[CitAUnitsName] = CPLStrdup(name+strlen("AUnits = "));
     292               0 :             nameFound = TRUE;
     293                 :         }
     294                 :     }
     295            1300 :     if( !nameFound && keyID == GeogCitationGeoKey && nameSet )
     296                 :     {
     297               4 :         ret[CitGcsName] = CPLStrdup(name);
     298               4 :         nameFound = TRUE;
     299                 :     }
     300            1300 :     if(!nameFound)
     301                 :     {
     302            1238 :         CPLFree( ret );
     303            1238 :         ret = (char**)NULL;
     304                 :     }
     305            1300 :     return ret;
     306                 : }
     307                 : 
     308                 : 
     309                 : /************************************************************************/
     310                 : /*                       SetLinearUnitCitation()                        */
     311                 : /*                                                                      */
     312                 : /*      Set linear unit Citation string                                 */
     313                 : /************************************************************************/
     314               4 : void SetLinearUnitCitation(GTIF* psGTIF, char* pszLinearUOMName)
     315                 : {
     316                 :     char szName[512];
     317               4 :     CPLString osCitation;
     318               4 :     int n = 0;
     319               4 :     if( GTIFKeyGet( psGTIF, PCSCitationGeoKey, szName, 0, sizeof(szName) ) )
     320               0 :         n = strlen(szName);
     321               4 :     if(n>0)
     322                 :     {
     323               0 :         osCitation = szName;
     324               0 :         if(osCitation[n-1] != '|')
     325               0 :             osCitation += "|";
     326               0 :         osCitation += "LUnits = ";
     327               0 :         osCitation += pszLinearUOMName;
     328               0 :         osCitation += "|";
     329                 :     }
     330                 :     else
     331                 :     {
     332               4 :         osCitation = "LUnits = ";
     333               4 :         osCitation += pszLinearUOMName;
     334                 :     }
     335               4 :     GTIFKeySet( psGTIF, PCSCitationGeoKey, TYPE_ASCII, 0, osCitation.c_str() );
     336               4 :     return;
     337                 : }
     338                 : 
     339                 : /************************************************************************/
     340                 : /*                         SetGeogCSCitation()                          */
     341                 : /*                                                                      */
     342                 : /*      Set geogcs Citation string                                      */
     343                 : /************************************************************************/
     344              54 : void SetGeogCSCitation(GTIF * psGTIF, OGRSpatialReference *poSRS, char* angUnitName, int nDatum, short nSpheroid)
     345                 : {
     346              54 :     int bRewriteGeogCitation = FALSE;
     347                 :     char szName[256];
     348              54 :     CPLString osCitation;
     349              54 :     size_t n = 0;
     350              54 :     if( GTIFKeyGet( psGTIF, GeogCitationGeoKey, szName, 0, sizeof(szName) ) )
     351              54 :         n = strlen(szName);
     352              54 :     if (n == 0)
     353                 :         return;
     354                 : 
     355              54 :     if(!EQUALN(szName, "GCS Name = ", strlen("GCS Name = ")))
     356                 :     {
     357              54 :         osCitation = "GCS Name = ";
     358              54 :         osCitation += szName;
     359                 :     }
     360                 :     else
     361                 :     {
     362               0 :         osCitation = szName;
     363                 :     }
     364                 : 
     365              54 :     if(nDatum == KvUserDefined )
     366                 :     {
     367              50 :         const char* datumName = poSRS->GetAttrValue( "DATUM" );
     368              50 :         if(datumName && strlen(datumName) > 0)
     369                 :         {
     370              50 :             osCitation += "|Datum = ";
     371              50 :             osCitation += datumName;
     372              50 :             bRewriteGeogCitation = TRUE;
     373                 :         }
     374                 :     }
     375              54 :     if(nSpheroid == KvUserDefined )
     376                 :     {
     377              54 :         const char* spheroidName = poSRS->GetAttrValue( "SPHEROID" );
     378              54 :         if(spheroidName && strlen(spheroidName) > 0)
     379                 :         {
     380              50 :             osCitation += "|Ellipsoid = ";
     381              50 :             osCitation += spheroidName;
     382              50 :             bRewriteGeogCitation = TRUE;
     383                 :         }
     384                 :     }
     385                 : 
     386              54 :     const char* primemName = poSRS->GetAttrValue( "PRIMEM" );
     387              54 :     if(primemName && strlen(primemName) > 0)
     388                 :     {
     389              50 :         osCitation += "|Primem = ";
     390              50 :         osCitation += primemName;
     391              50 :         bRewriteGeogCitation = TRUE;
     392                 : 
     393              50 :         double primemValue = poSRS->GetPrimeMeridian(NULL);
     394              50 :         if(angUnitName && !EQUAL(angUnitName, "Degree"))
     395                 :         {
     396               0 :             double aUnit = poSRS->GetAngularUnits(NULL);
     397               0 :             primemValue *= aUnit;
     398                 :         }
     399                 :         GTIFKeySet( psGTIF, GeogPrimeMeridianLongGeoKey, TYPE_DOUBLE, 1, 
     400              50 :                     primemValue );
     401                 :     } 
     402              54 :     if(angUnitName && strlen(angUnitName) > 0 && !EQUAL(angUnitName, "Degree"))
     403                 :     {
     404               0 :         osCitation += "|AUnits = ";
     405               0 :         osCitation += angUnitName;
     406               0 :         bRewriteGeogCitation = TRUE;
     407                 :     }
     408                 : 
     409              54 :     if (osCitation[strlen(osCitation) - 1] != '|')
     410              54 :         osCitation += "|";
     411                 : 
     412              54 :     if (bRewriteGeogCitation)
     413              50 :         GTIFKeySet( psGTIF, GeogCitationGeoKey, TYPE_ASCII, 0, osCitation.c_str() );
     414                 : 
     415               0 :     return;
     416                 : }
     417                 : 
     418                 : /************************************************************************/
     419                 : /*                          SetCitationToSRS()                          */
     420                 : /*                                                                      */
     421                 : /*      Parse and set Citation string to SRS                            */
     422                 : /************************************************************************/
     423            1246 : OGRBoolean SetCitationToSRS(GTIF* hGTIF, char* szCTString, int nCTStringLen,
     424                 :                             geokey_t geoKey,  OGRSpatialReference*  poSRS, OGRBoolean* linearUnitIsSet)
     425                 : {
     426            1246 :     OGRBoolean ret = FALSE;
     427            1246 :     char* lUnitName = NULL;
     428                 :     
     429            1246 :     poSRS->GetLinearUnits( &lUnitName );
     430            2488 :     if(!lUnitName || strlen(lUnitName) == 0  || EQUAL(lUnitName, "unknown"))
     431            1242 :         *linearUnitIsSet = FALSE;
     432                 :     else
     433               4 :         *linearUnitIsSet = TRUE;
     434                 : 
     435            1246 :     char* imgCTName = ImagineCitationTranslation(szCTString, geoKey);
     436            1246 :     if(imgCTName)
     437                 :     {
     438               2 :         strncpy(szCTString, imgCTName, nCTStringLen);
     439               2 :         szCTString[nCTStringLen-1] = '\0';
     440               2 :         CPLFree( imgCTName );
     441                 :     }
     442            1246 :     char** ctNames = CitationStringParse(szCTString, geoKey);
     443            1246 :     if(ctNames)
     444                 :     {
     445               8 :         if( poSRS->GetRoot() == NULL)
     446               2 :             poSRS->SetNode( "PROJCS", "unnamed" );
     447               8 :         if(ctNames[CitPcsName])
     448                 :         {
     449               2 :             poSRS->SetNode( "PROJCS", ctNames[CitPcsName] );
     450               2 :             ret = TRUE;
     451                 :         }
     452               8 :         if(ctNames[CitProjectionName])
     453               0 :             poSRS->SetProjection( ctNames[CitProjectionName] );
     454                 : 
     455               8 :         if(ctNames[CitLUnitsName])
     456                 :         {
     457               6 :             double unitSize = 0.0;
     458               6 :             int size = strlen(ctNames[CitLUnitsName]);
     459               6 :             if(strchr(ctNames[CitLUnitsName], '\0'))
     460               6 :                 size -= 1;
     461             252 :             for( int i = 0; apszUnitMap[i] != NULL; i += 2 )
     462                 :             {
     463             246 :                 if( EQUALN(apszUnitMap[i], ctNames[CitLUnitsName], size) )
     464                 :                 {
     465               0 :                     unitSize = atof(apszUnitMap[i+1]);
     466               0 :                     break;
     467                 :                 }
     468                 :             }
     469               6 :             if( unitSize == 0.0 )
     470                 :                 GTIFKeyGet(hGTIF, ProjLinearUnitSizeGeoKey, &unitSize, 0,
     471               6 :                            sizeof(unitSize) );
     472               6 :             poSRS->SetLinearUnits( ctNames[CitLUnitsName], unitSize);
     473               6 :             *linearUnitIsSet = TRUE;
     474                 :         }
     475              80 :         for(int i= 0; i<nCitationNameTypes; i++) 
     476              72 :             CPLFree( ctNames[i] );
     477               8 :         CPLFree( ctNames );
     478                 :     }
     479                 : 
     480                 :     /* if no "PCS Name = " (from Erdas) in GTCitationGeoKey */
     481            1246 :     if(geoKey == GTCitationGeoKey)
     482                 :     {
     483            1236 :         if(strlen(szCTString) > 0 && !strstr(szCTString, "PCS Name = "))
     484                 :         {
     485            1236 :             const char* pszProjCS = poSRS->GetAttrValue( "PROJCS" );
     486            1236 :             if((!(pszProjCS && strlen(pszProjCS) > 0) && !strstr(szCTString, "Projected Coordinates"))
     487                 :                ||(pszProjCS && strstr(pszProjCS, "unnamed")))
     488             172 :                 poSRS->SetNode( "PROJCS", szCTString );
     489            1236 :             ret = TRUE;
     490                 :         }
     491                 :     }
     492                 : 
     493            1246 :     return ret;
     494                 : }
     495                 : 
     496                 : /************************************************************************/
     497                 : /*                       GetGeogCSFromCitation()                        */
     498                 : /*                                                                      */
     499                 : /*      Parse and get geogcs names from a Citation string               */
     500                 : /************************************************************************/
     501              54 : void GetGeogCSFromCitation(char* szGCSName, int nGCSName,
     502                 :                            geokey_t geoKey, 
     503                 :                            char **ppszGeogName,
     504                 :                            char **ppszDatumName,
     505                 :                            char **ppszPMName,
     506                 :                            char **ppszSpheroidName,
     507                 :                            char **ppszAngularUnits)
     508                 : {
     509                 :     *ppszGeogName = *ppszDatumName = *ppszPMName = 
     510              54 :         *ppszSpheroidName = *ppszAngularUnits = NULL;
     511                 : 
     512              54 :     char* imgCTName = ImagineCitationTranslation(szGCSName, geoKey);
     513              54 :     if(imgCTName)
     514                 :     {
     515               0 :         strncpy(szGCSName, imgCTName, nGCSName);
     516               0 :         szGCSName[nGCSName-1] = '\0';
     517               0 :         CPLFree( imgCTName );
     518                 :     }
     519              54 :     char** ctNames = CitationStringParse(szGCSName, geoKey);
     520              54 :     if(ctNames)
     521                 :     {
     522              54 :         if(ctNames[CitGcsName])
     523              54 :             *ppszGeogName = CPLStrdup( ctNames[CitGcsName] );
     524                 : 
     525              54 :         if(ctNames[CitDatumName])
     526              50 :             *ppszDatumName = CPLStrdup( ctNames[CitDatumName] );
     527                 : 
     528              54 :         if(ctNames[CitEllipsoidName])
     529              50 :             *ppszSpheroidName = CPLStrdup( ctNames[CitEllipsoidName] );
     530                 : 
     531              54 :         if(ctNames[CitPrimemName])
     532              50 :             *ppszPMName = CPLStrdup( ctNames[CitPrimemName] );
     533                 : 
     534              54 :         if(ctNames[CitAUnitsName])
     535               0 :             *ppszAngularUnits = CPLStrdup( ctNames[CitAUnitsName] );
     536                 : 
     537             540 :         for(int i= 0; i<nCitationNameTypes; i++)
     538             486 :             CPLFree( ctNames[i] );
     539              54 :         CPLFree( ctNames );
     540                 :     }
     541                 :     return;
     542                 : }
     543                 : 
     544                 : 
     545                 : /************************************************************************/
     546                 : /*               CheckCitationKeyForStatePlaneUTM()                     */
     547                 : /*                                                                      */
     548                 : /*      Handle state plane and UTM in citation key                      */
     549                 : /************************************************************************/
     550            1148 : OGRBoolean CheckCitationKeyForStatePlaneUTM(GTIF* hGTIF, GTIFDefn* psDefn, OGRSpatialReference* poSRS, OGRBoolean* pLinearUnitIsSet)
     551                 : {
     552            1148 :     if( !hGTIF || !psDefn || !poSRS )
     553               0 :         return FALSE;
     554                 :     char  szCTString[512];
     555            1148 :     szCTString[0] = '\0';
     556                 : 
     557                 :     /* Check units */
     558                 :     char units[32];
     559            1148 :     units[0] = '\0';
     560                 : 
     561            1148 :     OGRBoolean hasUnits = FALSE;
     562            1148 :     if( GTIFKeyGet( hGTIF, GTCitationGeoKey, szCTString, 0, sizeof(szCTString) ) )
     563                 :     {
     564            1142 :         CPLString osLCCT = szCTString;
     565                 : 
     566            1142 :         osLCCT.tolower();
     567                 : 
     568            1142 :         if( strstr(osLCCT,"us") && strstr(osLCCT,"survey")
     569                 :             && (strstr(osLCCT,"feet") || strstr(osLCCT,"foot")) )
     570               0 :             strcpy(units, "us_survey_feet");
     571            1142 :         else if(strstr(osLCCT, "linear_feet")  
     572                 :                 || strstr(osLCCT, "linear_foot") 
     573                 :                 || strstr(osLCCT, "international"))
     574               2 :             strcpy(units, "international_feet");
     575            1140 :         else if( strstr(osLCCT,"meter") )
     576               0 :             strcpy(units, "meters");
     577                 : 
     578            1142 :         if (strlen(units) > 0)
     579               2 :             hasUnits = TRUE;
     580                 : 
     581            1142 :         if( strstr( szCTString, "Projection Name = ") && strstr( szCTString, "_StatePlane_"))
     582                 :         {
     583               2 :             const char *pStr = strstr( szCTString, "Projection Name = ") + strlen("Projection Name = ");
     584               2 :             const char* pReturn = strchr( pStr, '\n');
     585                 :             char CSName[128];
     586               2 :             strncpy(CSName, pStr, pReturn-pStr);
     587               2 :             CSName[pReturn-pStr] = '\0';
     588               2 :             if( poSRS->ImportFromESRIStatePlaneWKT(0, NULL, NULL, 32767, CSName) == OGRERR_NONE )
     589                 :             {
     590                 :                 // for some erdas citation keys, the state plane CS name is incomplete, the unit check is necessary.
     591               2 :                 OGRBoolean done = FALSE;
     592               2 :                 if (hasUnits)
     593                 :                 {
     594               2 :                     OGR_SRSNode *poUnit = poSRS->GetAttrNode( "PROJCS|UNIT" );
     595                 :       
     596               2 :                     if( poUnit != NULL && poUnit->GetChildCount() >= 2 )
     597                 :                     {
     598               2 :                         CPLString unitName = poUnit->GetChild(0)->GetValue();
     599               2 :                         unitName.tolower();
     600                 : 
     601               2 :                         if (strstr(units, "us_survey_feet"))
     602                 :                         {              
     603               0 :                             if (strstr(unitName, "us_survey_feet") || strstr(unitName, "foot_us") )
     604               0 :                                 done = TRUE;
     605                 :                         }
     606               2 :                         else if (strstr(units, "international_feet"))
     607                 :                         {
     608               2 :                             if (strstr(unitName, "feet") || strstr(unitName, "foot"))
     609               0 :                                 done = TRUE;
     610                 :                         }
     611               0 :                         else if (strstr(units, "meters"))
     612                 :                         {
     613               0 :                             if (strstr(unitName, "meter") )
     614               0 :                                 done = TRUE;
     615               2 :                         }
     616                 :                     }
     617                 :                 }
     618               2 :                 if (done)
     619               0 :                     return TRUE;
     620                 :             }
     621               0 :         }
     622                 :     }
     623            1148 :     if( !hasUnits )
     624                 :     {
     625            1146 :         char  *pszUnitsName = NULL;
     626            1146 :         GTIFGetUOMLengthInfo( psDefn->UOMLength, &pszUnitsName, NULL );
     627            1146 :         if( pszUnitsName && strlen(pszUnitsName) > 0 )
     628                 :         {
     629            1142 :             CPLString osLCCT = pszUnitsName;
     630            1142 :             GTIFFreeMemory( pszUnitsName );
     631            1142 :             osLCCT.tolower();
     632                 : 
     633            1142 :             if( strstr(osLCCT, "us") && strstr(osLCCT, "survey")
     634                 :                 && (strstr(osLCCT, "feet") || strstr(osLCCT, "foot")))
     635              24 :                 strcpy(units, "us_survey_feet");
     636            1118 :             else if(strstr(osLCCT, "feet") || strstr(osLCCT, "foot"))
     637               0 :                 strcpy(units, "international_feet");
     638            1118 :             else if(strstr(osLCCT, "meter"))
     639               0 :                 strcpy(units, "meters");
     640            1142 :             hasUnits = TRUE;
     641                 :         }
     642                 :     }
     643                 : 
     644            1148 :     if (strlen(units) == 0)
     645            1122 :         strcpy(units, "meters");
     646                 : 
     647                 :     /* check PCSCitationGeoKey if it exists */
     648            1148 :     szCTString[0] = '\0';
     649            1148 :     if( hGTIF && GTIFKeyGet( hGTIF, PCSCitationGeoKey, szCTString, 0, sizeof(szCTString)) )  
     650                 :     {
     651                 :         /* For tif created by LEICA(ERDAS), ESRI state plane pe string was used and */
     652                 :         /* the state plane zone is given in PCSCitation. Therefore try Esri pe string first. */
     653               8 :         SetCitationToSRS(hGTIF, szCTString, strlen(szCTString), PCSCitationGeoKey, poSRS, pLinearUnitIsSet);
     654               8 :         const char *pcsName = poSRS->GetAttrValue("PROJCS");
     655               8 :         const char *pStr = NULL;
     656               8 :         if( (pcsName && (pStr = strstr(pcsName, "State Plane Zone ")) != NULL)
     657                 :             || (pStr = strstr(szCTString, "State Plane Zone ")) != NULL )
     658                 :         {
     659               2 :             pStr += strlen("State Plane Zone ");
     660               2 :             int statePlaneZone = abs(atoi(pStr));
     661                 :             char nad[32];
     662               2 :             strcpy(nad, "HARN");
     663               2 :             if( strstr(szCTString, "NAD83") || strstr(szCTString, "NAD = 83") )
     664               0 :                 strcpy(nad, "NAD83");
     665               2 :             else if( strstr(szCTString, "NAD27") || strstr(szCTString, "NAD = 27") )
     666               0 :                 strcpy(nad, "NAD27");
     667               2 :             if( poSRS->ImportFromESRIStatePlaneWKT(statePlaneZone, (const char*)nad, (const char*)units, psDefn->PCS) == OGRERR_NONE )
     668               2 :                 return TRUE;
     669                 :         }
     670               6 :         else if( pcsName && (pStr = strstr(pcsName, "UTM Zone ")) != NULL )
     671               0 :             CheckUTM( psDefn, szCTString );
     672                 :     }
     673                 : 
     674                 :     /* check state plane again to see if a pe string is available */
     675            1146 :     if( psDefn->PCS != KvUserDefined )
     676                 :     {
     677            1046 :         if( poSRS->ImportFromESRIStatePlaneWKT(0, NULL, (const char*)units, psDefn->PCS) == OGRERR_NONE )
     678               2 :             return TRUE;
     679                 :     }
     680            1144 :     return FALSE;
     681                 : }
     682                 : 
     683                 : /************************************************************************/
     684                 : /*                               CheckUTM()                             */
     685                 : /*                                                                      */
     686                 : /*        Check utm proj code by its name.                              */
     687                 : /************************************************************************/
     688               0 : void CheckUTM( GTIFDefn * psDefn, char * pszCtString )
     689                 : {
     690               0 :     if(!psDefn || !pszCtString)
     691               0 :         return;
     692                 : 
     693                 :     static const char *apszUtmProjCode[] = {
     694                 :         "PSAD56", "17N", "16017",
     695                 :         "PSAD56", "18N", "16018",
     696                 :         "PSAD56", "19N", "16019",
     697                 :         "PSAD56", "20N", "16020",
     698                 :         "PSAD56", "21N", "16021",
     699                 :         "PSAD56", "17S", "16117",
     700                 :         "PSAD56", "18S", "16118",
     701                 :         "PSAD56", "19S", "16119",
     702                 :         "PSAD56", "20S", "16120",
     703                 :         "PSAD56", "21S", "16121",
     704                 :         "PSAD56", "22S", "16122",
     705                 :         NULL, NULL, NULL};
     706                 : 
     707               0 :     char* p = strstr(pszCtString, "Datum = ");
     708                 :     char datumName[128];
     709               0 :     if(p)
     710                 :     {
     711               0 :         p += strlen("Datum = ");
     712               0 :         char* p1 = strchr(p, '|');
     713               0 :         if(p1)
     714                 :         {
     715               0 :             strncpy(datumName, p, (p1-p));
     716               0 :             datumName[p1-p] = '\0';
     717                 :         }
     718                 :         else
     719               0 :             strcpy(datumName, p);
     720                 :     }
     721                 : 
     722                 :     char utmName[64];
     723               0 :     p = strstr(pszCtString, "UTM Zone ");
     724               0 :     if(p)
     725                 :     {
     726               0 :         p += strlen("UTM Zone ");
     727               0 :         char* p1 = strchr(p, '|');
     728               0 :         if(p1)
     729                 :         {
     730               0 :             strncpy(utmName, p, (p1-p));
     731               0 :             utmName[p1-p] = '\0';
     732                 :         }
     733                 :         else
     734               0 :             strcpy(utmName, p);
     735                 :     }
     736                 : 
     737               0 :     for(int i=0; apszUtmProjCode[i]!=NULL; i += 3)
     738                 :     {
     739               0 :         if(EQUALN(utmName, apszUtmProjCode[i+1], strlen(apszUtmProjCode[i+1])) &&
     740                 :            EQUAL(datumName, apszUtmProjCode[i]) )
     741                 :         {
     742               0 :             if(psDefn->ProjCode != atoi(apszUtmProjCode[i+2]))
     743                 :             {
     744               0 :                 psDefn->ProjCode = (short) atoi(apszUtmProjCode[i+2]);
     745                 :                 GTIFGetProjTRFInfo( psDefn->ProjCode, NULL, &(psDefn->Projection),
     746               0 :                                     psDefn->ProjParm );
     747               0 :                 break;
     748                 :             }
     749                 :         }
     750                 :     }
     751               0 :     return;
     752                 : }

Generated by: LCOV version 1.7