LCOV - code coverage report
Current view: directory - frmts/gtiff - gt_citation.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 363 183 50.4 %
Date: 2012-12-26 Functions: 8 7 87.5 %

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

Generated by: LCOV version 1.7