~ubuntu-branches/ubuntu/trusty/liblas/trusty-proposed

« back to all changes in this revision

Viewing changes to src/gt_citation.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2014-01-05 17:00:29 UTC
  • mfrom: (7.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140105170029-ddtp0j63x5jvck2u
Tags: 1.7.0+dfsg-2
Fixed missing linking of system boost component.
(closes: #733282)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id$
 
2
 * $Id: gt_citation.cpp 21848 2011-02-25 16:41:38Z warmerdam $
3
3
 *
4
4
 * Project:  GeoTIFF Driver
5
5
 * Purpose:  Implements special parsing of Imagine citation strings, and
31
31
#include "cpl_port.h"
32
32
#include "cpl_string.h"
33
33
 
34
 
#include "geo_normalize.h"
35
34
#include "geovalues.h"
36
 
#include "ogr_spatialref.h"
37
 
 
38
 
 
39
 
#define nCitationNameTypes 9
40
 
typedef enum 
41
 
{
42
 
  CitCsName = 0,
43
 
  CitPcsName = 1,
44
 
  CitProjectionName = 2,
45
 
  CitLUnitsName = 3,
46
 
  CitGcsName = 4,
47
 
  CitDatumName = 5,
48
 
  CitEllipsoidName = 6,
49
 
  CitPrimemName = 7,
50
 
  CitAUnitsName = 8
51
 
} CitationNameType;
52
 
 
53
 
char* ImagineCitationTranslation(const char* psCitation, geokey_t keyID);
54
 
char** CitationStringParse(const char* psCitation);
55
 
void SetLinearUnitCitation(GTIF* psGTIF, char* pszLinearUOMName);
56
 
void SetGeogCSCitation(GTIF * psGTIF, OGRSpatialReference *poSRS, char* angUnitName, int nDatum, short nSpheroid);
57
 
OGRBoolean SetCitationToSRS(GTIF* hGTIF, char* szCTString, int nCTStringLen,
58
 
                            geokey_t geoKey,  OGRSpatialReference* poSRS, OGRBoolean* linearUnitIsSet);
59
 
void GetGeogCSFromCitation(char* szGCSName, int nGCSName,
60
 
                           geokey_t geoKey, 
61
 
                          char  **ppszGeogName,
62
 
                          char  **ppszDatumName,
63
 
                          char  **ppszPMName,
64
 
                          char  **ppszSpheroidName,
65
 
                          char  **ppszAngularUnits);
 
35
#include "gt_citation.h"
 
36
 
 
37
CPL_CVSID("$Id: gt_citation.cpp 21848 2011-02-25 16:41:38Z 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
};
66
83
 
67
84
/************************************************************************/
68
85
/*                     ImagineCitationTranslation()                     */
69
86
/*                                                                      */
70
87
/*      Translate ERDAS Imagine GeoTif citation                         */
71
88
/************************************************************************/
72
 
char* ImagineCitationTranslation(const char* psCitation, geokey_t keyID)
 
89
char* ImagineCitationTranslation(char* psCitation, geokey_t keyID)
73
90
{
74
 
    char* ret = NULL;
75
 
    if(!psCitation)
76
 
        return ret;
77
 
    if(EQUALN(psCitation, "IMAGINE GeoTIFF Support", strlen("IMAGINE GeoTIFF Support")))
78
 
    {
79
 
        CPLString osName;
 
91
  static const char *keyNames[] = {
 
92
    "NAD = ", "Datum = ", "Ellipsoid = ", "Units = ", NULL
 
93
  };
80
94
 
81
 
        // this is a handle IMAGING style citation
82
 
        const char* p = NULL;
83
 
        p = strchr(psCitation, '$');
84
 
        if(p)
85
 
            p = strchr(p, '\n');
86
 
        if(p)
87
 
            p++;
88
 
        const char* p1 = NULL;
89
 
        if(p)
90
 
            p1 = strchr(p, '\n');
91
 
        if(p && p1)
92
 
        {
93
 
            switch (keyID)
94
 
            {
95
 
              case PCSCitationGeoKey:
96
 
                osName = "PCS Name = ";
97
 
                break;
98
 
              case GTCitationGeoKey:
99
 
                osName = "CS Name = ";
100
 
                break;
101
 
              case GeogCitationGeoKey:
102
 
                if(!strstr(p, "Unable to"))
103
 
                    osName = "GCS Name = ";
104
 
                break;
105
 
              default:
106
 
                break;
107
 
            }
108
 
            if(strlen(osName)>0)
109
 
            {
110
 
                osName.append(p, p1-p);
111
 
                osName += "|";
112
 
            }
113
 
        }
114
 
        p = strstr(psCitation, "Projection Name = ");
115
 
        if(p)
116
 
        {
117
 
            p += strlen("Projection Name = ");
118
 
            p1 = strchr(p, '\n');
119
 
            if(!p1)
120
 
                p1 = strchr(p, '\0');
121
 
        }
122
 
        if(p && p1)
123
 
        {
124
 
            osName.append(p, p1-p);
125
 
            osName += "|";
126
 
        }
127
 
        p = strstr(psCitation, "Datum = ");
128
 
        if(p)
129
 
        {
130
 
            p += strlen("Datum = ");
131
 
            p1 = strchr(p, '\n');
132
 
            if(!p1)
133
 
                p1 = strchr(p, '\0');
134
 
        }
135
 
        if(p && p1)
136
 
        {
137
 
            osName += "Datum = ";
138
 
            osName.append(p, p1-p);
139
 
            osName += "|";
140
 
        }
141
 
        p = strstr(psCitation, "Ellipsoid = ");
142
 
        if(p)
143
 
        {
144
 
            p += strlen("Ellipsoid = ");
145
 
            p1 = strchr(p, '\n');
146
 
            if(!p1)
147
 
                p1 = strchr(p, '\0');
148
 
        }
149
 
        if(p && p1)
150
 
        {
151
 
            osName += "Ellipsoid = ";
152
 
            osName.append(p, p1-p);
153
 
            osName += "|";
154
 
        }
155
 
        p = strstr(psCitation, "Units = ");
156
 
        if(p)
157
 
        {
158
 
            p += strlen("Units = ");
159
 
            p1 = strchr(p, '\n');
160
 
            if(!p1)
161
 
                p1 = strchr(p, '\0');
162
 
        }
163
 
        if(p && p1)
164
 
        {
165
 
            osName += "LUnits = ";
166
 
            osName.append(p, p1-p);
167
 
            osName += "|";
168
 
        }
169
 
        if(strlen(osName) > 0)
170
 
        {
171
 
            ret = CPLStrdup(osName);
172
 
        }
173
 
    }
 
95
  char* ret = NULL;
 
96
  int i;
 
97
  if(!psCitation)
174
98
    return ret;
 
99
  if(EQUALN(psCitation, "IMAGINE GeoTIFF Support", strlen("IMAGINE GeoTIFF Support")))
 
100
  {
 
101
    // this is a handle IMAGING style citation
 
102
    char name[256];
 
103
    name[0] = '\0';
 
104
    char* p = NULL;
 
105
    char* p1 = NULL;
 
106
 
 
107
    p = strchr(psCitation, '$');
 
108
    if( p && strchr(p, '\n') )
 
109
      p = strchr(p, '\n') + 1;
 
110
    if(p)
 
111
    {
 
112
      p1 = p + strlen(p);
 
113
      char *p2 = strchr(p, '\n');
 
114
      if(p2)
 
115
        p1 = MIN(p1, p2);
 
116
      p2 = strchr(p, '\0');
 
117
      if(p2)
 
118
        p1 = MIN(p1, p2);
 
119
      for(i=0; keyNames[i]!=NULL; i++)
 
120
      {
 
121
        p2 = strstr(p, keyNames[i]);
 
122
        if(p2)
 
123
          p1 = MIN(p1, p2);
 
124
      }
 
125
    }
 
126
 
 
127
    // PCS name, GCS name and PRJ name
 
128
    if(p && p1)
 
129
    {
 
130
      switch (keyID)
 
131
      {
 
132
        case PCSCitationGeoKey:
 
133
          if(strstr(psCitation, "Projection = "))
 
134
            strcpy(name, "PRJ Name = ");
 
135
          else
 
136
            strcpy(name, "PCS Name = ");
 
137
        break;
 
138
        case GTCitationGeoKey:
 
139
          strcpy(name, "PCS Name = ");
 
140
        break;
 
141
        case GeogCitationGeoKey:
 
142
          if(!strstr(p, "Unable to"))
 
143
            strcpy(name, "GCS Name = ");
 
144
        break;
 
145
        default:
 
146
        break;
 
147
      }
 
148
      if(strlen(name)>0)
 
149
      {
 
150
        char* p2;
 
151
        if((p2 = strstr(psCitation, "Projection Name = ")) != 0)
 
152
          p = p2 + strlen("Projection Name = ");
 
153
        if((p2 = strstr(psCitation, "Projection = ")) != 0)
 
154
          p = p2 + strlen("Projection = ");
 
155
        if(p1[0] == '\0' || p1[0] == '\n' || p1[0] == ' ')
 
156
          p1 --;
 
157
        p2 = p1 - 1;
 
158
        while( p2>0 && (p2[0] == ' ' || p2[0] == '\0' || p2[0] == '\n') )
 
159
          p2--;
 
160
        if(p2 != p1 - 1)
 
161
          p1 = p2;
 
162
        if(p1 >= p)
 
163
        {
 
164
          strncat(name, p, p1-p+1);
 
165
          strcat(name, "|");
 
166
          name[strlen(name)] = '\0';
 
167
        }
 
168
      }
 
169
    }
 
170
 
 
171
    // All other parameters
 
172
    for(i=0; keyNames[i]!=NULL; i++)
 
173
    {
 
174
      p = strstr(psCitation, keyNames[i]);
 
175
      if(p)
 
176
      {
 
177
        p += strlen(keyNames[i]);
 
178
        p1 = p + strlen(p);
 
179
        char *p2 = strchr(p, '\n');
 
180
        if(p2)
 
181
          p1 = MIN(p1, p2);
 
182
        p2 = strchr(p, '\0');
 
183
        if(p2)
 
184
          p1 = MIN(p1, p2);
 
185
        for(int j=0; keyNames[j]!=NULL; j++)
 
186
        {
 
187
          p2 = strstr(p, keyNames[j]);
 
188
          if(p2)
 
189
            p1 = MIN(p1, p2);
 
190
        }
 
191
      }
 
192
      if(p && p1 && p1>p)
 
193
      {
 
194
        if(EQUAL(keyNames[i], "Units = "))
 
195
          strcat(name, "LUnits = ");
 
196
        else
 
197
          strcat(name, keyNames[i]);
 
198
        if(p1[0] == '\0' || p1[0] == '\n' || p1[0] == ' ')
 
199
          p1 --;
 
200
        char* p2 = p1 - 1;
 
201
        while( p2>0 && (p2[0] == ' ' || p2[0] == '\0' || p2[0] == '\n') )
 
202
          p2--;
 
203
        if(p2 != p1 - 1)
 
204
          p1 = p2;
 
205
        if(p1 >= p)
 
206
        {
 
207
          strncat(name, p, p1-p+1);
 
208
          strcat(name, "|");
 
209
          name[strlen(name)] = '\0';
 
210
        }
 
211
      }
 
212
    }
 
213
    if(strlen(name) > 0)
 
214
      ret = CPLStrdup(name);
 
215
  }
 
216
  return ret;
 
217
 
175
218
}
176
219
 
177
220
/************************************************************************/
179
222
/*                                                                      */
180
223
/*      Parse a Citation string                                         */
181
224
/************************************************************************/
182
 
char** CitationStringParse(const char* psCitation)
 
225
 
 
226
char** CitationStringParse(char* psCitation, geokey_t keyID)
183
227
{
184
 
    char ** ret = NULL;
185
 
    if(!psCitation)
186
 
        return ret;
187
 
 
188
 
    ret = (char **) CPLCalloc(sizeof(char*), nCitationNameTypes); 
189
 
    const char* pDelimit = NULL;
190
 
    const char* pStr = psCitation;
191
 
    CPLString osName;
192
 
    int nCitationLen = strlen(psCitation);
193
 
    OGRBoolean nameFound = FALSE;
194
 
    while((pStr-psCitation+1)< nCitationLen)
195
 
    {
196
 
        if( (pDelimit = strstr(pStr, "|")) )
197
 
        {
198
 
            osName = "";
199
 
            osName.append(pStr, pDelimit-pStr);
200
 
            pStr = pDelimit+1;
201
 
        }
202
 
        else
203
 
        {
204
 
            osName = pStr;
205
 
            pStr += strlen(pStr);
206
 
        }
207
 
        const char* name = osName.c_str();
208
 
        if( strstr(name, "PCS Name = ") )
209
 
        {
210
 
            if (!ret[CitPcsName])
211
 
                ret[CitPcsName] = CPLStrdup(name+strlen("PCS Name = "));
212
 
            nameFound = TRUE;
213
 
        }
214
 
        if(strstr(name, "Projection Name = "))
215
 
        {
216
 
            if (!ret[CitProjectionName])
217
 
                ret[CitProjectionName] = CPLStrdup(name+strlen("Projection Name = "));
218
 
            nameFound = TRUE;
219
 
        }
220
 
        if(strstr(name, "LUnits = "))
221
 
        {
222
 
            if (!ret[CitLUnitsName])
223
 
                ret[CitLUnitsName] = CPLStrdup(name+strlen("LUnits = "));
224
 
            nameFound = TRUE;
225
 
        }
226
 
        if(strstr(name, "GCS Name = "))
227
 
        {
228
 
            if (!ret[CitGcsName])
229
 
                ret[CitGcsName] = CPLStrdup(name+strlen("GCS Name = "));
230
 
            nameFound = TRUE;
231
 
        }
232
 
        if(strstr(name, "Datum = "))
233
 
        {
234
 
            if (!ret[CitDatumName])
235
 
                ret[CitDatumName] = CPLStrdup(name+strlen("Datum = "));
236
 
            nameFound = TRUE;
237
 
        }
238
 
        if(strstr(name, "Ellipsoid = "))
239
 
        {
240
 
            if (!ret[CitEllipsoidName])
241
 
                ret[CitEllipsoidName] = CPLStrdup(name+strlen("Ellipsoid = "));
242
 
            nameFound = TRUE;
243
 
        }
244
 
        if(strstr(name, "Primem = "))
245
 
        {
246
 
            if (!ret[CitPrimemName])
247
 
                ret[CitPrimemName] = CPLStrdup(name+strlen("Primem = "));
248
 
            nameFound = TRUE;
249
 
        }
250
 
        if(strstr(name, "AUnits = "))
251
 
        {
252
 
            if (!ret[CitAUnitsName])
253
 
                ret[CitAUnitsName] = CPLStrdup(name+strlen("AUnits = "));
254
 
            nameFound = TRUE;
255
 
        }
256
 
    }
257
 
    if(!nameFound)
258
 
    {
259
 
        CPLFree( ret );
260
 
        ret = (char**)NULL;
261
 
    }
 
228
  char ** ret = NULL;
 
229
  if(!psCitation)
262
230
    return ret;
 
231
 
 
232
  ret = (char **) CPLCalloc(sizeof(char*), nCitationNameTypes); 
 
233
  char* pDelimit = NULL;
 
234
  char* pStr = psCitation;
 
235
  char name[512];
 
236
  int nameLen = strlen(psCitation);
 
237
  OGRBoolean nameFound = FALSE;
 
238
  while((pStr-psCitation+1)< nameLen)
 
239
  {
 
240
    if( (pDelimit = strstr(pStr, "|")) != NULL )
 
241
    {
 
242
      strncpy( name, pStr, pDelimit-pStr );
 
243
      name[pDelimit-pStr] = '\0';
 
244
      pStr = pDelimit+1;
 
245
    }
 
246
    else
 
247
    {
 
248
      strcpy (name, pStr);
 
249
      pStr += strlen(pStr);
 
250
    }
 
251
    if( strstr(name, "PCS Name = ") )
 
252
    {
 
253
      ret[CitPcsName] = CPLStrdup(name+strlen("PCS Name = "));
 
254
      nameFound = TRUE;
 
255
    }
 
256
    if(strstr(name, "PRJ Name = "))
 
257
    {
 
258
      ret[CitProjectionName] = CPLStrdup(name+strlen("PRJ Name = "));
 
259
      nameFound = TRUE;
 
260
    }
 
261
    if(strstr(name, "LUnits = "))
 
262
    {
 
263
      ret[CitLUnitsName] = CPLStrdup(name+strlen("LUnits = "));
 
264
      nameFound = TRUE;
 
265
    }
 
266
    if(strstr(name, "GCS Name = "))
 
267
    {
 
268
      ret[CitGcsName] = CPLStrdup(name+strlen("GCS Name = "));
 
269
      nameFound = TRUE;
 
270
    }
 
271
    if(strstr(name, "Datum = "))
 
272
    {
 
273
      ret[CitDatumName] = CPLStrdup(name+strlen("Datum = "));
 
274
      nameFound = TRUE;
 
275
    }
 
276
    if(strstr(name, "Ellipsoid = "))
 
277
    {
 
278
      ret[CitEllipsoidName] = CPLStrdup(name+strlen("Ellipsoid = "));
 
279
      nameFound = TRUE;
 
280
    }
 
281
    if(strstr(name, "Primem = "))
 
282
    {
 
283
      ret[CitPrimemName] = CPLStrdup(name+strlen("Primem = "));    
 
284
      nameFound = TRUE;
 
285
    }
 
286
    if(strstr(name, "AUnits = "))
 
287
    {
 
288
      ret[CitAUnitsName] = CPLStrdup(name+strlen("AUnits = "));
 
289
      nameFound = TRUE;
 
290
    }
 
291
  }
 
292
  if( !nameFound && keyID == GeogCitationGeoKey )
 
293
  {
 
294
    ret[CitGcsName] = CPLStrdup(name);
 
295
    nameFound = TRUE;
 
296
  }
 
297
  if(!nameFound)
 
298
  {
 
299
    CPLFree( ret );
 
300
    ret = (char**)NULL;
 
301
  }
 
302
  return ret;
263
303
}
264
304
 
 
305
 
265
306
/************************************************************************/
266
307
/*                       SetLinearUnitCitation()                        */
267
308
/*                                                                      */
379
420
OGRBoolean SetCitationToSRS(GTIF* hGTIF, char* szCTString, int nCTStringLen,
380
421
                            geokey_t geoKey,  OGRSpatialReference*      poSRS, OGRBoolean* linearUnitIsSet)
381
422
{
382
 
    OGRBoolean ret = FALSE;
 
423
  OGRBoolean ret = FALSE;
 
424
  char* lUnitName = NULL;
 
425
  if(!lUnitName || strlen(lUnitName) == 0  || EQUAL(lUnitName, "unknown"))
383
426
    *linearUnitIsSet = FALSE;
384
 
    char* imgCTName = ImagineCitationTranslation(szCTString, geoKey);
385
 
    if(imgCTName)
386
 
    {
387
 
        strncpy(szCTString, imgCTName, nCTStringLen);
388
 
        szCTString[nCTStringLen-1] = '\0';
389
 
        CPLFree( imgCTName );
390
 
    }
391
 
    char** ctNames = CitationStringParse(szCTString);
392
 
    if(ctNames)
393
 
    {
394
 
        if( poSRS->GetRoot() == NULL)
395
 
            poSRS->SetNode( "PROJCS", "unnamed" );
396
 
        if(ctNames[CitPcsName])
397
 
        {
398
 
            poSRS->SetNode( "PROJCS", ctNames[CitPcsName] );
399
 
            ret = TRUE;
400
 
        }
401
 
        else if(geoKey != GTCitationGeoKey) 
402
 
        {
403
 
            char    szPCSName[128];
404
 
            if( GTIFKeyGet( hGTIF, GTCitationGeoKey, szPCSName, 0, sizeof(szPCSName) ) )
405
 
            {
406
 
                poSRS->SetNode( "PROJCS", szPCSName );
407
 
                ret = TRUE;
408
 
            }
409
 
        }
410
 
    
411
 
        if(ctNames[CitProjectionName])
412
 
            poSRS->SetProjection( ctNames[CitProjectionName] );
413
 
 
414
 
        if(ctNames[CitLUnitsName])
415
 
        {
416
 
            double unitSize;
417
 
            if (GTIFKeyGet(hGTIF, ProjLinearUnitSizeGeoKey, &unitSize, 0,
418
 
                           sizeof(unitSize) ))
419
 
            {
420
 
                poSRS->SetLinearUnits( ctNames[CitLUnitsName], unitSize);
421
 
                *linearUnitIsSet = TRUE;
422
 
            }
423
 
        }
424
 
        for(int i= 0; i<nCitationNameTypes; i++) 
425
 
            CPLFree( ctNames[i] );
426
 
        CPLFree( ctNames );
427
 
    }
428
 
    return ret;
 
427
  else
 
428
    *linearUnitIsSet = TRUE;
 
429
 
 
430
  char* imgCTName = ImagineCitationTranslation(szCTString, geoKey);
 
431
  if(imgCTName)
 
432
  {
 
433
    strncpy(szCTString, imgCTName, nCTStringLen);
 
434
    szCTString[nCTStringLen-1] = '\0';
 
435
    CPLFree( imgCTName );
 
436
  }
 
437
  char** ctNames = CitationStringParse(szCTString, geoKey);
 
438
  if(ctNames)
 
439
  {
 
440
    if( poSRS->GetRoot() == NULL)
 
441
      poSRS->SetNode( "PROJCS", "unnamed" );
 
442
    if(ctNames[CitPcsName])
 
443
    {
 
444
      poSRS->SetNode( "PROJCS", ctNames[CitPcsName] );
 
445
      ret = TRUE;
 
446
    }
 
447
    if(ctNames[CitProjectionName])
 
448
      poSRS->SetProjection( ctNames[CitProjectionName] );
 
449
 
 
450
    if(ctNames[CitLUnitsName])
 
451
    {
 
452
      double unitSize = 0.0;
 
453
      int size = strlen(ctNames[CitLUnitsName]);
 
454
      if(strchr(ctNames[CitLUnitsName], '\0'))
 
455
        size -= 1;
 
456
      for( int i = 0; apszUnitMap[i] != NULL; i += 2 )
 
457
      {
 
458
            if( EQUALN(apszUnitMap[i], ctNames[CitLUnitsName], size) )
 
459
            {
 
460
                unitSize = atof(apszUnitMap[i+1]);
 
461
                break;
 
462
            }
 
463
      }
 
464
      if( unitSize == 0.0 )
 
465
        GTIFKeyGet(hGTIF, ProjLinearUnitSizeGeoKey, &unitSize, 0,
 
466
                         sizeof(unitSize) );
 
467
      poSRS->SetLinearUnits( ctNames[CitLUnitsName], unitSize);
 
468
      *linearUnitIsSet = TRUE;
 
469
    }
 
470
    for(int i= 0; i<nCitationNameTypes; i++) 
 
471
      CPLFree( ctNames[i] );
 
472
    CPLFree( ctNames );
 
473
  }
 
474
 
 
475
  /* if no "PCS Name = " (from Erdas) in GTCitationGeoKey */
 
476
  if(geoKey == GTCitationGeoKey)
 
477
  {
 
478
    if(strlen(szCTString) > 0 && !strstr(szCTString, "PCS Name = "))
 
479
    {
 
480
      const char* pszProjCS = poSRS->GetAttrValue( "PROJCS" );
 
481
      if((!(pszProjCS && strlen(pszProjCS) > 0) && !strstr(szCTString, "Projected Coordinates"))
 
482
         || strstr(pszProjCS, "unnamed"))
 
483
        poSRS->SetNode( "PROJCS", szCTString );
 
484
      ret = TRUE;
 
485
    }
 
486
  }
 
487
 
 
488
  return ret;
 
489
 
429
490
}
430
491
 
431
492
/************************************************************************/
451
512
        szGCSName[nGCSName-1] = '\0';
452
513
        CPLFree( imgCTName );
453
514
    }
454
 
    char** ctNames = CitationStringParse(szGCSName);
 
515
    char** ctNames = CitationStringParse(szGCSName, geoKey);
455
516
    if(ctNames)
456
517
    {
457
518
        if(ctNames[CitGcsName])
477
538
}
478
539
 
479
540
 
 
541
/************************************************************************/
 
542
/*               CheckCitationKeyForStatePlaneUTM()                     */
 
543
/*                                                                      */
 
544
/*      Handle state plane and UTM in citation key                      */
 
545
/************************************************************************/
 
546
OGRBoolean CheckCitationKeyForStatePlaneUTM(GTIF* hGTIF, GTIFDefn* psDefn, OGRSpatialReference* poSRS, OGRBoolean* pLinearUnitIsSet)
 
547
{
 
548
  if( !hGTIF || !psDefn || !poSRS )
 
549
    return FALSE;
 
550
  char  szCTString[512];
 
551
  szCTString[0] = '\0';
 
552
 
 
553
  /* Check units */
 
554
  char units[32];
 
555
  units[0] = '\0';
 
556
 
 
557
  OGRBoolean hasUnits = FALSE;
 
558
  if( GTIFKeyGet( hGTIF, GTCitationGeoKey, szCTString, 0, sizeof(szCTString) ) )
 
559
  {
 
560
    if( strstr(szCTString, "us") && strstr(szCTString, "survey")
 
561
     && (strstr(szCTString, "feet") || strstr(szCTString, "foot")))
 
562
     strcpy(units, "us_survey_feet");
 
563
    else if(strstr(szCTString, "feet") || strstr(szCTString, "foot"))
 
564
      strcpy(units, "international_feet");
 
565
    else if(strstr(szCTString, "meter"))
 
566
      strcpy(units, "meters");
 
567
 
 
568
    if (strlen(units) > 0)
 
569
      hasUnits = TRUE;
 
570
 
 
571
    if( strstr( szCTString, "Projection Name = ") && strstr( szCTString, "_StatePlane_"))
 
572
    {
 
573
      const char *pStr = strstr( szCTString, "Projection Name = ") + strlen("Projection Name = ");
 
574
      const char* pReturn = strchr( pStr, '\n');
 
575
      char CSName[128];
 
576
      strncpy(CSName, pStr, pReturn-pStr);
 
577
      CSName[pReturn-pStr] = '\0';
 
578
#if GDAL_VERSION_NUM >=1900
 
579
      if( poSRS->ImportFromESRIStatePlaneWKT(0, NULL, NULL, 32767, CSName) == OGRERR_NONE )
 
580
      {
 
581
        // for some erdas citation keys, the state plane CS name is incomplete, the unit check is necessary.
 
582
        OGRBoolean done = FALSE;
 
583
        if (hasUnits)
 
584
        {
 
585
          OGR_SRSNode *poUnit = poSRS->GetAttrNode( "PROJCS|UNIT" );
 
586
      
 
587
          if( poUnit != NULL && poUnit->GetChildCount() >= 2 )
 
588
          {
 
589
            const char* unitName = poUnit->GetChild(0)->GetValue();
 
590
            if (strstr(units, "us_survey_feet"))
 
591
            {              
 
592
              if (strstr(unitName, "us_survey_feet") || strstr(unitName, "Foot_US") || strstr(unitName, "foot_US"))
 
593
                done = TRUE;
 
594
            }
 
595
            else if (strstr(units, "international_feet"))
 
596
            {
 
597
              if (strstr(unitName, "international_feet") || strstr(unitName, "Foot") || strstr(unitName, "foot"))
 
598
                done = TRUE;
 
599
            }
 
600
            else if (strstr(units, "meters"))
 
601
            {
 
602
              if (strstr(unitName, "meter") || strstr(unitName, "Meter"))
 
603
                done = TRUE;
 
604
            }
 
605
          }
 
606
        }
 
607
        if (done)
 
608
          return TRUE;
 
609
      }
 
610
#endif
 
611
    }
 
612
  }
 
613
  if( !hasUnits )
 
614
  {
 
615
    char        *pszUnitsName = NULL;
 
616
    GTIFGetUOMLengthInfo( psDefn->UOMLength, &pszUnitsName, NULL );
 
617
    if( pszUnitsName && strlen(pszUnitsName) > 0 )
 
618
    {
 
619
      strcpy( szCTString, pszUnitsName );
 
620
      GTIFFreeMemory( pszUnitsName );
 
621
      if( strstr(szCTString, "us") && strstr(szCTString, "survey")
 
622
       && (strstr(szCTString, "feet") || strstr(szCTString, "foot")))
 
623
       strcpy(units, "us_survey_feet");
 
624
      else if(strstr(szCTString, "feet") || strstr(szCTString, "foot"))
 
625
        strcpy(units, "international_feet");
 
626
      else if(strstr(szCTString, "meter"))
 
627
        strcpy(units, "meters");
 
628
      hasUnits = TRUE;
 
629
    }
 
630
  }
 
631
 
 
632
  if (strlen(units) == 0)
 
633
    strcpy(units, "meters");
 
634
 
 
635
  /* check PCSCitationGeoKey if it exists */
 
636
  szCTString[0] = '\0';
 
637
  if( hGTIF && GTIFKeyGet( hGTIF, PCSCitationGeoKey, szCTString, 0, sizeof(szCTString)) )  
 
638
  {
 
639
      /* For tif created by LEICA(ERDAS), ESRI state plane pe string was used and */
 
640
      /* the state plane zone is given in PCSCitation. Therefore try Esri pe string first. */
 
641
      SetCitationToSRS(hGTIF, szCTString, strlen(szCTString), PCSCitationGeoKey, poSRS, pLinearUnitIsSet);
 
642
      const char *pcsName = poSRS->GetAttrValue("PROJCS");
 
643
      const char *pStr = NULL;
 
644
      if( (pcsName && (pStr = strstr(pcsName, "State Plane Zone ")) != NULL)
 
645
          || (pStr = strstr(szCTString, "State Plane Zone ")) != NULL )
 
646
      {
 
647
        pStr += strlen("State Plane Zone ");
 
648
        int statePlaneZone = abs(atoi(pStr));
 
649
        char nad[32];
 
650
        strcpy(nad, "HARN");
 
651
        if( strstr(szCTString, "NAD83") || strstr(szCTString, "NAD = 83") )
 
652
          strcpy(nad, "NAD83");
 
653
        else if( strstr(szCTString, "NAD27") || strstr(szCTString, "NAD = 27") )
 
654
          strcpy(nad, "NAD27");
 
655
#if GDAL_VERSION_NUM >=1900
 
656
        if( poSRS->ImportFromESRIStatePlaneWKT(statePlaneZone, (const char*)nad, (const char*)units, psDefn->PCS) == OGRERR_NONE )
 
657
          return TRUE;
 
658
#endif
 
659
      }
 
660
      else if( pcsName && (pStr = strstr(pcsName, "UTM Zone ")) != NULL )
 
661
        CheckUTM( psDefn, szCTString );
 
662
  }
 
663
 
 
664
  /* check state plane again to see if a pe string is available */
 
665
  if( psDefn->PCS != KvUserDefined )
 
666
  {
 
667
#if GDAL_VERSION_NUM >=1900
 
668
    if( poSRS->ImportFromESRIStatePlaneWKT(0, NULL, (const char*)units, psDefn->PCS) == OGRERR_NONE )
 
669
      return TRUE;
 
670
#endif
 
671
  }
 
672
  return FALSE;
 
673
}
 
674
 
 
675
/************************************************************************/
 
676
/*                               CheckUTM()                             */
 
677
/*                                                                      */
 
678
/*        Check utm proj code by its name.                              */
 
679
/************************************************************************/
 
680
void CheckUTM( GTIFDefn * psDefn, char * pszCtString )
 
681
{
 
682
  if(!psDefn || !pszCtString)
 
683
    return;
 
684
 
 
685
  static const char *apszUtmProjCode[] = {
 
686
    "PSAD56", "17N", "16017",
 
687
    "PSAD56", "18N", "16018",
 
688
    "PSAD56", "19N", "16019",
 
689
    "PSAD56", "20N", "16020",
 
690
    "PSAD56", "21N", "16021",
 
691
    "PSAD56", "17S", "16117",
 
692
    "PSAD56", "18S", "16118",
 
693
    "PSAD56", "19S", "16119",
 
694
    "PSAD56", "20S", "16120",
 
695
    "PSAD56", "21S", "16121",
 
696
    "PSAD56", "22S", "16122",
 
697
  NULL, NULL, NULL};
 
698
 
 
699
  char* p = strstr(pszCtString, "Datum = ");
 
700
  char datumName[128];
 
701
  if(p)
 
702
  {
 
703
    p += strlen("Datum = ");
 
704
    char* p1 = strchr(p, '|');
 
705
    if(p1)
 
706
    {
 
707
      strncpy(datumName, p, (p1-p));
 
708
      datumName[p1-p] = '\0';
 
709
    }
 
710
    else
 
711
      strcpy(datumName, p);
 
712
  }
 
713
 
 
714
  char utmName[64];
 
715
  p = strstr(pszCtString, "UTM Zone ");
 
716
  if(p)
 
717
  {
 
718
    p += strlen("UTM Zone ");
 
719
    char* p1 = strchr(p, '|');
 
720
    if(p1)
 
721
    {
 
722
      strncpy(utmName, p, (p1-p));
 
723
      utmName[p1-p] = '\0';
 
724
    }
 
725
    else
 
726
      strcpy(utmName, p);
 
727
  }
 
728
 
 
729
  for(int i=0; apszUtmProjCode[i]!=NULL; i += 3)
 
730
  {
 
731
    if(EQUALN(utmName, apszUtmProjCode[i+1], strlen(apszUtmProjCode[i+1])) &&
 
732
       EQUAL(datumName, apszUtmProjCode[i]) )
 
733
    {
 
734
      if(psDefn->ProjCode != atoi(apszUtmProjCode[i+2]))
 
735
      {
 
736
        psDefn->ProjCode = (short) atoi(apszUtmProjCode[i+2]);
 
737
        GTIFGetProjTRFInfo( psDefn->ProjCode, NULL, &(psDefn->Projection),
 
738
                            psDefn->ProjParm );
 
739
        break;
 
740
      }
 
741
    }
 
742
  }
 
743
  return;
 
744
}