diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index 66bd9d177c02fbb61355daf07fcbb688184d3a0c..21b76ce5d49efc0715e4a3bb9da4db80c1c0ac6e 100755 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -4,7 +4,7 @@ IF(NOT OTB_USE_EXTERNAL_ITK) SUBDIRS( ITK ) ENDIF(NOT OTB_USE_EXTERNAL_ITK) -SUBDIRS(BGL otbsvm dxflib InsightJournal otbossim otb6S) +SUBDIRS(BGL otbsvm dxflib InsightJournal otbossim otb6S otbgeotiff) IF(BUILD_TESTING) SUBDIRS( Dart ) diff --git a/Utilities/otbgeotiff/CMakeLists.txt b/Utilities/otbgeotiff/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0fad6e0e9048bdc08d47dfdb566de76b63951398 --- /dev/null +++ b/Utilities/otbgeotiff/CMakeLists.txt @@ -0,0 +1,20 @@ +PROJECT(libgeotiff) + +FILE(GLOB libgeotiff_SRCS "*.c") +FILE(GLOB libgeotiff_HDRS "*.h") + +CONFIGURE_FILE(geo_config.h.in geo_config.h) + +ADD_LIBRARY(otbgeotiff ${libgeotiff_SRCS}) +TARGET_LINK_LIBRARIES(otbgeotiff) + +INSTALL(TARGETS otbgeotiff +RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries +LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries +ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT Development) + +INSTALL(FILES ${libgeotiff_HDRS_HDRS} + DESTINATION ${OTB_INSTALL_INCLUDE_DIR}/Utilities/otbgeotiff + COMPONENT Development) + +SUBDIRS(libxtiff) diff --git a/Utilities/otbgeotiff/LICENSE b/Utilities/otbgeotiff/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..ac409dafebb2e6cc05c6dea5459e42ed1f154d03 --- /dev/null +++ b/Utilities/otbgeotiff/LICENSE @@ -0,0 +1,83 @@ + + libgeotiff Licensing + ==================== + +All the source code in this toolkit are either in the public domain, or under +an X style license. In any event it is all considered to be free to use +for any purpose (including commercial software). No credit is required +though some of the code requires that the specific source code modules +retain their existing copyright statements. The CSV files, and other tables +derived from the EPSG coordinate system database are also free to use. In +particular, no part of this code is "copyleft", nor does it imply any +requirement for users to disclose this or their own source code. + +All components not carrying their own copyright message, but distributed +with libgeotiff should be considered to be under the same license as +Niles' code. + +--------- + +Code by Frank Warmerdam has this copyright notice (directly copied from +X Consortium licence): + + * Copyright (c) 1999, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + +----------- + +Code by Niles Ritter is under this licence: + + * Written By: Niles D. Ritter. + * + * copyright (c) 1995 Niles D. Ritter + * + * Permission granted to use this software, so long as this copyright + * notice accompanies any products derived therefrom. + +----------- + +The EPSG Tables (from which the CSV files, and .inc files are derived) +carried this statement on use of the data (from the EPSG web site): + + Use of the Data + + The user assumes the entire risk as to the accuracy and the use of this + data. The data may be copied and distributed subject to the following + conditions: + + 1.All data pertinent to a specific coordinate system must be copied + without modification and all related pages must be included; + + 2.All components of this data set pertinent to any given coordinate + system must be distributed together (complete distribution of all + components of the data set is preferred, but the EPSG recognises + the need for a more limited distribution); + + 3.The data may not be distributed for profit by any third party; and + 4.The original source [EPSG] must be acknowledged. + + INFORMATION PROVIDED IN THIS DOCUMENT IS PROVIDED "AS + IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A + PARTICULAR PURPOSE. + + + diff --git a/Utilities/otbgeotiff/cpl_csv.c b/Utilities/otbgeotiff/cpl_csv.c new file mode 100644 index 0000000000000000000000000000000000000000..e37861cec6343725192cd19cca531f5992f9898a --- /dev/null +++ b/Utilities/otbgeotiff/cpl_csv.c @@ -0,0 +1,1016 @@ +/****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * cpl_csv.c: Support functions for accessing CSV files. + * + * $Log: cpl_csv.c,v $ + * Revision 1.16 2003/07/10 18:03:28 warmerda + * don't crash if NULL passed to gtCSVAccess() + * + * Revision 1.15 2003/01/20 06:46:35 warmerda + * search for pcs.csv, not horiz_cs.csv + * + * Revision 1.14 2003/01/15 04:39:58 warmerda + * change internal name of CSVAccess + * + * Revision 1.13 2002/11/28 22:26:41 warmerda + * upgraded to proper CSV formatting, and in-memory caching + * + * Revision 1.12 2002/06/19 03:51:15 warmerda + * migrated cpl_csv.h into cpl_serv.h + * + * Revision 1.11 2001/03/05 04:49:56 warmerda + * try to clear CPLReadLine buffer on deaccess + * + * Revision 1.10 2001/01/17 15:32:19 warmerda + * Include /usr/share/epsg_csv and share/epsg_csv in csv search path. + * + * Revision 1.9 2000/12/12 19:34:36 warmerda + * Use CSV_DATA_DIR if defined. + * + * Revision 1.8 2000/08/22 04:33:33 warmerda + * added support for /usr/local/shared/epsg_csv + * + * Revision 1.7 1999/12/03 14:42:59 warmerda + * Passing a NULL filename into CSVAccess() now results in a graceful + * failure to open the file. + * + * Revision 1.6 1999/06/26 17:28:51 warmerda + * Fixed reading of records with newlines embedded in quoted strings. + * + * Revision 1.5 1999/05/04 03:07:24 warmerda + * avoid warning + * + * Revision 1.4 1999/04/28 19:59:56 warmerda + * added some doxygen style documentation + * + * Revision 1.3 1999/03/17 19:53:15 geotiff + * sys includes moved to cpl_serv.h + * + * Revision 1.2 1999/03/10 16:54:42 geotiff + * Added use of the GEOTIFF_CSV environment variable to locate CSV files. + * + * Revision 1.1 1999/03/09 15:57:04 geotiff + * New + * + * Revision 1.2 1999/02/24 16:23:21 warmerda + * added lots + * + * Revision 1.1 1999/01/05 16:52:36 warmerda + * New + * + */ + +#include "cpl_serv.h" +#include "geo_tiffp.h" + +/* ==================================================================== */ +/* The CSVTable is a persistant set of info about an open CSV */ +/* table. While it doesn't currently maintain a record index, */ +/* or in-memory copy of the table, it could be changed to do so */ +/* in the future. */ +/* ==================================================================== */ +typedef struct ctb { + FILE *fp; + + struct ctb *psNext; + + char *pszFilename; + + char **papszFieldNames; + + char **papszRecFields; + + int iLastLine; + + /* Cache for whole file */ + int nLineCount; + char **papszLines; + int *panLineIndex; + char *pszRawData; +} CSVTable; + +static CSVTable *psCSVTableList = NULL; + +/************************************************************************/ +/* CSVAccess() */ +/* */ +/* This function will fetch a handle to the requested table. */ +/* If not found in the ``open table list'' the table will be */ +/* opened and added to the list. Eventually this function may */ +/* become public with an abstracted return type so that */ +/* applications can set options about the table. For now this */ +/* isn't done. */ +/************************************************************************/ + +static CSVTable *gtCSVAccess( const char * pszFilename ) + +{ + CSVTable *psTable; + FILE *fp; + + if( pszFilename == NULL ) + return NULL; + +/* -------------------------------------------------------------------- */ +/* Is the table already in the list. */ +/* -------------------------------------------------------------------- */ + for( psTable = psCSVTableList; psTable != NULL; psTable = psTable->psNext ) + { + if( EQUAL(psTable->pszFilename,pszFilename) ) + { + /* + * Eventually we should consider promoting to the front of + * the list to accelerate frequently accessed tables. + */ + + return( psTable ); + } + } + +/* -------------------------------------------------------------------- */ +/* If not, try to open it. */ +/* -------------------------------------------------------------------- */ + fp = VSIFOpen( pszFilename, "rb" ); + if( fp == NULL ) + return NULL; + +/* -------------------------------------------------------------------- */ +/* Create an information structure about this table, and add to */ +/* the front of the list. */ +/* -------------------------------------------------------------------- */ + psTable = (CSVTable *) CPLCalloc(sizeof(CSVTable),1); + + psTable->fp = fp; + psTable->pszFilename = CPLStrdup( pszFilename ); + psTable->psNext = psCSVTableList; + + psCSVTableList = psTable; + +/* -------------------------------------------------------------------- */ +/* Read the table header record containing the field names. */ +/* -------------------------------------------------------------------- */ + psTable->papszFieldNames = CSVReadParseLine( fp ); + + return( psTable ); +} + +/************************************************************************/ +/* CSVDeaccess() */ +/************************************************************************/ + +void CSVDeaccess( const char * pszFilename ) + +{ + CSVTable *psLast, *psTable; + +/* -------------------------------------------------------------------- */ +/* A NULL means deaccess all tables. */ +/* -------------------------------------------------------------------- */ + if( pszFilename == NULL ) + { + while( psCSVTableList != NULL ) + CSVDeaccess( psCSVTableList->pszFilename ); + + return; + } + +/* -------------------------------------------------------------------- */ +/* Find this table. */ +/* -------------------------------------------------------------------- */ + psLast = NULL; + for( psTable = psCSVTableList; + psTable != NULL && !EQUAL(psTable->pszFilename,pszFilename); + psTable = psTable->psNext ) + { + psLast = psTable; + } + + if( psTable == NULL ) + { + return; + } + +/* -------------------------------------------------------------------- */ +/* Remove the link from the list. */ +/* -------------------------------------------------------------------- */ + if( psLast != NULL ) + psLast->psNext = psTable->psNext; + else + psCSVTableList = psTable->psNext; + +/* -------------------------------------------------------------------- */ +/* Free the table. */ +/* -------------------------------------------------------------------- */ + if( psTable->fp != NULL ) + VSIFClose( psTable->fp ); + + CSLDestroy( psTable->papszFieldNames ); + CSLDestroy( psTable->papszRecFields ); + CPLFree( psTable->pszFilename ); + CPLFree( psTable->panLineIndex ); + CPLFree( psTable->pszRawData ); + CPLFree( psTable->papszLines ); + + CPLFree( psTable ); + + CPLReadLine( NULL ); +} + +/************************************************************************/ +/* CSVSplitLine() */ +/* */ +/* Tokenize a CSV line into fields in the form of a string */ +/* list. This is used instead of the CPLTokenizeString() */ +/* because it provides correct CSV escaping and quoting */ +/* semantics. */ +/************************************************************************/ + +static char **CSVSplitLine( const char *pszString ) + +{ + char **papszRetList = NULL; + char *pszToken; + int nTokenMax, nTokenLen; + + pszToken = (char *) CPLCalloc(10,1); + nTokenMax = 10; + + while( pszString != NULL && *pszString != '\0' ) + { + int bInString = FALSE; + + nTokenLen = 0; + + /* Try to find the next delimeter, marking end of token */ + for( ; *pszString != '\0'; pszString++ ) + { + + /* End if this is a delimeter skip it and break. */ + if( !bInString && *pszString == ',' ) + { + pszString++; + break; + } + + if( *pszString == '"' ) + { + if( !bInString || pszString[1] != '"' ) + { + bInString = !bInString; + continue; + } + else /* doubled quotes in string resolve to one quote */ + { + pszString++; + } + } + + if( nTokenLen >= nTokenMax-2 ) + { + nTokenMax = nTokenMax * 2 + 10; + pszToken = (char *) CPLRealloc( pszToken, nTokenMax ); + } + + pszToken[nTokenLen] = *pszString; + nTokenLen++; + } + + pszToken[nTokenLen] = '\0'; + papszRetList = CSLAddString( papszRetList, pszToken ); + + /* If the last token is an empty token, then we have to catch + * it now, otherwise we won't reenter the loop and it will be lost. + */ + if ( *pszString == '\0' && *(pszString-1) == ',' ) + { + papszRetList = CSLAddString( papszRetList, "" ); + } + } + + if( papszRetList == NULL ) + papszRetList = (char **) CPLCalloc(sizeof(char *),1); + + CPLFree( pszToken ); + + return papszRetList; +} + +/************************************************************************/ +/* CSVFindNextLine() */ +/* */ +/* Find the start of the next line, while at the same time zero */ +/* terminating this line. Take into account that there may be */ +/* newline indicators within quoted strings, and that quotes */ +/* can be escaped with a backslash. */ +/************************************************************************/ + +static char *CSVFindNextLine( char *pszThisLine ) + +{ + int nQuoteCount = 0, i; + + for( i = 0; pszThisLine[i] != '\0'; i++ ) + { + if( pszThisLine[i] == '\"' + && (i == 0 || pszThisLine[i-1] != '\\') ) + nQuoteCount++; + + if( (pszThisLine[i] == 10 || pszThisLine[i] == 13) + && (nQuoteCount % 2) == 0 ) + break; + } + + while( pszThisLine[i] == 10 || pszThisLine[i] == 13 ) + pszThisLine[i++] = '\0'; + + if( pszThisLine[i] == '\0' ) + return NULL; + else + return pszThisLine + i; +} + +/************************************************************************/ +/* CSVIngest() */ +/* */ +/* Load entire file into memory and setup index if possible. */ +/************************************************************************/ + +static void CSVIngest( const char *pszFilename ) + +{ + CSVTable *psTable = gtCSVAccess( pszFilename ); + int nFileLen, i, nMaxLineCount, iLine = 0; + char *pszThisLine; + + if( psTable->pszRawData != NULL ) + return; + +/* -------------------------------------------------------------------- */ +/* Ingest whole file. */ +/* -------------------------------------------------------------------- */ + VSIFSeek( psTable->fp, 0, SEEK_END ); + nFileLen = VSIFTell( psTable->fp ); + VSIRewind( psTable->fp ); + + psTable->pszRawData = (char *) CPLMalloc(nFileLen+1); + if( (int) VSIFRead( psTable->pszRawData, 1, nFileLen, psTable->fp ) + != nFileLen ) + { + CPLFree( psTable->pszRawData ); + psTable->pszRawData = NULL; + + CPLError( CE_Failure, CPLE_FileIO, "Read of file %s failed.", + psTable->pszFilename ); + return; + } + + psTable->pszRawData[nFileLen] = '\0'; + +/* -------------------------------------------------------------------- */ +/* Get count of newlines so we can allocate line array. */ +/* -------------------------------------------------------------------- */ + nMaxLineCount = 0; + for( i = 0; i < nFileLen; i++ ) + { + if( psTable->pszRawData[i] == 10 ) + nMaxLineCount++; + } + + psTable->papszLines = (char **) CPLCalloc(sizeof(char*),nMaxLineCount); + +/* -------------------------------------------------------------------- */ +/* Build a list of record pointers into the raw data buffer */ +/* based on line terminators. Zero terminate the line */ +/* strings. */ +/* -------------------------------------------------------------------- */ + /* skip header line */ + pszThisLine = CSVFindNextLine( psTable->pszRawData ); + + while( pszThisLine != NULL && iLine < nMaxLineCount ) + { + psTable->papszLines[iLine++] = pszThisLine; + pszThisLine = CSVFindNextLine( pszThisLine ); + } + + psTable->nLineCount = iLine; + +/* -------------------------------------------------------------------- */ +/* Allocate and populate index array. Ensure they are in */ +/* ascending order so that binary searches can be done on the */ +/* array. */ +/* -------------------------------------------------------------------- */ + psTable->panLineIndex = (int *) CPLMalloc(sizeof(int)*psTable->nLineCount); + for( i = 0; i < psTable->nLineCount; i++ ) + { + psTable->panLineIndex[i] = atoi(psTable->papszLines[i]); + + if( i > 0 && psTable->panLineIndex[i] < psTable->panLineIndex[i-1] ) + { + CPLFree( psTable->panLineIndex ); + psTable->panLineIndex = NULL; + break; + } + } + + psTable->iLastLine = -1; + +/* -------------------------------------------------------------------- */ +/* We should never need the file handle against, so close it. */ +/* -------------------------------------------------------------------- */ + VSIFClose( psTable->fp ); + psTable->fp = NULL; +} + +/************************************************************************/ +/* CSVReadParseLine() */ +/* */ +/* Read one line, and return split into fields. The return */ +/* result is a stringlist, in the sense of the CSL functions. */ +/************************************************************************/ + +char **CSVReadParseLine( FILE * fp ) + +{ + const char *pszLine; + char *pszWorkLine; + char **papszReturn; + + CPLAssert( fp != NULL ); + if( fp == NULL ) + return( NULL ); + + pszLine = CPLReadLine( fp ); + if( pszLine == NULL ) + return( NULL ); + +/* -------------------------------------------------------------------- */ +/* If there are no quotes, then this is the simple case. */ +/* Parse, and return tokens. */ +/* -------------------------------------------------------------------- */ + if( strchr(pszLine,'\"') == NULL ) + return CSVSplitLine( pszLine ); + +/* -------------------------------------------------------------------- */ +/* We must now count the quotes in our working string, and as */ +/* long as it is odd, keep adding new lines. */ +/* -------------------------------------------------------------------- */ + pszWorkLine = CPLStrdup( pszLine ); + + while( TRUE ) + { + int i, nCount = 0; + + for( i = 0; pszWorkLine[i] != '\0'; i++ ) + { + if( pszWorkLine[i] == '\"' + && (i == 0 || pszWorkLine[i-1] != '\\') ) + nCount++; + } + + if( nCount % 2 == 0 ) + break; + + pszLine = CPLReadLine( fp ); + if( pszLine == NULL ) + break; + + pszWorkLine = (char *) + CPLRealloc(pszWorkLine, + strlen(pszWorkLine) + strlen(pszLine) + 1); + strcat( pszWorkLine, pszLine ); + } + + papszReturn = CSVSplitLine( pszWorkLine ); + + CPLFree( pszWorkLine ); + + return papszReturn; +} + +/************************************************************************/ +/* CSVCompare() */ +/* */ +/* Compare a field to a search value using a particular */ +/* criteria. */ +/************************************************************************/ + +static int CSVCompare( const char * pszFieldValue, const char * pszTarget, + CSVCompareCriteria eCriteria ) + +{ + if( eCriteria == CC_ExactString ) + { + return( strcmp( pszFieldValue, pszTarget ) == 0 ); + } + else if( eCriteria == CC_ApproxString ) + { + return( EQUAL( pszFieldValue, pszTarget ) ); + } + else if( eCriteria == CC_Integer ) + { + return( atoi(pszFieldValue) == atoi(pszTarget) ); + } + + return FALSE; +} + +/************************************************************************/ +/* CSVScanLines() */ +/* */ +/* Read the file scanline for lines where the key field equals */ +/* the indicated value with the suggested comparison criteria. */ +/* Return the first matching line split into fields. */ +/************************************************************************/ + +char **CSVScanLines( FILE *fp, int iKeyField, const char * pszValue, + CSVCompareCriteria eCriteria ) + +{ + char **papszFields = NULL; + int bSelected = FALSE, nTestValue; + + CPLAssert( pszValue != NULL ); + CPLAssert( iKeyField >= 0 ); + CPLAssert( fp != NULL ); + + nTestValue = atoi(pszValue); + + while( !bSelected ) { + papszFields = CSVReadParseLine( fp ); + if( papszFields == NULL ) + return( NULL ); + + if( CSLCount( papszFields ) < iKeyField+1 ) + { + /* not selected */ + } + else if( eCriteria == CC_Integer + && atoi(papszFields[iKeyField]) == nTestValue ) + { + bSelected = TRUE; + } + else + { + bSelected = CSVCompare( papszFields[iKeyField], pszValue, + eCriteria ); + } + + if( !bSelected ) + { + CSLDestroy( papszFields ); + papszFields = NULL; + } + } + + return( papszFields ); +} + +/************************************************************************/ +/* CSVScanLinesIndexed() */ +/* */ +/* Read the file scanline for lines where the key field equals */ +/* the indicated value with the suggested comparison criteria. */ +/* Return the first matching line split into fields. */ +/************************************************************************/ + +static char ** +CSVScanLinesIndexed( CSVTable *psTable, int nKeyValue ) + +{ + int iTop, iBottom, iMiddle, iResult = -1; + + CPLAssert( psTable->panLineIndex != NULL ); + +/* -------------------------------------------------------------------- */ +/* Find target record with binary search. */ +/* -------------------------------------------------------------------- */ + iTop = psTable->nLineCount-1; + iBottom = 0; + + while( iTop >= iBottom ) + { + iMiddle = (iTop + iBottom) / 2; + if( psTable->panLineIndex[iMiddle] > nKeyValue ) + iTop = iMiddle - 1; + else if( psTable->panLineIndex[iMiddle] < nKeyValue ) + iBottom = iMiddle + 1; + else + { + iResult = iMiddle; + break; + } + } + + if( iResult == -1 ) + return NULL; + +/* -------------------------------------------------------------------- */ +/* Parse target line, and update iLastLine indicator. */ +/* -------------------------------------------------------------------- */ + psTable->iLastLine = iResult; + + return CSVSplitLine( psTable->papszLines[iResult] ); +} + +/************************************************************************/ +/* CSVScanLinesIngested() */ +/* */ +/* Read the file scanline for lines where the key field equals */ +/* the indicated value with the suggested comparison criteria. */ +/* Return the first matching line split into fields. */ +/************************************************************************/ + +static char ** +CSVScanLinesIngested( CSVTable *psTable, int iKeyField, const char * pszValue, + CSVCompareCriteria eCriteria ) + +{ + char **papszFields = NULL; + int bSelected = FALSE, nTestValue; + + CPLAssert( pszValue != NULL ); + CPLAssert( iKeyField >= 0 ); + + nTestValue = atoi(pszValue); + +/* -------------------------------------------------------------------- */ +/* Short cut for indexed files. */ +/* -------------------------------------------------------------------- */ + if( iKeyField == 0 && eCriteria == CC_Integer + && psTable->panLineIndex != NULL ) + return CSVScanLinesIndexed( psTable, nTestValue ); + +/* -------------------------------------------------------------------- */ +/* Scan from in-core lines. */ +/* -------------------------------------------------------------------- */ + while( !bSelected && psTable->iLastLine+1 < psTable->nLineCount ) { + psTable->iLastLine++; + papszFields = CSVSplitLine( psTable->papszLines[psTable->iLastLine] ); + + if( CSLCount( papszFields ) < iKeyField+1 ) + { + /* not selected */ + } + else if( eCriteria == CC_Integer + && atoi(papszFields[iKeyField]) == nTestValue ) + { + bSelected = TRUE; + } + else + { + bSelected = CSVCompare( papszFields[iKeyField], pszValue, + eCriteria ); + } + + if( !bSelected ) + { + CSLDestroy( papszFields ); + papszFields = NULL; + } + } + + return( papszFields ); +} + +/************************************************************************/ +/* CSVScanFile() */ +/* */ +/* Scan a whole file using criteria similar to above, but also */ +/* taking care of file opening and closing. */ +/************************************************************************/ + +char **CSVScanFile( const char * pszFilename, int iKeyField, + const char * pszValue, CSVCompareCriteria eCriteria ) + +{ + CSVTable *psTable; + +/* -------------------------------------------------------------------- */ +/* Get access to the table. */ +/* -------------------------------------------------------------------- */ + CPLAssert( pszFilename != NULL ); + + if( iKeyField < 0 ) + return NULL; + + psTable = gtCSVAccess( pszFilename ); + if( psTable == NULL ) + return NULL; + + CSVIngest( pszFilename ); + +/* -------------------------------------------------------------------- */ +/* Does the current record match the criteria? If so, just */ +/* return it again. */ +/* -------------------------------------------------------------------- */ + if( iKeyField >= 0 + && iKeyField < CSLCount(psTable->papszRecFields) + && CSVCompare(pszValue,psTable->papszRecFields[iKeyField],eCriteria) ) + { + return psTable->papszRecFields; + } + +/* -------------------------------------------------------------------- */ +/* Scan the file from the beginning, replacing the ``current */ +/* record'' in our structure with the one that is found. */ +/* -------------------------------------------------------------------- */ + psTable->iLastLine = -1; + CSLDestroy( psTable->papszRecFields ); + + if( psTable->pszRawData != NULL ) + psTable->papszRecFields = + CSVScanLinesIngested( psTable, iKeyField, pszValue, eCriteria ); + else + { + VSIRewind( psTable->fp ); + CPLReadLine( psTable->fp ); /* throw away the header line */ + + psTable->papszRecFields = + CSVScanLines( psTable->fp, iKeyField, pszValue, eCriteria ); + } + + return( psTable->papszRecFields ); +} + +/************************************************************************/ +/* CPLGetFieldId() */ +/* */ +/* Read the first record of a CSV file (rewinding to be sure), */ +/* and find the field with the indicated name. Returns -1 if */ +/* it fails to find the field name. Comparison is case */ +/* insensitive, but otherwise exact. After this function has */ +/* been called the file pointer will be positioned just after */ +/* the first record. */ +/************************************************************************/ + +int CSVGetFieldId( FILE * fp, const char * pszFieldName ) + +{ + char **papszFields; + int i; + + CPLAssert( fp != NULL && pszFieldName != NULL ); + + VSIRewind( fp ); + + papszFields = CSVReadParseLine( fp ); + for( i = 0; papszFields != NULL && papszFields[i] != NULL; i++ ) + { + if( EQUAL(papszFields[i],pszFieldName) ) + { + CSLDestroy( papszFields ); + return i; + } + } + + CSLDestroy( papszFields ); + + return -1; +} + +/************************************************************************/ +/* CSVGetFileFieldId() */ +/* */ +/* Same as CPLGetFieldId(), except that we get the file based */ +/* on filename, rather than having an existing handle. */ +/************************************************************************/ + +int CSVGetFileFieldId( const char * pszFilename, const char * pszFieldName ) + +{ + CSVTable *psTable; + int i; + +/* -------------------------------------------------------------------- */ +/* Get access to the table. */ +/* -------------------------------------------------------------------- */ + CPLAssert( pszFilename != NULL ); + + psTable = gtCSVAccess( pszFilename ); + if( psTable == NULL ) + return -1; + +/* -------------------------------------------------------------------- */ +/* Find the requested field. */ +/* -------------------------------------------------------------------- */ + for( i = 0; + psTable->papszFieldNames != NULL + && psTable->papszFieldNames[i] != NULL; + i++ ) + { + if( EQUAL(psTable->papszFieldNames[i],pszFieldName) ) + { + return i; + } + } + + return -1; +} + + +/************************************************************************/ +/* CSVScanFileByName() */ +/* */ +/* Same as CSVScanFile(), but using a field name instead of a */ +/* field number. */ +/************************************************************************/ + +char **CSVScanFileByName( const char * pszFilename, + const char * pszKeyFieldName, + const char * pszValue, CSVCompareCriteria eCriteria ) + +{ + int iKeyField; + + iKeyField = CSVGetFileFieldId( pszFilename, pszKeyFieldName ); + if( iKeyField == -1 ) + return NULL; + + return( CSVScanFile( pszFilename, iKeyField, pszValue, eCriteria ) ); +} + +/************************************************************************/ +/* CSVGetField() */ +/* */ +/* The all-in-one function to fetch a particular field value */ +/* from a CSV file. Note this function will return an empty */ +/* string, rather than NULL if it fails to find the desired */ +/* value for some reason. The caller can't establish that the */ +/* fetch failed. */ +/************************************************************************/ + +const char *CSVGetField( const char * pszFilename, + const char * pszKeyFieldName, + const char * pszKeyFieldValue, + CSVCompareCriteria eCriteria, + const char * pszTargetField ) + +{ + CSVTable *psTable; + char **papszRecord; + int iTargetField; + +/* -------------------------------------------------------------------- */ +/* Find the table. */ +/* -------------------------------------------------------------------- */ + psTable = gtCSVAccess( pszFilename ); + if( psTable == NULL ) + return ""; + +/* -------------------------------------------------------------------- */ +/* Find the correct record. */ +/* -------------------------------------------------------------------- */ + papszRecord = CSVScanFileByName( pszFilename, pszKeyFieldName, + pszKeyFieldValue, eCriteria ); + + if( papszRecord == NULL ) + return ""; + +/* -------------------------------------------------------------------- */ +/* Figure out which field we want out of this. */ +/* -------------------------------------------------------------------- */ + iTargetField = CSVGetFileFieldId( pszFilename, pszTargetField ); + if( iTargetField < 0 ) + return ""; + + if( iTargetField >= CSLCount( papszRecord ) ) + return ""; + + return( papszRecord[iTargetField] ); +} + +/************************************************************************/ +/* CSVFilename() */ +/* */ +/* Return the full path to a particular CSV file. This will */ +/* eventually be something the application can override. */ +/************************************************************************/ + +static const char *(*pfnCSVFilenameHook)(const char *) = NULL; + +const char * CSVFilename( const char *pszBasename ) + +{ + static char szPath[512]; + + if( pfnCSVFilenameHook == NULL ) + { + FILE *fp = NULL; + + if( getenv("GEOTIFF_CSV") != NULL ) + { + sprintf( szPath, "%s/%s", getenv("GEOTIFF_CSV"), pszBasename ); + } +#ifdef CSV_DATA_DIR + else + { + sprintf( szPath, "%s/%s", CSV_DATA_DIR, pszBasename ); + } +#else + else if( (fp = fopen( "/usr/local/share/epsg/csv/pcs.csv", "rt" )) != NULL ) + { + sprintf( szPath, "/usr/local/share/epsg/csv/%s", pszBasename ); + } + else if( (fp = fopen( "csv/pcs.csv", "rt" )) != NULL ) + { + sprintf( szPath, "csv/%s", pszBasename ); + } + else if( (fp = fopen( "share/epsg_csv/pcs.csv", "rt" )) != NULL ) + { + sprintf( szPath, "share/epsg_csv/%s", pszBasename ); + } + else if( (fp = fopen( "/usr/share/epsg_csv/pcs.csv", "rt" )) != NULL ) + { + sprintf( szPath, "/usr/share/epsg_csv/%s", pszBasename ); + } + else + { + sprintf( szPath, "/usr/local/share/epsg_csv/%s", pszBasename ); + } +#endif + + if( fp != NULL ) + fclose( fp ); + + return( szPath ); + } + else + return( pfnCSVFilenameHook( pszBasename ) ); +} + +/************************************************************************/ +/* SetCSVFilenameHook() */ +/* */ +/* Applications can use this to set a function that will */ +/* massage CSV filenames. */ +/************************************************************************/ + +/** + * Override CSV file search method. + * + * @param CSVFileOverride The pointer to a function which will return the + * full path for a given filename. + * + +This function allows an application to override how the GTIFGetDefn() and related function find the CSV (Comma Separated +Value) values required. The pfnHook argument should be a pointer to a function that will take in a CSV filename and return a +full path to the file. The returned string should be to an internal static buffer so that the caller doesn't have to free the result. + +<b>Example:</b><br> + +The listgeo utility uses the following override function if the user +specified a CSV file directory with the -t commandline switch (argument +put into CSVDirName). <p> + +<pre> + + ... + + + SetCSVFilenameHook( CSVFileOverride ); + + ... + + +static const char *CSVFileOverride( const char * pszInput ) + +{ + static char szPath[1024]; + +#ifdef WIN32 + sprintf( szPath, "%s\\%s", CSVDirName, pszInput ); +#else + sprintf( szPath, "%s/%s", CSVDirName, pszInput ); +#endif + + return( szPath ); +} +</pre> + +*/ + +void SetCSVFilenameHook( const char *(*pfnNewHook)( const char * ) ) + +{ + pfnCSVFilenameHook = pfnNewHook; +} diff --git a/Utilities/otbgeotiff/cpl_serv.c b/Utilities/otbgeotiff/cpl_serv.c new file mode 100644 index 0000000000000000000000000000000000000000..d9b59977efa8a3ed9cd46bd7f33145491b7136a6 --- /dev/null +++ b/Utilities/otbgeotiff/cpl_serv.c @@ -0,0 +1,596 @@ +/****************************************************************************** + * Copyright (c) 1998, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * cpl_serv.c: Various Common Portability Library derived convenience functions + * + * $Log: cpl_serv.c,v $ + * Revision 1.8 2001/07/09 20:14:37 warmerda + * Another problem freeing pszRLBuffer and not setting to NULL. + * + * Revision 1.7 2001/04/17 13:40:43 warmerda + * fixed freeing of line buffer in CPLReadLine(), init ptr to NULL + * + * Revision 1.6 2001/03/05 04:56:17 warmerda + * make it possible to deallocate CPLReadLine buffer + * + * Revision 1.5 2000/09/30 03:35:05 warmerda + * Fixed CPLReadLine() to use avoid calling VSIRealloc() on a NULL pointer. + * + * Revision 1.4 1999/06/25 04:35:26 warmerda + * Fixed to actually support long lines. + * + * Revision 1.3 1999/03/17 20:43:03 geotiff + * Avoid use of size_t keyword + * + * Revision 1.2 1999/03/10 18:22:39 geotiff + * Added string.h, fixed backslash escaping + * + * Revision 1.1 1999/03/09 15:57:04 geotiff + * New + * + */ + +#include "cpl_serv.h" +#include "geo_tiffp.h" + +#ifdef HAVE_STRING_H +# include <string.h> +#endif +#if defined(HAVE_STRINGS_H) && !defined(HAVE_STRING_H) +# include <strings.h> +#endif + +/************************************************************************/ +/* CPLCalloc() */ +/************************************************************************/ + +void *CPLCalloc( int nCount, int nSize ) + +{ + void *pReturn; + + if( nSize == 0 ) + return NULL; + + pReturn = VSICalloc( nCount, nSize ); + if( pReturn == NULL ) + { + CPLError( CE_Fatal, CPLE_OutOfMemory, + "CPLCalloc(): Out of memory allocating %d bytes.\n", + nSize * nCount ); + } + + return pReturn; +} + +/************************************************************************/ +/* CPLMalloc() */ +/************************************************************************/ + +void *CPLMalloc( int nSize ) + +{ + void *pReturn; + + if( nSize == 0 ) + return NULL; + + pReturn = VSIMalloc( nSize ); + if( pReturn == NULL ) + { + CPLError( CE_Fatal, CPLE_OutOfMemory, + "CPLMalloc(): Out of memory allocating %d bytes.\n", + nSize ); + } + + return pReturn; +} + +/************************************************************************/ +/* CPLRealloc() */ +/************************************************************************/ + +void * CPLRealloc( void * pData, int nNewSize ) + +{ + void *pReturn; + + if( pData == NULL ) + pReturn = VSIMalloc( nNewSize ); + else + pReturn = VSIRealloc( pData, nNewSize ); + + if( pReturn == NULL ) + { + CPLError( CE_Fatal, CPLE_OutOfMemory, + "CPLRealloc(): Out of memory allocating %d bytes.\n", + nNewSize ); + } + + return pReturn; +} + +/************************************************************************/ +/* CPLStrdup() */ +/************************************************************************/ + +char *CPLStrdup( const char * pszString ) + +{ + char *pszReturn; + + if( pszString == NULL ) + pszString = ""; + + pszReturn = VSIMalloc( strlen(pszString)+1 ); + + if( pszReturn == NULL ) + { + CPLError( CE_Fatal, CPLE_OutOfMemory, + "CPLStrdup(): Out of memory allocating %d bytes.\n", + strlen(pszString) ); + + } + + strcpy( pszReturn, pszString ); + + return( pszReturn ); +} + +/************************************************************************/ +/* CPLReadLine() */ +/* */ +/* Read a line of text from the given file handle, taking care */ +/* to capture CR and/or LF and strip off ... equivelent of */ +/* DKReadLine(). Pointer to an internal buffer is returned. */ +/* The application shouldn't free it, or depend on it's value */ +/* past the next call to CPLReadLine() */ +/************************************************************************/ + +const char *CPLReadLine( FILE * fp ) + +{ + static char *pszRLBuffer = NULL; + static int nRLBufferSize = 0; + int nLength, nReadSoFar = 0; + +/* -------------------------------------------------------------------- */ +/* Cleanup case. */ +/* -------------------------------------------------------------------- */ + if( fp == NULL ) + { + CPLFree( pszRLBuffer ); + pszRLBuffer = NULL; + nRLBufferSize = 0; + return NULL; + } + +/* -------------------------------------------------------------------- */ +/* Loop reading chunks of the line till we get to the end of */ +/* the line. */ +/* -------------------------------------------------------------------- */ + do { +/* -------------------------------------------------------------------- */ +/* Grow the working buffer if we have it nearly full. Fail out */ +/* of read line if we can't reallocate it big enough (for */ +/* instance for a _very large_ file with no newlines). */ +/* -------------------------------------------------------------------- */ + if( nRLBufferSize-nReadSoFar < 128 ) + { + nRLBufferSize = nRLBufferSize*2 + 128; + if( pszRLBuffer == NULL ) + pszRLBuffer = (char *) VSIMalloc(nRLBufferSize); + else + pszRLBuffer = (char *) VSIRealloc(pszRLBuffer, nRLBufferSize); + if( pszRLBuffer == NULL ) + { + nRLBufferSize = 0; + return NULL; + } + } + +/* -------------------------------------------------------------------- */ +/* Do the actual read. */ +/* -------------------------------------------------------------------- */ + if( VSIFGets( pszRLBuffer+nReadSoFar, nRLBufferSize-nReadSoFar, fp ) + == NULL ) + { + CPLFree( pszRLBuffer ); + pszRLBuffer = NULL; + nRLBufferSize = 0; + + return NULL; + } + + nReadSoFar = strlen(pszRLBuffer); + + } while( nReadSoFar == nRLBufferSize - 1 + && pszRLBuffer[nRLBufferSize-2] != 13 + && pszRLBuffer[nRLBufferSize-2] != 10 ); + +/* -------------------------------------------------------------------- */ +/* Clear CR and LF off the end. */ +/* -------------------------------------------------------------------- */ + nLength = strlen(pszRLBuffer); + if( nLength > 0 + && (pszRLBuffer[nLength-1] == 10 || pszRLBuffer[nLength-1] == 13) ) + { + pszRLBuffer[--nLength] = '\0'; + } + + if( nLength > 0 + && (pszRLBuffer[nLength-1] == 10 || pszRLBuffer[nLength-1] == 13) ) + { + pszRLBuffer[--nLength] = '\0'; + } + + return( pszRLBuffer ); +} + + +/*===================================================================== + StringList manipulation functions. + =====================================================================*/ + +/********************************************************************** + * CSLAddString() + * + * Append a string to a StringList and return a pointer to the modified + * StringList. + * If the input StringList is NULL, then a new StringList is created. + **********************************************************************/ +char **CSLAddString(char **papszStrList, const char *pszNewString) +{ + int nItems=0; + + if (pszNewString == NULL) + return papszStrList; /* Nothing to do!*/ + + /* Allocate room for the new string */ + if (papszStrList == NULL) + papszStrList = (char**) CPLCalloc(2,sizeof(char*)); + else + { + nItems = CSLCount(papszStrList); + papszStrList = (char**)CPLRealloc(papszStrList, + (nItems+2)*sizeof(char*)); + } + + /* Copy the string in the list */ + papszStrList[nItems] = CPLStrdup(pszNewString); + papszStrList[nItems+1] = NULL; + + return papszStrList; +} + +/********************************************************************** + * CSLCount() + * + * Return the number of lines in a Stringlist. + **********************************************************************/ +int CSLCount(char **papszStrList) +{ + int nItems=0; + + if (papszStrList) + { + while(*papszStrList != NULL) + { + nItems++; + papszStrList++; + } + } + + return nItems; +} + + +/************************************************************************/ +/* CSLGetField() */ +/* */ +/* Fetches the indicated field, being careful not to crash if */ +/* the field doesn't exist within this string list. The */ +/* returned pointer should not be freed, and doesn't */ +/* necessarily last long. */ +/************************************************************************/ + +const char * CSLGetField( char ** papszStrList, int iField ) + +{ + int i; + + if( papszStrList == NULL || iField < 0 ) + return( "" ); + + for( i = 0; i < iField+1; i++ ) + { + if( papszStrList[i] == NULL ) + return ""; + } + + return( papszStrList[iField] ); +} + +/********************************************************************** + * CSLDestroy() + * + * Free all memory used by a StringList. + **********************************************************************/ +void CSLDestroy(char **papszStrList) +{ + char **papszPtr; + + if (papszStrList) + { + papszPtr = papszStrList; + while(*papszPtr != NULL) + { + CPLFree(*papszPtr); + papszPtr++; + } + + CPLFree(papszStrList); + } +} + + +/********************************************************************** + * CSLDuplicate() + * + * Allocate and return a copy of a StringList. + **********************************************************************/ +char **CSLDuplicate(char **papszStrList) +{ + char **papszNewList, **papszSrc, **papszDst; + int nLines; + + nLines = CSLCount(papszStrList); + + if (nLines == 0) + return NULL; + + papszNewList = (char **)CPLMalloc((nLines+1)*sizeof(char*)); + papszSrc = papszStrList; + papszDst = papszNewList; + + while(*papszSrc != NULL) + { + *papszDst = CPLStrdup(*papszSrc); + + papszSrc++; + papszDst++; + } + *papszDst = NULL; + + return papszNewList; +} + +/********************************************************************** + * CSLTokenizeString() + * + * Tokenizes a string and returns a StringList with one string for + * each token. + **********************************************************************/ +char **CSLTokenizeString( const char *pszString ) +{ + return CSLTokenizeStringComplex( pszString, " ", TRUE, FALSE ); +} + +/************************************************************************/ +/* CSLTokenizeStringComplex() */ +/* */ +/* The ultimate tokenizer? */ +/************************************************************************/ + +char ** CSLTokenizeStringComplex( const char * pszString, + const char * pszDelimiters, + int bHonourStrings, int bAllowEmptyTokens ) + +{ + char **papszRetList = NULL; + char *pszToken; + int nTokenMax, nTokenLen; + + pszToken = (char *) CPLCalloc(10,1); + nTokenMax = 10; + + while( pszString != NULL && *pszString != '\0' ) + { + int bInString = FALSE; + + nTokenLen = 0; + + /* Try to find the next delimeter, marking end of token */ + for( ; *pszString != '\0'; pszString++ ) + { + + /* End if this is a delimeter skip it and break. */ + if( !bInString && strchr(pszDelimiters, *pszString) != NULL ) + { + pszString++; + break; + } + + /* If this is a quote, and we are honouring constant + strings, then process the constant strings, with out delim + but don't copy over the quotes */ + if( bHonourStrings && *pszString == '"' ) + { + if( bInString ) + { + bInString = FALSE; + continue; + } + else + { + bInString = TRUE; + continue; + } + } + + /* Within string constants we allow for escaped quotes, but + in processing them we will unescape the quotes */ + if( bInString && pszString[0] == '\\' && pszString[1] == '"' ) + { + pszString++; + } + + /* Within string constants a \\ sequence reduces to \ */ + else if( bInString + && pszString[0] == '\\' && pszString[1] == '\\' ) + { + pszString++; + } + + if( nTokenLen >= nTokenMax-1 ) + { + nTokenMax = nTokenMax * 2 + 10; + pszToken = (char *) CPLRealloc( pszToken, nTokenMax ); + } + + pszToken[nTokenLen] = *pszString; + nTokenLen++; + } + + pszToken[nTokenLen] = '\0'; + + if( pszToken[0] != '\0' || bAllowEmptyTokens ) + { + papszRetList = CSLAddString( papszRetList, pszToken ); + } + } + + if( papszRetList == NULL ) + papszRetList = (char **) CPLCalloc(sizeof(char *),1); + + CPLFree( pszToken ); + + return papszRetList; +} + +/* static buffer to store the last error message. We'll assume that error + * messages cannot be longer than 2000 chars... which is quite reasonable + * (that's 25 lines of 80 chars!!!) + */ +static char gszCPLLastErrMsg[2000] = ""; +static int gnCPLLastErrNo = 0; + +static void (*gpfnCPLErrorHandler)(CPLErr, int, const char *) = NULL; + +/********************************************************************** + * CPLError() + * + * This function records an error code and displays the error message + * to stderr. + * + * The error code can be accessed later using CPLGetLastErrNo() + **********************************************************************/ +void CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...) +{ + va_list args; + + /* Expand the error message + */ + va_start(args, fmt); + vsprintf(gszCPLLastErrMsg, fmt, args); + va_end(args); + + /* If the user provided his own error handling function, then call + * it, otherwise print the error to stderr and return. + */ + gnCPLLastErrNo = err_no; + + if (gpfnCPLErrorHandler != NULL) + { + gpfnCPLErrorHandler(eErrClass, err_no, gszCPLLastErrMsg); + } + else + { + fprintf(stderr, "ERROR %d: %s\n", gnCPLLastErrNo, gszCPLLastErrMsg); + } + + if( eErrClass == CE_Fatal ) + abort(); +} + +/********************************************************************** + * CPLErrorReset() + * + * Erase any traces of previous errors. + **********************************************************************/ +void CPLErrorReset() +{ + gnCPLLastErrNo = 0; + gszCPLLastErrMsg[0] = '\0'; +} + + +/********************************************************************** + * CPLGetLastErrorNo() + * + **********************************************************************/ +int CPLGetLastErrorNo() +{ + return gnCPLLastErrNo; +} + +/********************************************************************** + * CPLGetLastErrorMsg() + * + **********************************************************************/ +const char* CPLGetLastErrorMsg() +{ + return gszCPLLastErrMsg; +} + +/********************************************************************** + * CPLSetErrorHandler() + * + * Allow the library's user to specify his own error handler function. + * + * A valid error handler is a C function with the following prototype: + * + * void MyErrorHandler(int errno, const char *msg) + * + * Pass NULL to come back to the default behavior. + **********************************************************************/ + +void CPLSetErrorHandler(void (*pfnErrorHandler)(CPLErr, int, const char *)) +{ + gpfnCPLErrorHandler = pfnErrorHandler; +} + +/************************************************************************/ +/* _CPLAssert() */ +/* */ +/* This function is called only when an assertion fails. */ +/************************************************************************/ + +void _CPLAssert( const char * pszExpression, const char * pszFile, + int iLine ) + +{ + CPLError( CE_Fatal, CPLE_AssertionFailed, + "Assertion `%s' failed\n" + "in file `%s', line %d\n", + pszExpression, pszFile, iLine ); +} diff --git a/Utilities/otbgeotiff/cpl_serv.h b/Utilities/otbgeotiff/cpl_serv.h new file mode 100644 index 0000000000000000000000000000000000000000..0d7e0008fc0d42db83cf98dd7d504677d9a43784 --- /dev/null +++ b/Utilities/otbgeotiff/cpl_serv.h @@ -0,0 +1,276 @@ +/****************************************************************************** + * Copyright (c) 1998, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * cpl_serv.h + * + * This include file derived and simplified from the GDAL Common Portability + * Library. + */ + +#ifndef CPL_SERV_H_INCLUDED +#define CPL_SERV_H_INCLUDED + +/* ==================================================================== */ +/* Standard include files. */ +/* ==================================================================== */ + +#include "geo_config.h" +#include <stdio.h> + +#include <math.h> + +#ifdef HAVE_STRING_H +# include <string.h> +#endif +#if defined(HAVE_STRINGS_H) && !defined(HAVE_STRING_H) +# include <strings.h> +#endif +#ifdef HAVE_STDLIB_H +# include <stdlib.h> +#endif + +/********************************************************************** + * Do we want to build as a DLL on windows? + **********************************************************************/ +#if !defined(CPL_DLL) +# if defined(_WIN32) && defined(BUILD_AS_DLL) +# define CPL_DLL __declspec(dllexport) +# else +# define CPL_DLL +# endif +#endif + +/* ==================================================================== */ +/* Other standard services. */ +/* ==================================================================== */ +#ifdef __cplusplus +# define CPL_C_START extern "C" { +# define CPL_C_END } +#else +# define CPL_C_START +# define CPL_C_END +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#ifndef FALSE +# define FALSE 0 +#endif + +#ifndef TRUE +# define TRUE 1 +#endif + +#ifndef MAX +# define MIN(a,b) ((a<b) ? a : b) +# define MAX(a,b) ((a>b) ? a : b) +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef ABS +# define ABS(x) ((x<0) ? (-1*(x)) : x) +#endif + +#ifndef EQUAL +#if defined(_WIN32) && !defined(__CYGWIN__) +# define EQUALN(a,b,n) (strnicmp(a,b,n)==0) +# define EQUAL(a,b) (stricmp(a,b)==0) +#else +# define EQUALN(a,b,n) (strncasecmp(a,b,n)==0) +# define EQUAL(a,b) (strcasecmp(a,b)==0) +#endif +#endif + +/* ==================================================================== */ +/* VSI Services (just map directly onto Standard C services. */ +/* ==================================================================== */ + +#define VSIFOpen fopen +#define VSIFClose fclose +#define VSIFEof feof +#define VSIFPrintf fprintf +#define VSIFPuts fputs +#define VSIFPutc fputc +#define VSIFGets fgets +#define VSIRewind rewind +#define VSIFSeek fseek +#define VSIFTell ftell +#define VSIFRead fread + +#ifndef notdef +#define VSICalloc(x,y) _GTIFcalloc(x*y) +#define VSIMalloc _GTIFcalloc +#define VSIFree _GTIFFree +#define VSIRealloc _GTIFrealloc +#else +#define VSICalloc(x,y) (((char *) _GTIFcalloc(x*y+4)) + 4) +#define VSIMalloc(x) (((char *) _GTIFcalloc((x)+4)) + 4) +#define VSIFree(x) _GTIFFree(((char *) (x)) - 4) +#define VSIRealloc(p,n) (((char *) _GTIFrealloc(((char *)p)-4,(n)+4)) + 4) +#endif + +/* -------------------------------------------------------------------- */ +/* Safe malloc() API. Thin cover over VSI functions with fatal */ +/* error reporting if memory allocation fails. */ +/* -------------------------------------------------------------------- */ +CPL_C_START + +#define CPLMalloc gtCPLMalloc +#define CPLCalloc gtCPLCalloc +#define CPLRealloc gtCPLRealloc +#define CPLStrdup gtCPLStrdup + +void CPL_DLL *CPLMalloc( int ); +void CPL_DLL *CPLCalloc( int, int ); +void CPL_DLL *CPLRealloc( void *, int ); +char CPL_DLL *CPLStrdup( const char * ); + +#define CPLFree(x) { if( x != NULL ) VSIFree(x); } + +/* -------------------------------------------------------------------- */ +/* Read a line from a text file, and strip of CR/LF. */ +/* -------------------------------------------------------------------- */ + +#define CPLReadLine gtCPLReadLine + +const char CPL_DLL *CPLReadLine( FILE * ); + +/*===================================================================== + Error handling functions (cpl_error.c) + =====================================================================*/ + +typedef enum +{ + CE_None = 0, + CE_Log = 1, + CE_Warning = 2, + CE_Failure = 3, + CE_Fatal = 4 +} CPLErr; + +#define CPLError gtCPLError +#define CPLErrorReset gtCPLErrorReset +#define CPLGetLastErrorNo gtCPLGetLastErrorNo +#define CPLGetLastErrorMsg gtCPLGetLastErrorMsg +#define CPLSetErrorHandler gtCPLSetErrorHandler +#define _CPLAssert gt_CPLAssert + +void CPL_DLL CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...); +void CPL_DLL CPLErrorReset(); +int CPL_DLL CPLGetLastErrorNo(); +const char CPL_DLL * CPLGetLastErrorMsg(); +void CPL_DLL CPLSetErrorHandler(void(*pfnErrorHandler)(CPLErr,int, + const char *)); +void CPL_DLL _CPLAssert( const char *, const char *, int ); + +#ifdef DEBUG +# define CPLAssert(expr) ((expr) ? (void)(0) : _CPLAssert(#expr,__FILE__,__LINE__)) +#else +# define CPLAssert(expr) +#endif + +CPL_C_END + +/* ==================================================================== */ +/* Well known error codes. */ +/* ==================================================================== */ + +#define CPLE_AppDefined 1 +#define CPLE_OutOfMemory 2 +#define CPLE_FileIO 3 +#define CPLE_OpenFailed 4 +#define CPLE_IllegalArg 5 +#define CPLE_NotSupported 6 +#define CPLE_AssertionFailed 7 +#define CPLE_NoWriteAccess 8 + +/*===================================================================== + Stringlist functions (strlist.c) + =====================================================================*/ +CPL_C_START + +#define CSLAddString gtCSLAddString +#define CSLCount gtCSLCount +#define CSLGetField gtCSLGetField +#define CSLDestroy gtCSLDestroy +#define CSLDuplicate gtCSLDuplicate +#define CSLTokenizeString gtCSLTokenizeString +#define CSLTokenizeStringComplex gtCSLTokenizeStringComplex + +char CPL_DLL **CSLAddString(char **papszStrList, const char *pszNewString); +int CPL_DLL CSLCount(char **papszStrList); +const char CPL_DLL *CSLGetField( char **, int ); +void CPL_DLL CSLDestroy(char **papszStrList); +char CPL_DLL **CSLDuplicate(char **papszStrList); + +char CPL_DLL **CSLTokenizeString(const char *pszString ); +char CPL_DLL **CSLTokenizeStringComplex(const char *pszString, + const char *pszDelimiter, + int bHonourStrings, int bAllowEmptyTokens ); + +/* ==================================================================== */ +/* .csv file related functions (from cpl_csv.c) */ +/* ==================================================================== */ + +typedef enum { + CC_ExactString, + CC_ApproxString, + CC_Integer +} CSVCompareCriteria; + +#define CSVFilename gtCSVFilename +#define CSVReadParseLine gtCSVReadParseLine +#define CSVScanLines gtCSVScanLines +#define CSVScanFile gtCSVScanFile +#define CSVScanFileByName gtCSVScanFileByName +#define CSVGetFieldId gtCSVGetFieldId +#define CSVDeaccess gtCSVDeaccess +#define CSVGetField gtCSVGetField +#define SetCSVFilenameHook gtSetCSVFilenameHook +#define CSVGetFileFieldId gtCSVGetFileFieldId + +const char CPL_DLL *CSVFilename( const char * ); + +char CPL_DLL **CSVReadParseLine( FILE * ); +char CPL_DLL **CSVScanLines( FILE *, int, const char *, CSVCompareCriteria ); +char CPL_DLL **CSVScanFile( const char *, int, const char *, + CSVCompareCriteria ); +char CPL_DLL **CSVScanFileByName( const char *, const char *, const char *, + CSVCompareCriteria ); +int CPL_DLL CSVGetFieldId( FILE *, const char * ); +int CPL_DLL CSVGetFileFieldId( const char *, const char * ); + +void CPL_DLL CSVDeaccess( const char * ); + +const char CPL_DLL *CSVGetField( const char *, const char *, const char *, + CSVCompareCriteria, const char * ); + +void CPL_DLL SetCSVFilenameHook( const char *(*)(const char *) ); + +CPL_C_END + +#endif /* ndef CPL_SERV_H_INCLUDED */ diff --git a/Utilities/otbgeotiff/defs.h b/Utilities/otbgeotiff/defs.h new file mode 100644 index 0000000000000000000000000000000000000000..365734f3816d42f97bdd883587c92116d549d300 --- /dev/null +++ b/Utilities/otbgeotiff/defs.h @@ -0,0 +1,13 @@ + +/* + * This file is included by the CSV ".c" files in the csv directory. + */ + +#include <stdio.h> + +/* Data structures */ +typedef const char * datafile_rows_t; +typedef struct datafile_s { + const char *name; + const datafile_rows_t **rows; +} datafile_t; diff --git a/Utilities/otbgeotiff/epsg_datum.inc b/Utilities/otbgeotiff/epsg_datum.inc new file mode 100644 index 0000000000000000000000000000000000000000..198e78ff2ab669b7c241b7ad5f83125bd049f978 --- /dev/null +++ b/Utilities/otbgeotiff/epsg_datum.inc @@ -0,0 +1,174 @@ +/* + * EPSG/POSC Datum database -- GeoTIFF Rev. 0.2 + */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +#ifdef INCLUDE_OLD_CODES +#include old_datum.inc +#endif /* OLD Codes */ + +/* New datums */ +ValuePair(Datum_Dealul_Piscului_1970,6317) + +/* Datums for which only the ellipsoid is known */ +ValuePair(DatumE_Airy1830, 6001) +ValuePair(DatumE_AiryModified1849, 6002) +ValuePair(DatumE_AustralianNationalSpheroid, 6003) +ValuePair(DatumE_Bessel1841, 6004) +ValuePair(DatumE_BesselModified, 6005) +ValuePair(DatumE_BesselNamibia, 6006) +ValuePair(DatumE_Clarke1858, 6007) +ValuePair(DatumE_Clarke1866, 6008) +ValuePair(DatumE_Clarke1866Michigan, 6009) +ValuePair(DatumE_Clarke1880_Benoit, 6010) +ValuePair(DatumE_Clarke1880_IGN, 6011) +ValuePair(DatumE_Clarke1880_RGS, 6012) +ValuePair(DatumE_Clarke1880_Arc, 6013) +ValuePair(DatumE_Clarke1880_SGA1922, 6014) +ValuePair(DatumE_Everest1830_1937Adjustment, 6015) +ValuePair(DatumE_Everest1830_1967Definition, 6016) +ValuePair(DatumE_Everest1830_1975Definition, 6017) +ValuePair(DatumE_Everest1830Modified, 6018) +ValuePair(DatumE_GRS1980, 6019) +ValuePair(DatumE_Helmert1906, 6020) +ValuePair(DatumE_IndonesianNationalSpheroid, 6021) +ValuePair(DatumE_International1924, 6022) +ValuePair(DatumE_International1967, 6023) +ValuePair(DatumE_Krassowsky1960, 6024) +ValuePair(DatumE_NWL9D, 6025) +ValuePair(DatumE_NWL10D, 6026) +ValuePair(DatumE_Plessis1817, 6027) +ValuePair(DatumE_Struve1860, 6028) +ValuePair(DatumE_WarOffice, 6029) +ValuePair(DatumE_WGS84, 6030) +ValuePair(DatumE_GEM10C, 6031) +ValuePair(DatumE_OSU86F, 6032) +ValuePair(DatumE_OSU91A, 6033) +ValuePair(DatumE_Clarke1880, 6034) +ValuePair(DatumE_Sphere, 6035) + +/* standard datums */ +ValuePair(Datum_Adindan, 6201) +ValuePair(Datum_Australian_Geodetic_Datum_1966, 6202) +ValuePair(Datum_Australian_Geodetic_Datum_1984, 6203) +ValuePair(Datum_Ain_el_Abd_1970, 6204) +ValuePair(Datum_Afgooye, 6205) +ValuePair(Datum_Agadez, 6206) +ValuePair(Datum_Lisbon, 6207) +ValuePair(Datum_Aratu, 6208) +ValuePair(Datum_Arc_1950, 6209) +ValuePair(Datum_Arc_1960, 6210) +ValuePair(Datum_Batavia, 6211) +ValuePair(Datum_Barbados, 6212) +ValuePair(Datum_Beduaram, 6213) +ValuePair(Datum_Beijing_1954, 6214) +ValuePair(Datum_Reseau_National_Belge_1950, 6215) +ValuePair(Datum_Bermuda_1957, 6216) +ValuePair(Datum_Bern_1898, 6217) +ValuePair(Datum_Bogota, 6218) +ValuePair(Datum_Bukit_Rimpah, 6219) +ValuePair(Datum_Camacupa, 6220) +ValuePair(Datum_Campo_Inchauspe, 6221) +ValuePair(Datum_Cape, 6222) +ValuePair(Datum_Carthage, 6223) +ValuePair(Datum_Chua, 6224) +ValuePair(Datum_Corrego_Alegre, 6225) +ValuePair(Datum_Cote_d_Ivoire, 6226) +ValuePair(Datum_Deir_ez_Zor, 6227) +ValuePair(Datum_Douala, 6228) +ValuePair(Datum_Egypt_1907, 6229) +ValuePair(Datum_European_Datum_1950, 6230) +ValuePair(Datum_European_Datum_1987, 6231) +ValuePair(Datum_Fahud, 6232) +ValuePair(Datum_Gandajika_1970, 6233) +ValuePair(Datum_Garoua, 6234) +ValuePair(Datum_Guyane_Francaise, 6235) +ValuePair(Datum_Hu_Tzu_Shan, 6236) +ValuePair(Datum_Hungarian_Datum_1972, 6237) +ValuePair(Datum_Indonesian_Datum_1974, 6238) +ValuePair(Datum_Indian_1954, 6239) +ValuePair(Datum_Indian_1975, 6240) +ValuePair(Datum_Jamaica_1875, 6241) +ValuePair(Datum_Jamaica_1969, 6242) +ValuePair(Datum_Kalianpur, 6243) +ValuePair(Datum_Kandawala, 6244) +ValuePair(Datum_Kertau, 6245) +ValuePair(Datum_Kuwait_Oil_Company, 6246) +ValuePair(Datum_La_Canoa, 6247) +ValuePair(Datum_Provisional_S_American_Datum_1956, 6248) +ValuePair(Datum_Lake, 6249) +ValuePair(Datum_Leigon, 6250) +ValuePair(Datum_Liberia_1964, 6251) +ValuePair(Datum_Lome, 6252) +ValuePair(Datum_Luzon_1911, 6253) +ValuePair(Datum_Hito_XVIII_1963, 6254) +ValuePair(Datum_Herat_North, 6255) +ValuePair(Datum_Mahe_1971, 6256) +ValuePair(Datum_Makassar, 6257) +ValuePair(Datum_European_Reference_System_1989, 6258) +ValuePair(Datum_Malongo_1987, 6259) +ValuePair(Datum_Manoca, 6260) +ValuePair(Datum_Merchich, 6261) +ValuePair(Datum_Massawa, 6262) +ValuePair(Datum_Minna, 6263) +ValuePair(Datum_Mhast, 6264) +ValuePair(Datum_Monte_Mario, 6265) +ValuePair(Datum_M_poraloko, 6266) +ValuePair(Datum_North_American_Datum_1927, 6267) +ValuePair(Datum_NAD_Michigan, 6268) +ValuePair(Datum_North_American_Datum_1983, 6269) +ValuePair(Datum_Nahrwan_1967, 6270) +ValuePair(Datum_Naparima_1972, 6271) +ValuePair(Datum_New_Zealand_Geodetic_Datum_1949, 6272) +ValuePair(Datum_NGO_1948, 6273) +ValuePair(Datum_Datum_73, 6274) +ValuePair(Datum_Nouvelle_Triangulation_Francaise, 6275) +ValuePair(Datum_NSWC_9Z_2, 6276) +ValuePair(Datum_OSGB_1936, 6277) +ValuePair(Datum_OSGB_1970_SN, 6278) +ValuePair(Datum_OS_SN_1980, 6279) +ValuePair(Datum_Padang_1884, 6280) +ValuePair(Datum_Palestine_1923, 6281) +ValuePair(Datum_Pointe_Noire, 6282) +ValuePair(Datum_Geocentric_Datum_of_Australia_1994, 6283) +ValuePair(Datum_Pulkovo_1942, 6284) +ValuePair(Datum_Qatar, 6285) +ValuePair(Datum_Qatar_1948, 6286) +ValuePair(Datum_Qornoq, 6287) +ValuePair(Datum_Loma_Quintana, 6288) +ValuePair(Datum_Amersfoort, 6289) +ValuePair(Datum_RT38, 6290) +ValuePair(Datum_South_American_Datum_1969, 6291) +ValuePair(Datum_Sapper_Hill_1943, 6292) +ValuePair(Datum_Schwarzeck, 6293) +ValuePair(Datum_Segora, 6294) +ValuePair(Datum_Serindung, 6295) +ValuePair(Datum_Sudan, 6296) +ValuePair(Datum_Tananarive_1925, 6297) +ValuePair(Datum_Timbalai_1948, 6298) +ValuePair(Datum_TM65, 6299) +ValuePair(Datum_TM75, 6300) +ValuePair(Datum_Tokyo, 6301) +ValuePair(Datum_Trinidad_1903, 6302) +ValuePair(Datum_Trucial_Coast_1948, 6303) +ValuePair(Datum_Voirol_1875, 6304) +ValuePair(Datum_Voirol_Unifie_1960, 6305) +ValuePair(Datum_Bern_1938, 6306) +ValuePair(Datum_Nord_Sahara_1959, 6307) +ValuePair(Datum_Stockholm_1938, 6308) +ValuePair(Datum_Yacare, 6309) +ValuePair(Datum_Yoff, 6310) +ValuePair(Datum_Zanderij, 6311) +ValuePair(Datum_Militar_Geographische_Institut, 6312) +ValuePair(Datum_Reseau_National_Belge_1972, 6313) +ValuePair(Datum_Deutsche_Hauptdreiecksnetz, 6314) +ValuePair(Datum_Conakry_1905, 6315) +ValuePair(Datum_WGS72, 6322) +ValuePair(Datum_WGS72_Transit_Broadcast_Ephemeris, 6324) +ValuePair(Datum_WGS84, 6326) +ValuePair(Datum_Ancienne_Triangulation_Francaise, 6901) +ValuePair(Datum_Nord_de_Guerre, 6902) +/* end of list */ diff --git a/Utilities/otbgeotiff/epsg_ellipse.inc b/Utilities/otbgeotiff/epsg_ellipse.inc new file mode 100644 index 0000000000000000000000000000000000000000..95c14321f75cb0ea4b919a3861f8f1d6645b2257 --- /dev/null +++ b/Utilities/otbgeotiff/epsg_ellipse.inc @@ -0,0 +1,48 @@ +/* + * GeoTIFF Rev. 0.2 Ellipsoids + */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +#ifdef INCLUDE_OLD_CODES +#include old_ellipse.inc +#endif /* OLD Codes */ + +ValuePair(Ellipse_Airy_1830, 7001) +ValuePair(Ellipse_Airy_Modified_1849, 7002) +ValuePair(Ellipse_Australian_National_Spheroid, 7003) +ValuePair(Ellipse_Bessel_1841, 7004) +ValuePair(Ellipse_Bessel_Modified, 7005) +ValuePair(Ellipse_Bessel_Namibia, 7006) +ValuePair(Ellipse_Clarke_1858, 7007) +ValuePair(Ellipse_Clarke_1866, 7008) +ValuePair(Ellipse_Clarke_1866_Michigan, 7009) +ValuePair(Ellipse_Clarke_1880_Benoit, 7010) +ValuePair(Ellipse_Clarke_1880_IGN, 7011) +ValuePair(Ellipse_Clarke_1880_RGS, 7012) +ValuePair(Ellipse_Clarke_1880_Arc, 7013) +ValuePair(Ellipse_Clarke_1880_SGA_1922, 7014) +ValuePair(Ellipse_Everest_1830_1937_Adjustment, 7015) +ValuePair(Ellipse_Everest_1830_1967_Definition, 7016) +ValuePair(Ellipse_Everest_1830_1975_Definition, 7017) +ValuePair(Ellipse_Everest_1830_Modified, 7018) +ValuePair(Ellipse_GRS_1980, 7019) +ValuePair(Ellipse_Helmert_1906, 7020) +ValuePair(Ellipse_Indonesian_National_Spheroid, 7021) +ValuePair(Ellipse_International_1924, 7022) +ValuePair(Ellipse_International_1967, 7023) +ValuePair(Ellipse_Krassowsky_1940, 7024) +ValuePair(Ellipse_NWL_9D, 7025) +ValuePair(Ellipse_NWL_10D, 7026) +ValuePair(Ellipse_Plessis_1817, 7027) +ValuePair(Ellipse_Struve_1860, 7028) +ValuePair(Ellipse_War_Office, 7029) +ValuePair(Ellipse_WGS_84, 7030) +ValuePair(Ellipse_GEM_10C, 7031) +ValuePair(Ellipse_OSU86F, 7032) +ValuePair(Ellipse_OSU91A, 7033) +ValuePair(Ellipse_Clarke_1880, 7034) +ValuePair(Ellipse_Sphere, 7035) +/* end of list */ diff --git a/Utilities/otbgeotiff/epsg_gcs.inc b/Utilities/otbgeotiff/epsg_gcs.inc new file mode 100644 index 0000000000000000000000000000000000000000..4917964d8262475e47946acb4edd1856222d0ff2 --- /dev/null +++ b/Utilities/otbgeotiff/epsg_gcs.inc @@ -0,0 +1,193 @@ +/* + * EPSG/POSC GCS Codes -- GeoTIFF Rev. 0.2 + */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +#ifdef INCLUDE_OLD_CODES +#include old_gcs.inc +#endif /* OLD Codes */ + +/* Unspecified GCS based on ellipsoid */ +ValuePair(GCSE_Airy1830, 4001) +ValuePair(GCSE_AiryModified1849, 4002) +ValuePair(GCSE_AustralianNationalSpheroid, 4003) +ValuePair(GCSE_Bessel1841, 4004) +ValuePair(GCSE_BesselModified, 4005) +ValuePair(GCSE_BesselNamibia, 4006) +ValuePair(GCSE_Clarke1858, 4007) +ValuePair(GCSE_Clarke1866, 4008) +ValuePair(GCSE_Clarke1866Michigan, 4009) +ValuePair(GCSE_Clarke1880_Benoit, 4010) +ValuePair(GCSE_Clarke1880_IGN, 4011) +ValuePair(GCSE_Clarke1880_RGS, 4012) +ValuePair(GCSE_Clarke1880_Arc, 4013) +ValuePair(GCSE_Clarke1880_SGA1922, 4014) +ValuePair(GCSE_Everest1830_1937Adjustment, 4015) +ValuePair(GCSE_Everest1830_1967Definition, 4016) +ValuePair(GCSE_Everest1830_1975Definition, 4017) +ValuePair(GCSE_Everest1830Modified, 4018) +ValuePair(GCSE_GRS1980, 4019) +ValuePair(GCSE_Helmert1906, 4020) +ValuePair(GCSE_IndonesianNationalSpheroid, 4021) +ValuePair(GCSE_International1924, 4022) +ValuePair(GCSE_International1967, 4023) +ValuePair(GCSE_Krassowsky1940, 4024) +ValuePair(GCSE_NWL9D, 4025) +ValuePair(GCSE_NWL10D, 4026) +ValuePair(GCSE_Plessis1817, 4027) +ValuePair(GCSE_Struve1860, 4028) +ValuePair(GCSE_WarOffice, 4029) +ValuePair(GCSE_WGS84, 4030) +ValuePair(GCSE_GEM10C, 4031) +ValuePair(GCSE_OSU86F, 4032) +ValuePair(GCSE_OSU91A, 4033) +ValuePair(GCSE_Clarke1880, 4034) +ValuePair(GCSE_Sphere, 4035) + +/* New GCS */ +ValuePair(GCS_Greek,4120) +ValuePair(GCS_GGRS87,4121) +ValuePair(GCS_KKJ,4123) +ValuePair(GCS_RT90,4124) +ValuePair(GCS_EST92,4133) +ValuePair(GCS_Dealul_Piscului_1970,4317) +ValuePair(GCS_Greek_Athens,4815) + +/* Standard GCS */ +ValuePair(GCS_Adindan, 4201) +ValuePair(GCS_AGD66, 4202) +ValuePair(GCS_AGD84, 4203) +ValuePair(GCS_Ain_el_Abd, 4204) +ValuePair(GCS_Afgooye, 4205) +ValuePair(GCS_Agadez, 4206) +ValuePair(GCS_Lisbon, 4207) +ValuePair(GCS_Aratu, 4208) +ValuePair(GCS_Arc_1950, 4209) +ValuePair(GCS_Arc_1960, 4210) +ValuePair(GCS_Batavia, 4211) +ValuePair(GCS_Barbados, 4212) +ValuePair(GCS_Beduaram, 4213) +ValuePair(GCS_Beijing_1954, 4214) +ValuePair(GCS_Belge_1950, 4215) +ValuePair(GCS_Bermuda_1957, 4216) +ValuePair(GCS_Bern_1898, 4217) +ValuePair(GCS_Bogota, 4218) +ValuePair(GCS_Bukit_Rimpah, 4219) +ValuePair(GCS_Camacupa, 4220) +ValuePair(GCS_Campo_Inchauspe, 4221) +ValuePair(GCS_Cape, 4222) +ValuePair(GCS_Carthage, 4223) +ValuePair(GCS_Chua, 4224) +ValuePair(GCS_Corrego_Alegre, 4225) +ValuePair(GCS_Cote_d_Ivoire, 4226) +ValuePair(GCS_Deir_ez_Zor, 4227) +ValuePair(GCS_Douala, 4228) +ValuePair(GCS_Egypt_1907, 4229) +ValuePair(GCS_ED50, 4230) +ValuePair(GCS_ED87, 4231) +ValuePair(GCS_Fahud, 4232) +ValuePair(GCS_Gandajika_1970, 4233) +ValuePair(GCS_Garoua, 4234) +ValuePair(GCS_Guyane_Francaise, 4235) +ValuePair(GCS_Hu_Tzu_Shan, 4236) +ValuePair(GCS_HD72, 4237) +ValuePair(GCS_ID74, 4238) +ValuePair(GCS_Indian_1954, 4239) +ValuePair(GCS_Indian_1975, 4240) +ValuePair(GCS_Jamaica_1875, 4241) +ValuePair(GCS_JAD69, 4242) +ValuePair(GCS_Kalianpur, 4243) +ValuePair(GCS_Kandawala, 4244) +ValuePair(GCS_Kertau, 4245) +ValuePair(GCS_KOC, 4246) +ValuePair(GCS_La_Canoa, 4247) +ValuePair(GCS_PSAD56, 4248) +ValuePair(GCS_Lake, 4249) +ValuePair(GCS_Leigon, 4250) +ValuePair(GCS_Liberia_1964, 4251) +ValuePair(GCS_Lome, 4252) +ValuePair(GCS_Luzon_1911, 4253) +ValuePair(GCS_Hito_XVIII_1963, 4254) +ValuePair(GCS_Herat_North, 4255) +ValuePair(GCS_Mahe_1971, 4256) +ValuePair(GCS_Makassar, 4257) +ValuePair(GCS_EUREF89, 4258) +ValuePair(GCS_Malongo_1987, 4259) +ValuePair(GCS_Manoca, 4260) +ValuePair(GCS_Merchich, 4261) +ValuePair(GCS_Massawa, 4262) +ValuePair(GCS_Minna, 4263) +ValuePair(GCS_Mhast, 4264) +ValuePair(GCS_Monte_Mario, 4265) +ValuePair(GCS_M_poraloko, 4266) +ValuePair(GCS_NAD27, 4267) +ValuePair(GCS_NAD_Michigan, 4268) +ValuePair(GCS_NAD83, 4269) +ValuePair(GCS_Nahrwan_1967, 4270) +ValuePair(GCS_Naparima_1972, 4271) +ValuePair(GCS_GD49, 4272) +ValuePair(GCS_NGO_1948, 4273) +ValuePair(GCS_Datum_73, 4274) +ValuePair(GCS_NTF, 4275) +ValuePair(GCS_NSWC_9Z_2, 4276) +ValuePair(GCS_OSGB_1936, 4277) +ValuePair(GCS_OSGB70, 4278) +ValuePair(GCS_OS_SN80, 4279) +ValuePair(GCS_Padang, 4280) +ValuePair(GCS_Palestine_1923, 4281) +ValuePair(GCS_Pointe_Noire, 4282) +ValuePair(GCS_GDA94, 4283) +ValuePair(GCS_Pulkovo_1942, 4284) +ValuePair(GCS_Qatar, 4285) +ValuePair(GCS_Qatar_1948, 4286) +ValuePair(GCS_Qornoq, 4287) +ValuePair(GCS_Loma_Quintana, 4288) +ValuePair(GCS_Amersfoort, 4289) +ValuePair(GCS_RT38, 4290) +ValuePair(GCS_SAD69, 4291) +ValuePair(GCS_Sapper_Hill_1943, 4292) +ValuePair(GCS_Schwarzeck, 4293) +ValuePair(GCS_Segora, 4294) +ValuePair(GCS_Serindung, 4295) +ValuePair(GCS_Sudan, 4296) +ValuePair(GCS_Tananarive, 4297) +ValuePair(GCS_Timbalai_1948, 4298) +ValuePair(GCS_TM65, 4299) +ValuePair(GCS_TM75, 4300) +ValuePair(GCS_Tokyo, 4301) +ValuePair(GCS_Trinidad_1903, 4302) +ValuePair(GCS_TC_1948, 4303) +ValuePair(GCS_Voirol_1875, 4304) +ValuePair(GCS_Voirol_Unifie, 4305) +ValuePair(GCS_Bern_1938, 4306) +ValuePair(GCS_Nord_Sahara_1959, 4307) +ValuePair(GCS_Stockholm_1938, 4308) +ValuePair(GCS_Yacare, 4309) +ValuePair(GCS_Yoff, 4310) +ValuePair(GCS_Zanderij, 4311) +ValuePair(GCS_MGI, 4312) +ValuePair(GCS_Belge_1972, 4313) +ValuePair(GCS_DHDN, 4314) +ValuePair(GCS_Conakry_1905, 4315) +ValuePair(GCS_WGS_72, 4322) +ValuePair(GCS_WGS_72BE, 4324) +ValuePair(GCS_WGS_84, 4326) +ValuePair(GCS_Bern_1898_Bern, 4801) +ValuePair(GCS_Bogota_Bogota, 4802) +ValuePair(GCS_Lisbon_Lisbon, 4803) +ValuePair(GCS_Makassar_Jakarta, 4804) +ValuePair(GCS_MGI_Ferro, 4805) +ValuePair(GCS_Monte_Mario_Rome, 4806) +ValuePair(GCS_NTF_Paris, 4807) +ValuePair(GCS_Padang_Jakarta, 4808) +ValuePair(GCS_Belge_1950_Brussels, 4809) +ValuePair(GCS_Tananarive_Paris, 4810) +ValuePair(GCS_Voirol_1875_Paris, 4811) +ValuePair(GCS_Voirol_Unifie_Paris, 4812) +ValuePair(GCS_Batavia_Jakarta, 4813) +ValuePair(GCS_ATF_Paris, 4901) +ValuePair(GCS_NDG_Paris, 4902) +/* End of list */ diff --git a/Utilities/otbgeotiff/epsg_pcs.inc b/Utilities/otbgeotiff/epsg_pcs.inc new file mode 100644 index 0000000000000000000000000000000000000000..e8a5ef50a4c167e5147404d3d845d9f54f831054 --- /dev/null +++ b/Utilities/otbgeotiff/epsg_pcs.inc @@ -0,0 +1,1012 @@ +/* + * EPSG PCS Codes - GeoTIFF Rev 0.2 + */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +#ifdef INCLUDE_OLD_CODES +#include old_pcs.inc +#endif /* OLD Codes */ + +/* Newer PCS */ +ValuePair(PCS_Hjorsey_1955_Lambert, 3053) +ValuePair(PCS_ISN93_Lambert_1993, 3057) +ValuePair(PCS_ETRS89_Poland_CS2000_zone_5,2176) +ValuePair(PCS_ETRS89_Poland_CS2000_zone_6,2177) +ValuePair(PCS_ETRS89_Poland_CS2000_zone_7,2177) +ValuePair(PCS_ETRS89_Poland_CS2000_zone_8,2178) +ValuePair(PCS_ETRS89_Poland_CS92,2180) + +/* New PCS */ +ValuePair(PCS_GGRS87_Greek_Grid,2100) +ValuePair(PCS_KKJ_Finland_zone_1,2391) +ValuePair(PCS_KKJ_Finland_zone_2,2392) +ValuePair(PCS_KKJ_Finland_zone_3,2393) +ValuePair(PCS_KKJ_Finland_zone_4,2394) +ValuePair(PCS_RT90_2_5_gon_W,2400) +ValuePair(PCS_Lietuvos_Koordinoei_Sistema_1994,2600) +ValuePair(PCS_Estonian_Coordinate_System_of_1992,3300) +ValuePair(PCS_HD72_EOV,23700) +ValuePair(PCS_Dealul_Piscului_1970_Stereo_70,31700) + +ValuePair(PCS_Adindan_UTM_zone_37N, 20137) +ValuePair(PCS_Adindan_UTM_zone_38N, 20138) +ValuePair(PCS_AGD66_AMG_zone_48, 20248) +ValuePair(PCS_AGD66_AMG_zone_49, 20249) +ValuePair(PCS_AGD66_AMG_zone_50, 20250) +ValuePair(PCS_AGD66_AMG_zone_51, 20251) +ValuePair(PCS_AGD66_AMG_zone_52, 20252) +ValuePair(PCS_AGD66_AMG_zone_53, 20253) +ValuePair(PCS_AGD66_AMG_zone_54, 20254) +ValuePair(PCS_AGD66_AMG_zone_55, 20255) +ValuePair(PCS_AGD66_AMG_zone_56, 20256) +ValuePair(PCS_AGD66_AMG_zone_57, 20257) +ValuePair(PCS_AGD66_AMG_zone_58, 20258) +ValuePair(PCS_AGD84_AMG_zone_48, 20348) +ValuePair(PCS_AGD84_AMG_zone_49, 20349) +ValuePair(PCS_AGD84_AMG_zone_50, 20350) +ValuePair(PCS_AGD84_AMG_zone_51, 20351) +ValuePair(PCS_AGD84_AMG_zone_52, 20352) +ValuePair(PCS_AGD84_AMG_zone_53, 20353) +ValuePair(PCS_AGD84_AMG_zone_54, 20354) +ValuePair(PCS_AGD84_AMG_zone_55, 20355) +ValuePair(PCS_AGD84_AMG_zone_56, 20356) +ValuePair(PCS_AGD84_AMG_zone_57, 20357) +ValuePair(PCS_AGD84_AMG_zone_58, 20358) +ValuePair(PCS_Ain_el_Abd_UTM_zone_37N, 20437) +ValuePair(PCS_Ain_el_Abd_UTM_zone_38N, 20438) +ValuePair(PCS_Ain_el_Abd_UTM_zone_39N, 20439) +ValuePair(PCS_Ain_el_Abd_Bahrain_Grid, 20499) +ValuePair(PCS_Afgooye_UTM_zone_38N, 20538) +ValuePair(PCS_Afgooye_UTM_zone_39N, 20539) +ValuePair(PCS_Lisbon_Portugese_Grid, 20700) +ValuePair(PCS_Aratu_UTM_zone_22S, 20822) +ValuePair(PCS_Aratu_UTM_zone_23S, 20823) +ValuePair(PCS_Aratu_UTM_zone_24S, 20824) +ValuePair(PCS_Arc_1950_Lo13, 20973) +ValuePair(PCS_Arc_1950_Lo15, 20975) +ValuePair(PCS_Arc_1950_Lo17, 20977) +ValuePair(PCS_Arc_1950_Lo19, 20979) +ValuePair(PCS_Arc_1950_Lo21, 20981) +ValuePair(PCS_Arc_1950_Lo23, 20983) +ValuePair(PCS_Arc_1950_Lo25, 20985) +ValuePair(PCS_Arc_1950_Lo27, 20987) +ValuePair(PCS_Arc_1950_Lo29, 20989) +ValuePair(PCS_Arc_1950_Lo31, 20991) +ValuePair(PCS_Arc_1950_Lo33, 20993) +ValuePair(PCS_Arc_1950_Lo35, 20995) +ValuePair(PCS_Batavia_NEIEZ, 21100) +ValuePair(PCS_Batavia_UTM_zone_48S, 21148) +ValuePair(PCS_Batavia_UTM_zone_49S, 21149) +ValuePair(PCS_Batavia_UTM_zone_50S, 21150) +ValuePair(PCS_Beijing_Gauss_zone_13, 21413) +ValuePair(PCS_Beijing_Gauss_zone_14, 21414) +ValuePair(PCS_Beijing_Gauss_zone_15, 21415) +ValuePair(PCS_Beijing_Gauss_zone_16, 21416) +ValuePair(PCS_Beijing_Gauss_zone_17, 21417) +ValuePair(PCS_Beijing_Gauss_zone_18, 21418) +ValuePair(PCS_Beijing_Gauss_zone_19, 21419) +ValuePair(PCS_Beijing_Gauss_zone_20, 21420) +ValuePair(PCS_Beijing_Gauss_zone_21, 21421) +ValuePair(PCS_Beijing_Gauss_zone_22, 21422) +ValuePair(PCS_Beijing_Gauss_zone_23, 21423) +ValuePair(PCS_Beijing_Gauss_13N, 21473) +ValuePair(PCS_Beijing_Gauss_14N, 21474) +ValuePair(PCS_Beijing_Gauss_15N, 21475) +ValuePair(PCS_Beijing_Gauss_16N, 21476) +ValuePair(PCS_Beijing_Gauss_17N, 21477) +ValuePair(PCS_Beijing_Gauss_18N, 21478) +ValuePair(PCS_Beijing_Gauss_19N, 21479) +ValuePair(PCS_Beijing_Gauss_20N, 21480) +ValuePair(PCS_Beijing_Gauss_21N, 21481) +ValuePair(PCS_Beijing_Gauss_22N, 21482) +ValuePair(PCS_Beijing_Gauss_23N, 21483) +ValuePair(PCS_Belge_Lambert_50, 21500) +ValuePair(PCS_Bern_1898_Swiss_Old, 21790) +ValuePair(PCS_Bogota_UTM_zone_17N, 21817) +ValuePair(PCS_Bogota_UTM_zone_18N, 21818) +ValuePair(PCS_Bogota_Colombia_3W, 21891) +ValuePair(PCS_Bogota_Colombia_Bogota, 21892) +ValuePair(PCS_Bogota_Colombia_3E, 21893) +ValuePair(PCS_Bogota_Colombia_6E, 21894) +ValuePair(PCS_Camacupa_UTM_32S, 22032) +ValuePair(PCS_Camacupa_UTM_33S, 22033) +ValuePair(PCS_C_Inchauspe_Argentina_1, 22191) +ValuePair(PCS_C_Inchauspe_Argentina_2, 22192) +ValuePair(PCS_C_Inchauspe_Argentina_3, 22193) +ValuePair(PCS_C_Inchauspe_Argentina_4, 22194) +ValuePair(PCS_C_Inchauspe_Argentina_5, 22195) +ValuePair(PCS_C_Inchauspe_Argentina_6, 22196) +ValuePair(PCS_C_Inchauspe_Argentina_7, 22197) +ValuePair(PCS_Carthage_UTM_zone_32N, 22332) +ValuePair(PCS_Carthage_Nord_Tunisie, 22391) +ValuePair(PCS_Carthage_Sud_Tunisie, 22392) +ValuePair(PCS_Corrego_Alegre_UTM_23S, 22523) +ValuePair(PCS_Corrego_Alegre_UTM_24S, 22524) +ValuePair(PCS_Douala_UTM_zone_32N, 22832) +ValuePair(PCS_Egypt_1907_Red_Belt, 22992) +ValuePair(PCS_Egypt_1907_Purple_Belt, 22993) +ValuePair(PCS_Egypt_1907_Ext_Purple, 22994) +ValuePair(PCS_ED50_UTM_zone_28N, 23028) +ValuePair(PCS_ED50_UTM_zone_29N, 23029) +ValuePair(PCS_ED50_UTM_zone_30N, 23030) +ValuePair(PCS_ED50_UTM_zone_31N, 23031) +ValuePair(PCS_ED50_UTM_zone_32N, 23032) +ValuePair(PCS_ED50_UTM_zone_33N, 23033) +ValuePair(PCS_ED50_UTM_zone_34N, 23034) +ValuePair(PCS_ED50_UTM_zone_35N, 23035) +ValuePair(PCS_ED50_UTM_zone_36N, 23036) +ValuePair(PCS_ED50_UTM_zone_37N, 23037) +ValuePair(PCS_ED50_UTM_zone_38N, 23038) +ValuePair(PCS_Fahud_UTM_zone_39N, 23239) +ValuePair(PCS_Fahud_UTM_zone_40N, 23240) +ValuePair(PCS_Garoua_UTM_zone_33N, 23433) +ValuePair(PCS_ID74_UTM_zone_46N, 23846) +ValuePair(PCS_ID74_UTM_zone_47N, 23847) +ValuePair(PCS_ID74_UTM_zone_48N, 23848) +ValuePair(PCS_ID74_UTM_zone_49N, 23849) +ValuePair(PCS_ID74_UTM_zone_50N, 23850) +ValuePair(PCS_ID74_UTM_zone_51N, 23851) +ValuePair(PCS_ID74_UTM_zone_52N, 23852) +ValuePair(PCS_ID74_UTM_zone_53N, 23853) +ValuePair(PCS_ID74_UTM_zone_46S, 23886) +ValuePair(PCS_ID74_UTM_zone_47S, 23887) +ValuePair(PCS_ID74_UTM_zone_48S, 23888) +ValuePair(PCS_ID74_UTM_zone_49S, 23889) +ValuePair(PCS_ID74_UTM_zone_50S, 23890) +ValuePair(PCS_ID74_UTM_zone_51S, 23891) +ValuePair(PCS_ID74_UTM_zone_52S, 23892) +ValuePair(PCS_ID74_UTM_zone_53S, 23893) +ValuePair(PCS_ID74_UTM_zone_54S, 23894) +ValuePair(PCS_Indian_1954_UTM_47N, 23947) +ValuePair(PCS_Indian_1954_UTM_48N, 23948) +ValuePair(PCS_Indian_1975_UTM_47N, 24047) +ValuePair(PCS_Indian_1975_UTM_48N, 24048) +ValuePair(PCS_Jamaica_1875_Old_Grid, 24100) +ValuePair(PCS_JAD69_Jamaica_Grid, 24200) +ValuePair(PCS_Kalianpur_India_0, 24370) +ValuePair(PCS_Kalianpur_India_I, 24371) +ValuePair(PCS_Kalianpur_India_IIa, 24372) +ValuePair(PCS_Kalianpur_India_IIIa, 24373) +ValuePair(PCS_Kalianpur_India_IVa, 24374) +ValuePair(PCS_Kalianpur_India_IIb, 24382) +ValuePair(PCS_Kalianpur_India_IIIb, 24383) +ValuePair(PCS_Kalianpur_India_IVb, 24384) +ValuePair(PCS_Kertau_Singapore_Grid, 24500) +ValuePair(PCS_Kertau_UTM_zone_47N, 24547) +ValuePair(PCS_Kertau_UTM_zone_48N, 24548) +ValuePair(PCS_La_Canoa_UTM_zone_20N, 24720) +ValuePair(PCS_La_Canoa_UTM_zone_21N, 24721) +ValuePair(PCS_PSAD56_UTM_zone_18N, 24818) +ValuePair(PCS_PSAD56_UTM_zone_19N, 24819) +ValuePair(PCS_PSAD56_UTM_zone_20N, 24820) +ValuePair(PCS_PSAD56_UTM_zone_21N, 24821) +ValuePair(PCS_PSAD56_UTM_zone_17S, 24877) +ValuePair(PCS_PSAD56_UTM_zone_18S, 24878) +ValuePair(PCS_PSAD56_UTM_zone_19S, 24879) +ValuePair(PCS_PSAD56_UTM_zone_20S, 24880) +ValuePair(PCS_PSAD56_Peru_west_zone, 24891) +ValuePair(PCS_PSAD56_Peru_central, 24892) +ValuePair(PCS_PSAD56_Peru_east_zone, 24893) +ValuePair(PCS_Leigon_Ghana_Grid, 25000) +ValuePair(PCS_Lome_UTM_zone_31N, 25231) +ValuePair(PCS_Luzon_Philippines_I, 25391) +ValuePair(PCS_Luzon_Philippines_II, 25392) +ValuePair(PCS_Luzon_Philippines_III, 25393) +ValuePair(PCS_Luzon_Philippines_IV, 25394) +ValuePair(PCS_Luzon_Philippines_V, 25395) +ValuePair(PCS_Makassar_NEIEZ, 25700) +ValuePair(PCS_Malongo_1987_UTM_32S, 25932) +ValuePair(PCS_Merchich_Nord_Maroc, 26191) +ValuePair(PCS_Merchich_Sud_Maroc, 26192) +ValuePair(PCS_Merchich_Sahara, 26193) +ValuePair(PCS_Massawa_UTM_zone_37N, 26237) +ValuePair(PCS_Minna_UTM_zone_31N, 26331) +ValuePair(PCS_Minna_UTM_zone_32N, 26332) +ValuePair(PCS_Minna_Nigeria_West, 26391) +ValuePair(PCS_Minna_Nigeria_Mid_Belt, 26392) +ValuePair(PCS_Minna_Nigeria_East, 26393) +ValuePair(PCS_Mhast_UTM_zone_32S, 26432) +ValuePair(PCS_Monte_Mario_Italy_1, 26591) +ValuePair(PCS_Monte_Mario_Italy_2, 26592) +ValuePair(PCS_M_poraloko_UTM_32N, 26632) +ValuePair(PCS_M_poraloko_UTM_32S, 26692) +ValuePair(PCS_NAD27_UTM_zone_3N, 26703) +ValuePair(PCS_NAD27_UTM_zone_4N, 26704) +ValuePair(PCS_NAD27_UTM_zone_5N, 26705) +ValuePair(PCS_NAD27_UTM_zone_6N, 26706) +ValuePair(PCS_NAD27_UTM_zone_7N, 26707) +ValuePair(PCS_NAD27_UTM_zone_8N, 26708) +ValuePair(PCS_NAD27_UTM_zone_9N, 26709) +ValuePair(PCS_NAD27_UTM_zone_10N, 26710) +ValuePair(PCS_NAD27_UTM_zone_11N, 26711) +ValuePair(PCS_NAD27_UTM_zone_12N, 26712) +ValuePair(PCS_NAD27_UTM_zone_13N, 26713) +ValuePair(PCS_NAD27_UTM_zone_14N, 26714) +ValuePair(PCS_NAD27_UTM_zone_15N, 26715) +ValuePair(PCS_NAD27_UTM_zone_16N, 26716) +ValuePair(PCS_NAD27_UTM_zone_17N, 26717) +ValuePair(PCS_NAD27_UTM_zone_18N, 26718) +ValuePair(PCS_NAD27_UTM_zone_19N, 26719) +ValuePair(PCS_NAD27_UTM_zone_20N, 26720) +ValuePair(PCS_NAD27_UTM_zone_21N, 26721) +ValuePair(PCS_NAD27_UTM_zone_22N, 26722) +ValuePair(PCS_NAD27_Alabama_East, 26729) +ValuePair(PCS_NAD27_Alabama_West, 26730) +ValuePair(PCS_NAD27_Alaska_zone_1, 26731) +ValuePair(PCS_NAD27_Alaska_zone_2, 26732) +ValuePair(PCS_NAD27_Alaska_zone_3, 26733) +ValuePair(PCS_NAD27_Alaska_zone_4, 26734) +ValuePair(PCS_NAD27_Alaska_zone_5, 26735) +ValuePair(PCS_NAD27_Alaska_zone_6, 26736) +ValuePair(PCS_NAD27_Alaska_zone_7, 26737) +ValuePair(PCS_NAD27_Alaska_zone_8, 26738) +ValuePair(PCS_NAD27_Alaska_zone_9, 26739) +ValuePair(PCS_NAD27_Alaska_zone_10, 26740) +ValuePair(PCS_NAD27_California_I, 26741) +ValuePair(PCS_NAD27_California_II, 26742) +ValuePair(PCS_NAD27_California_III, 26743) +ValuePair(PCS_NAD27_California_IV, 26744) +ValuePair(PCS_NAD27_California_V, 26745) +ValuePair(PCS_NAD27_California_VI, 26746) +ValuePair(PCS_NAD27_California_VII, 26747) +ValuePair(PCS_NAD27_Arizona_East, 26748) +ValuePair(PCS_NAD27_Arizona_Central, 26749) +ValuePair(PCS_NAD27_Arizona_West, 26750) +ValuePair(PCS_NAD27_Arkansas_North, 26751) +ValuePair(PCS_NAD27_Arkansas_South, 26752) +ValuePair(PCS_NAD27_Colorado_North, 26753) +ValuePair(PCS_NAD27_Colorado_Central, 26754) +ValuePair(PCS_NAD27_Colorado_South, 26755) +ValuePair(PCS_NAD27_Connecticut, 26756) +ValuePair(PCS_NAD27_Delaware, 26757) +ValuePair(PCS_NAD27_Florida_East, 26758) +ValuePair(PCS_NAD27_Florida_West, 26759) +ValuePair(PCS_NAD27_Florida_North, 26760) +ValuePair(PCS_NAD27_Hawaii_zone_1, 26761) +ValuePair(PCS_NAD27_Hawaii_zone_2, 26762) +ValuePair(PCS_NAD27_Hawaii_zone_3, 26763) +ValuePair(PCS_NAD27_Hawaii_zone_4, 26764) +ValuePair(PCS_NAD27_Hawaii_zone_5, 26765) +ValuePair(PCS_NAD27_Georgia_East, 26766) +ValuePair(PCS_NAD27_Georgia_West, 26767) +ValuePair(PCS_NAD27_Idaho_East, 26768) +ValuePair(PCS_NAD27_Idaho_Central, 26769) +ValuePair(PCS_NAD27_Idaho_West, 26770) +ValuePair(PCS_NAD27_Illinois_East, 26771) +ValuePair(PCS_NAD27_Illinois_West, 26772) +ValuePair(PCS_NAD27_Indiana_East, 26773) +ValuePair(PCS_NAD27_BLM_14N_feet, 26774) +ValuePair(PCS_NAD27_Indiana_West, 26774) +ValuePair(PCS_NAD27_BLM_15N_feet, 26775) +ValuePair(PCS_NAD27_Iowa_North, 26775) +ValuePair(PCS_NAD27_BLM_16N_feet, 26776) +ValuePair(PCS_NAD27_Iowa_South, 26776) +ValuePair(PCS_NAD27_BLM_17N_feet, 26777) +ValuePair(PCS_NAD27_Kansas_North, 26777) +ValuePair(PCS_NAD27_Kansas_South, 26778) +ValuePair(PCS_NAD27_Kentucky_North, 26779) +ValuePair(PCS_NAD27_Kentucky_South, 26780) +ValuePair(PCS_NAD27_Louisiana_North, 26781) +ValuePair(PCS_NAD27_Louisiana_South, 26782) +ValuePair(PCS_NAD27_Maine_East, 26783) +ValuePair(PCS_NAD27_Maine_West, 26784) +ValuePair(PCS_NAD27_Maryland, 26785) +ValuePair(PCS_NAD27_Massachusetts, 26786) +ValuePair(PCS_NAD27_Massachusetts_Is, 26787) +ValuePair(PCS_NAD27_Michigan_North, 26788) +ValuePair(PCS_NAD27_Michigan_Central, 26789) +ValuePair(PCS_NAD27_Michigan_South, 26790) +ValuePair(PCS_NAD27_Minnesota_North, 26791) +ValuePair(PCS_NAD27_Minnesota_Cent, 26792) +ValuePair(PCS_NAD27_Minnesota_South, 26793) +ValuePair(PCS_NAD27_Mississippi_East, 26794) +ValuePair(PCS_NAD27_Mississippi_West, 26795) +ValuePair(PCS_NAD27_Missouri_East, 26796) +ValuePair(PCS_NAD27_Missouri_Central, 26797) +ValuePair(PCS_NAD27_Missouri_West, 26798) +ValuePair(PCS_NAD_Michigan_Michigan_East, 26801) +ValuePair(PCS_NAD_Michigan_Michigan_Old_Central, 26802) +ValuePair(PCS_NAD_Michigan_Michigan_West, 26803) +ValuePair(PCS_NAD83_UTM_zone_3N, 26903) +ValuePair(PCS_NAD83_UTM_zone_4N, 26904) +ValuePair(PCS_NAD83_UTM_zone_5N, 26905) +ValuePair(PCS_NAD83_UTM_zone_6N, 26906) +ValuePair(PCS_NAD83_UTM_zone_7N, 26907) +ValuePair(PCS_NAD83_UTM_zone_8N, 26908) +ValuePair(PCS_NAD83_UTM_zone_9N, 26909) +ValuePair(PCS_NAD83_UTM_zone_10N, 26910) +ValuePair(PCS_NAD83_UTM_zone_11N, 26911) +ValuePair(PCS_NAD83_UTM_zone_12N, 26912) +ValuePair(PCS_NAD83_UTM_zone_13N, 26913) +ValuePair(PCS_NAD83_UTM_zone_14N, 26914) +ValuePair(PCS_NAD83_UTM_zone_15N, 26915) +ValuePair(PCS_NAD83_UTM_zone_16N, 26916) +ValuePair(PCS_NAD83_UTM_zone_17N, 26917) +ValuePair(PCS_NAD83_UTM_zone_18N, 26918) +ValuePair(PCS_NAD83_UTM_zone_19N, 26919) +ValuePair(PCS_NAD83_UTM_zone_20N, 26920) +ValuePair(PCS_NAD83_UTM_zone_21N, 26921) +ValuePair(PCS_NAD83_UTM_zone_22N, 26922) +ValuePair(PCS_NAD83_UTM_zone_23N, 26923) +ValuePair(PCS_NAD83_Alabama_East, 26929) +ValuePair(PCS_NAD83_Alabama_West, 26930) +ValuePair(PCS_NAD83_Alaska_zone_1, 26931) +ValuePair(PCS_NAD83_Alaska_zone_2, 26932) +ValuePair(PCS_NAD83_Alaska_zone_3, 26933) +ValuePair(PCS_NAD83_Alaska_zone_4, 26934) +ValuePair(PCS_NAD83_Alaska_zone_5, 26935) +ValuePair(PCS_NAD83_Alaska_zone_6, 26936) +ValuePair(PCS_NAD83_Alaska_zone_7, 26937) +ValuePair(PCS_NAD83_Alaska_zone_8, 26938) +ValuePair(PCS_NAD83_Alaska_zone_9, 26939) +ValuePair(PCS_NAD83_Alaska_zone_10, 26940) +ValuePair(PCS_NAD83_California_1, 26941) +ValuePair(PCS_NAD83_California_2, 26942) +ValuePair(PCS_NAD83_California_3, 26943) +ValuePair(PCS_NAD83_California_4, 26944) +ValuePair(PCS_NAD83_California_5, 26945) +ValuePair(PCS_NAD83_California_6, 26946) +ValuePair(PCS_NAD83_Arizona_East, 26948) +ValuePair(PCS_NAD83_Arizona_Central, 26949) +ValuePair(PCS_NAD83_Arizona_West, 26950) +ValuePair(PCS_NAD83_Arkansas_North, 26951) +ValuePair(PCS_NAD83_Arkansas_South, 26952) +ValuePair(PCS_NAD83_Colorado_North, 26953) +ValuePair(PCS_NAD83_Colorado_Central, 26954) +ValuePair(PCS_NAD83_Colorado_South, 26955) +ValuePair(PCS_NAD83_Connecticut, 26956) +ValuePair(PCS_NAD83_Delaware, 26957) +ValuePair(PCS_NAD83_Florida_East, 26958) +ValuePair(PCS_NAD83_Florida_West, 26959) +ValuePair(PCS_NAD83_Florida_North, 26960) +ValuePair(PCS_NAD83_Hawaii_zone_1, 26961) +ValuePair(PCS_NAD83_Hawaii_zone_2, 26962) +ValuePair(PCS_NAD83_Hawaii_zone_3, 26963) +ValuePair(PCS_NAD83_Hawaii_zone_4, 26964) +ValuePair(PCS_NAD83_Hawaii_zone_5, 26965) +ValuePair(PCS_NAD83_Georgia_East, 26966) +ValuePair(PCS_NAD83_Georgia_West, 26967) +ValuePair(PCS_NAD83_Idaho_East, 26968) +ValuePair(PCS_NAD83_Idaho_Central, 26969) +ValuePair(PCS_NAD83_Idaho_West, 26970) +ValuePair(PCS_NAD83_Illinois_East, 26971) +ValuePair(PCS_NAD83_Illinois_West, 26972) +ValuePair(PCS_NAD83_Indiana_East, 26973) +ValuePair(PCS_NAD83_Indiana_West, 26974) +ValuePair(PCS_NAD83_Iowa_North, 26975) +ValuePair(PCS_NAD83_Iowa_South, 26976) +ValuePair(PCS_NAD83_Kansas_North, 26977) +ValuePair(PCS_NAD83_Kansas_South, 26978) +ValuePair(PCS_NAD83_Kentucky_North, 2205) +ValuePair(PCS_NAD83_Kentucky_South, 26980) +ValuePair(PCS_NAD83_Louisiana_North, 26981) +ValuePair(PCS_NAD83_Louisiana_South, 26982) +ValuePair(PCS_NAD83_Maine_East, 26983) +ValuePair(PCS_NAD83_Maine_West, 26984) +ValuePair(PCS_NAD83_Maryland, 26985) +ValuePair(PCS_NAD83_Massachusetts, 26986) +ValuePair(PCS_NAD83_Massachusetts_Is, 26987) +ValuePair(PCS_NAD83_Michigan_North, 26988) +ValuePair(PCS_NAD83_Michigan_Central, 26989) +ValuePair(PCS_NAD83_Michigan_South, 26990) +ValuePair(PCS_NAD83_Minnesota_North, 26991) +ValuePair(PCS_NAD83_Minnesota_Cent, 26992) +ValuePair(PCS_NAD83_Minnesota_South, 26993) +ValuePair(PCS_NAD83_Mississippi_East, 26994) +ValuePair(PCS_NAD83_Mississippi_West, 26995) +ValuePair(PCS_NAD83_Missouri_East, 26996) +ValuePair(PCS_NAD83_Missouri_Central, 26997) +ValuePair(PCS_NAD83_Missouri_West, 26998) +ValuePair(PCS_Nahrwan_1967_UTM_38N, 27038) +ValuePair(PCS_Nahrwan_1967_UTM_39N, 27039) +ValuePair(PCS_Nahrwan_1967_UTM_40N, 27040) +ValuePair(PCS_Naparima_UTM_20N, 27120) +ValuePair(PCS_GD49_NZ_Map_Grid, 27200) +ValuePair(PCS_GD49_North_Island_Grid, 27291) +ValuePair(PCS_GD49_South_Island_Grid, 27292) +ValuePair(PCS_Datum_73_UTM_zone_29N, 27429) +ValuePair(PCS_ATF_Nord_de_Guerre, 27500) +ValuePair(PCS_NTF_France_I, 27581) +ValuePair(PCS_NTF_France_II, 27582) +ValuePair(PCS_NTF_France_III, 27583) +ValuePair(PCS_NTF_Nord_France, 27591) +ValuePair(PCS_NTF_Centre_France, 27592) +ValuePair(PCS_NTF_Sud_France, 27593) +ValuePair(PCS_British_National_Grid, 27700) +ValuePair(PCS_Point_Noire_UTM_32S, 28232) +ValuePair(PCS_GDA94_MGA_zone_48, 28348) +ValuePair(PCS_GDA94_MGA_zone_49, 28349) +ValuePair(PCS_GDA94_MGA_zone_50, 28350) +ValuePair(PCS_GDA94_MGA_zone_51, 28351) +ValuePair(PCS_GDA94_MGA_zone_52, 28352) +ValuePair(PCS_GDA94_MGA_zone_53, 28353) +ValuePair(PCS_GDA94_MGA_zone_54, 28354) +ValuePair(PCS_GDA94_MGA_zone_55, 28355) +ValuePair(PCS_GDA94_MGA_zone_56, 28356) +ValuePair(PCS_GDA94_MGA_zone_57, 28357) +ValuePair(PCS_GDA94_MGA_zone_58, 28358) +ValuePair(PCS_Pulkovo_Gauss_zone_4, 28404) +ValuePair(PCS_Pulkovo_Gauss_zone_5, 28405) +ValuePair(PCS_Pulkovo_Gauss_zone_6, 28406) +ValuePair(PCS_Pulkovo_Gauss_zone_7, 28407) +ValuePair(PCS_Pulkovo_Gauss_zone_8, 28408) +ValuePair(PCS_Pulkovo_Gauss_zone_9, 28409) +ValuePair(PCS_Pulkovo_Gauss_zone_10, 28410) +ValuePair(PCS_Pulkovo_Gauss_zone_11, 28411) +ValuePair(PCS_Pulkovo_Gauss_zone_12, 28412) +ValuePair(PCS_Pulkovo_Gauss_zone_13, 28413) +ValuePair(PCS_Pulkovo_Gauss_zone_14, 28414) +ValuePair(PCS_Pulkovo_Gauss_zone_15, 28415) +ValuePair(PCS_Pulkovo_Gauss_zone_16, 28416) +ValuePair(PCS_Pulkovo_Gauss_zone_17, 28417) +ValuePair(PCS_Pulkovo_Gauss_zone_18, 28418) +ValuePair(PCS_Pulkovo_Gauss_zone_19, 28419) +ValuePair(PCS_Pulkovo_Gauss_zone_20, 28420) +ValuePair(PCS_Pulkovo_Gauss_zone_21, 28421) +ValuePair(PCS_Pulkovo_Gauss_zone_22, 28422) +ValuePair(PCS_Pulkovo_Gauss_zone_23, 28423) +ValuePair(PCS_Pulkovo_Gauss_zone_24, 28424) +ValuePair(PCS_Pulkovo_Gauss_zone_25, 28425) +ValuePair(PCS_Pulkovo_Gauss_zone_26, 28426) +ValuePair(PCS_Pulkovo_Gauss_zone_27, 28427) +ValuePair(PCS_Pulkovo_Gauss_zone_28, 28428) +ValuePair(PCS_Pulkovo_Gauss_zone_29, 28429) +ValuePair(PCS_Pulkovo_Gauss_zone_30, 28430) +ValuePair(PCS_Pulkovo_Gauss_zone_31, 28431) +ValuePair(PCS_Pulkovo_Gauss_zone_32, 28432) +ValuePair(PCS_Pulkovo_Gauss_4N, 28464) +ValuePair(PCS_Pulkovo_Gauss_5N, 28465) +ValuePair(PCS_Pulkovo_Gauss_6N, 28466) +ValuePair(PCS_Pulkovo_Gauss_7N, 28467) +ValuePair(PCS_Pulkovo_Gauss_8N, 28468) +ValuePair(PCS_Pulkovo_Gauss_9N, 28469) +ValuePair(PCS_Pulkovo_Gauss_10N, 28470) +ValuePair(PCS_Pulkovo_Gauss_11N, 28471) +ValuePair(PCS_Pulkovo_Gauss_12N, 28472) +ValuePair(PCS_Pulkovo_Gauss_13N, 28473) +ValuePair(PCS_Pulkovo_Gauss_14N, 28474) +ValuePair(PCS_Pulkovo_Gauss_15N, 28475) +ValuePair(PCS_Pulkovo_Gauss_16N, 28476) +ValuePair(PCS_Pulkovo_Gauss_17N, 28477) +ValuePair(PCS_Pulkovo_Gauss_18N, 28478) +ValuePair(PCS_Pulkovo_Gauss_19N, 28479) +ValuePair(PCS_Pulkovo_Gauss_20N, 28480) +ValuePair(PCS_Pulkovo_Gauss_21N, 28481) +ValuePair(PCS_Pulkovo_Gauss_22N, 28482) +ValuePair(PCS_Pulkovo_Gauss_23N, 28483) +ValuePair(PCS_Pulkovo_Gauss_24N, 28484) +ValuePair(PCS_Pulkovo_Gauss_25N, 28485) +ValuePair(PCS_Pulkovo_Gauss_26N, 28486) +ValuePair(PCS_Pulkovo_Gauss_27N, 28487) +ValuePair(PCS_Pulkovo_Gauss_28N, 28488) +ValuePair(PCS_Pulkovo_Gauss_29N, 28489) +ValuePair(PCS_Pulkovo_Gauss_30N, 28490) +ValuePair(PCS_Pulkovo_Gauss_31N, 28491) +ValuePair(PCS_Pulkovo_Gauss_32N, 28492) +ValuePair(PCS_Qatar_National_Grid, 28600) +ValuePair(PCS_RD_Netherlands_Old, 28991) +ValuePair(PCS_RD_Netherlands_New, 28992) +ValuePair(PCS_SAD69_UTM_zone_18N, 29118) +ValuePair(PCS_SAD69_UTM_zone_19N, 29119) +ValuePair(PCS_SAD69_UTM_zone_20N, 29120) +ValuePair(PCS_SAD69_UTM_zone_21N, 29121) +ValuePair(PCS_SAD69_UTM_zone_22N, 29122) +ValuePair(PCS_SAD69_UTM_zone_17S, 29177) +ValuePair(PCS_SAD69_UTM_zone_18S, 29178) +ValuePair(PCS_SAD69_UTM_zone_19S, 29179) +ValuePair(PCS_SAD69_UTM_zone_20S, 29180) +ValuePair(PCS_SAD69_UTM_zone_21S, 29181) +ValuePair(PCS_SAD69_UTM_zone_22S, 29182) +ValuePair(PCS_SAD69_UTM_zone_23S, 29183) +ValuePair(PCS_SAD69_UTM_zone_24S, 29184) +ValuePair(PCS_SAD69_UTM_zone_25S, 29185) +ValuePair(PCS_Sapper_Hill_UTM_20S, 29220) +ValuePair(PCS_Sapper_Hill_UTM_21S, 29221) +ValuePair(PCS_Schwarzeck_UTM_33S, 29333) +ValuePair(PCS_Sudan_UTM_zone_35N, 29635) +ValuePair(PCS_Sudan_UTM_zone_36N, 29636) +ValuePair(PCS_Tananarive_Laborde, 29700) +ValuePair(PCS_Tananarive_UTM_38S, 29738) +ValuePair(PCS_Tananarive_UTM_39S, 29739) +ValuePair(PCS_Timbalai_1948_Borneo, 29800) +ValuePair(PCS_Timbalai_1948_UTM_49N, 29849) +ValuePair(PCS_Timbalai_1948_UTM_50N, 29850) +ValuePair(PCS_TM65_Irish_Nat_Grid, 29900) +ValuePair(PCS_Trinidad_1903_Trinidad, 30200) +ValuePair(PCS_TC_1948_UTM_zone_39N, 30339) +ValuePair(PCS_TC_1948_UTM_zone_40N, 30340) +ValuePair(PCS_Voirol_N_Algerie_ancien, 30491) +ValuePair(PCS_Voirol_S_Algerie_ancien, 30492) +ValuePair(PCS_Voirol_Unifie_N_Algerie, 30591) +ValuePair(PCS_Voirol_Unifie_S_Algerie, 30592) +ValuePair(PCS_Bern_1938_Swiss_New, 30600) +ValuePair(PCS_Nord_Sahara_UTM_29N, 30729) +ValuePair(PCS_Nord_Sahara_UTM_30N, 30730) +ValuePair(PCS_Nord_Sahara_UTM_31N, 30731) +ValuePair(PCS_Nord_Sahara_UTM_32N, 30732) +ValuePair(PCS_Yoff_UTM_zone_28N, 31028) +ValuePair(PCS_Zanderij_UTM_zone_21N, 31121) +ValuePair(PCS_MGI_Austria_West, 31291) +ValuePair(PCS_MGI_Austria_Central, 31292) +ValuePair(PCS_MGI_Austria_East, 31293) +ValuePair(PCS_Belge_Lambert_72, 31300) +ValuePair(PCS_DHDN_Germany_zone_1, 31491) +ValuePair(PCS_DHDN_Germany_zone_2, 31492) +ValuePair(PCS_DHDN_Germany_zone_3, 31493) +ValuePair(PCS_DHDN_Germany_zone_4, 31494) +ValuePair(PCS_DHDN_Germany_zone_5, 31495) +ValuePair(PCS_NAD27_Montana_North, 32001) +ValuePair(PCS_NAD27_Montana_Central, 32002) +ValuePair(PCS_NAD27_Montana_South, 32003) +ValuePair(PCS_NAD27_Nebraska_North, 32005) +ValuePair(PCS_NAD27_Nebraska_South, 32006) +ValuePair(PCS_NAD27_Nevada_East, 32007) +ValuePair(PCS_NAD27_Nevada_Central, 32008) +ValuePair(PCS_NAD27_Nevada_West, 32009) +ValuePair(PCS_NAD27_New_Hampshire, 32010) +ValuePair(PCS_NAD27_New_Jersey, 32011) +ValuePair(PCS_NAD27_New_Mexico_East, 32012) +ValuePair(PCS_NAD27_New_Mexico_Cent, 32013) +ValuePair(PCS_NAD27_New_Mexico_West, 32014) +ValuePair(PCS_NAD27_New_York_East, 32015) +ValuePair(PCS_NAD27_New_York_Central, 32016) +ValuePair(PCS_NAD27_New_York_West, 32017) +ValuePair(PCS_NAD27_New_York_Long_Is, 32018) +ValuePair(PCS_NAD27_North_Carolina, 32019) +ValuePair(PCS_NAD27_North_Dakota_N, 32020) +ValuePair(PCS_NAD27_North_Dakota_S, 32021) +ValuePair(PCS_NAD27_Ohio_North, 32022) +ValuePair(PCS_NAD27_Ohio_South, 32023) +ValuePair(PCS_NAD27_Oklahoma_North, 32024) +ValuePair(PCS_NAD27_Oklahoma_South, 32025) +ValuePair(PCS_NAD27_Oregon_North, 32026) +ValuePair(PCS_NAD27_Oregon_South, 32027) +ValuePair(PCS_NAD27_Pennsylvania_N, 32028) +ValuePair(PCS_NAD27_Pennsylvania_S, 32029) +ValuePair(PCS_NAD27_Rhode_Island, 32030) +ValuePair(PCS_NAD27_South_Carolina_N, 32031) +ValuePair(PCS_NAD27_South_Carolina_S, 32033) +ValuePair(PCS_NAD27_South_Dakota_N, 32034) +ValuePair(PCS_NAD27_South_Dakota_S, 32035) +ValuePair(PCS_NAD27_Tennessee, 2204) +ValuePair(PCS_NAD27_Texas_North, 32037) +ValuePair(PCS_NAD27_Texas_North_Cen, 32038) +ValuePair(PCS_NAD27_Texas_Central, 32039) +ValuePair(PCS_NAD27_Texas_South_Cen, 32040) +ValuePair(PCS_NAD27_Texas_South, 32041) +ValuePair(PCS_NAD27_Utah_North, 32042) +ValuePair(PCS_NAD27_Utah_Central, 32043) +ValuePair(PCS_NAD27_Utah_South, 32044) +ValuePair(PCS_NAD27_Vermont, 32045) +ValuePair(PCS_NAD27_Virginia_North, 32046) +ValuePair(PCS_NAD27_Virginia_South, 32047) +ValuePair(PCS_NAD27_Washington_North, 32048) +ValuePair(PCS_NAD27_Washington_South, 32049) +ValuePair(PCS_NAD27_West_Virginia_N, 32050) +ValuePair(PCS_NAD27_West_Virginia_S, 32051) +ValuePair(PCS_NAD27_Wisconsin_North, 32052) +ValuePair(PCS_NAD27_Wisconsin_Cen, 32053) +ValuePair(PCS_NAD27_Wisconsin_South, 32054) +ValuePair(PCS_NAD27_Wyoming_East, 32055) +ValuePair(PCS_NAD27_Wyoming_E_Cen, 32056) +ValuePair(PCS_NAD27_Wyoming_W_Cen, 32057) +ValuePair(PCS_NAD27_Wyoming_West, 32058) +ValuePair(PCS_NAD27_Puerto_Rico, 32059) +ValuePair(PCS_NAD27_St_Croix, 32060) +ValuePair(PCS_NAD83_Montana, 32100) +ValuePair(PCS_NAD83_Nebraska, 32104) +ValuePair(PCS_NAD83_Nevada_East, 32107) +ValuePair(PCS_NAD83_Nevada_Central, 32108) +ValuePair(PCS_NAD83_Nevada_West, 32109) +ValuePair(PCS_NAD83_New_Hampshire, 32110) +ValuePair(PCS_NAD83_New_Jersey, 32111) +ValuePair(PCS_NAD83_New_Mexico_East, 32112) +ValuePair(PCS_NAD83_New_Mexico_Cent, 32113) +ValuePair(PCS_NAD83_New_Mexico_West, 32114) +ValuePair(PCS_NAD83_New_York_East, 32115) +ValuePair(PCS_NAD83_New_York_Central, 32116) +ValuePair(PCS_NAD83_New_York_West, 32117) +ValuePair(PCS_NAD83_New_York_Long_Is, 32118) +ValuePair(PCS_NAD83_North_Carolina, 32119) +ValuePair(PCS_NAD83_North_Dakota_N, 32120) +ValuePair(PCS_NAD83_North_Dakota_S, 32121) +ValuePair(PCS_NAD83_Ohio_North, 32122) +ValuePair(PCS_NAD83_Ohio_South, 32123) +ValuePair(PCS_NAD83_Oklahoma_North, 32124) +ValuePair(PCS_NAD83_Oklahoma_South, 32125) +ValuePair(PCS_NAD83_Oregon_North, 32126) +ValuePair(PCS_NAD83_Oregon_South, 32127) +ValuePair(PCS_NAD83_Pennsylvania_N, 32128) +ValuePair(PCS_NAD83_Pennsylvania_S, 32129) +ValuePair(PCS_NAD83_Rhode_Island, 32130) +ValuePair(PCS_NAD83_South_Carolina, 32133) +ValuePair(PCS_NAD83_South_Dakota_N, 32134) +ValuePair(PCS_NAD83_South_Dakota_S, 32135) +ValuePair(PCS_NAD83_Tennessee, 32136) +ValuePair(PCS_NAD83_Texas_North, 32137) +ValuePair(PCS_NAD83_Texas_North_Cen, 32138) +ValuePair(PCS_NAD83_Texas_Central, 32139) +ValuePair(PCS_NAD83_Texas_South_Cen, 32140) +ValuePair(PCS_NAD83_Texas_South, 32141) +ValuePair(PCS_NAD83_Utah_North, 32142) +ValuePair(PCS_NAD83_Utah_Central, 32143) +ValuePair(PCS_NAD83_Utah_South, 32144) +ValuePair(PCS_NAD83_Vermont, 32145) +ValuePair(PCS_NAD83_Virginia_North, 32146) +ValuePair(PCS_NAD83_Virginia_South, 32147) +ValuePair(PCS_NAD83_Washington_North, 32148) +ValuePair(PCS_NAD83_Washington_South, 32149) +ValuePair(PCS_NAD83_West_Virginia_N, 32150) +ValuePair(PCS_NAD83_West_Virginia_S, 32151) +ValuePair(PCS_NAD83_Wisconsin_North, 32152) +ValuePair(PCS_NAD83_Wisconsin_Cen, 32153) +ValuePair(PCS_NAD83_Wisconsin_South, 32154) +ValuePair(PCS_NAD83_Wyoming_East, 32155) +ValuePair(PCS_NAD83_Wyoming_E_Cen, 32156) +ValuePair(PCS_NAD83_Wyoming_W_Cen, 32157) +ValuePair(PCS_NAD83_Wyoming_West, 32158) +ValuePair(PCS_NAD83_Puerto_Rico_Virgin_Is, 32161) +ValuePair(PCS_WGS72_UTM_zone_1N, 32201) +ValuePair(PCS_WGS72_UTM_zone_2N, 32202) +ValuePair(PCS_WGS72_UTM_zone_3N, 32203) +ValuePair(PCS_WGS72_UTM_zone_4N, 32204) +ValuePair(PCS_WGS72_UTM_zone_5N, 32205) +ValuePair(PCS_WGS72_UTM_zone_6N, 32206) +ValuePair(PCS_WGS72_UTM_zone_7N, 32207) +ValuePair(PCS_WGS72_UTM_zone_8N, 32208) +ValuePair(PCS_WGS72_UTM_zone_9N, 32209) +ValuePair(PCS_WGS72_UTM_zone_10N, 32210) +ValuePair(PCS_WGS72_UTM_zone_11N, 32211) +ValuePair(PCS_WGS72_UTM_zone_12N, 32212) +ValuePair(PCS_WGS72_UTM_zone_13N, 32213) +ValuePair(PCS_WGS72_UTM_zone_14N, 32214) +ValuePair(PCS_WGS72_UTM_zone_15N, 32215) +ValuePair(PCS_WGS72_UTM_zone_16N, 32216) +ValuePair(PCS_WGS72_UTM_zone_17N, 32217) +ValuePair(PCS_WGS72_UTM_zone_18N, 32218) +ValuePair(PCS_WGS72_UTM_zone_19N, 32219) +ValuePair(PCS_WGS72_UTM_zone_20N, 32220) +ValuePair(PCS_WGS72_UTM_zone_21N, 32221) +ValuePair(PCS_WGS72_UTM_zone_22N, 32222) +ValuePair(PCS_WGS72_UTM_zone_23N, 32223) +ValuePair(PCS_WGS72_UTM_zone_24N, 32224) +ValuePair(PCS_WGS72_UTM_zone_25N, 32225) +ValuePair(PCS_WGS72_UTM_zone_26N, 32226) +ValuePair(PCS_WGS72_UTM_zone_27N, 32227) +ValuePair(PCS_WGS72_UTM_zone_28N, 32228) +ValuePair(PCS_WGS72_UTM_zone_29N, 32229) +ValuePair(PCS_WGS72_UTM_zone_30N, 32230) +ValuePair(PCS_WGS72_UTM_zone_31N, 32231) +ValuePair(PCS_WGS72_UTM_zone_32N, 32232) +ValuePair(PCS_WGS72_UTM_zone_33N, 32233) +ValuePair(PCS_WGS72_UTM_zone_34N, 32234) +ValuePair(PCS_WGS72_UTM_zone_35N, 32235) +ValuePair(PCS_WGS72_UTM_zone_36N, 32236) +ValuePair(PCS_WGS72_UTM_zone_37N, 32237) +ValuePair(PCS_WGS72_UTM_zone_38N, 32238) +ValuePair(PCS_WGS72_UTM_zone_39N, 32239) +ValuePair(PCS_WGS72_UTM_zone_40N, 32240) +ValuePair(PCS_WGS72_UTM_zone_41N, 32241) +ValuePair(PCS_WGS72_UTM_zone_42N, 32242) +ValuePair(PCS_WGS72_UTM_zone_43N, 32243) +ValuePair(PCS_WGS72_UTM_zone_44N, 32244) +ValuePair(PCS_WGS72_UTM_zone_45N, 32245) +ValuePair(PCS_WGS72_UTM_zone_46N, 32246) +ValuePair(PCS_WGS72_UTM_zone_47N, 32247) +ValuePair(PCS_WGS72_UTM_zone_48N, 32248) +ValuePair(PCS_WGS72_UTM_zone_49N, 32249) +ValuePair(PCS_WGS72_UTM_zone_50N, 32250) +ValuePair(PCS_WGS72_UTM_zone_51N, 32251) +ValuePair(PCS_WGS72_UTM_zone_52N, 32252) +ValuePair(PCS_WGS72_UTM_zone_53N, 32253) +ValuePair(PCS_WGS72_UTM_zone_54N, 32254) +ValuePair(PCS_WGS72_UTM_zone_55N, 32255) +ValuePair(PCS_WGS72_UTM_zone_56N, 32256) +ValuePair(PCS_WGS72_UTM_zone_57N, 32257) +ValuePair(PCS_WGS72_UTM_zone_58N, 32258) +ValuePair(PCS_WGS72_UTM_zone_59N, 32259) +ValuePair(PCS_WGS72_UTM_zone_60N, 32260) +ValuePair(PCS_WGS72_UTM_zone_1S, 32301) +ValuePair(PCS_WGS72_UTM_zone_2S, 32302) +ValuePair(PCS_WGS72_UTM_zone_3S, 32303) +ValuePair(PCS_WGS72_UTM_zone_4S, 32304) +ValuePair(PCS_WGS72_UTM_zone_5S, 32305) +ValuePair(PCS_WGS72_UTM_zone_6S, 32306) +ValuePair(PCS_WGS72_UTM_zone_7S, 32307) +ValuePair(PCS_WGS72_UTM_zone_8S, 32308) +ValuePair(PCS_WGS72_UTM_zone_9S, 32309) +ValuePair(PCS_WGS72_UTM_zone_10S, 32310) +ValuePair(PCS_WGS72_UTM_zone_11S, 32311) +ValuePair(PCS_WGS72_UTM_zone_12S, 32312) +ValuePair(PCS_WGS72_UTM_zone_13S, 32313) +ValuePair(PCS_WGS72_UTM_zone_14S, 32314) +ValuePair(PCS_WGS72_UTM_zone_15S, 32315) +ValuePair(PCS_WGS72_UTM_zone_16S, 32316) +ValuePair(PCS_WGS72_UTM_zone_17S, 32317) +ValuePair(PCS_WGS72_UTM_zone_18S, 32318) +ValuePair(PCS_WGS72_UTM_zone_19S, 32319) +ValuePair(PCS_WGS72_UTM_zone_20S, 32320) +ValuePair(PCS_WGS72_UTM_zone_21S, 32321) +ValuePair(PCS_WGS72_UTM_zone_22S, 32322) +ValuePair(PCS_WGS72_UTM_zone_23S, 32323) +ValuePair(PCS_WGS72_UTM_zone_24S, 32324) +ValuePair(PCS_WGS72_UTM_zone_25S, 32325) +ValuePair(PCS_WGS72_UTM_zone_26S, 32326) +ValuePair(PCS_WGS72_UTM_zone_27S, 32327) +ValuePair(PCS_WGS72_UTM_zone_28S, 32328) +ValuePair(PCS_WGS72_UTM_zone_29S, 32329) +ValuePair(PCS_WGS72_UTM_zone_30S, 32330) +ValuePair(PCS_WGS72_UTM_zone_31S, 32331) +ValuePair(PCS_WGS72_UTM_zone_32S, 32332) +ValuePair(PCS_WGS72_UTM_zone_33S, 32333) +ValuePair(PCS_WGS72_UTM_zone_34S, 32334) +ValuePair(PCS_WGS72_UTM_zone_35S, 32335) +ValuePair(PCS_WGS72_UTM_zone_36S, 32336) +ValuePair(PCS_WGS72_UTM_zone_37S, 32337) +ValuePair(PCS_WGS72_UTM_zone_38S, 32338) +ValuePair(PCS_WGS72_UTM_zone_39S, 32339) +ValuePair(PCS_WGS72_UTM_zone_40S, 32340) +ValuePair(PCS_WGS72_UTM_zone_41S, 32341) +ValuePair(PCS_WGS72_UTM_zone_42S, 32342) +ValuePair(PCS_WGS72_UTM_zone_43S, 32343) +ValuePair(PCS_WGS72_UTM_zone_44S, 32344) +ValuePair(PCS_WGS72_UTM_zone_45S, 32345) +ValuePair(PCS_WGS72_UTM_zone_46S, 32346) +ValuePair(PCS_WGS72_UTM_zone_47S, 32347) +ValuePair(PCS_WGS72_UTM_zone_48S, 32348) +ValuePair(PCS_WGS72_UTM_zone_49S, 32349) +ValuePair(PCS_WGS72_UTM_zone_50S, 32350) +ValuePair(PCS_WGS72_UTM_zone_51S, 32351) +ValuePair(PCS_WGS72_UTM_zone_52S, 32352) +ValuePair(PCS_WGS72_UTM_zone_53S, 32353) +ValuePair(PCS_WGS72_UTM_zone_54S, 32354) +ValuePair(PCS_WGS72_UTM_zone_55S, 32355) +ValuePair(PCS_WGS72_UTM_zone_56S, 32356) +ValuePair(PCS_WGS72_UTM_zone_57S, 32357) +ValuePair(PCS_WGS72_UTM_zone_58S, 32358) +ValuePair(PCS_WGS72_UTM_zone_59S, 32359) +ValuePair(PCS_WGS72_UTM_zone_60S, 32360) +ValuePair(PCS_WGS72BE_UTM_zone_1N, 32401) +ValuePair(PCS_WGS72BE_UTM_zone_2N, 32402) +ValuePair(PCS_WGS72BE_UTM_zone_3N, 32403) +ValuePair(PCS_WGS72BE_UTM_zone_4N, 32404) +ValuePair(PCS_WGS72BE_UTM_zone_5N, 32405) +ValuePair(PCS_WGS72BE_UTM_zone_6N, 32406) +ValuePair(PCS_WGS72BE_UTM_zone_7N, 32407) +ValuePair(PCS_WGS72BE_UTM_zone_8N, 32408) +ValuePair(PCS_WGS72BE_UTM_zone_9N, 32409) +ValuePair(PCS_WGS72BE_UTM_zone_10N, 32410) +ValuePair(PCS_WGS72BE_UTM_zone_11N, 32411) +ValuePair(PCS_WGS72BE_UTM_zone_12N, 32412) +ValuePair(PCS_WGS72BE_UTM_zone_13N, 32413) +ValuePair(PCS_WGS72BE_UTM_zone_14N, 32414) +ValuePair(PCS_WGS72BE_UTM_zone_15N, 32415) +ValuePair(PCS_WGS72BE_UTM_zone_16N, 32416) +ValuePair(PCS_WGS72BE_UTM_zone_17N, 32417) +ValuePair(PCS_WGS72BE_UTM_zone_18N, 32418) +ValuePair(PCS_WGS72BE_UTM_zone_19N, 32419) +ValuePair(PCS_WGS72BE_UTM_zone_20N, 32420) +ValuePair(PCS_WGS72BE_UTM_zone_21N, 32421) +ValuePair(PCS_WGS72BE_UTM_zone_22N, 32422) +ValuePair(PCS_WGS72BE_UTM_zone_23N, 32423) +ValuePair(PCS_WGS72BE_UTM_zone_24N, 32424) +ValuePair(PCS_WGS72BE_UTM_zone_25N, 32425) +ValuePair(PCS_WGS72BE_UTM_zone_26N, 32426) +ValuePair(PCS_WGS72BE_UTM_zone_27N, 32427) +ValuePair(PCS_WGS72BE_UTM_zone_28N, 32428) +ValuePair(PCS_WGS72BE_UTM_zone_29N, 32429) +ValuePair(PCS_WGS72BE_UTM_zone_30N, 32430) +ValuePair(PCS_WGS72BE_UTM_zone_31N, 32431) +ValuePair(PCS_WGS72BE_UTM_zone_32N, 32432) +ValuePair(PCS_WGS72BE_UTM_zone_33N, 32433) +ValuePair(PCS_WGS72BE_UTM_zone_34N, 32434) +ValuePair(PCS_WGS72BE_UTM_zone_35N, 32435) +ValuePair(PCS_WGS72BE_UTM_zone_36N, 32436) +ValuePair(PCS_WGS72BE_UTM_zone_37N, 32437) +ValuePair(PCS_WGS72BE_UTM_zone_38N, 32438) +ValuePair(PCS_WGS72BE_UTM_zone_39N, 32439) +ValuePair(PCS_WGS72BE_UTM_zone_40N, 32440) +ValuePair(PCS_WGS72BE_UTM_zone_41N, 32441) +ValuePair(PCS_WGS72BE_UTM_zone_42N, 32442) +ValuePair(PCS_WGS72BE_UTM_zone_43N, 32443) +ValuePair(PCS_WGS72BE_UTM_zone_44N, 32444) +ValuePair(PCS_WGS72BE_UTM_zone_45N, 32445) +ValuePair(PCS_WGS72BE_UTM_zone_46N, 32446) +ValuePair(PCS_WGS72BE_UTM_zone_47N, 32447) +ValuePair(PCS_WGS72BE_UTM_zone_48N, 32448) +ValuePair(PCS_WGS72BE_UTM_zone_49N, 32449) +ValuePair(PCS_WGS72BE_UTM_zone_50N, 32450) +ValuePair(PCS_WGS72BE_UTM_zone_51N, 32451) +ValuePair(PCS_WGS72BE_UTM_zone_52N, 32452) +ValuePair(PCS_WGS72BE_UTM_zone_53N, 32453) +ValuePair(PCS_WGS72BE_UTM_zone_54N, 32454) +ValuePair(PCS_WGS72BE_UTM_zone_55N, 32455) +ValuePair(PCS_WGS72BE_UTM_zone_56N, 32456) +ValuePair(PCS_WGS72BE_UTM_zone_57N, 32457) +ValuePair(PCS_WGS72BE_UTM_zone_58N, 32458) +ValuePair(PCS_WGS72BE_UTM_zone_59N, 32459) +ValuePair(PCS_WGS72BE_UTM_zone_60N, 32460) +ValuePair(PCS_WGS72BE_UTM_zone_1S, 32501) +ValuePair(PCS_WGS72BE_UTM_zone_2S, 32502) +ValuePair(PCS_WGS72BE_UTM_zone_3S, 32503) +ValuePair(PCS_WGS72BE_UTM_zone_4S, 32504) +ValuePair(PCS_WGS72BE_UTM_zone_5S, 32505) +ValuePair(PCS_WGS72BE_UTM_zone_6S, 32506) +ValuePair(PCS_WGS72BE_UTM_zone_7S, 32507) +ValuePair(PCS_WGS72BE_UTM_zone_8S, 32508) +ValuePair(PCS_WGS72BE_UTM_zone_9S, 32509) +ValuePair(PCS_WGS72BE_UTM_zone_10S, 32510) +ValuePair(PCS_WGS72BE_UTM_zone_11S, 32511) +ValuePair(PCS_WGS72BE_UTM_zone_12S, 32512) +ValuePair(PCS_WGS72BE_UTM_zone_13S, 32513) +ValuePair(PCS_WGS72BE_UTM_zone_14S, 32514) +ValuePair(PCS_WGS72BE_UTM_zone_15S, 32515) +ValuePair(PCS_WGS72BE_UTM_zone_16S, 32516) +ValuePair(PCS_WGS72BE_UTM_zone_17S, 32517) +ValuePair(PCS_WGS72BE_UTM_zone_18S, 32518) +ValuePair(PCS_WGS72BE_UTM_zone_19S, 32519) +ValuePair(PCS_WGS72BE_UTM_zone_20S, 32520) +ValuePair(PCS_WGS72BE_UTM_zone_21S, 32521) +ValuePair(PCS_WGS72BE_UTM_zone_22S, 32522) +ValuePair(PCS_WGS72BE_UTM_zone_23S, 32523) +ValuePair(PCS_WGS72BE_UTM_zone_24S, 32524) +ValuePair(PCS_WGS72BE_UTM_zone_25S, 32525) +ValuePair(PCS_WGS72BE_UTM_zone_26S, 32526) +ValuePair(PCS_WGS72BE_UTM_zone_27S, 32527) +ValuePair(PCS_WGS72BE_UTM_zone_28S, 32528) +ValuePair(PCS_WGS72BE_UTM_zone_29S, 32529) +ValuePair(PCS_WGS72BE_UTM_zone_30S, 32530) +ValuePair(PCS_WGS72BE_UTM_zone_31S, 32531) +ValuePair(PCS_WGS72BE_UTM_zone_32S, 32532) +ValuePair(PCS_WGS72BE_UTM_zone_33S, 32533) +ValuePair(PCS_WGS72BE_UTM_zone_34S, 32534) +ValuePair(PCS_WGS72BE_UTM_zone_35S, 32535) +ValuePair(PCS_WGS72BE_UTM_zone_36S, 32536) +ValuePair(PCS_WGS72BE_UTM_zone_37S, 32537) +ValuePair(PCS_WGS72BE_UTM_zone_38S, 32538) +ValuePair(PCS_WGS72BE_UTM_zone_39S, 32539) +ValuePair(PCS_WGS72BE_UTM_zone_40S, 32540) +ValuePair(PCS_WGS72BE_UTM_zone_41S, 32541) +ValuePair(PCS_WGS72BE_UTM_zone_42S, 32542) +ValuePair(PCS_WGS72BE_UTM_zone_43S, 32543) +ValuePair(PCS_WGS72BE_UTM_zone_44S, 32544) +ValuePair(PCS_WGS72BE_UTM_zone_45S, 32545) +ValuePair(PCS_WGS72BE_UTM_zone_46S, 32546) +ValuePair(PCS_WGS72BE_UTM_zone_47S, 32547) +ValuePair(PCS_WGS72BE_UTM_zone_48S, 32548) +ValuePair(PCS_WGS72BE_UTM_zone_49S, 32549) +ValuePair(PCS_WGS72BE_UTM_zone_50S, 32550) +ValuePair(PCS_WGS72BE_UTM_zone_51S, 32551) +ValuePair(PCS_WGS72BE_UTM_zone_52S, 32552) +ValuePair(PCS_WGS72BE_UTM_zone_53S, 32553) +ValuePair(PCS_WGS72BE_UTM_zone_54S, 32554) +ValuePair(PCS_WGS72BE_UTM_zone_55S, 32555) +ValuePair(PCS_WGS72BE_UTM_zone_56S, 32556) +ValuePair(PCS_WGS72BE_UTM_zone_57S, 32557) +ValuePair(PCS_WGS72BE_UTM_zone_58S, 32558) +ValuePair(PCS_WGS72BE_UTM_zone_59S, 32559) +ValuePair(PCS_WGS72BE_UTM_zone_60S, 32560) +ValuePair(PCS_WGS84_UTM_zone_1N, 32601) +ValuePair(PCS_WGS84_UTM_zone_2N, 32602) +ValuePair(PCS_WGS84_UTM_zone_3N, 32603) +ValuePair(PCS_WGS84_UTM_zone_4N, 32604) +ValuePair(PCS_WGS84_UTM_zone_5N, 32605) +ValuePair(PCS_WGS84_UTM_zone_6N, 32606) +ValuePair(PCS_WGS84_UTM_zone_7N, 32607) +ValuePair(PCS_WGS84_UTM_zone_8N, 32608) +ValuePair(PCS_WGS84_UTM_zone_9N, 32609) +ValuePair(PCS_WGS84_UTM_zone_10N, 32610) +ValuePair(PCS_WGS84_UTM_zone_11N, 32611) +ValuePair(PCS_WGS84_UTM_zone_12N, 32612) +ValuePair(PCS_WGS84_UTM_zone_13N, 32613) +ValuePair(PCS_WGS84_UTM_zone_14N, 32614) +ValuePair(PCS_WGS84_UTM_zone_15N, 32615) +ValuePair(PCS_WGS84_UTM_zone_16N, 32616) +ValuePair(PCS_WGS84_UTM_zone_17N, 32617) +ValuePair(PCS_WGS84_UTM_zone_18N, 32618) +ValuePair(PCS_WGS84_UTM_zone_19N, 32619) +ValuePair(PCS_WGS84_UTM_zone_20N, 32620) +ValuePair(PCS_WGS84_UTM_zone_21N, 32621) +ValuePair(PCS_WGS84_UTM_zone_22N, 32622) +ValuePair(PCS_WGS84_UTM_zone_23N, 32623) +ValuePair(PCS_WGS84_UTM_zone_24N, 32624) +ValuePair(PCS_WGS84_UTM_zone_25N, 32625) +ValuePair(PCS_WGS84_UTM_zone_26N, 32626) +ValuePair(PCS_WGS84_UTM_zone_27N, 32627) +ValuePair(PCS_WGS84_UTM_zone_28N, 32628) +ValuePair(PCS_WGS84_UTM_zone_29N, 32629) +ValuePair(PCS_WGS84_UTM_zone_30N, 32630) +ValuePair(PCS_WGS84_UTM_zone_31N, 32631) +ValuePair(PCS_WGS84_UTM_zone_32N, 32632) +ValuePair(PCS_WGS84_UTM_zone_33N, 32633) +ValuePair(PCS_WGS84_UTM_zone_34N, 32634) +ValuePair(PCS_WGS84_UTM_zone_35N, 32635) +ValuePair(PCS_WGS84_UTM_zone_36N, 32636) +ValuePair(PCS_WGS84_UTM_zone_37N, 32637) +ValuePair(PCS_WGS84_UTM_zone_38N, 32638) +ValuePair(PCS_WGS84_UTM_zone_39N, 32639) +ValuePair(PCS_WGS84_UTM_zone_40N, 32640) +ValuePair(PCS_WGS84_UTM_zone_41N, 32641) +ValuePair(PCS_WGS84_UTM_zone_42N, 32642) +ValuePair(PCS_WGS84_UTM_zone_43N, 32643) +ValuePair(PCS_WGS84_UTM_zone_44N, 32644) +ValuePair(PCS_WGS84_UTM_zone_45N, 32645) +ValuePair(PCS_WGS84_UTM_zone_46N, 32646) +ValuePair(PCS_WGS84_UTM_zone_47N, 32647) +ValuePair(PCS_WGS84_UTM_zone_48N, 32648) +ValuePair(PCS_WGS84_UTM_zone_49N, 32649) +ValuePair(PCS_WGS84_UTM_zone_50N, 32650) +ValuePair(PCS_WGS84_UTM_zone_51N, 32651) +ValuePair(PCS_WGS84_UTM_zone_52N, 32652) +ValuePair(PCS_WGS84_UTM_zone_53N, 32653) +ValuePair(PCS_WGS84_UTM_zone_54N, 32654) +ValuePair(PCS_WGS84_UTM_zone_55N, 32655) +ValuePair(PCS_WGS84_UTM_zone_56N, 32656) +ValuePair(PCS_WGS84_UTM_zone_57N, 32657) +ValuePair(PCS_WGS84_UTM_zone_58N, 32658) +ValuePair(PCS_WGS84_UTM_zone_59N, 32659) +ValuePair(PCS_WGS84_UTM_zone_60N, 32660) +ValuePair(PCS_WGS84_UTM_zone_1S, 32701) +ValuePair(PCS_WGS84_UTM_zone_2S, 32702) +ValuePair(PCS_WGS84_UTM_zone_3S, 32703) +ValuePair(PCS_WGS84_UTM_zone_4S, 32704) +ValuePair(PCS_WGS84_UTM_zone_5S, 32705) +ValuePair(PCS_WGS84_UTM_zone_6S, 32706) +ValuePair(PCS_WGS84_UTM_zone_7S, 32707) +ValuePair(PCS_WGS84_UTM_zone_8S, 32708) +ValuePair(PCS_WGS84_UTM_zone_9S, 32709) +ValuePair(PCS_WGS84_UTM_zone_10S, 32710) +ValuePair(PCS_WGS84_UTM_zone_11S, 32711) +ValuePair(PCS_WGS84_UTM_zone_12S, 32712) +ValuePair(PCS_WGS84_UTM_zone_13S, 32713) +ValuePair(PCS_WGS84_UTM_zone_14S, 32714) +ValuePair(PCS_WGS84_UTM_zone_15S, 32715) +ValuePair(PCS_WGS84_UTM_zone_16S, 32716) +ValuePair(PCS_WGS84_UTM_zone_17S, 32717) +ValuePair(PCS_WGS84_UTM_zone_18S, 32718) +ValuePair(PCS_WGS84_UTM_zone_19S, 32719) +ValuePair(PCS_WGS84_UTM_zone_20S, 32720) +ValuePair(PCS_WGS84_UTM_zone_21S, 32721) +ValuePair(PCS_WGS84_UTM_zone_22S, 32722) +ValuePair(PCS_WGS84_UTM_zone_23S, 32723) +ValuePair(PCS_WGS84_UTM_zone_24S, 32724) +ValuePair(PCS_WGS84_UTM_zone_25S, 32725) +ValuePair(PCS_WGS84_UTM_zone_26S, 32726) +ValuePair(PCS_WGS84_UTM_zone_27S, 32727) +ValuePair(PCS_WGS84_UTM_zone_28S, 32728) +ValuePair(PCS_WGS84_UTM_zone_29S, 32729) +ValuePair(PCS_WGS84_UTM_zone_30S, 32730) +ValuePair(PCS_WGS84_UTM_zone_31S, 32731) +ValuePair(PCS_WGS84_UTM_zone_32S, 32732) +ValuePair(PCS_WGS84_UTM_zone_33S, 32733) +ValuePair(PCS_WGS84_UTM_zone_34S, 32734) +ValuePair(PCS_WGS84_UTM_zone_35S, 32735) +ValuePair(PCS_WGS84_UTM_zone_36S, 32736) +ValuePair(PCS_WGS84_UTM_zone_37S, 32737) +ValuePair(PCS_WGS84_UTM_zone_38S, 32738) +ValuePair(PCS_WGS84_UTM_zone_39S, 32739) +ValuePair(PCS_WGS84_UTM_zone_40S, 32740) +ValuePair(PCS_WGS84_UTM_zone_41S, 32741) +ValuePair(PCS_WGS84_UTM_zone_42S, 32742) +ValuePair(PCS_WGS84_UTM_zone_43S, 32743) +ValuePair(PCS_WGS84_UTM_zone_44S, 32744) +ValuePair(PCS_WGS84_UTM_zone_45S, 32745) +ValuePair(PCS_WGS84_UTM_zone_46S, 32746) +ValuePair(PCS_WGS84_UTM_zone_47S, 32747) +ValuePair(PCS_WGS84_UTM_zone_48S, 32748) +ValuePair(PCS_WGS84_UTM_zone_49S, 32749) +ValuePair(PCS_WGS84_UTM_zone_50S, 32750) +ValuePair(PCS_WGS84_UTM_zone_51S, 32751) +ValuePair(PCS_WGS84_UTM_zone_52S, 32752) +ValuePair(PCS_WGS84_UTM_zone_53S, 32753) +ValuePair(PCS_WGS84_UTM_zone_54S, 32754) +ValuePair(PCS_WGS84_UTM_zone_55S, 32755) +ValuePair(PCS_WGS84_UTM_zone_56S, 32756) +ValuePair(PCS_WGS84_UTM_zone_57S, 32757) +ValuePair(PCS_WGS84_UTM_zone_58S, 32758) +ValuePair(PCS_WGS84_UTM_zone_59S, 32759) +ValuePair(PCS_WGS84_UTM_zone_60S, 32760) +/* end of list */ diff --git a/Utilities/otbgeotiff/epsg_pm.inc b/Utilities/otbgeotiff/epsg_pm.inc new file mode 100644 index 0000000000000000000000000000000000000000..1e4159881962d0f4cf8dd128ba59aa5b0332ab5a --- /dev/null +++ b/Utilities/otbgeotiff/epsg_pm.inc @@ -0,0 +1,22 @@ +/* EPSG/GeoTIFF Rev 0.2 Prime Meridian Database */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +#ifdef INCLUDE_OLD_CODES +#include old_pm.inc +#endif /* OLD Codes */ + +ValuePair(PM_Greenwich, 8901) +ValuePair(PM_Lisbon, 8902) +ValuePair(PM_Paris, 8903) +ValuePair(PM_Bogota, 8904) +ValuePair(PM_Madrid, 8905) +ValuePair(PM_Rome, 8906) +ValuePair(PM_Bern, 8907) +ValuePair(PM_Jakarta, 8908) +ValuePair(PM_Ferro, 8909) +ValuePair(PM_Brussels, 8910) +ValuePair(PM_Stockholm, 8911) +/* end of list */ diff --git a/Utilities/otbgeotiff/epsg_proj.inc b/Utilities/otbgeotiff/epsg_proj.inc new file mode 100644 index 0000000000000000000000000000000000000000..d6c8791556fa3d0e67a2f9ced579f977c34ccad5 --- /dev/null +++ b/Utilities/otbgeotiff/epsg_proj.inc @@ -0,0 +1,443 @@ +/* + * EPSG/POSC Projection Codes - GeoTIFF Rev 0.2 + */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +#ifdef INCLUDE_OLD_CODES +#include old_proj.inc +#endif /* OLD Codes */ + +/* New codes */ + +ValuePair(Proj_Stereo_70,19926) + +/* old codes */ + +ValuePair(Proj_Alabama_CS27_East, 10101) +ValuePair(Proj_Alabama_CS27_West, 10102) +ValuePair(Proj_Alabama_CS83_East, 10131) +ValuePair(Proj_Alabama_CS83_West, 10132) +ValuePair(Proj_Arizona_Coordinate_System_east, 10201) +ValuePair(Proj_Arizona_Coordinate_System_Central, 10202) +ValuePair(Proj_Arizona_Coordinate_System_west, 10203) +ValuePair(Proj_Arizona_CS83_east, 10231) +ValuePair(Proj_Arizona_CS83_Central, 10232) +ValuePair(Proj_Arizona_CS83_west, 10233) +ValuePair(Proj_Arkansas_CS27_North, 10301) +ValuePair(Proj_Arkansas_CS27_South, 10302) +ValuePair(Proj_Arkansas_CS83_North, 10331) +ValuePair(Proj_Arkansas_CS83_South, 10332) +ValuePair(Proj_California_CS27_I, 10401) +ValuePair(Proj_California_CS27_II, 10402) +ValuePair(Proj_California_CS27_III, 10403) +ValuePair(Proj_California_CS27_IV, 10404) +ValuePair(Proj_California_CS27_V, 10405) +ValuePair(Proj_California_CS27_VI, 10406) +ValuePair(Proj_California_CS27_VII, 10407) +ValuePair(Proj_California_CS83_1, 10431) +ValuePair(Proj_California_CS83_2, 10432) +ValuePair(Proj_California_CS83_3, 10433) +ValuePair(Proj_California_CS83_4, 10434) +ValuePair(Proj_California_CS83_5, 10435) +ValuePair(Proj_California_CS83_6, 10436) +ValuePair(Proj_Colorado_CS27_North, 10501) +ValuePair(Proj_Colorado_CS27_Central, 10502) +ValuePair(Proj_Colorado_CS27_South, 10503) +ValuePair(Proj_Colorado_CS83_North, 10531) +ValuePair(Proj_Colorado_CS83_Central, 10532) +ValuePair(Proj_Colorado_CS83_South, 10533) +ValuePair(Proj_Connecticut_CS27, 10600) +ValuePair(Proj_Connecticut_CS83, 10630) +ValuePair(Proj_Delaware_CS27, 10700) +ValuePair(Proj_Delaware_CS83, 10730) +ValuePair(Proj_Florida_CS27_East, 10901) +ValuePair(Proj_Florida_CS27_West, 10902) +ValuePair(Proj_Florida_CS27_North, 10903) +ValuePair(Proj_Florida_CS83_East, 10931) +ValuePair(Proj_Florida_CS83_West, 10932) +ValuePair(Proj_Florida_CS83_North, 10933) +ValuePair(Proj_Georgia_CS27_East, 11001) +ValuePair(Proj_Georgia_CS27_West, 11002) +ValuePair(Proj_Georgia_CS83_East, 11031) +ValuePair(Proj_Georgia_CS83_West, 11032) +ValuePair(Proj_Idaho_CS27_East, 11101) +ValuePair(Proj_Idaho_CS27_Central, 11102) +ValuePair(Proj_Idaho_CS27_West, 11103) +ValuePair(Proj_Idaho_CS83_East, 11131) +ValuePair(Proj_Idaho_CS83_Central, 11132) +ValuePair(Proj_Idaho_CS83_West, 11133) +ValuePair(Proj_Illinois_CS27_East, 11201) +ValuePair(Proj_Illinois_CS27_West, 11202) +ValuePair(Proj_Illinois_CS83_East, 11231) +ValuePair(Proj_Illinois_CS83_West, 11232) +ValuePair(Proj_Indiana_CS27_East, 11301) +ValuePair(Proj_Indiana_CS27_West, 11302) +ValuePair(Proj_Indiana_CS83_East, 11331) +ValuePair(Proj_Indiana_CS83_West, 11332) +ValuePair(Proj_Iowa_CS27_North, 11401) +ValuePair(Proj_Iowa_CS27_South, 11402) +ValuePair(Proj_Iowa_CS83_North, 11431) +ValuePair(Proj_Iowa_CS83_South, 11432) +ValuePair(Proj_Kansas_CS27_North, 11501) +ValuePair(Proj_Kansas_CS27_South, 11502) +ValuePair(Proj_Kansas_CS83_North, 11531) +ValuePair(Proj_Kansas_CS83_South, 11532) +ValuePair(Proj_Kentucky_CS27_North, 11601) +ValuePair(Proj_Kentucky_CS27_South, 11602) +ValuePair(Proj_Kentucky_CS83_North, 15303) +ValuePair(Proj_Kentucky_CS83_South, 11632) +ValuePair(Proj_Louisiana_CS27_North, 11701) +ValuePair(Proj_Louisiana_CS27_South, 11702) +ValuePair(Proj_Louisiana_CS83_North, 11731) +ValuePair(Proj_Louisiana_CS83_South, 11732) +ValuePair(Proj_Maine_CS27_East, 11801) +ValuePair(Proj_Maine_CS27_West, 11802) +ValuePair(Proj_Maine_CS83_East, 11831) +ValuePair(Proj_Maine_CS83_West, 11832) +ValuePair(Proj_Maryland_CS27, 11900) +ValuePair(Proj_Maryland_CS83, 11930) +ValuePair(Proj_Massachusetts_CS27_Mainland, 12001) +ValuePair(Proj_Massachusetts_CS27_Island, 12002) +ValuePair(Proj_Massachusetts_CS83_Mainland, 12031) +ValuePair(Proj_Massachusetts_CS83_Island, 12032) +ValuePair(Proj_Michigan_State_Plane_East, 12101) +ValuePair(Proj_Michigan_State_Plane_Old_Central, 12102) +ValuePair(Proj_Michigan_State_Plane_West, 12103) +ValuePair(Proj_Michigan_CS27_North, 12111) +ValuePair(Proj_Michigan_CS27_Central, 12112) +ValuePair(Proj_Michigan_CS27_South, 12113) +ValuePair(Proj_Michigan_CS83_North, 12141) +ValuePair(Proj_Michigan_CS83_Central, 12142) +ValuePair(Proj_Michigan_CS83_South, 12143) +ValuePair(Proj_Minnesota_CS27_North, 12201) +ValuePair(Proj_Minnesota_CS27_Central, 12202) +ValuePair(Proj_Minnesota_CS27_South, 12203) +ValuePair(Proj_Minnesota_CS83_North, 12231) +ValuePair(Proj_Minnesota_CS83_Central, 12232) +ValuePair(Proj_Minnesota_CS83_South, 12233) +ValuePair(Proj_Mississippi_CS27_East, 12301) +ValuePair(Proj_Mississippi_CS27_West, 12302) +ValuePair(Proj_Mississippi_CS83_East, 12331) +ValuePair(Proj_Mississippi_CS83_West, 12332) +ValuePair(Proj_Missouri_CS27_East, 12401) +ValuePair(Proj_Missouri_CS27_Central, 12402) +ValuePair(Proj_Missouri_CS27_West, 12403) +ValuePair(Proj_Missouri_CS83_East, 12431) +ValuePair(Proj_Missouri_CS83_Central, 12432) +ValuePair(Proj_Missouri_CS83_West, 12433) +ValuePair(Proj_Montana_CS27_North, 12501) +ValuePair(Proj_Montana_CS27_Central, 12502) +ValuePair(Proj_Montana_CS27_South, 12503) +ValuePair(Proj_Montana_CS83, 12530) +ValuePair(Proj_Nebraska_CS27_North, 12601) +ValuePair(Proj_Nebraska_CS27_South, 12602) +ValuePair(Proj_Nebraska_CS83, 12630) +ValuePair(Proj_Nevada_CS27_East, 12701) +ValuePair(Proj_Nevada_CS27_Central, 12702) +ValuePair(Proj_Nevada_CS27_West, 12703) +ValuePair(Proj_Nevada_CS83_East, 12731) +ValuePair(Proj_Nevada_CS83_Central, 12732) +ValuePair(Proj_Nevada_CS83_West, 12733) +ValuePair(Proj_New_Hampshire_CS27, 12800) +ValuePair(Proj_New_Hampshire_CS83, 12830) +ValuePair(Proj_New_Jersey_CS27, 12900) +ValuePair(Proj_New_Jersey_CS83, 12930) +ValuePair(Proj_New_Mexico_CS27_East, 13001) +ValuePair(Proj_New_Mexico_CS27_Central, 13002) +ValuePair(Proj_New_Mexico_CS27_West, 13003) +ValuePair(Proj_New_Mexico_CS83_East, 13031) +ValuePair(Proj_New_Mexico_CS83_Central, 13032) +ValuePair(Proj_New_Mexico_CS83_West, 13033) +ValuePair(Proj_New_York_CS27_East, 13101) +ValuePair(Proj_New_York_CS27_Central, 13102) +ValuePair(Proj_New_York_CS27_West, 13103) +ValuePair(Proj_New_York_CS27_Long_Island, 13104) +ValuePair(Proj_New_York_CS83_East, 13131) +ValuePair(Proj_New_York_CS83_Central, 13132) +ValuePair(Proj_New_York_CS83_West, 13133) +ValuePair(Proj_New_York_CS83_Long_Island, 13134) +ValuePair(Proj_North_Carolina_CS27, 13200) +ValuePair(Proj_North_Carolina_CS83, 13230) +ValuePair(Proj_North_Dakota_CS27_North, 13301) +ValuePair(Proj_North_Dakota_CS27_South, 13302) +ValuePair(Proj_North_Dakota_CS83_North, 13331) +ValuePair(Proj_North_Dakota_CS83_South, 13332) +ValuePair(Proj_Ohio_CS27_North, 13401) +ValuePair(Proj_Ohio_CS27_South, 13402) +ValuePair(Proj_Ohio_CS83_North, 13431) +ValuePair(Proj_Ohio_CS83_South, 13432) +ValuePair(Proj_Oklahoma_CS27_North, 13501) +ValuePair(Proj_Oklahoma_CS27_South, 13502) +ValuePair(Proj_Oklahoma_CS83_North, 13531) +ValuePair(Proj_Oklahoma_CS83_South, 13532) +ValuePair(Proj_Oregon_CS27_North, 13601) +ValuePair(Proj_Oregon_CS27_South, 13602) +ValuePair(Proj_Oregon_CS83_North, 13631) +ValuePair(Proj_Oregon_CS83_South, 13632) +ValuePair(Proj_Pennsylvania_CS27_North, 13701) +ValuePair(Proj_Pennsylvania_CS27_South, 13702) +ValuePair(Proj_Pennsylvania_CS83_North, 13731) +ValuePair(Proj_Pennsylvania_CS83_South, 13732) +ValuePair(Proj_Rhode_Island_CS27, 13800) +ValuePair(Proj_Rhode_Island_CS83, 13830) +ValuePair(Proj_South_Carolina_CS27_North, 13901) +ValuePair(Proj_South_Carolina_CS27_South, 13902) +ValuePair(Proj_South_Carolina_CS83, 13930) +ValuePair(Proj_South_Dakota_CS27_North, 14001) +ValuePair(Proj_South_Dakota_CS27_South, 14002) +ValuePair(Proj_South_Dakota_CS83_North, 14031) +ValuePair(Proj_South_Dakota_CS83_South, 14032) +ValuePair(Proj_Tennessee_CS27, 15302) +ValuePair(Proj_Tennessee_CS83, 14130) +ValuePair(Proj_Texas_CS27_North, 14201) +ValuePair(Proj_Texas_CS27_North_Central, 14202) +ValuePair(Proj_Texas_CS27_Central, 14203) +ValuePair(Proj_Texas_CS27_South_Central, 14204) +ValuePair(Proj_Texas_CS27_South, 14205) +ValuePair(Proj_Texas_CS83_North, 14231) +ValuePair(Proj_Texas_CS83_North_Central, 14232) +ValuePair(Proj_Texas_CS83_Central, 14233) +ValuePair(Proj_Texas_CS83_South_Central, 14234) +ValuePair(Proj_Texas_CS83_South, 14235) +ValuePair(Proj_Utah_CS27_North, 14301) +ValuePair(Proj_Utah_CS27_Central, 14302) +ValuePair(Proj_Utah_CS27_South, 14303) +ValuePair(Proj_Utah_CS83_North, 14331) +ValuePair(Proj_Utah_CS83_Central, 14332) +ValuePair(Proj_Utah_CS83_South, 14333) +ValuePair(Proj_Vermont_CS27, 14400) +ValuePair(Proj_Vermont_CS83, 14430) +ValuePair(Proj_Virginia_CS27_North, 14501) +ValuePair(Proj_Virginia_CS27_South, 14502) +ValuePair(Proj_Virginia_CS83_North, 14531) +ValuePair(Proj_Virginia_CS83_South, 14532) +ValuePair(Proj_Washington_CS27_North, 14601) +ValuePair(Proj_Washington_CS27_South, 14602) +ValuePair(Proj_Washington_CS83_North, 14631) +ValuePair(Proj_Washington_CS83_South, 14632) +ValuePair(Proj_West_Virginia_CS27_North, 14701) +ValuePair(Proj_West_Virginia_CS27_South, 14702) +ValuePair(Proj_West_Virginia_CS83_North, 14731) +ValuePair(Proj_West_Virginia_CS83_South, 14732) +ValuePair(Proj_Wisconsin_CS27_North, 14801) +ValuePair(Proj_Wisconsin_CS27_Central, 14802) +ValuePair(Proj_Wisconsin_CS27_South, 14803) +ValuePair(Proj_Wisconsin_CS83_North, 14831) +ValuePair(Proj_Wisconsin_CS83_Central, 14832) +ValuePair(Proj_Wisconsin_CS83_South, 14833) +ValuePair(Proj_Wyoming_CS27_East, 14901) +ValuePair(Proj_Wyoming_CS27_East_Central, 14902) +ValuePair(Proj_Wyoming_CS27_West_Central, 14903) +ValuePair(Proj_Wyoming_CS27_West, 14904) +ValuePair(Proj_Wyoming_CS83_East, 14931) +ValuePair(Proj_Wyoming_CS83_East_Central, 14932) +ValuePair(Proj_Wyoming_CS83_West_Central, 14933) +ValuePair(Proj_Wyoming_CS83_West, 14934) +ValuePair(Proj_Alaska_CS27_1, 15001) +ValuePair(Proj_Alaska_CS27_2, 15002) +ValuePair(Proj_Alaska_CS27_3, 15003) +ValuePair(Proj_Alaska_CS27_4, 15004) +ValuePair(Proj_Alaska_CS27_5, 15005) +ValuePair(Proj_Alaska_CS27_6, 15006) +ValuePair(Proj_Alaska_CS27_7, 15007) +ValuePair(Proj_Alaska_CS27_8, 15008) +ValuePair(Proj_Alaska_CS27_9, 15009) +ValuePair(Proj_Alaska_CS27_10, 15010) +ValuePair(Proj_Alaska_CS83_1, 15031) +ValuePair(Proj_Alaska_CS83_2, 15032) +ValuePair(Proj_Alaska_CS83_3, 15033) +ValuePair(Proj_Alaska_CS83_4, 15034) +ValuePair(Proj_Alaska_CS83_5, 15035) +ValuePair(Proj_Alaska_CS83_6, 15036) +ValuePair(Proj_Alaska_CS83_7, 15037) +ValuePair(Proj_Alaska_CS83_8, 15038) +ValuePair(Proj_Alaska_CS83_9, 15039) +ValuePair(Proj_Alaska_CS83_10, 15040) +ValuePair(Proj_Hawaii_CS27_1, 15101) +ValuePair(Proj_Hawaii_CS27_2, 15102) +ValuePair(Proj_Hawaii_CS27_3, 15103) +ValuePair(Proj_Hawaii_CS27_4, 15104) +ValuePair(Proj_Hawaii_CS27_5, 15105) +ValuePair(Proj_Hawaii_CS83_1, 15131) +ValuePair(Proj_Hawaii_CS83_2, 15132) +ValuePair(Proj_Hawaii_CS83_3, 15133) +ValuePair(Proj_Hawaii_CS83_4, 15134) +ValuePair(Proj_Hawaii_CS83_5, 15135) +ValuePair(Proj_Puerto_Rico_CS27, 15201) +ValuePair(Proj_St_Croix, 15202) +ValuePair(Proj_Puerto_Rico_Virgin_Is, 15230) +ValuePair(Proj_BLM_14N_feet, 15914) +ValuePair(Proj_BLM_15N_feet, 15915) +ValuePair(Proj_BLM_16N_feet, 15916) +ValuePair(Proj_BLM_17N_feet, 15917) +ValuePair(Proj_UTM_zone_1N, 16001) +ValuePair(Proj_UTM_zone_2N, 16002) +ValuePair(Proj_UTM_zone_3N, 16003) +ValuePair(Proj_UTM_zone_4N, 16004) +ValuePair(Proj_UTM_zone_5N, 16005) +ValuePair(Proj_UTM_zone_6N, 16006) +ValuePair(Proj_UTM_zone_7N, 16007) +ValuePair(Proj_UTM_zone_8N, 16008) +ValuePair(Proj_UTM_zone_9N, 16009) +ValuePair(Proj_UTM_zone_10N, 16010) +ValuePair(Proj_UTM_zone_11N, 16011) +ValuePair(Proj_UTM_zone_12N, 16012) +ValuePair(Proj_UTM_zone_13N, 16013) +ValuePair(Proj_UTM_zone_14N, 16014) +ValuePair(Proj_UTM_zone_15N, 16015) +ValuePair(Proj_UTM_zone_16N, 16016) +ValuePair(Proj_UTM_zone_17N, 16017) +ValuePair(Proj_UTM_zone_18N, 16018) +ValuePair(Proj_UTM_zone_19N, 16019) +ValuePair(Proj_UTM_zone_20N, 16020) +ValuePair(Proj_UTM_zone_21N, 16021) +ValuePair(Proj_UTM_zone_22N, 16022) +ValuePair(Proj_UTM_zone_23N, 16023) +ValuePair(Proj_UTM_zone_24N, 16024) +ValuePair(Proj_UTM_zone_25N, 16025) +ValuePair(Proj_UTM_zone_26N, 16026) +ValuePair(Proj_UTM_zone_27N, 16027) +ValuePair(Proj_UTM_zone_28N, 16028) +ValuePair(Proj_UTM_zone_29N, 16029) +ValuePair(Proj_UTM_zone_30N, 16030) +ValuePair(Proj_UTM_zone_31N, 16031) +ValuePair(Proj_UTM_zone_32N, 16032) +ValuePair(Proj_UTM_zone_33N, 16033) +ValuePair(Proj_UTM_zone_34N, 16034) +ValuePair(Proj_UTM_zone_35N, 16035) +ValuePair(Proj_UTM_zone_36N, 16036) +ValuePair(Proj_UTM_zone_37N, 16037) +ValuePair(Proj_UTM_zone_38N, 16038) +ValuePair(Proj_UTM_zone_39N, 16039) +ValuePair(Proj_UTM_zone_40N, 16040) +ValuePair(Proj_UTM_zone_41N, 16041) +ValuePair(Proj_UTM_zone_42N, 16042) +ValuePair(Proj_UTM_zone_43N, 16043) +ValuePair(Proj_UTM_zone_44N, 16044) +ValuePair(Proj_UTM_zone_45N, 16045) +ValuePair(Proj_UTM_zone_46N, 16046) +ValuePair(Proj_UTM_zone_47N, 16047) +ValuePair(Proj_UTM_zone_48N, 16048) +ValuePair(Proj_UTM_zone_49N, 16049) +ValuePair(Proj_UTM_zone_50N, 16050) +ValuePair(Proj_UTM_zone_51N, 16051) +ValuePair(Proj_UTM_zone_52N, 16052) +ValuePair(Proj_UTM_zone_53N, 16053) +ValuePair(Proj_UTM_zone_54N, 16054) +ValuePair(Proj_UTM_zone_55N, 16055) +ValuePair(Proj_UTM_zone_56N, 16056) +ValuePair(Proj_UTM_zone_57N, 16057) +ValuePair(Proj_UTM_zone_58N, 16058) +ValuePair(Proj_UTM_zone_59N, 16059) +ValuePair(Proj_UTM_zone_60N, 16060) +ValuePair(Proj_UTM_zone_1S, 16101) +ValuePair(Proj_UTM_zone_2S, 16102) +ValuePair(Proj_UTM_zone_3S, 16103) +ValuePair(Proj_UTM_zone_4S, 16104) +ValuePair(Proj_UTM_zone_5S, 16105) +ValuePair(Proj_UTM_zone_6S, 16106) +ValuePair(Proj_UTM_zone_7S, 16107) +ValuePair(Proj_UTM_zone_8S, 16108) +ValuePair(Proj_UTM_zone_9S, 16109) +ValuePair(Proj_UTM_zone_10S, 16110) +ValuePair(Proj_UTM_zone_11S, 16111) +ValuePair(Proj_UTM_zone_12S, 16112) +ValuePair(Proj_UTM_zone_13S, 16113) +ValuePair(Proj_UTM_zone_14S, 16114) +ValuePair(Proj_UTM_zone_15S, 16115) +ValuePair(Proj_UTM_zone_16S, 16116) +ValuePair(Proj_UTM_zone_17S, 16117) +ValuePair(Proj_UTM_zone_18S, 16118) +ValuePair(Proj_UTM_zone_19S, 16119) +ValuePair(Proj_UTM_zone_20S, 16120) +ValuePair(Proj_UTM_zone_21S, 16121) +ValuePair(Proj_UTM_zone_22S, 16122) +ValuePair(Proj_UTM_zone_23S, 16123) +ValuePair(Proj_UTM_zone_24S, 16124) +ValuePair(Proj_UTM_zone_25S, 16125) +ValuePair(Proj_UTM_zone_26S, 16126) +ValuePair(Proj_UTM_zone_27S, 16127) +ValuePair(Proj_UTM_zone_28S, 16128) +ValuePair(Proj_UTM_zone_29S, 16129) +ValuePair(Proj_UTM_zone_30S, 16130) +ValuePair(Proj_UTM_zone_31S, 16131) +ValuePair(Proj_UTM_zone_32S, 16132) +ValuePair(Proj_UTM_zone_33S, 16133) +ValuePair(Proj_UTM_zone_34S, 16134) +ValuePair(Proj_UTM_zone_35S, 16135) +ValuePair(Proj_UTM_zone_36S, 16136) +ValuePair(Proj_UTM_zone_37S, 16137) +ValuePair(Proj_UTM_zone_38S, 16138) +ValuePair(Proj_UTM_zone_39S, 16139) +ValuePair(Proj_UTM_zone_40S, 16140) +ValuePair(Proj_UTM_zone_41S, 16141) +ValuePair(Proj_UTM_zone_42S, 16142) +ValuePair(Proj_UTM_zone_43S, 16143) +ValuePair(Proj_UTM_zone_44S, 16144) +ValuePair(Proj_UTM_zone_45S, 16145) +ValuePair(Proj_UTM_zone_46S, 16146) +ValuePair(Proj_UTM_zone_47S, 16147) +ValuePair(Proj_UTM_zone_48S, 16148) +ValuePair(Proj_UTM_zone_49S, 16149) +ValuePair(Proj_UTM_zone_50S, 16150) +ValuePair(Proj_UTM_zone_51S, 16151) +ValuePair(Proj_UTM_zone_52S, 16152) +ValuePair(Proj_UTM_zone_53S, 16153) +ValuePair(Proj_UTM_zone_54S, 16154) +ValuePair(Proj_UTM_zone_55S, 16155) +ValuePair(Proj_UTM_zone_56S, 16156) +ValuePair(Proj_UTM_zone_57S, 16157) +ValuePair(Proj_UTM_zone_58S, 16158) +ValuePair(Proj_UTM_zone_59S, 16159) +ValuePair(Proj_UTM_zone_60S, 16160) +ValuePair(Proj_Gauss_Kruger_zone_0, 16200) +ValuePair(Proj_Gauss_Kruger_zone_1, 16201) +ValuePair(Proj_Gauss_Kruger_zone_2, 16202) +ValuePair(Proj_Gauss_Kruger_zone_3, 16203) +ValuePair(Proj_Gauss_Kruger_zone_4, 16204) +ValuePair(Proj_Gauss_Kruger_zone_5, 16205) +ValuePair(Proj_Map_Grid_of_Australia_48, 17348) +ValuePair(Proj_Map_Grid_of_Australia_49, 17349) +ValuePair(Proj_Map_Grid_of_Australia_50, 17350) +ValuePair(Proj_Map_Grid_of_Australia_51, 17351) +ValuePair(Proj_Map_Grid_of_Australia_52, 17352) +ValuePair(Proj_Map_Grid_of_Australia_53, 17353) +ValuePair(Proj_Map_Grid_of_Australia_54, 17354) +ValuePair(Proj_Map_Grid_of_Australia_55, 17355) +ValuePair(Proj_Map_Grid_of_Australia_56, 17356) +ValuePair(Proj_Map_Grid_of_Australia_57, 17357) +ValuePair(Proj_Map_Grid_of_Australia_58, 17358) +ValuePair(Proj_Australian_Map_Grid_48, 17448) +ValuePair(Proj_Australian_Map_Grid_49, 17449) +ValuePair(Proj_Australian_Map_Grid_50, 17450) +ValuePair(Proj_Australian_Map_Grid_51, 17451) +ValuePair(Proj_Australian_Map_Grid_52, 17452) +ValuePair(Proj_Australian_Map_Grid_53, 17453) +ValuePair(Proj_Australian_Map_Grid_54, 17454) +ValuePair(Proj_Australian_Map_Grid_55, 17455) +ValuePair(Proj_Australian_Map_Grid_56, 17456) +ValuePair(Proj_Australian_Map_Grid_57, 17457) +ValuePair(Proj_Australian_Map_Grid_58, 17458) +ValuePair(Proj_Argentina_1, 18031) +ValuePair(Proj_Argentina_2, 18032) +ValuePair(Proj_Argentina_3, 18033) +ValuePair(Proj_Argentina_4, 18034) +ValuePair(Proj_Argentina_5, 18035) +ValuePair(Proj_Argentina_6, 18036) +ValuePair(Proj_Argentina_7, 18037) +ValuePair(Proj_Colombia_3W, 18051) +ValuePair(Proj_Colombia_Bogota, 18052) +ValuePair(Proj_Colombia_3E, 18053) +ValuePair(Proj_Colombia_6E, 18054) +ValuePair(Proj_Egypt_Red_Belt, 18072) +ValuePair(Proj_Egypt_Purple_Belt, 18073) +ValuePair(Proj_Extended_Purple_Belt, 18074) +ValuePair(Proj_New_Zealand_North_Island_Nat_Grid, 18141) +ValuePair(Proj_New_Zealand_South_Island_Nat_Grid, 18142) +ValuePair(Proj_Bahrain_Grid, 19900) +ValuePair(Proj_Netherlands_E_Indies_Equatorial, 19905) +ValuePair(Proj_RSO_Borneo, 19912) +/* end of list */ diff --git a/Utilities/otbgeotiff/epsg_units.inc b/Utilities/otbgeotiff/epsg_units.inc new file mode 100644 index 0000000000000000000000000000000000000000..fe1b5db7bfde9b69555e50019b49926b5f42e305 --- /dev/null +++ b/Utilities/otbgeotiff/epsg_units.inc @@ -0,0 +1,35 @@ +/* + * Rev. 0.2 EPSG/POSC Units Database. + */ + +#ifdef INCLUDE_OLD_CODES +#include geo_units.inc +#endif /* OLD Codes */ + +ValuePair(Linear_Meter, 9001) +ValuePair(Linear_Foot, 9002) +ValuePair(Linear_Foot_US_Survey, 9003) +ValuePair(Linear_Foot_Modified_American, 9004) +ValuePair(Linear_Foot_Clarke, 9005) +ValuePair(Linear_Foot_Indian, 9006) +ValuePair(Linear_Link, 9007) +ValuePair(Linear_Link_Benoit, 9008) +ValuePair(Linear_Link_Sears, 9009) +ValuePair(Linear_Chain_Benoit, 9010) +ValuePair(Linear_Chain_Sears, 9011) +ValuePair(Linear_Yard_Sears, 9012) +ValuePair(Linear_Yard_Indian, 9013) +ValuePair(Linear_Fathom, 9014) +ValuePair(Linear_Mile_International_Nautical, 9015) +/* + * Angular Units + */ +ValuePair(Angular_Radian, 9101) +ValuePair(Angular_Degree, 9102) +ValuePair(Angular_Arc_Minute, 9103) +ValuePair(Angular_Arc_Second, 9104) +ValuePair(Angular_Grad, 9105) +ValuePair(Angular_Gon, 9106) +ValuePair(Angular_DMS, 9107) +ValuePair(Angular_DMS_Hemisphere, 9108) +/* end of list */ diff --git a/Utilities/otbgeotiff/epsg_vertcs.inc b/Utilities/otbgeotiff/epsg_vertcs.inc new file mode 100644 index 0000000000000000000000000000000000000000..d6b6791cb301dc6d7833a988e7c05a1448677ba2 --- /dev/null +++ b/Utilities/otbgeotiff/epsg_vertcs.inc @@ -0,0 +1,46 @@ +/* + * EPSG/POSC Ellipsoid-referenced Vertical CS + * Note: these should correspond exactly with the Ellipsoid database. + */ +ValuePair(VertCS_Airy_1830_ellipsoid, 5001) +ValuePair(VertCS_Airy_Modified_1849_ellipsoid, 5002) +ValuePair(VertCS_ANS_ellipsoid, 5003) +ValuePair(VertCS_Bessel_1841_ellipsoid, 5004) +ValuePair(VertCS_Bessel_Modified_ellipsoid, 5005) +ValuePair(VertCS_Bessel_Namibia_ellipsoid, 5006) +ValuePair(VertCS_Clarke_1858_ellipsoid, 5007) +ValuePair(VertCS_Clarke_1866_ellipsoid, 5008) +ValuePair(VertCS_Clarke_1880_Benoit_ellipsoid, 5010) +ValuePair(VertCS_Clarke_1880_IGN_ellipsoid, 5011) +ValuePair(VertCS_Clarke_1880_RGS_ellipsoid, 5012) +ValuePair(VertCS_Clarke_1880_Arc_ellipsoid, 5013) +ValuePair(VertCS_Clarke_1880_SGA_1922_ellipsoid, 5014) +ValuePair(VertCS_Everest_1830_1937_Adjustment_ellipsoid, 5015) +ValuePair(VertCS_Everest_1830_1967_Definition_ellipsoid, 5016) +ValuePair(VertCS_Everest_1830_1975_Definition_ellipsoid, 5017) +ValuePair(VertCS_Everest_1830_Modified_ellipsoid, 5018) +ValuePair(VertCS_GRS_1980_ellipsoid, 5019) +ValuePair(VertCS_Helmert_1906_ellipsoid, 5020) +ValuePair(VertCS_INS_ellipsoid, 5021) +ValuePair(VertCS_International_1924_ellipsoid, 5022) +ValuePair(VertCS_International_1967_ellipsoid, 5023) +ValuePair(VertCS_Krassowsky_1940_ellipsoid, 5024) +ValuePair(VertCS_NWL_9D_ellipsoid, 5025) +ValuePair(VertCS_NWL_10D_ellipsoid, 5026) +ValuePair(VertCS_Plessis_1817_ellipsoid, 5027) +ValuePair(VertCS_Struve_1860_ellipsoid, 5028) +ValuePair(VertCS_War_Office_ellipsoid, 5029) +ValuePair(VertCS_WGS_84_ellipsoid, 5030) +ValuePair(VertCS_GEM_10C_ellipsoid, 5031) +ValuePair(VertCS_OSU86F_ellipsoid, 5032) +ValuePair(VertCS_OSU91A_ellipsoid, 5033) +/* + * Other established Vertical CS + */ +ValuePair(VertCS_Newlyn, 5101) +ValuePair(VertCS_North_American_Vertical_Datum_1929, 5102) +ValuePair(VertCS_North_American_Vertical_Datum_1988, 5103) +ValuePair(VertCS_Yellow_Sea_1956, 5104) +ValuePair(VertCS_Baltic_Sea, 5105) +ValuePair(VertCS_Caspian_Sea, 5106) +/* end of list */ diff --git a/Utilities/otbgeotiff/geo_config.h.in b/Utilities/otbgeotiff/geo_config.h.in new file mode 100644 index 0000000000000000000000000000000000000000..85660c5cda477cd6492077fa2473b48ab4992786 --- /dev/null +++ b/Utilities/otbgeotiff/geo_config.h.in @@ -0,0 +1,19 @@ +#ifndef GEO_CONFIG_H +#define GEO_CONFIG_H + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +#undef HAVE_LIBPROJ +#undef HAVE_PROJECTS_H + +#endif /* ndef GEO_CONFIG_H */ diff --git a/Utilities/otbgeotiff/geo_ctrans.inc b/Utilities/otbgeotiff/geo_ctrans.inc new file mode 100644 index 0000000000000000000000000000000000000000..5ebc643dc9b421c2e4a6746046d6b834d7c4d7f4 --- /dev/null +++ b/Utilities/otbgeotiff/geo_ctrans.inc @@ -0,0 +1,91 @@ +/****************************************************************************** + * $Id: geo_ctrans.inc,v 1.3 2005/03/04 03:59:11 fwarmerdam Exp $ + * + * Project: libgeotiff + * Purpose: GeoTIFF Projection Method codes. + * Author: Frank Warmerdam, warmerdam@pobox.com + * + ****************************************************************************** + * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: geo_ctrans.inc,v $ + * Revision 1.3 2005/03/04 03:59:11 fwarmerdam + * Added header. + * + */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +/* + * Revised 12 Jul 1995 NDR -- changed South Oriented to a code + * Revised 28 Sep 1995 NDR -- Added Rev. 1.0 aliases. + */ + +ValuePair(CT_TransverseMercator, 1) +ValuePair(CT_TransvMercator_Modified_Alaska, 2) +ValuePair(CT_ObliqueMercator, 3) +ValuePair(CT_ObliqueMercator_Laborde, 4) +ValuePair(CT_ObliqueMercator_Rosenmund, 5) +ValuePair(CT_ObliqueMercator_Spherical, 6) /* not advisable */ +ValuePair(CT_Mercator, 7) +ValuePair(CT_LambertConfConic_2SP, 8) +ValuePair(CT_LambertConfConic,CT_LambertConfConic_2SP) /* Alias */ +ValuePair(CT_LambertConfConic_1SP, 9) +ValuePair(CT_LambertConfConic_Helmert,CT_LambertConfConic_1SP) /* alias */ +ValuePair(CT_LambertAzimEqualArea, 10) +ValuePair(CT_AlbersEqualArea, 11) +ValuePair(CT_AzimuthalEquidistant, 12) +ValuePair(CT_EquidistantConic, 13) +ValuePair(CT_Stereographic, 14) +ValuePair(CT_PolarStereographic, 15) +ValuePair(CT_ObliqueStereographic, 16) /* not advisable */ +ValuePair(CT_Equirectangular, 17) +ValuePair(CT_CassiniSoldner, 18) +ValuePair(CT_Gnomonic, 19) +ValuePair(CT_MillerCylindrical, 20) +ValuePair(CT_Orthographic, 21) +ValuePair(CT_Polyconic, 22) +ValuePair(CT_Robinson, 23) +ValuePair(CT_Sinusoidal, 24) +ValuePair(CT_VanDerGrinten, 25) +ValuePair(CT_NewZealandMapGrid, 26) +/* Added for 1.0 */ +ValuePair(CT_TransvMercator_SouthOrientated, 27) + +/* Added Feb 2005 */ +ValuePair(CT_CylindricalEqualArea, 28) + + +/* Aliases */ + +ValuePair(CT_SouthOrientedGaussConformal,CT_TransvMercator_SouthOrientated) +ValuePair(CT_AlaskaConformal, CT_TransvMercator_Modified_Alaska) +ValuePair(CT_TransvEquidistCylindrical, CT_CassiniSoldner) +ValuePair(CT_ObliqueMercator_Hotine, CT_ObliqueMercator) +ValuePair(CT_SwissObliqueCylindrical, CT_ObliqueMercator_Rosenmund) +ValuePair(CT_GaussBoaga, CT_TransverseMercator) +ValuePair(CT_GaussKruger, CT_TransverseMercator) +ValuePair(CT_TransvMercator_SouthOriented, CT_TransvMercator_SouthOrientated) + + diff --git a/Utilities/otbgeotiff/geo_extra.c b/Utilities/otbgeotiff/geo_extra.c new file mode 100644 index 0000000000000000000000000000000000000000..a1fdecf22a8977514ae4bfa3a6d873ca29e259bb --- /dev/null +++ b/Utilities/otbgeotiff/geo_extra.c @@ -0,0 +1,747 @@ +/****************************************************************************** + * $Id: geo_extra.c,v 1.4 2002/12/01 23:44:34 warmerda Exp $ + * + * Project: libgeotiff + * Purpose: Code to normalize a few common PCS values without use of CSV + * files. + * Author: Frank Warmerdam, warmerda@home.com + * + ****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: geo_extra.c,v $ + * Revision 1.4 2002/12/01 23:44:34 warmerda + * Fixed typo in last fix. + * + * Revision 1.3 2002/12/01 23:42:06 warmerda + * added overrides for two deprecated stateplane zones + * + * Revision 1.2 1999/05/04 03:09:33 warmerda + * avoid warnings + * + * Revision 1.1 1999/04/28 20:01:29 warmerda + * new + * + */ + +/* +#include "geotiff.h" +#include "geo_tiffp.h" +#include "geo_keyp.h" +*/ + +#include "geo_normalize.h" +#include "geovalues.h" + +static int StatePlaneTable[] = +{ + PCS_NAD83_Alabama_East, Proj_Alabama_CS83_East, + PCS_NAD83_Alabama_West, Proj_Alabama_CS83_West, + + PCS_NAD83_Alaska_zone_1, Proj_Alaska_CS83_1, + PCS_NAD83_Alaska_zone_2, Proj_Alaska_CS83_2, + PCS_NAD83_Alaska_zone_3, Proj_Alaska_CS83_3, + PCS_NAD83_Alaska_zone_4, Proj_Alaska_CS83_4, + PCS_NAD83_Alaska_zone_5, Proj_Alaska_CS83_5, + PCS_NAD83_Alaska_zone_6, Proj_Alaska_CS83_6, + PCS_NAD83_Alaska_zone_7, Proj_Alaska_CS83_7, + PCS_NAD83_Alaska_zone_8, Proj_Alaska_CS83_8, + PCS_NAD83_Alaska_zone_9, Proj_Alaska_CS83_9, + PCS_NAD83_Alaska_zone_10, Proj_Alaska_CS83_10, + + PCS_NAD83_California_1, Proj_California_CS83_1, + PCS_NAD83_California_2, Proj_California_CS83_2, + PCS_NAD83_California_3, Proj_California_CS83_3, + PCS_NAD83_California_4, Proj_California_CS83_4, + PCS_NAD83_California_5, Proj_California_CS83_5, + PCS_NAD83_California_6, Proj_California_CS83_6, + + PCS_NAD83_Arizona_East, Proj_Arizona_CS83_east, + PCS_NAD83_Arizona_Central, Proj_Arizona_CS83_Central, + PCS_NAD83_Arizona_West, Proj_Arizona_CS83_west, + + PCS_NAD83_Arkansas_North, Proj_Arkansas_CS83_North, + PCS_NAD83_Arkansas_South, Proj_Arkansas_CS83_South, + + PCS_NAD83_Colorado_North, Proj_Colorado_CS83_North, + PCS_NAD83_Colorado_Central, Proj_Colorado_CS83_Central, + PCS_NAD83_Colorado_South, Proj_Colorado_CS83_South, + + PCS_NAD83_Connecticut, Proj_Connecticut_CS83, + + PCS_NAD83_Delaware, Proj_Delaware_CS83, + + PCS_NAD83_Florida_East, Proj_Florida_CS83_East, + PCS_NAD83_Florida_North, Proj_Florida_CS83_North, + PCS_NAD83_Florida_West, Proj_Florida_CS83_West, + + PCS_NAD83_Hawaii_zone_1, Proj_Hawaii_CS83_1, + PCS_NAD83_Hawaii_zone_2, Proj_Hawaii_CS83_2, + PCS_NAD83_Hawaii_zone_3, Proj_Hawaii_CS83_3, + PCS_NAD83_Hawaii_zone_4, Proj_Hawaii_CS83_4, + PCS_NAD83_Hawaii_zone_5, Proj_Hawaii_CS83_5, + + PCS_NAD83_Georgia_East, Proj_Georgia_CS83_East, + PCS_NAD83_Georgia_West, Proj_Georgia_CS83_West, + + PCS_NAD83_Idaho_East, Proj_Idaho_CS83_East, + PCS_NAD83_Idaho_Central, Proj_Idaho_CS83_Central, + PCS_NAD83_Idaho_West, Proj_Idaho_CS83_West, + + PCS_NAD83_Illinois_East, Proj_Illinois_CS83_East, + PCS_NAD83_Illinois_West, Proj_Illinois_CS83_West, + + PCS_NAD83_Indiana_East, Proj_Indiana_CS83_East, + PCS_NAD83_Indiana_West, Proj_Indiana_CS83_West, + + PCS_NAD83_Iowa_North, Proj_Iowa_CS83_North, + PCS_NAD83_Iowa_South, Proj_Iowa_CS83_South, + + PCS_NAD83_Kansas_North, Proj_Kansas_CS83_North, + PCS_NAD83_Kansas_South, Proj_Kansas_CS83_South, + + PCS_NAD83_Kentucky_North, Proj_Kentucky_CS83_North, + PCS_NAD83_Kentucky_South, Proj_Kentucky_CS83_South, + + PCS_NAD83_Louisiana_North, Proj_Louisiana_CS83_North, + PCS_NAD83_Louisiana_South, Proj_Louisiana_CS83_South, + + PCS_NAD83_Maine_East, Proj_Maine_CS83_East, + PCS_NAD83_Maine_West, Proj_Maine_CS83_West, + + PCS_NAD83_Maryland, Proj_Maryland_CS83, + + PCS_NAD83_Massachusetts, Proj_Massachusetts_CS83_Mainland, + PCS_NAD83_Massachusetts_Is, Proj_Massachusetts_CS83_Island, + + PCS_NAD83_Michigan_North, Proj_Michigan_CS83_North, + PCS_NAD83_Michigan_Central, Proj_Michigan_CS83_Central, + PCS_NAD83_Michigan_South, Proj_Michigan_CS83_South, + + PCS_NAD83_Minnesota_North, Proj_Minnesota_CS83_North, + PCS_NAD83_Minnesota_Cent, Proj_Minnesota_CS83_Central, + PCS_NAD83_Minnesota_South, Proj_Minnesota_CS83_South, + + PCS_NAD83_Mississippi_East, Proj_Mississippi_CS83_East, + PCS_NAD83_Mississippi_West, Proj_Mississippi_CS83_West, + + PCS_NAD83_Missouri_East, Proj_Missouri_CS83_East, + PCS_NAD83_Missouri_Central, Proj_Missouri_CS83_Central, + PCS_NAD83_Missouri_West, Proj_Missouri_CS83_West, + + PCS_NAD83_Montana, Proj_Montana_CS83, + + PCS_NAD83_Nebraska, Proj_Nebraska_CS83, + + PCS_NAD83_Nevada_East, Proj_Nevada_CS83_East, + PCS_NAD83_Nevada_Central, Proj_Nevada_CS83_Central, + PCS_NAD83_Nevada_West, Proj_Nevada_CS83_West, + + PCS_NAD83_New_Hampshire, Proj_New_Hampshire_CS83, + + PCS_NAD83_New_Jersey, Proj_New_Jersey_CS83, + + PCS_NAD83_New_Mexico_East, Proj_New_Mexico_CS83_East, + PCS_NAD83_New_Mexico_Cent, Proj_New_Mexico_CS83_Central, + PCS_NAD83_New_Mexico_West, Proj_New_Mexico_CS83_West, + + PCS_NAD83_New_York_East, Proj_New_York_CS83_East, + PCS_NAD83_New_York_Central, Proj_New_York_CS83_Central, + PCS_NAD83_New_York_West, Proj_New_York_CS83_West, + PCS_NAD83_New_York_Long_Is, Proj_New_York_CS83_Long_Island, + + PCS_NAD83_North_Carolina, Proj_North_Carolina_CS83, + + PCS_NAD83_North_Dakota_N, Proj_North_Dakota_CS83_North, + PCS_NAD83_North_Dakota_S, Proj_North_Dakota_CS83_South, + + PCS_NAD83_Ohio_North, Proj_Ohio_CS83_North, + PCS_NAD83_Ohio_South, Proj_Ohio_CS83_South, + + PCS_NAD83_Oklahoma_North, Proj_Oklahoma_CS83_North, + PCS_NAD83_Oklahoma_South, Proj_Oklahoma_CS83_South, + + PCS_NAD83_Oregon_North, Proj_Oregon_CS83_North, + PCS_NAD83_Oregon_South, Proj_Oregon_CS83_South, + + PCS_NAD83_Pennsylvania_N, Proj_Pennsylvania_CS83_North, + PCS_NAD83_Pennsylvania_S, Proj_Pennsylvania_CS83_South, + + PCS_NAD83_Rhode_Island, Proj_Rhode_Island_CS83, + + PCS_NAD83_South_Carolina, Proj_South_Carolina_CS83, + + PCS_NAD83_South_Dakota_N, Proj_South_Dakota_CS83_North, + PCS_NAD83_South_Dakota_S, Proj_South_Dakota_CS83_South, + + PCS_NAD83_Tennessee, Proj_Tennessee_CS83, + + PCS_NAD83_Texas_North, Proj_Texas_CS83_North, + PCS_NAD83_Texas_North_Cen, Proj_Texas_CS83_North_Central, + PCS_NAD83_Texas_Central, Proj_Texas_CS83_Central, + PCS_NAD83_Texas_South_Cen, Proj_Texas_CS83_South_Central, + PCS_NAD83_Texas_South, Proj_Texas_CS83_South, + + PCS_NAD83_Utah_North, Proj_Utah_CS83_North, + PCS_NAD83_Utah_Central, Proj_Utah_CS83_Central, + PCS_NAD83_Utah_South, Proj_Utah_CS83_South, + + PCS_NAD83_Vermont, Proj_Vermont_CS83, + + PCS_NAD83_Virginia_North, Proj_Virginia_CS83_North, + PCS_NAD83_Virginia_South, Proj_Virginia_CS83_South, + + PCS_NAD83_Washington_North, Proj_Washington_CS83_North, + PCS_NAD83_Washington_South, Proj_Washington_CS83_South, + + PCS_NAD83_West_Virginia_N, Proj_West_Virginia_CS83_North, + PCS_NAD83_West_Virginia_S, Proj_West_Virginia_CS83_South, + + PCS_NAD83_Wisconsin_North, Proj_Wisconsin_CS83_North, + PCS_NAD83_Wisconsin_Cen, Proj_Wisconsin_CS83_Central, + PCS_NAD83_Wisconsin_South, Proj_Wisconsin_CS83_South, + + PCS_NAD83_Wyoming_East, Proj_Wyoming_CS83_East, + PCS_NAD83_Wyoming_E_Cen, Proj_Wyoming_CS83_East_Central, + PCS_NAD83_Wyoming_W_Cen, Proj_Wyoming_CS83_West_Central, + PCS_NAD83_Wyoming_West, Proj_Wyoming_CS83_West, + + PCS_NAD83_Puerto_Rico_Virgin_Is, Proj_Puerto_Rico_Virgin_Is, + + PCS_NAD27_Alabama_East, Proj_Alabama_CS27_East, + PCS_NAD27_Alabama_West, Proj_Alabama_CS27_West, + + PCS_NAD27_Alaska_zone_1, Proj_Alaska_CS27_1, + PCS_NAD27_Alaska_zone_2, Proj_Alaska_CS27_2, + PCS_NAD27_Alaska_zone_3, Proj_Alaska_CS27_3, + PCS_NAD27_Alaska_zone_4, Proj_Alaska_CS27_4, + PCS_NAD27_Alaska_zone_5, Proj_Alaska_CS27_5, + PCS_NAD27_Alaska_zone_6, Proj_Alaska_CS27_6, + PCS_NAD27_Alaska_zone_7, Proj_Alaska_CS27_7, + PCS_NAD27_Alaska_zone_8, Proj_Alaska_CS27_8, + PCS_NAD27_Alaska_zone_9, Proj_Alaska_CS27_9, + PCS_NAD27_Alaska_zone_10, Proj_Alaska_CS27_10, + + PCS_NAD27_California_I, Proj_California_CS27_I, + PCS_NAD27_California_II, Proj_California_CS27_II, + PCS_NAD27_California_III, Proj_California_CS27_III, + PCS_NAD27_California_IV, Proj_California_CS27_IV, + PCS_NAD27_California_V, Proj_California_CS27_V, + PCS_NAD27_California_VI, Proj_California_CS27_VI, + PCS_NAD27_California_VII, Proj_California_CS27_VII, + + PCS_NAD27_Arizona_East, Proj_Arizona_Coordinate_System_east, + PCS_NAD27_Arizona_Central, Proj_Arizona_Coordinate_System_Central, + PCS_NAD27_Arizona_West, Proj_Arizona_Coordinate_System_west, + + PCS_NAD27_Arkansas_North, Proj_Arkansas_CS27_North, + PCS_NAD27_Arkansas_South, Proj_Arkansas_CS27_South, + + PCS_NAD27_Colorado_North, Proj_Colorado_CS27_North, + PCS_NAD27_Colorado_Central, Proj_Colorado_CS27_Central, + PCS_NAD27_Colorado_South, Proj_Colorado_CS27_South, + + PCS_NAD27_Connecticut, Proj_Connecticut_CS27, + + PCS_NAD27_Delaware, Proj_Delaware_CS27, + + PCS_NAD27_Florida_East, Proj_Florida_CS27_East, + PCS_NAD27_Florida_North, Proj_Florida_CS27_North, + PCS_NAD27_Florida_West, Proj_Florida_CS27_West, + + PCS_NAD27_Hawaii_zone_1, Proj_Hawaii_CS27_1, + PCS_NAD27_Hawaii_zone_2, Proj_Hawaii_CS27_2, + PCS_NAD27_Hawaii_zone_3, Proj_Hawaii_CS27_3, + PCS_NAD27_Hawaii_zone_4, Proj_Hawaii_CS27_4, + PCS_NAD27_Hawaii_zone_5, Proj_Hawaii_CS27_5, + + PCS_NAD27_Georgia_East, Proj_Georgia_CS27_East, + PCS_NAD27_Georgia_West, Proj_Georgia_CS27_West, + + PCS_NAD27_Idaho_East, Proj_Idaho_CS27_East, + PCS_NAD27_Idaho_Central, Proj_Idaho_CS27_Central, + PCS_NAD27_Idaho_West, Proj_Idaho_CS27_West, + + PCS_NAD27_Illinois_East, Proj_Illinois_CS27_East, + PCS_NAD27_Illinois_West, Proj_Illinois_CS27_West, + + PCS_NAD27_Indiana_East, Proj_Indiana_CS27_East, + PCS_NAD27_Indiana_West, Proj_Indiana_CS27_West, + + PCS_NAD27_Iowa_North, Proj_Iowa_CS27_North, + PCS_NAD27_Iowa_South, Proj_Iowa_CS27_South, + + PCS_NAD27_Kansas_North, Proj_Kansas_CS27_North, + PCS_NAD27_Kansas_South, Proj_Kansas_CS27_South, + + PCS_NAD27_Kentucky_North, Proj_Kentucky_CS27_North, + PCS_NAD27_Kentucky_South, Proj_Kentucky_CS27_South, + + PCS_NAD27_Louisiana_North, Proj_Louisiana_CS27_North, + PCS_NAD27_Louisiana_South, Proj_Louisiana_CS27_South, + + PCS_NAD27_Maine_East, Proj_Maine_CS27_East, + PCS_NAD27_Maine_West, Proj_Maine_CS27_West, + + PCS_NAD27_Maryland, Proj_Maryland_CS27, + + PCS_NAD27_Massachusetts, Proj_Massachusetts_CS27_Mainland, + PCS_NAD27_Massachusetts_Is, Proj_Massachusetts_CS27_Island, + + PCS_NAD27_Michigan_North, Proj_Michigan_CS27_North, + PCS_NAD27_Michigan_Central, Proj_Michigan_CS27_Central, + PCS_NAD27_Michigan_South, Proj_Michigan_CS27_South, + + PCS_NAD27_Minnesota_North, Proj_Minnesota_CS27_North, + PCS_NAD27_Minnesota_Cent, Proj_Minnesota_CS27_Central, + PCS_NAD27_Minnesota_South, Proj_Minnesota_CS27_South, + + PCS_NAD27_Mississippi_East, Proj_Mississippi_CS27_East, + PCS_NAD27_Mississippi_West, Proj_Mississippi_CS27_West, + + PCS_NAD27_Missouri_East, Proj_Missouri_CS27_East, + PCS_NAD27_Missouri_Central, Proj_Missouri_CS27_Central, + PCS_NAD27_Missouri_West, Proj_Missouri_CS27_West, + + PCS_NAD27_Montana_North, Proj_Montana_CS27_North, + PCS_NAD27_Montana_Central, Proj_Montana_CS27_Central, + PCS_NAD27_Montana_South, Proj_Montana_CS27_South, + + PCS_NAD27_Nebraska_North, Proj_Nebraska_CS27_North, + PCS_NAD27_Nebraska_South, Proj_Nebraska_CS27_South, + + PCS_NAD27_Nevada_East, Proj_Nevada_CS27_East, + PCS_NAD27_Nevada_Central, Proj_Nevada_CS27_Central, + PCS_NAD27_Nevada_West, Proj_Nevada_CS27_West, + + PCS_NAD27_New_Hampshire, Proj_New_Hampshire_CS27, + + PCS_NAD27_New_Jersey, Proj_New_Jersey_CS27, + + PCS_NAD27_New_Mexico_East, Proj_New_Mexico_CS27_East, + PCS_NAD27_New_Mexico_Cent, Proj_New_Mexico_CS27_Central, + PCS_NAD27_New_Mexico_West, Proj_New_Mexico_CS27_West, + + PCS_NAD27_New_York_East, Proj_New_York_CS27_East, + PCS_NAD27_New_York_Central, Proj_New_York_CS27_Central, + PCS_NAD27_New_York_West, Proj_New_York_CS27_West, + PCS_NAD27_New_York_Long_Is, Proj_New_York_CS27_Long_Island, + + PCS_NAD27_North_Carolina, Proj_North_Carolina_CS27, + + PCS_NAD27_North_Dakota_N, Proj_North_Dakota_CS27_North, + PCS_NAD27_North_Dakota_S, Proj_North_Dakota_CS27_South, + + PCS_NAD27_Ohio_North, Proj_Ohio_CS27_North, + PCS_NAD27_Ohio_South, Proj_Ohio_CS27_South, + + PCS_NAD27_Oklahoma_North, Proj_Oklahoma_CS27_North, + PCS_NAD27_Oklahoma_South, Proj_Oklahoma_CS27_South, + + PCS_NAD27_Oregon_North, Proj_Oregon_CS27_North, + PCS_NAD27_Oregon_South, Proj_Oregon_CS27_South, + + PCS_NAD27_Pennsylvania_N, Proj_Pennsylvania_CS27_North, + PCS_NAD27_Pennsylvania_S, Proj_Pennsylvania_CS27_South, + + PCS_NAD27_Rhode_Island, Proj_Rhode_Island_CS27, + + PCS_NAD27_South_Carolina_N, Proj_South_Carolina_CS27_North, + PCS_NAD27_South_Carolina_S, Proj_South_Carolina_CS27_South, + + PCS_NAD27_South_Dakota_N, Proj_South_Dakota_CS27_North, + PCS_NAD27_South_Dakota_S, Proj_South_Dakota_CS27_South, + + PCS_NAD27_Tennessee, Proj_Tennessee_CS27, + + PCS_NAD27_Texas_North, Proj_Texas_CS27_North, + PCS_NAD27_Texas_North_Cen, Proj_Texas_CS27_North_Central, + PCS_NAD27_Texas_Central, Proj_Texas_CS27_Central, + PCS_NAD27_Texas_South_Cen, Proj_Texas_CS27_South_Central, + PCS_NAD27_Texas_South, Proj_Texas_CS27_South, + + PCS_NAD27_Utah_North, Proj_Utah_CS27_North, + PCS_NAD27_Utah_Central, Proj_Utah_CS27_Central, + PCS_NAD27_Utah_South, Proj_Utah_CS27_South, + + PCS_NAD27_Vermont, Proj_Vermont_CS27, + + PCS_NAD27_Virginia_North, Proj_Virginia_CS27_North, + PCS_NAD27_Virginia_South, Proj_Virginia_CS27_South, + + PCS_NAD27_Washington_North, Proj_Washington_CS27_North, + PCS_NAD27_Washington_South, Proj_Washington_CS27_South, + + PCS_NAD27_West_Virginia_N, Proj_West_Virginia_CS27_North, + PCS_NAD27_West_Virginia_S, Proj_West_Virginia_CS27_South, + + PCS_NAD27_Wisconsin_North, Proj_Wisconsin_CS27_North, + PCS_NAD27_Wisconsin_Cen, Proj_Wisconsin_CS27_Central, + PCS_NAD27_Wisconsin_South, Proj_Wisconsin_CS27_South, + + PCS_NAD27_Wyoming_East, Proj_Wyoming_CS27_East, + PCS_NAD27_Wyoming_E_Cen, Proj_Wyoming_CS27_East_Central, + PCS_NAD27_Wyoming_W_Cen, Proj_Wyoming_CS27_West_Central, + PCS_NAD27_Wyoming_West, Proj_Wyoming_CS27_West, + + PCS_NAD27_Puerto_Rico, Proj_Puerto_Rico_CS27, + + KvUserDefined +}; + +/************************************************************************/ +/* GTIFMapSysToPCS() */ +/* */ +/* Given a Datum, MapSys and zone value generate the best PCS */ +/* code possible. */ +/************************************************************************/ + +int GTIFMapSysToPCS( int MapSys, int Datum, int nZone ) + +{ + int PCSCode = KvUserDefined; + + if( MapSys == MapSys_UTM_North ) + { + if( Datum == GCS_NAD27 ) + PCSCode = PCS_NAD27_UTM_zone_3N + nZone - 3; + else if( Datum == GCS_NAD83 ) + PCSCode = PCS_NAD83_UTM_zone_3N + nZone - 3; + else if( Datum == GCS_WGS_72 ) + PCSCode = PCS_WGS72_UTM_zone_1N + nZone - 1; + else if( Datum == GCS_WGS_72BE ) + PCSCode = PCS_WGS72BE_UTM_zone_1N + nZone - 1; + else if( Datum == GCS_WGS_84 ) + PCSCode = PCS_WGS84_UTM_zone_1N + nZone - 1; + } + else if( MapSys == MapSys_UTM_South ) + { + if( Datum == GCS_WGS_72 ) + PCSCode = PCS_WGS72_UTM_zone_1S + nZone - 1; + else if( Datum == GCS_WGS_72BE ) + PCSCode = PCS_WGS72BE_UTM_zone_1S + nZone - 1; + else if( Datum == GCS_WGS_84 ) + PCSCode = PCS_WGS84_UTM_zone_1S + nZone - 1; + } + else if( MapSys == MapSys_State_Plane_27 ) + { + int i; + + PCSCode = 10000 + nZone; + for( i = 0; StatePlaneTable[i] != KvUserDefined; i += 2 ) + { + if( StatePlaneTable[i+1] == PCSCode ) + PCSCode = StatePlaneTable[i]; + } + + /* Old EPSG code was in error for Tennesse CS27, override */ + if( nZone == 4100 ) + PCSCode = 2204; + } + else if( MapSys == MapSys_State_Plane_83 ) + { + int i; + + PCSCode = 10000 + nZone + 30; + + for( i = 0; StatePlaneTable[i] != KvUserDefined; i += 2 ) + { + if( StatePlaneTable[i+1] == PCSCode ) + PCSCode = StatePlaneTable[i]; + } + + /* Old EPSG code was in error for Kentucky North CS83, override */ + if( nZone == 1601 ) + PCSCode = 2205; + } + + return( PCSCode ); +} + +/************************************************************************/ +/* GTIFMapSysToProj() */ +/* */ +/* Given a MapSys and zone value generate the best Proj_ */ +/* code possible. */ +/************************************************************************/ + +int GTIFMapSysToProj( int MapSys, int nZone ) + +{ + int ProjCode = KvUserDefined; + + if( MapSys == MapSys_UTM_North ) + { + ProjCode = Proj_UTM_zone_1N + nZone - 1; + } + else if( MapSys == MapSys_UTM_South ) + { + ProjCode = Proj_UTM_zone_1S + nZone - 1; + } + else if( MapSys == MapSys_State_Plane_27 ) + { + ProjCode = 10000 + nZone; + + /* Tennesse override */ + if( nZone == 4100 ) + ProjCode = 15302; + } + else if( MapSys == MapSys_State_Plane_83 ) + { + ProjCode = 10000 + nZone + 30; + + /* Kentucky North override */ + if( nZone == 1601 ) + ProjCode = 15303; + } + + return( ProjCode ); +} + +/************************************************************************/ +/* GTIFPCSToMapSys() */ +/************************************************************************/ + +/** + * Translate a PCS_ code into a UTM or State Plane map system, a datum, + * and a zone if possible. + * + * @param PCSCode The projection code (PCS_*) as would be stored in the + * ProjectedCSTypeGeoKey of a GeoTIFF file. + * + * @param pDatum Pointer to an integer into which the datum code (GCS_*) + * is put if the function succeeds. + * + * @param pZone Pointer to an integer into which the zone will be placed + * if the function is successful. + * + * @return Returns either MapSys_UTM_North, MapSys_UTM_South, + * MapSys_State_Plane_83, MapSys_State_Plane_27 or KvUserDefined. + * KvUserDefined indicates that the + * function failed to recognise the projection as UTM or State Plane. + * + * The zone value is only set if the return code is other than KvUserDefined. + * For utm map system the returned zone will be between 1 and 60. For + * State Plane, the USGS state plane zone number is returned. For instance, + * Alabama East is zone 101. + * + * The datum (really this is the GCS) is set to a GCS_ value such as GCS_NAD27. + * + * This function is useful to recognise (most) UTM and State Plane coordinate + * systems, even if CSV files aren't available to translate them automatically. + * It is used as a fallback mechanism by GTIFGetDefn() for normalization when + * CSV files aren't found. + */ + +int GTIFPCSToMapSys( int PCSCode, int * pDatum, int * pZone ) + +{ + int Datum = KvUserDefined, Proj = KvUserDefined; + int nZone = KvUserDefined, i; + +/* -------------------------------------------------------------------- */ +/* UTM with various datums. Note there are lots of PCS UTM */ +/* codes not done yet which use strange datums. */ +/* -------------------------------------------------------------------- */ + if( PCSCode >= PCS_NAD27_UTM_zone_3N && PCSCode <= PCS_NAD27_UTM_zone_22N ) + { + Datum = GCS_NAD27; + Proj = MapSys_UTM_North; + nZone = PCSCode - PCS_NAD27_UTM_zone_3N + 3; + } + else if( PCSCode >= PCS_NAD83_UTM_zone_3N + && PCSCode <= PCS_NAD83_UTM_zone_23N ) + { + Datum = GCS_NAD83; + Proj = MapSys_UTM_North; + nZone = PCSCode - PCS_NAD83_UTM_zone_3N + 3; + } + + else if( PCSCode >= PCS_WGS72_UTM_zone_1N + && PCSCode <= PCS_WGS72_UTM_zone_60N ) + { + Datum = GCS_WGS_72; + Proj = MapSys_UTM_North; + nZone = PCSCode - PCS_WGS72_UTM_zone_1N + 1; + } + else if( PCSCode >= PCS_WGS72_UTM_zone_1S + && PCSCode <= PCS_WGS72_UTM_zone_60S ) + { + Datum = GCS_WGS_72; + Proj = MapSys_UTM_South; + nZone = PCSCode - PCS_WGS72_UTM_zone_1S + 1; + } + + else if( PCSCode >= PCS_WGS72BE_UTM_zone_1N + && PCSCode <= PCS_WGS72BE_UTM_zone_60N ) + { + Datum = GCS_WGS_72BE; + Proj = MapSys_UTM_North; + nZone = PCSCode - PCS_WGS72BE_UTM_zone_1N + 1; + } + else if( PCSCode >= PCS_WGS72BE_UTM_zone_1S + && PCSCode <= PCS_WGS72BE_UTM_zone_60S ) + { + Datum = GCS_WGS_72BE; + Proj = MapSys_UTM_South; + nZone = PCSCode - PCS_WGS72BE_UTM_zone_1S + 1; + } + + else if( PCSCode >= PCS_WGS84_UTM_zone_1N + && PCSCode <= PCS_WGS84_UTM_zone_60N ) + { + Datum = GCS_WGS_84; + Proj = MapSys_UTM_North; + nZone = PCSCode - PCS_WGS84_UTM_zone_1N + 1; + } + else if( PCSCode >= PCS_WGS84_UTM_zone_1S + && PCSCode <= PCS_WGS84_UTM_zone_60S ) + { + Datum = GCS_WGS_84; + Proj = MapSys_UTM_South; + nZone = PCSCode - PCS_WGS84_UTM_zone_1S + 1; + } + else if( PCSCode >= PCS_SAD69_UTM_zone_18N + && PCSCode <= PCS_SAD69_UTM_zone_22N ) + { + Datum = KvUserDefined; + Proj = MapSys_UTM_North; + nZone = PCSCode - PCS_SAD69_UTM_zone_18N + 18; + } + else if( PCSCode >= PCS_SAD69_UTM_zone_17S + && PCSCode <= PCS_SAD69_UTM_zone_25S ) + { + Datum = KvUserDefined; + Proj = MapSys_UTM_South; + nZone = PCSCode - PCS_SAD69_UTM_zone_17S + 17; + } + +/* -------------------------------------------------------------------- */ +/* State Plane zones, first we translate any PCS_ codes to */ +/* a Proj_ code that we can get a handle on. */ +/* -------------------------------------------------------------------- */ + for( i = 0; StatePlaneTable[i] != KvUserDefined; i += 2 ) + { + if( StatePlaneTable[i] == PCSCode ) + PCSCode = StatePlaneTable[i+1]; + } + + if( PCSCode <= 15900 && PCSCode >= 10000 ) + { + if( (PCSCode % 100) >= 30 ) + { + Proj = MapSys_State_Plane_83; + Datum = GCS_NAD83; + } + else + { + Proj = MapSys_State_Plane_27; + Datum = GCS_NAD27; + } + + nZone = PCSCode - 10000; + if( Datum == GCS_NAD83 ) + nZone -= 30; + } + + if( pDatum != NULL ) + *pDatum = Datum; + + if( pZone != NULL ) + *pZone = nZone; + + return( Proj ); +} + +/************************************************************************/ +/* GTIFProjToMapSys() */ +/************************************************************************/ + +/** + * Translate a Proj_ code into a UTM or State Plane map system, and a zone + * if possible. + * + * @param ProjCode The projection code (Proj_*) as would be stored in the + * ProjectionGeoKey of a GeoTIFF file. + * @param pZone Pointer to an integer into which the zone will be placed + * if the function is successful. + * + * @return Returns either MapSys_UTM_North, MapSys_UTM_South, + * MapSys_State_Plane_27, MapSys_State_Plane_83 or KvUserDefined. + * KvUserDefined indicates that the + * function failed to recognise the projection as UTM or State Plane. + * + * The zone value is only set if the return code is other than KvUserDefined. + * For utm map system the returned zone will be between 1 and 60. For + * State Plane, the USGS state plane zone number is returned. For instance, + * Alabama East is zone 101. + * + * This function is useful to recognise UTM and State Plane coordinate + * systems, and to extract zone numbers so the projections can be + * represented as UTM rather than as the underlying projection method such + * Transverse Mercator for instance. + */ + +int GTIFProjToMapSys( int ProjCode, int * pZone ) + +{ + int nZone = KvUserDefined; + int MapSys = KvUserDefined; + +/* -------------------------------------------------------------------- */ +/* Handle UTM. */ +/* -------------------------------------------------------------------- */ + if( ProjCode >= Proj_UTM_zone_1N && ProjCode <= Proj_UTM_zone_60N ) + { + MapSys = MapSys_UTM_North; + nZone = ProjCode - Proj_UTM_zone_1N + 1; + } + else if( ProjCode >= Proj_UTM_zone_1S && ProjCode <= Proj_UTM_zone_60S ) + { + MapSys = MapSys_UTM_South; + nZone = ProjCode - Proj_UTM_zone_1S + 1; + } + +/* -------------------------------------------------------------------- */ +/* Handle State Plane. I think there are some anomolies in */ +/* here, so this is a bit risky. */ +/* -------------------------------------------------------------------- */ + else if( ProjCode >= 10101 && ProjCode <= 15299 ) + { + if( ProjCode % 100 >= 30 ) + { + MapSys = MapSys_State_Plane_83; + nZone = ProjCode - 10000 - 30; + } + else + { + MapSys = MapSys_State_Plane_27; + nZone = ProjCode - 10000; + } + } + + if( pZone != NULL ) + *pZone = nZone; + + return( MapSys ); +} + diff --git a/Utilities/otbgeotiff/geo_free.c b/Utilities/otbgeotiff/geo_free.c new file mode 100644 index 0000000000000000000000000000000000000000..a43fcad354634ceebc9470cda83027cdf5303c51 --- /dev/null +++ b/Utilities/otbgeotiff/geo_free.c @@ -0,0 +1,62 @@ +/********************************************************************** + * + * geo_free.c -- Public routines for GEOTIFF GeoKey access. + * + * Written By: Niles D. Ritter. + * + * copyright (c) 1995 Niles D. Ritter + * + * Permission granted to use this software, so long as this copyright + * notice accompanies any products derived therefrom. + * + **********************************************************************/ + +#include "geotiff.h" /* public interface */ +#include "geo_tiffp.h" /* external TIFF interface */ +#include "geo_keyp.h" /* private interface */ + + +/********************************************************************** + * + * Public Routines + * + **********************************************************************/ + +/** + +This function deallocates an existing GeoTIFF access handle previously +created with GTIFNew(). If the handle was +used to write GeoTIFF keys to the TIFF file, the +GTIFWriteKeys() function should be used +to flush results to the file before calling GTIFFree(). GTIFFree() +should be called before XTIFFClose() is +called on the corresponding TIFF file handle.<p> + +*/ + +void GTIFFree(GTIF* gtif) +{ + int i; + + if (!gtif) return; + + /* Free parameter arrays */ + if (gtif->gt_double) _GTIFFree (gtif->gt_double); + if (gtif->gt_short) _GTIFFree (gtif->gt_short); + + /* Free GeoKey arrays */ + if (gtif->gt_keys) + { + for (i = 0; i < MAX_KEYS; i++) + { + if (gtif->gt_keys[i].gk_type == TYPE_ASCII) + { + _GTIFFree (gtif->gt_keys[i].gk_data); + } + } + _GTIFFree (gtif->gt_keys); + } + if (gtif->gt_keyindex) _GTIFFree (gtif->gt_keyindex); + + _GTIFFree (gtif); +} diff --git a/Utilities/otbgeotiff/geo_get.c b/Utilities/otbgeotiff/geo_get.c new file mode 100644 index 0000000000000000000000000000000000000000..f027bd3aa278d9a342b283207ee0cf18de1c477a --- /dev/null +++ b/Utilities/otbgeotiff/geo_get.c @@ -0,0 +1,176 @@ +/********************************************************************** + * + * geo_get.c -- Public routines for GEOTIFF GeoKey access. + * + * Written By: Niles D. Ritter. + * + * copyright (c) 1995 Niles D. Ritter + * + * Permission granted to use this software, so long as this copyright + * notice accompanies any products derived therefrom. + * + * Revision History; + * + * 20 June, 1995 Niles D. Ritter New + * 3 July, 1995 Greg Martin Fix strings and index + * 6 July, 1995 Niles D. Ritter Unfix indexing. + * + **********************************************************************/ + +#include "geotiff.h" /* public interface */ +#include "geo_tiffp.h" /* external TIFF interface */ +#include "geo_keyp.h" /* private interface */ + +/* return the Header info of this geotiff file */ + +void GTIFDirectoryInfo(GTIF *gtif, int version[3], int *keycount) +{ + if (version) + { + version[0] = gtif->gt_version; + version[1] = gtif->gt_rev_major; + version[2] = gtif->gt_rev_minor; + } + if (keycount) *keycount = gtif->gt_num_keys; +} + + +int GTIFKeyInfo(GTIF *gtif, geokey_t key, int *size, tagtype_t* type) +{ + int index = gtif->gt_keyindex[ key ]; + GeoKey *keyptr; + + if (!index) return 0; + + keyptr = gtif->gt_keys + index; + if (size) *size = (int) keyptr->gk_size; + if (type) *type = keyptr->gk_type; + + return keyptr->gk_count; +} + +/** + +This function reads the value of a single GeoKey from a GeoTIFF file. + +@param gtif The geotiff information handle from GTIFNew(). + +@param thekey The geokey_t name (such as ProjectedCSTypeGeoKey). +This must come from the list of legal geokey_t values +(an enumeration) listed below. + +@param val The <b>val</b> argument is a pointer to the +variable into which the value should be read. The type of the variable +varies depending on the geokey_t given. While there is no ready mapping +of geokey_t values onto types, in general code values are of type <i>short</i>, +citations are strings, and everything else is of type <i>double</i>. Note +that pointer's to <i>int</i> should never be passed to GTIFKeyGet() for +integer values as they will be shorts, and the int's may not be properly +initialized (and will be grossly wrong on MSB systems). + +@param index Indicates how far into the list of values +for this geokey to offset. Should normally be zero. + +@param count Indicates how many values +to read. At this time all keys except for strings have only one value, +so <b>index</b> should be zero, and <b>count</b> should be one. + +@return The GTIFKeyGet() function returns the number of values read. Normally +this would be one if successful or zero if the key doesn't exist for this +file. + +From geokeys.inc we see the following geokey_t values are possible:<p> + +<pre> +-- 6.2.1 GeoTIFF Configuration Keys -- + +ValuePair( GTModelTypeGeoKey, 1024) -- Section 6.3.1.1 Codes -- +ValuePair( GTRasterTypeGeoKey, 1025) -- Section 6.3.1.2 Codes -- +ValuePair( GTCitationGeoKey, 1026) -- documentation -- + +-- 6.2.2 Geographic CS Parameter Keys -- + +ValuePair( GeographicTypeGeoKey, 2048) -- Section 6.3.2.1 Codes -- +ValuePair( GeogCitationGeoKey, 2049) -- documentation -- +ValuePair( GeogGeodeticDatumGeoKey, 2050) -- Section 6.3.2.2 Codes -- +ValuePair( GeogPrimeMeridianGeoKey, 2051) -- Section 6.3.2.4 codes -- +ValuePair( GeogLinearUnitsGeoKey, 2052) -- Section 6.3.1.3 Codes -- +ValuePair( GeogLinearUnitSizeGeoKey, 2053) -- meters -- +ValuePair( GeogAngularUnitsGeoKey, 2054) -- Section 6.3.1.4 Codes -- +ValuePair( GeogAngularUnitSizeGeoKey, 2055) -- radians -- +ValuePair( GeogEllipsoidGeoKey, 2056) -- Section 6.3.2.3 Codes -- +ValuePair( GeogSemiMajorAxisGeoKey, 2057) -- GeogLinearUnits -- +ValuePair( GeogSemiMinorAxisGeoKey, 2058) -- GeogLinearUnits -- +ValuePair( GeogInvFlatteningGeoKey, 2059) -- ratio -- +ValuePair( GeogAzimuthUnitsGeoKey, 2060) -- Section 6.3.1.4 Codes -- +ValuePair( GeogPrimeMeridianLongGeoKey, 2061) -- GeoAngularUnit -- + +-- 6.2.3 Projected CS Parameter Keys -- +-- Several keys have been renamed,-- +-- and the deprecated names aliased for backward compatibility -- + +ValuePair( ProjectedCSTypeGeoKey, 3072) -- Section 6.3.3.1 codes -- +ValuePair( PCSCitationGeoKey, 3073) -- documentation -- +ValuePair( ProjectionGeoKey, 3074) -- Section 6.3.3.2 codes -- +ValuePair( ProjCoordTransGeoKey, 3075) -- Section 6.3.3.3 codes -- +ValuePair( ProjLinearUnitsGeoKey, 3076) -- Section 6.3.1.3 codes -- +ValuePair( ProjLinearUnitSizeGeoKey, 3077) -- meters -- +ValuePair( ProjStdParallel1GeoKey, 3078) -- GeogAngularUnit -- +ValuePair( ProjStdParallelGeoKey,ProjStdParallel1GeoKey) -- ** alias ** -- +ValuePair( ProjStdParallel2GeoKey, 3079) -- GeogAngularUnit -- +ValuePair( ProjNatOriginLongGeoKey, 3080) -- GeogAngularUnit -- +ValuePair( ProjOriginLongGeoKey,ProjNatOriginLongGeoKey) -- ** alias ** -- +ValuePair( ProjNatOriginLatGeoKey, 3081) -- GeogAngularUnit -- +ValuePair( ProjOriginLatGeoKey,ProjNatOriginLatGeoKey) -- ** alias ** -- +ValuePair( ProjFalseEastingGeoKey, 3082) -- ProjLinearUnits -- +ValuePair( ProjFalseNorthingGeoKey, 3083) -- ProjLinearUnits -- +ValuePair( ProjFalseOriginLongGeoKey, 3084) -- GeogAngularUnit -- +ValuePair( ProjFalseOriginLatGeoKey, 3085) -- GeogAngularUnit -- +ValuePair( ProjFalseOriginEastingGeoKey, 3086) -- ProjLinearUnits -- +ValuePair( ProjFalseOriginNorthingGeoKey, 3087) -- ProjLinearUnits -- +ValuePair( ProjCenterLongGeoKey, 3088) -- GeogAngularUnit -- +ValuePair( ProjCenterLatGeoKey, 3089) -- GeogAngularUnit -- +ValuePair( ProjCenterEastingGeoKey, 3090) -- ProjLinearUnits -- +ValuePair( ProjCenterNorthingGeoKey, 3091) -- ProjLinearUnits -- +ValuePair( ProjScaleAtNatOriginGeoKey, 3092) -- ratio -- +ValuePair( ProjScaleAtOriginGeoKey,ProjScaleAtNatOriginGeoKey) -- ** alias ** -- +ValuePair( ProjScaleAtCenterGeoKey, 3093) -- ratio -- +ValuePair( ProjAzimuthAngleGeoKey, 3094) -- GeogAzimuthUnit -- +ValuePair( ProjStraightVertPoleLongGeoKey, 3095) -- GeogAngularUnit -- + + 6.2.4 Vertical CS Keys + +ValuePair( VerticalCSTypeGeoKey, 4096) -- Section 6.3.4.1 codes -- +ValuePair( VerticalCitationGeoKey, 4097) -- documentation -- +ValuePair( VerticalDatumGeoKey, 4098) -- Section 6.3.4.2 codes -- +ValuePair( VerticalUnitsGeoKey, 4099) -- Section 6.3.1 (.x) codes -- +</pre> +*/ + +int GTIFKeyGet(GTIF *gtif, geokey_t thekey, void *val, int index, int count) +{ + int kindex = gtif->gt_keyindex[ thekey ]; + GeoKey *key; + gsize_t size; + char *data; + tagtype_t type; + + if (!kindex) return 0; + + key = gtif->gt_keys+kindex; + if (!count) count = key->gk_count - index; + if (count <=0) return 0; + if (count > key->gk_count) count = key->gk_count; + size = key->gk_size; + type = key->gk_type; + + if (count==1 && type==TYPE_SHORT) data = (char *)&key->gk_data; + else data = key->gk_data; + + _GTIFmemcpy( val, data + index*size, count*size ); + + if (type==TYPE_ASCII) + ((char *)val)[count-1] = '\0'; /* replace last char with NULL */ + + return count; +} diff --git a/Utilities/otbgeotiff/geo_keyp.h b/Utilities/otbgeotiff/geo_keyp.h new file mode 100644 index 0000000000000000000000000000000000000000..140bf403acaa469ad7a2811c7f2ef83ad813cceb --- /dev/null +++ b/Utilities/otbgeotiff/geo_keyp.h @@ -0,0 +1,98 @@ +/********************************************************************** + * + * geo_keyp.h - private interface for GeoTIFF geokey tag parsing + * + * Written by: Niles D. Ritter + * + **********************************************************************/ + +#ifndef __geo_keyp_h_ +#define __geo_keyp_h_ + +#include <stdlib.h> /* for size_t */ + +/* + * This structure contains the internal program + * representation of the key entry. + */ +struct GeoKey { + int gk_key; /* GeoKey ID */ + size_t gk_size; /* data byte size */ + tagtype_t gk_type; /* TIFF data type */ + long gk_count; /* number of values */ + char* gk_data; /* pointer to data, or value */ +}; +typedef struct GeoKey GeoKey; + +/* + * This structure represents the file-organization of + * the key entry. Note that it assumes that short entries + * are aligned along 2-byte boundaries. + */ +struct KeyEntry { + pinfo_t ent_key; /* GeoKey ID */ + pinfo_t ent_location; /* TIFF Tag ID or 0 */ + pinfo_t ent_count; /* GeoKey value count */ + pinfo_t ent_val_offset; /* value or tag offset */ +}; +typedef struct KeyEntry KeyEntry; + +/* + * This is the header of the CoordSystemInfoTag. The 'Version' + * will only change if the CoorSystemInfoTag structure changes; + * The Major Revision will be incremented whenever a new set of + * Keys is added or changed, while the Minor revision will be + * incremented when only the set of Key-values is increased. + */ +struct KeyHeader{ + pinfo_t hdr_version; /* GeoTIFF Version */ + pinfo_t hdr_rev_major; /* GeoKey Major Revision # */ + pinfo_t hdr_rev_minor; /* GeoKey Minor Revision # */ + pinfo_t hdr_num_keys; /* Number of GeoKeys */ +}; +typedef struct KeyHeader KeyHeader; + +/* + * This structure holds temporary data while reading or writing + * the tags. + */ +struct TempKeyData { + char *tk_asciiParams; + int tk_asciiParamsLength; + int tk_asciiParamsOffset; +}; +typedef struct TempKeyData TempKeyData; + + +struct gtiff { + tiff_t* gt_tif; /* TIFF file descriptor */ + TIFFMethod gt_methods; /* TIFF i/o methods */ + int gt_flags; /* file flags */ + + pinfo_t gt_version; /* GeoTIFF Version */ + pinfo_t gt_rev_major;/* GeoKey Key Revision */ + pinfo_t gt_rev_minor;/* GeoKey Code Revision */ + + int gt_num_keys; /* number of keys */ + GeoKey* gt_keys; /* array of keys */ + int* gt_keyindex; /* index of a key, if set*/ + int gt_keymin; /* smallest key set */ + int gt_keymax; /* largest key set */ + + pinfo_t* gt_short; /* array of SHORT vals */ + double* gt_double; /* array of DOUBLE vals */ + int gt_nshorts; /* number of SHORT vals */ + int gt_ndoubles; /* number of DOUBLE vals */ +}; + +typedef enum { + FLAG_FILE_OPEN=1, + FLAG_FILE_MODIFIED=2 +} gtiff_flags; + +#define MAX_KEYINDEX 65535 /* largest possible key */ +#define MAX_KEYS 100 /* maximum keys in a file */ +#define MAX_VALUES 1000 /* maximum values in a tag */ + +#endif /* __geo_keyp_h_ */ + diff --git a/Utilities/otbgeotiff/geo_names.c b/Utilities/otbgeotiff/geo_names.c new file mode 100644 index 0000000000000000000000000000000000000000..de58ca2a635fd52ab0f1914f4645eddb154edf7d --- /dev/null +++ b/Utilities/otbgeotiff/geo_names.c @@ -0,0 +1,175 @@ +/* + * geo_names.c + * + * This encapsulates all of the value-naming mechanism of + * libgeotiff. + * + * Written By: Niles Ritter + */ + +#include "geotiffio.h" +#include "geonames.h" +#include "geo_tiffp.h" /* for tag names */ + +static KeyInfo _formatInfo[] = { + {TYPE_BYTE, "Byte"}, + {TYPE_SHORT, "Short"}, + {TYPE_LONG, "Long"}, + {TYPE_RATIONAL,"Rational"}, + {TYPE_ASCII, "Ascii"}, + {TYPE_FLOAT, "Float"}, + {TYPE_DOUBLE, "Double"}, + {TYPE_SBYTE, "SignedByte"}, + {TYPE_SSHORT, "SignedShort"}, + {TYPE_SLONG, "SignedLong"}, + {TYPE_UNKNOWN, "Unknown"}, + END_LIST +}; + +static KeyInfo _tagInfo[] = { + {GTIFF_PIXELSCALE, "ModelPixelScaleTag"}, + {GTIFF_TRANSMATRIX, "ModelTransformationTag"}, + {GTIFF_TIEPOINTS, "ModelTiepointTag"}, + /* This alias maps the Intergraph symbol to the current tag */ + {GTIFF_TRANSMATRIX, "IntergraphMatrixTag"}, + END_LIST +}; + +static char *FindName(KeyInfo *info,int key) +{ + static char errmsg[80]; + + while (info->ki_key>=0 && info->ki_key != key) info++; + + if (info->ki_key<0) + { + sprintf(errmsg,"Unknown-%d", key ); + return errmsg; + } + return info->ki_name; +} + +char *GTIFKeyName(geokey_t key) +{ + return FindName( &_keyInfo[0],key); +} + +char *GTIFTypeName(tagtype_t type) +{ + return FindName( &_formatInfo[0],type); +} + +char *GTIFTagName(int tag) +{ + return FindName( &_tagInfo[0],tag); +} + +char *GTIFValueName(geokey_t key, int value) +{ + KeyInfo *info; + + switch (key) + { + /* All codes using linear/angular/whatever units */ + case GeogLinearUnitsGeoKey: + case ProjLinearUnitsGeoKey: + case GeogAngularUnitsGeoKey: + case GeogAzimuthUnitsGeoKey: + info=_geounitsValue; break; + + /* put other key-dependent lists here */ + case GTModelTypeGeoKey: info=_modeltypeValue; break; + case GTRasterTypeGeoKey: info=_rastertypeValue; break; + case GeographicTypeGeoKey: info=_geographicValue; break; + case GeogGeodeticDatumGeoKey: info=_geodeticdatumValue; break; + case GeogEllipsoidGeoKey: info=_ellipsoidValue; break; + case GeogPrimeMeridianGeoKey: info=_primemeridianValue; break; + case ProjectedCSTypeGeoKey: info=_pcstypeValue; break; + case ProjectionGeoKey: info=_projectionValue; break; + case ProjCoordTransGeoKey: info=_coordtransValue; break; + case VerticalCSTypeGeoKey: info=_vertcstypeValue; break; + case VerticalDatumGeoKey: info=_vdatumValue; break; + + /* And if all else fails... */ + default: info = _csdefaultValue;break; + } + + return FindName( info,value); +} + +/* + * Inverse Utilities (name->code) + */ + + +static int FindCode(KeyInfo *info,char *key) +{ + while (info->ki_key>=0 && strcmp(info->ki_name,key) ) info++; + + if (info->ki_key<0) + { + /* not a registered key; might be generic code */ + if (!strncmp(key,"Unknown-",8)) + { + int code=-1; + sscanf(key,"Unknown-%d",&code); + return code; + } + else return -1; + } + return info->ki_key; +} + +int GTIFKeyCode(char *key) +{ + return FindCode( &_keyInfo[0],key); +} + +int GTIFTypeCode(char *type) +{ + return FindCode( &_formatInfo[0],type); +} + +int GTIFTagCode(char *tag) +{ + return FindCode( &_tagInfo[0],tag); +} + + +/* + * The key must be determined with GTIFKeyCode() before + * the name can be encoded. + */ +int GTIFValueCode(geokey_t key, char *name) +{ + KeyInfo *info; + + switch (key) + { + /* All codes using linear/angular/whatever units */ + case GeogLinearUnitsGeoKey: + case ProjLinearUnitsGeoKey: + case GeogAngularUnitsGeoKey: + case GeogAzimuthUnitsGeoKey: + info=_geounitsValue; break; + + /* put other key-dependent lists here */ + case GTModelTypeGeoKey: info=_modeltypeValue; break; + case GTRasterTypeGeoKey: info=_rastertypeValue; break; + case GeographicTypeGeoKey: info=_geographicValue; break; + case GeogGeodeticDatumGeoKey: info=_geodeticdatumValue; break; + case GeogEllipsoidGeoKey: info=_ellipsoidValue; break; + case GeogPrimeMeridianGeoKey: info=_primemeridianValue; break; + case ProjectedCSTypeGeoKey: info=_pcstypeValue; break; + case ProjectionGeoKey: info=_projectionValue; break; + case ProjCoordTransGeoKey: info=_coordtransValue; break; + case VerticalCSTypeGeoKey: info=_vertcstypeValue; break; + case VerticalDatumGeoKey: info=_vdatumValue; break; + + /* And if all else fails... */ + default: info = _csdefaultValue;break; + } + + return FindCode( info,name); +} + diff --git a/Utilities/otbgeotiff/geo_new.c b/Utilities/otbgeotiff/geo_new.c new file mode 100644 index 0000000000000000000000000000000000000000..2e53b7fe37ce87da7a1f184d6522c4cddf3c3e3c --- /dev/null +++ b/Utilities/otbgeotiff/geo_new.c @@ -0,0 +1,255 @@ +/********************************************************************** + * + * geo_new.c -- Public routines for GEOTIFF GeoKey access. + * + * Written By: Niles D. Ritter. + * + * copyright (c) 1995 Niles D. Ritter + * + * Permission granted to use this software, so long as this copyright + * notice accompanies any products derived therefrom. + * + * 20 June, 1995 Niles D. Ritter New + * 7 July, 1995 Greg Martin Fix index + * + * $Log: geo_new.c,v $ + * Revision 1.12 2006/06/26 20:03:37 fwarmerdam + * If the ascii parameters list is too short for the declared size + * of an ascii parameter, but it doesn't start off the end of the + * available string then just trim the length. This is to make the + * ESRI sample data file 34105h2.tif work properly. I wish we had + * a way of issuing warnings! + * + * Revision 1.11 2004/04/27 21:32:08 warmerda + * Allow GTIFNew(NULL) to work + * + * Revision 1.10 2003/09/02 13:52:17 warmerda + * various hacks to support improperly terminated asciiparms + * + * Revision 1.9 2003/06/19 20:04:11 warmerda + * fix memory underwrite if ascii parameter string is zero length + * + * Revision 1.8 2003/06/05 14:20:45 warmerda + * cosmetic formatting changes + * + **********************************************************************/ + +#include "geotiffio.h" /* public interface */ +#include "geo_tiffp.h" /* external TIFF interface */ +#include "geo_keyp.h" /* private interface */ + +/* private local routines */ +static int ReadKey(GTIF* gt, TempKeyData* tempData, + KeyEntry* entptr, GeoKey* keyptr); + + +/********************************************************************** + * + * Public Routines + * + **********************************************************************/ + + +/** + * Given an open TIFF file, look for GTIF keys and + * values and return GTIF structure. + +This function creates a GeoTIFF information interpretation handle +(GTIF *) based on a passed in TIFF handle originally from +XTIFFOpen(). Even though the argument +(<b>tif</b>) is shown as type <tt>void *</tt>, it is really normally +of type <tt>TIFF *</tt>.<p> + +The returned GTIF handle can be used to read or write GeoTIFF tags +using the various GTIF functions. The handle should be destroyed using +GTIFFree() before the file is closed with TIFFClose().<p> + +If the file accessed has no GeoTIFF keys, an valid (but empty) GTIF is +still returned. GTIFNew() is used both for existing files being read, and +for new TIFF files that will have GeoTIFF tags written to them.<p> + + */ + +GTIF* GTIFNew(void *tif) +{ + GTIF* gt=(GTIF*)0; + int count,bufcount,index; + GeoKey *keyptr; + pinfo_t *data; + KeyEntry *entptr; + KeyHeader *header; + TempKeyData tempData; + + gt = (GTIF*)_GTIFcalloc( sizeof(GTIF)); + if (!gt) goto failure; + + /* install TIFF file and I/O methods */ + gt->gt_tif = (tiff_t *)tif; + _GTIFSetDefaultTIFF(>->gt_methods); + + tempData.tk_asciiParams = 0; + tempData.tk_asciiParamsLength = 0; + tempData.tk_asciiParamsOffset = 0; + + /* since this is an array, GTIF will allocate the memory */ + if ( tif == NULL + || !(gt->gt_methods.get)(tif, GTIFF_GEOKEYDIRECTORY, >->gt_nshorts, &data )) + { + /* No ProjectionInfo, create a blank one */ + data=(pinfo_t*)_GTIFcalloc((4+MAX_VALUES)*sizeof(pinfo_t)); + if (!data) goto failure; + header = (KeyHeader *)data; + header->hdr_version = GvCurrentVersion; + header->hdr_rev_major = GvCurrentRevision; + header->hdr_rev_minor = GvCurrentMinorRev; + gt->gt_nshorts=sizeof(KeyHeader)/sizeof(pinfo_t); + } + gt->gt_short = data; + header = (KeyHeader *)data; + + if (header->hdr_version > GvCurrentVersion) goto failure; + if (header->hdr_rev_major > GvCurrentRevision) + { + /* issue warning */ + } + + /* If we got here, then the geokey can be parsed */ + count = header->hdr_num_keys; + gt->gt_num_keys = count; + gt->gt_version = header->hdr_version; + gt->gt_rev_major = header->hdr_rev_major; + gt->gt_rev_minor = header->hdr_rev_minor; + + bufcount = count+MAX_KEYS; /* allow for expansion */ + + /* Get the PARAMS Tags, if any */ + if (tif == NULL + || !(gt->gt_methods.get)(tif, GTIFF_DOUBLEPARAMS, + >->gt_ndoubles, >->gt_double )) + { + gt->gt_double=(double*)_GTIFcalloc(MAX_VALUES*sizeof(double)); + if (!gt->gt_double) goto failure; + } + if ( tif == NULL + || !(gt->gt_methods.get)(tif, GTIFF_ASCIIPARAMS, + &tempData.tk_asciiParamsLength, + &tempData.tk_asciiParams )) + { + tempData.tk_asciiParams = 0; + tempData.tk_asciiParamsLength = 0; + } + else + { + /* last NULL doesn't count; "|" used for delimiter */ + --tempData.tk_asciiParamsLength; + } + + /* allocate space for GeoKey array and its index */ + gt->gt_keys = (GeoKey *)_GTIFcalloc( sizeof(GeoKey)*bufcount); + if (!gt->gt_keys) goto failure; + gt->gt_keyindex = (int *)_GTIFcalloc( sizeof(int)*(MAX_KEYINDEX+1)); + if (!gt->gt_keyindex) goto failure; + + /* Loop to get all GeoKeys */ + entptr = ((KeyEntry *)data) + 1; + keyptr = gt->gt_keys; + gt->gt_keymin = MAX_KEYINDEX; + gt->gt_keymax = 0; + for (index=1; index<=count; index++,entptr++) + { + if (!ReadKey(gt, &tempData, entptr, ++keyptr)) + goto failure; + + /* Set up the index (start at 1, since 0=unset) */ + gt->gt_keyindex[entptr->ent_key] = index; + } + + if( tempData.tk_asciiParams != NULL ) + _GTIFFree( tempData.tk_asciiParams ); + + return gt; + + failure: + /* Notify of error */ + GTIFFree (gt); + return (GTIF *)0; +} + +/********************************************************************** + * + * Private Routines + * + **********************************************************************/ + +/* + * Given KeyEntry, read in the GeoKey value location and set up + * the Key structure, returning 0 if failure. + */ + +static int ReadKey(GTIF* gt, TempKeyData* tempData, + KeyEntry* entptr, GeoKey* keyptr) +{ + int offset,count; + + keyptr->gk_key = entptr->ent_key; + keyptr->gk_count = entptr->ent_count; + count = entptr->ent_count; + offset = entptr->ent_val_offset; + if (gt->gt_keymin > keyptr->gk_key) gt->gt_keymin=keyptr->gk_key; + if (gt->gt_keymax < keyptr->gk_key) gt->gt_keymax=keyptr->gk_key; + + if (entptr->ent_location) + keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,entptr->ent_location); + else + keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,GTIFF_GEOKEYDIRECTORY); + + switch (entptr->ent_location) + { + case GTIFF_LOCAL: + /* store value into data value */ + *(pinfo_t *)(&keyptr->gk_data) = entptr->ent_val_offset; + break; + case GTIFF_GEOKEYDIRECTORY: + keyptr->gk_data = (char *)(gt->gt_short+offset); + if (gt->gt_nshorts < offset+count) + gt->gt_nshorts = offset+count; + break; + case GTIFF_DOUBLEPARAMS: + keyptr->gk_data = (char *)(gt->gt_double+offset); + if (gt->gt_ndoubles < offset+count) + gt->gt_ndoubles = offset+count; + break; + case GTIFF_ASCIIPARAMS: + if( offset + count == tempData->tk_asciiParamsLength + 1 + && count > 0 ) + { + /* some vendors seem to feel they should not use the + terminating '|' char, but do include a terminating '\0' + which we lose in the low level reading code. + If this is the case, drop the extra character */ + count--; + } + else if (offset < tempData->tk_asciiParamsLength + && offset + count > tempData->tk_asciiParamsLength ) + { + count = tempData->tk_asciiParamsLength - offset; + /* issue warning... if we could */ + } + else if (offset + count > tempData->tk_asciiParamsLength) + return (0); + + keyptr->gk_data = (char *) _GTIFcalloc (MAX(1,count+1)); + _GTIFmemcpy (keyptr->gk_data, + tempData->tk_asciiParams + offset, count); + if( keyptr->gk_data[MAX(0,count-1)] == '|' ) + keyptr->gk_data[MAX(0,count-1)] = '\0'; + else + keyptr->gk_data[MAX(0,count)] = '\0'; + break; + default: + return 0; /* failure */ + } + keyptr->gk_size = _gtiff_size[keyptr->gk_type]; + + return 1; /* success */ +} diff --git a/Utilities/otbgeotiff/geo_normalize.c b/Utilities/otbgeotiff/geo_normalize.c new file mode 100644 index 0000000000000000000000000000000000000000..214ae79c9a105e55432650f7b47986ceb05e31c7 --- /dev/null +++ b/Utilities/otbgeotiff/geo_normalize.c @@ -0,0 +1,2468 @@ +/****************************************************************************** + * $Id: geo_normalize.c,v 1.50 2007/07/28 13:55:21 fwarmerdam Exp $ + * + * Project: libgeotiff + * Purpose: Code to normalize PCS and other composite codes in a GeoTIFF file. + * Author: Frank Warmerdam, warmerda@home.com + * + ****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: geo_normalize.c,v $ + * Revision 1.50 2007/07/28 13:55:21 fwarmerdam + * Fix name for GCS_WGS_72 per gdal bug #1715. + * + * Revision 1.49 2007/07/20 18:10:41 fwarmerdam + * Pre-search pcs.override.csv and gcs.override.csv. + * + * Revision 1.48 2007/06/06 02:17:04 fwarmerdam + * added builtin known values for foot and us survey foot + * + * Revision 1.47 2007/03/13 18:04:33 fwarmerdam + * added new zealand map grid support per bug 1519 + * + * Revision 1.46 2006/04/11 19:25:06 fwarmerdam + * Be careful about falling back to gdal_datum.csv as it can interfere + * with incode datum.csv support. + * + * Revision 1.45 2005/03/15 16:01:18 fwarmerdam + * zero inv flattening interpreted as sphere + * + * Revision 1.44 2005/03/04 04:32:37 fwarmerdam + * added cylindricalequalarea support + * + * Revision 1.43 2005/03/04 04:02:40 fwarmerdam + * Fixed initialization of dfStdParallel2 for AEA and EC. + * + * Revision 1.42 2005/02/17 01:21:38 fwarmerdam + * fixed handling of ProjFalseOrigin{Easting,Northing}GeoKey + * + * Revision 1.41 2004/12/01 22:06:42 fwarmerdam + * bug 698: GTIFGetGCSInfo should not fail on missing pm if pm info not req. + * + * Revision 1.40 2004/07/09 17:27:37 warmerda + * Added 9122 as an alias for simple degrees. + * + * Revision 1.39 2004/06/07 12:57:13 warmerda + * fallback to using gdal_datum.csv if datum.csv not found + * + * Revision 1.38 2004/03/19 12:20:40 dron + * Initialize projection parameters in GTIFFetchProjParms() before using. + * + * Revision 1.37 2003/07/08 17:31:30 warmerda + * cleanup various warnings + * + * Revision 1.36 2003/01/28 18:31:58 warmerda + * Default dfInDegrees in GTIFAngleToDD(). + * + * Revision 1.35 2003/01/15 04:39:16 warmerda + * Added GTIFDeaccessCSV + * + * Revision 1.34 2003/01/15 03:37:40 warmerda + * added GTIFFreeMemory() + * + * Revision 1.33 2002/12/05 19:21:01 warmerda + * fixed dfInDegrees to actually be in degrees, not radians! + * + * Revision 1.32 2002/11/30 16:01:11 warmerda + * fixed some problems in GTIFGetUOMAngleInfo + * + * Revision 1.31 2002/11/30 15:44:35 warmerda + * fixed GetCTParms EPSG code mappings + * + * Revision 1.30 2002/11/28 22:27:42 warmerda + * preliminary upgrade to EPSG 6.2.2 tables + * + * Revision 1.29 2002/06/19 03:51:15 warmerda + * migrated cpl_csv.h into cpl_serv.h + * + * Revision 1.28 2002/01/03 21:28:25 warmerda + * call CSVDeaccess(NULL) at end of GTIFPrintDefn() + * + * Revision 1.27 2001/04/17 13:41:10 warmerda + * fix memory leaks in GTIFPrintDefn() + * + * Revision 1.26 2001/04/17 13:23:07 warmerda + * added support for reading custom ellipsoid definitions + * + * Revision 1.25 2001/03/05 04:55:26 warmerda + * CVSDeaccess at end of GTIFGetDefn to avoid file leak + * + * Revision 1.24 2001/03/05 03:26:29 warmerda + * fixed memory leaks in GTIFPrintDefn() + * + * Revision 1.23 2001/02/23 13:49:48 warmerda + * Fixed GTIFPrintDefn() to use fprintf( fp ), instead of printf(). + * + * Revision 1.22 2000/10/13 14:30:57 warmerda + * fixed LCC parm order when parameters read directly from geotiff file + * + * Revision 1.21 2000/09/15 19:30:14 warmerda + * report units of linear proj parms + * + * Revision 1.20 2000/09/15 18:21:07 warmerda + * Fixed order of parameters for LCC 2SP. When parameters + * were read from EPSG CSV files the standard parallels and origin + * were mixed up. This affects alot of state plane zones! + * + * Revision 1.19 2000/06/09 14:05:43 warmerda + * added default knowledge of NAD27/NAD83/WGS72/WGS84 + * + * Revision 1.18 1999/12/10 21:28:12 warmerda + * fixed Stereographic to look for ProjCenterLat/Long + * + * Revision 1.17 1999/12/10 20:06:58 warmerda + * fixed up scale geokey used for a couple of projections + * + * Revision 1.16 1999/12/10 19:50:21 warmerda + * Added EquidistantConic support, fixed return of StdParallel2GeoKey for + * LCC2, and Albers. + * + * Revision 1.15 1999/12/10 19:39:26 warmerda + * Fixed bug setting the false northing for files with + * ProjCenterNorthingGeoKey set in GTIFGetDefn(). + * + * Revision 1.14 1999/09/17 14:58:37 warmerda + * Added ProjRectifiedGridAngleGeoKey(3096) and support for it's + * use with Oblique Mercator in geo_normalize.c. + * + * Revision 1.13 1999/09/17 00:55:26 warmerda + * added GTIFGetUOMAngleInfo(), and UOMAngle in GTIFDefn + * + * Revision 1.12 1999/09/15 18:51:31 warmerda + * Map 9808 to TM South Oriented, not TM Modified Alaska. + * + * Revision 1.11 1999/09/15 16:44:06 warmerda + * Change meter to metre to match EPSG database in GTIFGetUOMLengthInfo() + * shortcut. + * + * Revision 1.10 1999/09/15 16:35:15 warmerda + * Fixed the fractions of second handling properly in GTIFAngleStringToDD(). + * + * Revision 1.9 1999/09/15 14:24:17 warmerda + * Fixed serious bug in geo_normalize.c with translation of + * DD.MMSSsss values. Return value was seriously off if any + * fraction of a second was included in the string. + * + * Revision 1.8 1999/07/13 03:12:52 warmerda + * Make scale a parameter of CT_Stereographic. + * + * Revision 1.7 1999/05/04 03:13:22 warmerda + * fixed a serious bug in parsing DMSmmss.sss values, and a bug in forming DMS strings + * + * Revision 1.6 1999/05/03 17:50:31 warmerda + * avoid warnings on IRIX + * + * Revision 1.5 1999/04/28 20:04:51 warmerda + * Added doxygen style documentation. + * Use GTIFPCSToMapSys() and related functions to partially normalize + * projections when we don't have the CSV files. + * + * Revision 1.4 1999/03/18 21:34:59 geotiff + * added GTIFDecToDMS + * + * Revision 1.3 1999/03/17 19:53:15 geotiff + * sys includes moved to cpl_serv.h + * + * Revision 1.2 1999/03/10 18:24:06 geotiff + * corrected to use int' + * + * Revision 1.1 1999/03/09 15:57:04 geotiff + * New + * + * Revision 1.4 1999/03/03 02:29:38 warmerda + * Define PI if not already defined. + * + * Revision 1.3 1999/03/02 21:10:57 warmerda + * added lots of projections + * + * Revision 1.2 1999/02/24 16:24:15 warmerda + * Continuing to evolve + * + * Revision 1.1 1999/02/22 18:51:08 warmerda + * New + * + */ + +#include "cpl_serv.h" +#include "geo_tiffp.h" +#include "geovalues.h" +#include "geo_normalize.h" + +#ifndef KvUserDefined +# define KvUserDefined 32767 +#endif + +#ifndef PI +# define PI 3.14159265358979323846 +#endif + +/* EPSG Codes for projection parameters. Unfortunately, these bear no + relationship to the GeoTIFF codes even though the names are so similar. */ + +#define EPSGNatOriginLat 8801 +#define EPSGNatOriginLong 8802 +#define EPSGNatOriginScaleFactor 8805 +#define EPSGFalseEasting 8806 +#define EPSGFalseNorthing 8807 +#define EPSGProjCenterLat 8811 +#define EPSGProjCenterLong 8812 +#define EPSGAzimuth 8813 +#define EPSGAngleRectifiedToSkewedGrid 8814 +#define EPSGInitialLineScaleFactor 8815 +#define EPSGProjCenterEasting 8816 +#define EPSGProjCenterNorthing 8817 +#define EPSGPseudoStdParallelLat 8818 +#define EPSGPseudoStdParallelScaleFactor 8819 +#define EPSGFalseOriginLat 8821 +#define EPSGFalseOriginLong 8822 +#define EPSGStdParallel1Lat 8823 +#define EPSGStdParallel2Lat 8824 +#define EPSGFalseOriginEasting 8826 +#define EPSGFalseOriginNorthing 8827 +#define EPSGSphericalOriginLat 8828 +#define EPSGSphericalOriginLong 8829 +#define EPSGInitialLongitude 8830 +#define EPSGZoneWidth 8831 + +/************************************************************************/ +/* GTIFGetPCSInfo() */ +/************************************************************************/ + +int GTIFGetPCSInfo( int nPCSCode, char **ppszEPSGName, + short *pnProjOp, short *pnUOMLengthCode, + short *pnGeogCS ) + +{ + char **papszRecord; + char szSearchKey[24]; + const char *pszFilename; + +/* -------------------------------------------------------------------- */ +/* Search the pcs.override table for this PCS. */ +/* -------------------------------------------------------------------- */ + pszFilename = CSVFilename( "pcs.override.csv" ); + sprintf( szSearchKey, "%d", nPCSCode ); + papszRecord = CSVScanFileByName( pszFilename, "COORD_REF_SYS_CODE", + szSearchKey, CC_Integer ); + +/* -------------------------------------------------------------------- */ +/* If not found, search the EPSG PCS database. */ +/* -------------------------------------------------------------------- */ + if( papszRecord == NULL ) + { + pszFilename = CSVFilename( "pcs.csv" ); + + sprintf( szSearchKey, "%d", nPCSCode ); + papszRecord = CSVScanFileByName( pszFilename, "COORD_REF_SYS_CODE", + szSearchKey, CC_Integer ); + + if( papszRecord == NULL ) + return FALSE; + } + +/* -------------------------------------------------------------------- */ +/* Get the name, if requested. */ +/* -------------------------------------------------------------------- */ + if( ppszEPSGName != NULL ) + { + *ppszEPSGName = + CPLStrdup( CSLGetField( papszRecord, + CSVGetFileFieldId(pszFilename, + "COORD_REF_SYS_NAME") )); + } + +/* -------------------------------------------------------------------- */ +/* Get the UOM Length code, if requested. */ +/* -------------------------------------------------------------------- */ + if( pnUOMLengthCode != NULL ) + { + const char *pszValue; + + pszValue = + CSLGetField( papszRecord, + CSVGetFileFieldId(pszFilename,"UOM_CODE")); + if( atoi(pszValue) > 0 ) + *pnUOMLengthCode = (short) atoi(pszValue); + else + *pnUOMLengthCode = KvUserDefined; + } + +/* -------------------------------------------------------------------- */ +/* Get the UOM Length code, if requested. */ +/* -------------------------------------------------------------------- */ + if( pnProjOp != NULL ) + { + const char *pszValue; + + pszValue = + CSLGetField( papszRecord, + CSVGetFileFieldId(pszFilename,"COORD_OP_CODE")); + if( atoi(pszValue) > 0 ) + *pnProjOp = (short) atoi(pszValue); + else + *pnUOMLengthCode = KvUserDefined; + } + +/* -------------------------------------------------------------------- */ +/* Get the GeogCS (Datum with PM) code, if requested. */ +/* -------------------------------------------------------------------- */ + if( pnGeogCS != NULL ) + { + const char *pszValue; + + pszValue = + CSLGetField( papszRecord, + CSVGetFileFieldId(pszFilename,"SOURCE_GEOGCRS_CODE")); + if( atoi(pszValue) > 0 ) + *pnGeogCS = (short) atoi(pszValue); + else + *pnGeogCS = KvUserDefined; + } + + return TRUE; +} + +/************************************************************************/ +/* GTIFAngleToDD() */ +/* */ +/* Convert a numeric angle to decimal degress. */ +/************************************************************************/ + +double GTIFAngleToDD( double dfAngle, int nUOMAngle ) + +{ + if( nUOMAngle == 9110 ) /* DDD.MMSSsss */ + { + char szAngleString[32]; + + sprintf( szAngleString, "%12.7f", dfAngle ); + dfAngle = GTIFAngleStringToDD( szAngleString, nUOMAngle ); + } + else + { + double dfInDegrees = 1.0; + + GTIFGetUOMAngleInfo( nUOMAngle, NULL, &dfInDegrees ); + dfAngle = dfAngle * dfInDegrees; + } + + return( dfAngle ); +} + +/************************************************************************/ +/* GTIFAngleStringToDD() */ +/* */ +/* Convert an angle in the specified units to decimal degrees. */ +/************************************************************************/ + +double GTIFAngleStringToDD( const char * pszAngle, int nUOMAngle ) + +{ + double dfAngle; + + if( nUOMAngle == 9110 ) /* DDD.MMSSsss */ + { + char *pszDecimal; + + dfAngle = ABS(atoi(pszAngle)); + pszDecimal = strchr(pszAngle,'.'); + if( pszDecimal != NULL && strlen(pszDecimal) > 1 ) + { + char szMinutes[3]; + char szSeconds[64]; + + szMinutes[0] = pszDecimal[1]; + if( pszDecimal[2] >= '0' && pszDecimal[2] <= '9' ) + szMinutes[1] = pszDecimal[2]; + else + szMinutes[1] = '0'; + + szMinutes[2] = '\0'; + dfAngle += atoi(szMinutes) / 60.0; + + if( strlen(pszDecimal) > 3 ) + { + szSeconds[0] = pszDecimal[3]; + if( pszDecimal[4] >= '0' && pszDecimal[4] <= '9' ) + { + szSeconds[1] = pszDecimal[4]; + szSeconds[2] = '.'; + strcpy( szSeconds+3, pszDecimal + 5 ); + } + else + { + szSeconds[1] = '0'; + szSeconds[2] = '\0'; + } + dfAngle += atof(szSeconds) / 3600.0; + } + } + + if( pszAngle[0] == '-' ) + dfAngle *= -1; + } + else if( nUOMAngle == 9105 || nUOMAngle == 9106 ) /* grad */ + { + dfAngle = 180 * (atof(pszAngle ) / 200); + } + else if( nUOMAngle == 9101 ) /* radians */ + { + dfAngle = 180 * (atof(pszAngle ) / PI); + } + else if( nUOMAngle == 9103 ) /* arc-minute */ + { + dfAngle = atof(pszAngle) / 60; + } + else if( nUOMAngle == 9104 ) /* arc-second */ + { + dfAngle = atof(pszAngle) / 3600; + } + else /* decimal degrees ... some cases missing but seeminly never used */ + { + CPLAssert( nUOMAngle == 9102 || nUOMAngle == KvUserDefined + || nUOMAngle == 0 ); + + dfAngle = atof(pszAngle ); + } + + return( dfAngle ); +} + +/************************************************************************/ +/* GTIFGetGCSInfo() */ +/* */ +/* Fetch the datum, and prime meridian related to a particular */ +/* GCS. */ +/************************************************************************/ + +int GTIFGetGCSInfo( int nGCSCode, char ** ppszName, + short * pnDatum, short * pnPM, short *pnUOMAngle ) + +{ + char szSearchKey[24]; + int nDatum, nPM, nUOMAngle; + const char *pszFilename; + +/* -------------------------------------------------------------------- */ +/* Search the database for the corresponding datum code. */ +/* -------------------------------------------------------------------- */ + pszFilename = CSVFilename("gcs.override.csv"); + sprintf( szSearchKey, "%d", nGCSCode ); + nDatum = atoi(CSVGetField( pszFilename, + "COORD_REF_SYS_CODE", szSearchKey, + CC_Integer, "DATUM_CODE" ) ); + + if( nDatum < 1 ) + { + pszFilename = CSVFilename("gcs.csv"); + sprintf( szSearchKey, "%d", nGCSCode ); + nDatum = atoi(CSVGetField( pszFilename, + "COORD_REF_SYS_CODE", szSearchKey, + CC_Integer, "DATUM_CODE" ) ); + } + +/* -------------------------------------------------------------------- */ +/* Handle some "well known" GCS codes directly if the table */ +/* wasn't found. */ +/* -------------------------------------------------------------------- */ + if( nDatum < 1 ) + { + const char * pszName = NULL; + nPM = PM_Greenwich; + nUOMAngle = Angular_DMS_Hemisphere; + if( nGCSCode == GCS_NAD27 ) + { + nDatum = Datum_North_American_Datum_1927; + pszName = "NAD27"; + } + else if( nGCSCode == GCS_NAD83 ) + { + nDatum = Datum_North_American_Datum_1983; + pszName = "NAD83"; + } + else if( nGCSCode == GCS_WGS_84 ) + { + nDatum = Datum_WGS84; + pszName = "WGS 84"; + } + else if( nGCSCode == GCS_WGS_72 ) + { + nDatum = Datum_WGS72; + pszName = "WGS 72"; + } + else + return FALSE; + + if( ppszName != NULL ) + *ppszName = CPLStrdup( pszName ); + if( pnDatum != NULL ) + *pnDatum = (short) nDatum; + if( pnPM != NULL ) + *pnPM = (short) nPM; + if( pnUOMAngle != NULL ) + *pnUOMAngle = (short) nUOMAngle; + + return TRUE; + } + + if( pnDatum != NULL ) + *pnDatum = (short) nDatum; + +/* -------------------------------------------------------------------- */ +/* Get the PM. */ +/* -------------------------------------------------------------------- */ + if( pnPM != NULL ) + { + nPM = atoi(CSVGetField( pszFilename, + "COORD_REF_SYS_CODE", szSearchKey, CC_Integer, + "PRIME_MERIDIAN_CODE" ) ); + + if( nPM < 1 ) + return FALSE; + + *pnPM = (short) nPM; + } + +/* -------------------------------------------------------------------- */ +/* Get the angular units. */ +/* -------------------------------------------------------------------- */ + nUOMAngle = atoi(CSVGetField( pszFilename, + "COORD_REF_SYS_CODE",szSearchKey, CC_Integer, + "UOM_CODE" ) ); + + if( nUOMAngle < 1 ) + return FALSE; + + if( pnUOMAngle != NULL ) + *pnUOMAngle = (short) nUOMAngle; + +/* -------------------------------------------------------------------- */ +/* Get the name, if requested. */ +/* -------------------------------------------------------------------- */ + if( ppszName != NULL ) + *ppszName = + CPLStrdup(CSVGetField( pszFilename, + "COORD_REF_SYS_CODE",szSearchKey,CC_Integer, + "COORD_REF_SYS_NAME" )); + + return( TRUE ); +} + +/************************************************************************/ +/* GTIFGetEllipsoidInfo() */ +/* */ +/* Fetch info about an ellipsoid. Axes are always returned in */ +/* meters. SemiMajor computed based on inverse flattening */ +/* where that is provided. */ +/************************************************************************/ + +int GTIFGetEllipsoidInfo( int nEllipseCode, char ** ppszName, + double * pdfSemiMajor, double * pdfSemiMinor ) + +{ + char szSearchKey[24]; + double dfSemiMajor, dfToMeters = 1.0; + int nUOMLength; + +/* -------------------------------------------------------------------- */ +/* Get the semi major axis. */ +/* -------------------------------------------------------------------- */ + sprintf( szSearchKey, "%d", nEllipseCode ); + + dfSemiMajor = + atof(CSVGetField( CSVFilename("ellipsoid.csv" ), + "ELLIPSOID_CODE", szSearchKey, CC_Integer, + "SEMI_MAJOR_AXIS" ) ); + +/* -------------------------------------------------------------------- */ +/* Try some well known ellipsoids. */ +/* -------------------------------------------------------------------- */ + if( dfSemiMajor == 0.0 ) + { + double dfInvFlattening, dfSemiMinor; + const char *pszName = NULL; + + if( nEllipseCode == Ellipse_Clarke_1866 ) + { + pszName = "Clarke 1866"; + dfSemiMajor = 6378206.4; + dfSemiMinor = 6356583.8; + dfInvFlattening = 0.0; + } + else if( nEllipseCode == Ellipse_GRS_1980 ) + { + pszName = "GRS 1980"; + dfSemiMajor = 6378137.0; + dfSemiMinor = 0.0; + dfInvFlattening = 298.257222101; + } + else if( nEllipseCode == Ellipse_WGS_84 ) + { + pszName = "WGS 84"; + dfSemiMajor = 6378137.0; + dfSemiMinor = 0.0; + dfInvFlattening = 298.257223563; + } + else if( nEllipseCode == 7043 ) + { + pszName = "WGS 72"; + dfSemiMajor = 6378135.0; + dfSemiMinor = 0.0; + dfInvFlattening = 298.26; + } + else + return FALSE; + + if( dfSemiMinor == 0.0 ) + dfSemiMinor = dfSemiMajor * (1 - 1.0/dfInvFlattening); + + if( pdfSemiMinor != NULL ) + *pdfSemiMinor = dfSemiMinor; + if( pdfSemiMajor != NULL ) + *pdfSemiMajor = dfSemiMajor; + if( ppszName != NULL ) + *ppszName = CPLStrdup( pszName ); + + return TRUE; + } + +/* -------------------------------------------------------------------- */ +/* Get the translation factor into meters. */ +/* -------------------------------------------------------------------- */ + nUOMLength = atoi(CSVGetField( CSVFilename("ellipsoid.csv" ), + "ELLIPSOID_CODE", szSearchKey, CC_Integer, + "UOM_CODE" )); + GTIFGetUOMLengthInfo( nUOMLength, NULL, &dfToMeters ); + + dfSemiMajor *= dfToMeters; + + if( pdfSemiMajor != NULL ) + *pdfSemiMajor = dfSemiMajor; + +/* -------------------------------------------------------------------- */ +/* Get the semi-minor if requested. If the Semi-minor axis */ +/* isn't available, compute it based on the inverse flattening. */ +/* -------------------------------------------------------------------- */ + if( pdfSemiMinor != NULL ) + { + *pdfSemiMinor = + atof(CSVGetField( CSVFilename("ellipsoid.csv" ), + "ELLIPSOID_CODE", szSearchKey, CC_Integer, + "SEMI_MINOR_AXIS" )) * dfToMeters; + + if( *pdfSemiMinor == 0.0 ) + { + double dfInvFlattening; + + dfInvFlattening = + atof(CSVGetField( CSVFilename("ellipsoid.csv" ), + "ELLIPSOID_CODE", szSearchKey, CC_Integer, + "INV_FLATTENING" )); + *pdfSemiMinor = dfSemiMajor * (1 - 1.0/dfInvFlattening); + } + } + +/* -------------------------------------------------------------------- */ +/* Get the name, if requested. */ +/* -------------------------------------------------------------------- */ + if( ppszName != NULL ) + *ppszName = + CPLStrdup(CSVGetField( CSVFilename("ellipsoid.csv" ), + "ELLIPSOID_CODE", szSearchKey, CC_Integer, + "ELLIPSOID_NAME" )); + + return( TRUE ); +} + +/************************************************************************/ +/* GTIFGetPMInfo() */ +/* */ +/* Get the offset between a given prime meridian and Greenwich */ +/* in degrees. */ +/************************************************************************/ + +int GTIFGetPMInfo( int nPMCode, char ** ppszName, double *pdfOffset ) + +{ + char szSearchKey[24]; + int nUOMAngle; + const char *pszFilename = CSVFilename("prime_meridian.csv"); + +/* -------------------------------------------------------------------- */ +/* Use a special short cut for Greenwich, since it is so common. */ +/* -------------------------------------------------------------------- */ + if( nPMCode == PM_Greenwich ) + { + if( pdfOffset != NULL ) + *pdfOffset = 0.0; + if( ppszName != NULL ) + *ppszName = CPLStrdup( "Greenwich" ); + return TRUE; + } + +/* -------------------------------------------------------------------- */ +/* Search the database for the corresponding datum code. */ +/* -------------------------------------------------------------------- */ + sprintf( szSearchKey, "%d", nPMCode ); + + nUOMAngle = + atoi(CSVGetField( pszFilename, + "PRIME_MERIDIAN_CODE", szSearchKey, CC_Integer, + "UOM_CODE" ) ); + if( nUOMAngle < 1 ) + return FALSE; + +/* -------------------------------------------------------------------- */ +/* Get the PM offset. */ +/* -------------------------------------------------------------------- */ + if( pdfOffset != NULL ) + { + *pdfOffset = + GTIFAngleStringToDD( + CSVGetField( pszFilename, + "PRIME_MERIDIAN_CODE", szSearchKey, CC_Integer, + "GREENWICH_LONGITUDE" ), + nUOMAngle ); + } + +/* -------------------------------------------------------------------- */ +/* Get the name, if requested. */ +/* -------------------------------------------------------------------- */ + if( ppszName != NULL ) + *ppszName = + CPLStrdup( + CSVGetField( pszFilename, + "PRIME_MERIDIAN_CODE", szSearchKey, CC_Integer, + "PRIME_MERIDIAN_NAME" )); + + return( TRUE ); +} + +/************************************************************************/ +/* GTIFGetDatumInfo() */ +/* */ +/* Fetch the ellipsoid, and name for a datum. */ +/************************************************************************/ + +int GTIFGetDatumInfo( int nDatumCode, char ** ppszName, short * pnEllipsoid ) + +{ + char szSearchKey[24]; + int nEllipsoid; + const char *pszFilename = CSVFilename( "datum.csv" ); + FILE *fp; + +/* -------------------------------------------------------------------- */ +/* If we can't find datum.csv then gdal_datum.csv is an */ +/* acceptable fallback. Mostly this is for GDAL. */ +/* -------------------------------------------------------------------- */ + if( (fp = VSIFOpen(pszFilename,"r")) == NULL ) + { + if( (fp = VSIFOpen(CSVFilename("gdal_datum.csv"), "r")) != NULL ) + { + pszFilename = CSVFilename( "gdal_datum.csv" ); + VSIFClose( fp ); + } + } + else + VSIFClose( fp ); + +/* -------------------------------------------------------------------- */ +/* Search the database for the corresponding datum code. */ +/* -------------------------------------------------------------------- */ + sprintf( szSearchKey, "%d", nDatumCode ); + + nEllipsoid = atoi(CSVGetField( pszFilename, + "DATUM_CODE", szSearchKey, CC_Integer, + "ELLIPSOID_CODE" ) ); + + if( pnEllipsoid != NULL ) + *pnEllipsoid = (short) nEllipsoid; + +/* -------------------------------------------------------------------- */ +/* Handle a few built-in datums. */ +/* -------------------------------------------------------------------- */ + if( nEllipsoid < 1 ) + { + const char *pszName = NULL; + + if( nDatumCode == Datum_North_American_Datum_1927 ) + { + nEllipsoid = Ellipse_Clarke_1866; + pszName = "North American Datum 1927"; + } + else if( nDatumCode == Datum_North_American_Datum_1983 ) + { + nEllipsoid = Ellipse_GRS_1980; + pszName = "North American Datum 1983"; + } + else if( nDatumCode == Datum_WGS84 ) + { + nEllipsoid = Ellipse_WGS_84; + pszName = "World Geodetic System 1984"; + } + else if( nDatumCode == Datum_WGS72 ) + { + nEllipsoid = 7043; /* WGS7 */ + pszName = "World Geodetic System 1972"; + } + else + return FALSE; + + if( pnEllipsoid != NULL ) + *pnEllipsoid = (short) nEllipsoid; + + if( ppszName != NULL ) + *ppszName = CPLStrdup( pszName ); + + return TRUE; + } + +/* -------------------------------------------------------------------- */ +/* Get the name, if requested. */ +/* -------------------------------------------------------------------- */ + if( ppszName != NULL ) + *ppszName = + CPLStrdup(CSVGetField( pszFilename, + "DATUM_CODE", szSearchKey, CC_Integer, + "DATUM_NAME" )); + + return( TRUE ); +} + + +/************************************************************************/ +/* GTIFGetUOMLengthInfo() */ +/* */ +/* Note: This function should eventually also know how to */ +/* lookup length aliases in the UOM_LE_ALIAS table. */ +/************************************************************************/ + +int GTIFGetUOMLengthInfo( int nUOMLengthCode, + char **ppszUOMName, + double * pdfInMeters ) + +{ + char **papszUnitsRecord; + char szSearchKey[24]; + int iNameField; + const char *pszFilename; + +/* -------------------------------------------------------------------- */ +/* We short cut meter to save work and avoid failure for missing */ +/* in the most common cases. */ +/* -------------------------------------------------------------------- */ + if( nUOMLengthCode == 9001 ) + { + if( ppszUOMName != NULL ) + *ppszUOMName = CPLStrdup( "metre" ); + if( pdfInMeters != NULL ) + *pdfInMeters = 1.0; + + return TRUE; + } + + if( nUOMLengthCode == 9002 ) + { + if( ppszUOMName != NULL ) + *ppszUOMName = CPLStrdup( "foot" ); + if( pdfInMeters != NULL ) + *pdfInMeters = 0.3048; + + return TRUE; + } + + if( nUOMLengthCode == 9003 ) + { + if( ppszUOMName != NULL ) + *ppszUOMName = CPLStrdup( "US survey foot" ); + if( pdfInMeters != NULL ) + *pdfInMeters = 12.0 / 39.37; + + return TRUE; + } + +/* -------------------------------------------------------------------- */ +/* Search the units database for this unit. If we don't find */ +/* it return failure. */ +/* -------------------------------------------------------------------- */ + pszFilename = CSVFilename( "unit_of_measure.csv" ); + + sprintf( szSearchKey, "%d", nUOMLengthCode ); + papszUnitsRecord = + CSVScanFileByName( pszFilename, + "UOM_CODE", szSearchKey, CC_Integer ); + + if( papszUnitsRecord == NULL ) + return FALSE; + +/* -------------------------------------------------------------------- */ +/* Get the name, if requested. */ +/* -------------------------------------------------------------------- */ + if( ppszUOMName != NULL ) + { + iNameField = CSVGetFileFieldId( pszFilename, + "UNIT_OF_MEAS_NAME" ); + *ppszUOMName = CPLStrdup( CSLGetField(papszUnitsRecord, iNameField) ); + } + +/* -------------------------------------------------------------------- */ +/* Get the A and B factor fields, and create the multiplicative */ +/* factor. */ +/* -------------------------------------------------------------------- */ + if( pdfInMeters != NULL ) + { + int iBFactorField, iCFactorField; + + iBFactorField = CSVGetFileFieldId( pszFilename, "FACTOR_B" ); + iCFactorField = CSVGetFileFieldId( pszFilename, "FACTOR_C" ); + + if( atof(CSLGetField(papszUnitsRecord, iCFactorField)) > 0.0 ) + *pdfInMeters = atof(CSLGetField(papszUnitsRecord, iBFactorField)) + / atof(CSLGetField(papszUnitsRecord, iCFactorField)); + else + *pdfInMeters = 0.0; + } + + return( TRUE ); +} + +/************************************************************************/ +/* GTIFGetUOMAngleInfo() */ +/************************************************************************/ + +int GTIFGetUOMAngleInfo( int nUOMAngleCode, + char **ppszUOMName, + double * pdfInDegrees ) + +{ + const char *pszUOMName = NULL; + double dfInDegrees = 1.0; + const char *pszFilename = CSVFilename( "unit_of_measure.csv" ); + char szSearchKey[24]; + + sprintf( szSearchKey, "%d", nUOMAngleCode ); + pszUOMName = CSVGetField( pszFilename, + "UOM_CODE", szSearchKey, CC_Integer, + "UNIT_OF_MEAS_NAME" ); + +/* -------------------------------------------------------------------- */ +/* If the file is found, read from there. Note that FactorC is */ +/* an empty field for any of the DMS style formats, and in this */ +/* case we really want to return the default InDegrees value */ +/* (1.0) from above. */ +/* -------------------------------------------------------------------- */ + if( pszUOMName != NULL ) + { + double dfFactorB, dfFactorC, dfInRadians; + + dfFactorB = + atof(CSVGetField( pszFilename, + "UOM_CODE", szSearchKey, CC_Integer, + "FACTOR_B" )); + + dfFactorC = + atof(CSVGetField( pszFilename, + "UOM_CODE", szSearchKey, CC_Integer, + "FACTOR_C" )); + + if( dfFactorC != 0.0 ) + { + dfInRadians = (dfFactorB / dfFactorC); + dfInDegrees = dfInRadians * 180.0 / PI; + } + + + /* We do a special override of some of the DMS formats name */ + if( nUOMAngleCode == 9102 || nUOMAngleCode == 9107 + || nUOMAngleCode == 9108 || nUOMAngleCode == 9110 + || nUOMAngleCode == 9122 ) + { + dfInDegrees = 1.0; + pszUOMName = "degree"; + } + } + +/* -------------------------------------------------------------------- */ +/* Otherwise handle a few well known units directly. */ +/* -------------------------------------------------------------------- */ + else + { + switch( nUOMAngleCode ) + { + case 9101: + pszUOMName = "radian"; + dfInDegrees = 180.0 / PI; + break; + + case 9102: + case 9107: + case 9108: + case 9110: + pszUOMName = "degree"; + dfInDegrees = 1.0; + break; + + case 9103: + pszUOMName = "arc-minute"; + dfInDegrees = 1 / 60.0; + break; + + case 9104: + pszUOMName = "arc-second"; + dfInDegrees = 1 / 3600.0; + break; + + case 9105: + pszUOMName = "grad"; + dfInDegrees = 180.0 / 200.0; + break; + + case 9106: + pszUOMName = "gon"; + dfInDegrees = 180.0 / 200.0; + break; + + case 9109: + pszUOMName = "microradian"; + dfInDegrees = 180.0 / (PI * 1000000.0); + break; + + default: + return FALSE; + } + } + +/* -------------------------------------------------------------------- */ +/* Return to caller. */ +/* -------------------------------------------------------------------- */ + if( ppszUOMName != NULL ) + { + if( pszUOMName != NULL ) + *ppszUOMName = CPLStrdup( pszUOMName ); + else + *ppszUOMName = NULL; + } + + if( pdfInDegrees != NULL ) + *pdfInDegrees = dfInDegrees; + + return( TRUE ); +} + +/************************************************************************/ +/* EPSGProjMethodToCTProjMethod() */ +/* */ +/* Convert between the EPSG enumeration for projection methods, */ +/* and the GeoTIFF CT codes. */ +/************************************************************************/ + +static int EPSGProjMethodToCTProjMethod( int nEPSG ) + +{ + /* see trf_method.csv for list of EPSG codes */ + + switch( nEPSG ) + { + case 9801: + return( CT_LambertConfConic_1SP ); + + case 9802: + return( CT_LambertConfConic_2SP ); + + case 9803: + return( CT_LambertConfConic_2SP ); /* Belgian variant not supported */ + + case 9804: + return( CT_Mercator ); /* 1SP and 2SP not differentiated */ + + case 9805: + return( CT_Mercator ); /* 1SP and 2SP not differentiated */ + + case 9806: + return( CT_CassiniSoldner ); + + case 9807: + return( CT_TransverseMercator ); + + case 9808: + return( CT_TransvMercator_SouthOriented ); + + case 9809: + return( CT_ObliqueStereographic ); + + case 9810: + return( CT_PolarStereographic ); + + case 9811: + return( CT_NewZealandMapGrid ); + + case 9812: + return( CT_ObliqueMercator ); /* is hotine actually different? */ + + case 9813: + return( CT_ObliqueMercator_Laborde ); + + case 9814: + return( CT_ObliqueMercator_Rosenmund ); /* swiss */ + + case 9815: + return( CT_ObliqueMercator ); + + case 9816: /* tunesia mining grid has no counterpart */ + return( KvUserDefined ); + } + + return( KvUserDefined ); +} + +/************************************************************************/ +/* SetGTParmIds() */ +/* */ +/* This is hardcoded logic to set the GeoTIFF parmaeter */ +/* identifiers for all the EPSG supported projections. As the */ +/* trf_method.csv table grows with new projections, this code */ +/* will need to be updated. */ +/************************************************************************/ + +static int SetGTParmIds( int nCTProjection, + int *panProjParmId, + int *panEPSGCodes ) + +{ + int anWorkingDummy[7]; + + if( panEPSGCodes == NULL ) + panEPSGCodes = anWorkingDummy; + if( panProjParmId == NULL ) + panProjParmId = anWorkingDummy; + + memset( panEPSGCodes, 0, sizeof(int) * 7 ); + + /* psDefn->nParms = 7; */ + + switch( nCTProjection ) + { + case CT_CassiniSoldner: + case CT_NewZealandMapGrid: + panProjParmId[0] = ProjNatOriginLatGeoKey; + panProjParmId[1] = ProjNatOriginLongGeoKey; + panProjParmId[5] = ProjFalseEastingGeoKey; + panProjParmId[6] = ProjFalseNorthingGeoKey; + + panEPSGCodes[0] = EPSGNatOriginLat; + panEPSGCodes[1] = EPSGNatOriginLong; + panEPSGCodes[5] = EPSGFalseEasting; + panEPSGCodes[6] = EPSGFalseNorthing; + return TRUE; + + case CT_ObliqueMercator: + panProjParmId[0] = ProjCenterLatGeoKey; + panProjParmId[1] = ProjCenterLongGeoKey; + panProjParmId[2] = ProjAzimuthAngleGeoKey; + panProjParmId[3] = ProjRectifiedGridAngleGeoKey; + panProjParmId[4] = ProjScaleAtCenterGeoKey; + panProjParmId[5] = ProjFalseEastingGeoKey; + panProjParmId[6] = ProjFalseNorthingGeoKey; + + panEPSGCodes[0] = EPSGProjCenterLat; + panEPSGCodes[1] = EPSGProjCenterLong; + panEPSGCodes[2] = EPSGAzimuth; + panEPSGCodes[3] = EPSGAngleRectifiedToSkewedGrid; + panEPSGCodes[4] = EPSGInitialLineScaleFactor; + panEPSGCodes[5] = EPSGProjCenterEasting; + panEPSGCodes[6] = EPSGProjCenterNorthing; + return TRUE; + + case CT_ObliqueMercator_Laborde: + panProjParmId[0] = ProjCenterLatGeoKey; + panProjParmId[1] = ProjCenterLongGeoKey; + panProjParmId[2] = ProjAzimuthAngleGeoKey; + panProjParmId[4] = ProjScaleAtCenterGeoKey; + panProjParmId[5] = ProjFalseEastingGeoKey; + panProjParmId[6] = ProjFalseNorthingGeoKey; + + panEPSGCodes[0] = EPSGProjCenterLat; + panEPSGCodes[1] = EPSGProjCenterLong; + panEPSGCodes[2] = EPSGAzimuth; + panEPSGCodes[4] = EPSGInitialLineScaleFactor; + panEPSGCodes[5] = EPSGProjCenterEasting; + panEPSGCodes[6] = EPSGProjCenterNorthing; + return TRUE; + + case CT_LambertConfConic_1SP: + case CT_Mercator: + case CT_ObliqueStereographic: + case CT_PolarStereographic: + case CT_TransverseMercator: + case CT_TransvMercator_SouthOriented: + panProjParmId[0] = ProjNatOriginLatGeoKey; + panProjParmId[1] = ProjNatOriginLongGeoKey; + panProjParmId[4] = ProjScaleAtNatOriginGeoKey; + panProjParmId[5] = ProjFalseEastingGeoKey; + panProjParmId[6] = ProjFalseNorthingGeoKey; + + panEPSGCodes[0] = EPSGNatOriginLat; + panEPSGCodes[1] = EPSGNatOriginLong; + panEPSGCodes[4] = EPSGNatOriginScaleFactor; + panEPSGCodes[5] = EPSGFalseEasting; + panEPSGCodes[6] = EPSGFalseNorthing; + return TRUE; + + case CT_LambertConfConic_2SP: + panProjParmId[0] = ProjFalseOriginLatGeoKey; + panProjParmId[1] = ProjFalseOriginLongGeoKey; + panProjParmId[2] = ProjStdParallel1GeoKey; + panProjParmId[3] = ProjStdParallel2GeoKey; + panProjParmId[5] = ProjFalseEastingGeoKey; + panProjParmId[6] = ProjFalseNorthingGeoKey; + + panEPSGCodes[0] = EPSGFalseOriginLat; + panEPSGCodes[1] = EPSGFalseOriginLong; + panEPSGCodes[2] = EPSGStdParallel1Lat; + panEPSGCodes[3] = EPSGStdParallel2Lat; + panEPSGCodes[5] = EPSGFalseOriginEasting; + panEPSGCodes[6] = EPSGFalseOriginNorthing; + return TRUE; + + case CT_SwissObliqueCylindrical: + panProjParmId[0] = ProjCenterLatGeoKey; + panProjParmId[1] = ProjCenterLongGeoKey; + panProjParmId[5] = ProjFalseEastingGeoKey; + panProjParmId[6] = ProjFalseNorthingGeoKey; + + /* EPSG codes? */ + return TRUE; + + default: + return( FALSE ); + } +} + +/************************************************************************/ +/* GTIFGetProjTRFInfo() */ +/* */ +/* Transform a PROJECTION_TRF_CODE into a projection method, */ +/* and a set of parameters. The parameters identify will */ +/* depend on the returned method, but they will all have been */ +/* normalized into degrees and meters. */ +/************************************************************************/ + +int GTIFGetProjTRFInfo( /* COORD_OP_CODE from coordinate_operation.csv */ + int nProjTRFCode, + char **ppszProjTRFName, + short * pnProjMethod, + double * padfProjParms ) + +{ + int nProjMethod, i, anEPSGCodes[7]; + double adfProjParms[7]; + char szTRFCode[16]; + int nCTProjMethod; + char *pszFilename = CPLStrdup(CSVFilename("projop_wparm.csv")); + +/* -------------------------------------------------------------------- */ +/* Get the proj method. If this fails to return a meaningful */ +/* number, then the whole function fails. */ +/* -------------------------------------------------------------------- */ + sprintf( szTRFCode, "%d", nProjTRFCode ); + nProjMethod = + atoi( CSVGetField( pszFilename, + "COORD_OP_CODE", szTRFCode, CC_Integer, + "COORD_OP_METHOD_CODE" ) ); + if( nProjMethod == 0 ) + { + CPLFree( pszFilename ); + return FALSE; + } + +/* -------------------------------------------------------------------- */ +/* Initialize a definition of what EPSG codes need to be loaded */ +/* into what fields in adfProjParms. */ +/* -------------------------------------------------------------------- */ + nCTProjMethod = EPSGProjMethodToCTProjMethod( nProjMethod ); + SetGTParmIds( nCTProjMethod, NULL, anEPSGCodes ); + +/* -------------------------------------------------------------------- */ +/* Get the parameters for this projection. For the time being */ +/* I am assuming the first four parameters are angles, the */ +/* fifth is unitless (normally scale), and the remainder are */ +/* linear measures. This works fine for the existing */ +/* projections, but is a pretty fragile approach. */ +/* -------------------------------------------------------------------- */ + + for( i = 0; i < 7; i++ ) + { + char szParamUOMID[32], szParamValueID[32], szParamCodeID[32]; + const char *pszValue; + int nUOM; + int nEPSGCode = anEPSGCodes[i]; + int iEPSG; + + /* Establish default */ + if( nEPSGCode == EPSGAngleRectifiedToSkewedGrid ) + adfProjParms[i] = 90.0; + else if( nEPSGCode == EPSGNatOriginScaleFactor + || nEPSGCode == EPSGInitialLineScaleFactor + || nEPSGCode == EPSGPseudoStdParallelScaleFactor ) + adfProjParms[i] = 1.0; + else + adfProjParms[i] = 0.0; + + /* If there is no parameter, skip */ + if( nEPSGCode == 0 ) + continue; + + /* Find the matching parameter */ + for( iEPSG = 0; iEPSG < 7; iEPSG++ ) + { + sprintf( szParamCodeID, "PARAMETER_CODE_%d", iEPSG+1 ); + + if( atoi(CSVGetField( pszFilename, + "COORD_OP_CODE", szTRFCode, CC_Integer, + szParamCodeID )) == nEPSGCode ) + break; + } + + /* not found, accept the default */ + if( iEPSG == 7 ) + continue; + + /* Get the value, and UOM */ + sprintf( szParamUOMID, "PARAMETER_UOM_%d", iEPSG+1 ); + sprintf( szParamValueID, "PARAMETER_VALUE_%d", iEPSG+1 ); + + nUOM = atoi(CSVGetField( pszFilename, + "COORD_OP_CODE", szTRFCode, CC_Integer, + szParamUOMID )); + pszValue = CSVGetField( pszFilename, + "COORD_OP_CODE", szTRFCode, CC_Integer, + szParamValueID ); + + /* Transform according to the UOM */ + if( nUOM >= 9100 && nUOM < 9200 ) + adfProjParms[i] = GTIFAngleStringToDD( pszValue, nUOM ); + else if( nUOM > 9000 && nUOM < 9100 ) + { + double dfInMeters; + + if( !GTIFGetUOMLengthInfo( nUOM, NULL, &dfInMeters ) ) + dfInMeters = 1.0; + adfProjParms[i] = atof(pszValue) * dfInMeters; + } + else + adfProjParms[i] = atof(pszValue); + } + +/* -------------------------------------------------------------------- */ +/* Get the name, if requested. */ +/* -------------------------------------------------------------------- */ + if( ppszProjTRFName != NULL ) + { + *ppszProjTRFName = + CPLStrdup(CSVGetField( pszFilename, + "COORD_OP_CODE", szTRFCode, CC_Integer, + "COORD_OP_NAME" )); + } + +/* -------------------------------------------------------------------- */ +/* Transfer requested data into passed variables. */ +/* -------------------------------------------------------------------- */ + if( pnProjMethod != NULL ) + *pnProjMethod = (short) nProjMethod; + + if( padfProjParms != NULL ) + { + for( i = 0; i < 7; i++ ) + padfProjParms[i] = adfProjParms[i]; + } + + CPLFree( pszFilename ); + + return TRUE; +} + +/************************************************************************/ +/* GTIFFetchProjParms() */ +/* */ +/* Fetch the projection parameters for a particular projection */ +/* from a GeoTIFF file, and fill the GTIFDefn structure out */ +/* with them. */ +/************************************************************************/ + +static void GTIFFetchProjParms( GTIF * psGTIF, GTIFDefn * psDefn ) + +{ + double dfNatOriginLong = 0.0, dfNatOriginLat = 0.0, dfRectGridAngle = 0.0; + double dfFalseEasting = 0.0, dfFalseNorthing = 0.0, dfNatOriginScale = 1.0; + double dfStdParallel1 = 0.0, dfStdParallel2 = 0.0, dfAzimuth = 0.0; + +/* -------------------------------------------------------------------- */ +/* Get the false easting, and northing if available. */ +/* -------------------------------------------------------------------- */ + if( !GTIFKeyGet(psGTIF, ProjFalseEastingGeoKey, &dfFalseEasting, 0, 1) + && !GTIFKeyGet(psGTIF, ProjCenterEastingGeoKey, + &dfFalseEasting, 0, 1) + && !GTIFKeyGet(psGTIF, ProjFalseOriginEastingGeoKey, + &dfFalseEasting, 0, 1) ) + dfFalseEasting = 0.0; + + if( !GTIFKeyGet(psGTIF, ProjFalseNorthingGeoKey, &dfFalseNorthing,0,1) + && !GTIFKeyGet(psGTIF, ProjCenterNorthingGeoKey, + &dfFalseNorthing, 0, 1) + && !GTIFKeyGet(psGTIF, ProjFalseOriginNorthingGeoKey, + &dfFalseNorthing, 0, 1) ) + dfFalseNorthing = 0.0; + + switch( psDefn->CTProjection ) + { +/* -------------------------------------------------------------------- */ + case CT_Stereographic: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + if( GTIFKeyGet(psGTIF, ProjScaleAtNatOriginGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 ) + dfNatOriginScale = 1.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfNatOriginLat; + psDefn->ProjParmId[0] = ProjCenterLatGeoKey; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjCenterLongGeoKey; + psDefn->ProjParm[4] = dfNatOriginScale; + psDefn->ProjParmId[4] = ProjScaleAtNatOriginGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_LambertConfConic_1SP: + case CT_Mercator: + case CT_ObliqueStereographic: + case CT_TransverseMercator: + case CT_TransvMercator_SouthOriented: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + if( GTIFKeyGet(psGTIF, ProjScaleAtNatOriginGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 ) + dfNatOriginScale = 1.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfNatOriginLat; + psDefn->ProjParmId[0] = ProjNatOriginLatGeoKey; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjNatOriginLongGeoKey; + psDefn->ProjParm[4] = dfNatOriginScale; + psDefn->ProjParmId[4] = ProjScaleAtNatOriginGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_ObliqueMercator: /* hotine */ +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + if( GTIFKeyGet(psGTIF, ProjAzimuthAngleGeoKey, + &dfAzimuth, 0, 1 ) == 0 ) + dfAzimuth = 0.0; + + if( GTIFKeyGet(psGTIF, ProjRectifiedGridAngleGeoKey, + &dfRectGridAngle, 0, 1 ) == 0 ) + dfRectGridAngle = 90.0; + + if( GTIFKeyGet(psGTIF, ProjScaleAtNatOriginGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjScaleAtCenterGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 ) + dfNatOriginScale = 1.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfNatOriginLat; + psDefn->ProjParmId[0] = ProjCenterLatGeoKey; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjCenterLongGeoKey; + psDefn->ProjParm[2] = dfAzimuth; + psDefn->ProjParmId[2] = ProjAzimuthAngleGeoKey; + psDefn->ProjParm[3] = dfRectGridAngle; + psDefn->ProjParmId[3] = ProjRectifiedGridAngleGeoKey; + psDefn->ProjParm[4] = dfNatOriginScale; + psDefn->ProjParmId[4] = ProjScaleAtCenterGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_CassiniSoldner: + case CT_Polyconic: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + if( GTIFKeyGet(psGTIF, ProjScaleAtNatOriginGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjScaleAtCenterGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 ) + dfNatOriginScale = 1.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfNatOriginLat; + psDefn->ProjParmId[0] = ProjNatOriginLatGeoKey; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjNatOriginLongGeoKey; + psDefn->ProjParm[4] = dfNatOriginScale; + psDefn->ProjParmId[4] = ProjScaleAtNatOriginGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_AzimuthalEquidistant: + case CT_MillerCylindrical: + case CT_Equirectangular: + case CT_Gnomonic: + case CT_LambertAzimEqualArea: + case CT_Orthographic: + case CT_NewZealandMapGrid: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfNatOriginLat; + psDefn->ProjParmId[0] = ProjCenterLatGeoKey; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjCenterLongGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_Robinson: + case CT_Sinusoidal: + case CT_VanDerGrinten: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjCenterLongGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_PolarStereographic: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjStraightVertPoleLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + if( GTIFKeyGet(psGTIF, ProjScaleAtNatOriginGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjScaleAtCenterGeoKey, + &dfNatOriginScale, 0, 1 ) == 0 ) + dfNatOriginScale = 1.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfNatOriginLat; + psDefn->ProjParmId[0] = ProjNatOriginLatGeoKey;; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjStraightVertPoleLongGeoKey; + psDefn->ProjParm[4] = dfNatOriginScale; + psDefn->ProjParmId[4] = ProjScaleAtNatOriginGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_LambertConfConic_2SP: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjStdParallel1GeoKey, + &dfStdParallel1, 0, 1 ) == 0 ) + dfStdParallel1 = 0.0; + + if( GTIFKeyGet(psGTIF, ProjStdParallel2GeoKey, + &dfStdParallel2, 0, 1 ) == 0 ) + dfStdParallel1 = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfNatOriginLat; + psDefn->ProjParmId[0] = ProjFalseOriginLatGeoKey; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjFalseOriginLongGeoKey; + psDefn->ProjParm[2] = dfStdParallel1; + psDefn->ProjParmId[2] = ProjStdParallel1GeoKey; + psDefn->ProjParm[3] = dfStdParallel2; + psDefn->ProjParmId[3] = ProjStdParallel2GeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_AlbersEqualArea: + case CT_EquidistantConic: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjStdParallel1GeoKey, + &dfStdParallel1, 0, 1 ) == 0 ) + dfStdParallel1 = 0.0; + + if( GTIFKeyGet(psGTIF, ProjStdParallel2GeoKey, + &dfStdParallel2, 0, 1 ) == 0 ) + dfStdParallel2 = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLatGeoKey, + &dfNatOriginLat, 0, 1 ) == 0 ) + dfNatOriginLat = 0.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfStdParallel1; + psDefn->ProjParmId[0] = ProjStdParallel1GeoKey; + psDefn->ProjParm[1] = dfStdParallel2; + psDefn->ProjParmId[1] = ProjStdParallel2GeoKey; + psDefn->ProjParm[2] = dfNatOriginLat; + psDefn->ProjParmId[2] = ProjNatOriginLatGeoKey; + psDefn->ProjParm[3] = dfNatOriginLong; + psDefn->ProjParmId[3] = ProjNatOriginLongGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + +/* -------------------------------------------------------------------- */ + case CT_CylindricalEqualArea: +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF, ProjStdParallel1GeoKey, + &dfStdParallel1, 0, 1 ) == 0 ) + dfStdParallel1 = 0.0; + + if( GTIFKeyGet(psGTIF, ProjNatOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjFalseOriginLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 + && GTIFKeyGet(psGTIF, ProjCenterLongGeoKey, + &dfNatOriginLong, 0, 1 ) == 0 ) + dfNatOriginLong = 0.0; + + /* notdef: should transform to decimal degrees at this point */ + + psDefn->ProjParm[0] = dfStdParallel1; + psDefn->ProjParmId[0] = ProjStdParallel1GeoKey; + psDefn->ProjParm[1] = dfNatOriginLong; + psDefn->ProjParmId[1] = ProjNatOriginLongGeoKey; + psDefn->ProjParm[5] = dfFalseEasting; + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[6] = dfFalseNorthing; + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + psDefn->nParms = 7; + break; + } +} + +/************************************************************************/ +/* GTIFGetDefn() */ +/************************************************************************/ + +/** +@param psGTIF GeoTIFF information handle as returned by GTIFNew. +@param psDefn Pointer to an existing GTIFDefn structure. This structure +does not need to have been pre-initialized at all. + +@return TRUE if the function has been successful, otherwise FALSE. + +This function reads the coordinate system definition from a GeoTIFF file, +and <i>normalizes</i> it into a set of component information using +definitions from CSV (Comma Seperated Value ASCII) files derived from +EPSG tables. This function is intended to simplify correct support for +reading files with defined PCS (Projected Coordinate System) codes that +wouldn't otherwise be directly known by application software by reducing +it to the underlying projection method, parameters, datum, ellipsoid, +prime meridian and units.<p> + +The application should pass a pointer to an existing uninitialized +GTIFDefn structure, and GTIFGetDefn() will fill it in. The fuction +currently always returns TRUE but in the future will return FALSE if +CSV files are not found. In any event, all geokeys actually found in the +file will be copied into the GTIFDefn. However, if the CSV files aren't +found codes implied by other codes will not be set properly.<p> + +GTIFGetDefn() will not generally work if the EPSG derived CSV files cannot +be found. By default a modest attempt will be made to find them, but +in general it is necessary for the calling application to override the +logic to find them. This can be done by calling the +SetCSVFilenameHook() function to +override the search method based on application knowledge of where they are +found.<p> + +The normalization methodology operates by fetching tags from the GeoTIFF +file, and then setting all other tags implied by them in the structure. The +implied relationships are worked out by reading definitions from the +various EPSG derived CSV tables.<p> + +For instance, if a PCS (ProjectedCSTypeGeoKey) is found in the GeoTIFF file +this code is used to lookup a record in the <tt>horiz_cs.csv</tt> CSV +file. For example given the PCS 26746 we can find the name +(NAD27 / California zone VI), the GCS 4257 (NAD27), and the ProjectionCode +10406 (California CS27 zone VI). The GCS, and ProjectionCode can in turn +be looked up in other tables until all the details of units, ellipsoid, +prime meridian, datum, projection (LambertConfConic_2SP) and projection +parameters are established. A full listgeo dump of a file +for this result might look like the following, all based on a single PCS +value:<p> + +<pre> +% listgeo -norm ~/data/geotiff/pci_eg/spaf27.tif +Geotiff_Information: + Version: 1 + Key_Revision: 1.0 + Tagged_Information: + ModelTiepointTag (2,3): + 0 0 0 + 1577139.71 634349.176 0 + ModelPixelScaleTag (1,3): + 195.509321 198.32184 0 + End_Of_Tags. + Keyed_Information: + GTModelTypeGeoKey (Short,1): ModelTypeProjected + GTRasterTypeGeoKey (Short,1): RasterPixelIsArea + ProjectedCSTypeGeoKey (Short,1): PCS_NAD27_California_VI + End_Of_Keys. + End_Of_Geotiff. + +PCS = 26746 (NAD27 / California zone VI) +Projection = 10406 (California CS27 zone VI) +Projection Method: CT_LambertConfConic_2SP + ProjStdParallel1GeoKey: 33.883333 + ProjStdParallel2GeoKey: 32.766667 + ProjFalseOriginLatGeoKey: 32.166667 + ProjFalseOriginLongGeoKey: -116.233333 + ProjFalseEastingGeoKey: 609601.219202 + ProjFalseNorthingGeoKey: 0.000000 +GCS: 4267/NAD27 +Datum: 6267/North American Datum 1927 +Ellipsoid: 7008/Clarke 1866 (6378206.40,6356583.80) +Prime Meridian: 8901/Greenwich (0.000000) +Projection Linear Units: 9003/US survey foot (0.304801m) +</pre> + +Note that GTIFGetDefn() does not inspect or return the tiepoints and scale. +This must be handled seperately as it normally would. It is intended to +simplify capture and normalization of the coordinate system definition. +Note that GTIFGetDefn() also does the following things: + +<ol> +<li> Convert all angular values to decimal degrees. +<li> Convert all linear values to meters. +<li> Return the linear units and conversion to meters for the tiepoints and +scale (though the tiepoints and scale remain in their native units). +<li> When reading projection parameters a variety of differences between +different GeoTIFF generators are handled, and a normalized set of parameters +for each projection are always returned. +</ol> + +Code fields in the GTIFDefn are filled with KvUserDefined if there is not +value to assign. The parameter lists for each of the underlying projection +transform methods can be found at the +<a href="http://www.remotesensing.org/geotiff/proj_list">Projections</a> +page. Note that nParms will be set based on the maximum parameter used. +Some of the parameters may not be used in which case the +GTIFDefn::ProjParmId[] will +be zero. This is done to retain correspondence to the EPSG parameter +numbering scheme.<p> + +The +<a href="http://www.remotesensing.org/cgi-bin/cvsweb.cgi/~checkout~/osrs/geotiff/libgeotiff/geotiff_proj4.c">geotiff_proj4.c</a> module distributed with libgeotiff can +be used as an example of code that converts a GTIFDefn into another projection +system.<p> + +@see GTIFKeySet(), SetCSVFilenameHook() + +*/ + +int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn ) + +{ + int i; + short nGeogUOMLinear; + double dfInvFlattening; + +/* -------------------------------------------------------------------- */ +/* Initially we default all the information we can. */ +/* -------------------------------------------------------------------- */ + psDefn->Model = KvUserDefined; + psDefn->PCS = KvUserDefined; + psDefn->GCS = KvUserDefined; + psDefn->UOMLength = KvUserDefined; + psDefn->UOMLengthInMeters = 1.0; + psDefn->UOMAngle = KvUserDefined; + psDefn->UOMAngleInDegrees = 1.0; + psDefn->Datum = KvUserDefined; + psDefn->Ellipsoid = KvUserDefined; + psDefn->SemiMajor = 0.0; + psDefn->SemiMinor = 0.0; + psDefn->PM = KvUserDefined; + psDefn->PMLongToGreenwich = 0.0; + + psDefn->ProjCode = KvUserDefined; + psDefn->Projection = KvUserDefined; + psDefn->CTProjection = KvUserDefined; + + psDefn->nParms = 0; + for( i = 0; i < MAX_GTIF_PROJPARMS; i++ ) + { + psDefn->ProjParm[i] = 0.0; + psDefn->ProjParmId[i] = 0; + } + + psDefn->MapSys = KvUserDefined; + psDefn->Zone = 0; + +/* -------------------------------------------------------------------- */ +/* Try to get the overall model type. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF,GTModelTypeGeoKey,&(psDefn->Model),0,1); + +/* -------------------------------------------------------------------- */ +/* Extract the Geog units. */ +/* -------------------------------------------------------------------- */ + nGeogUOMLinear = 9001; /* Linear_Meter */ + GTIFKeyGet(psGTIF, GeogLinearUnitsGeoKey, &nGeogUOMLinear, 0, 1 ); + +/* -------------------------------------------------------------------- */ +/* Try to get a PCS. */ +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF,ProjectedCSTypeGeoKey, &(psDefn->PCS),0,1) == 1 + && psDefn->PCS != KvUserDefined ) + { + /* + * Translate this into useful information. + */ + GTIFGetPCSInfo( psDefn->PCS, NULL, &(psDefn->ProjCode), + &(psDefn->UOMLength), &(psDefn->GCS) ); + } + +/* -------------------------------------------------------------------- */ +/* If we have the PCS code, but didn't find it in the CSV files */ +/* (likely because we can't find them) we will try some ``jiffy */ +/* rules'' for UTM and state plane. */ +/* -------------------------------------------------------------------- */ + if( psDefn->PCS != KvUserDefined && psDefn->ProjCode == KvUserDefined ) + { + int nMapSys, nZone; + int nGCS = psDefn->GCS; + + nMapSys = GTIFPCSToMapSys( psDefn->PCS, &nGCS, &nZone ); + if( nMapSys != KvUserDefined ) + { + psDefn->ProjCode = (short) GTIFMapSysToProj( nMapSys, nZone ); + psDefn->GCS = (short) nGCS; + } + } + +/* -------------------------------------------------------------------- */ +/* If the Proj_ code is specified directly, use that. */ +/* -------------------------------------------------------------------- */ + if( psDefn->ProjCode == KvUserDefined ) + GTIFKeyGet(psGTIF, ProjectionGeoKey, &(psDefn->ProjCode), 0, 1 ); + + if( psDefn->ProjCode != KvUserDefined ) + { + /* + * We have an underlying projection transformation value. Look + * this up. For a PCS of ``WGS 84 / UTM 11'' the transformation + * would be Transverse Mercator, with a particular set of options. + * The nProjTRFCode itself would correspond to the name + * ``UTM zone 11N'', and doesn't include datum info. + */ + GTIFGetProjTRFInfo( psDefn->ProjCode, NULL, &(psDefn->Projection), + psDefn->ProjParm ); + + /* + * Set the GeoTIFF identity of the parameters. + */ + psDefn->CTProjection = (short) + EPSGProjMethodToCTProjMethod( psDefn->Projection ); + + SetGTParmIds( psDefn->CTProjection, psDefn->ProjParmId, NULL); + psDefn->nParms = 7; + } + +/* -------------------------------------------------------------------- */ +/* Try to get a GCS. If found, it will override any implied by */ +/* the PCS. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF, GeographicTypeGeoKey, &(psDefn->GCS), 0, 1 ); + +/* -------------------------------------------------------------------- */ +/* Derive the datum, and prime meridian from the GCS. */ +/* -------------------------------------------------------------------- */ + if( psDefn->GCS != KvUserDefined ) + { + GTIFGetGCSInfo( psDefn->GCS, NULL, &(psDefn->Datum), &(psDefn->PM), + &(psDefn->UOMAngle) ); + } + +/* -------------------------------------------------------------------- */ +/* Handle the GCS angular units. GeogAngularUnitsGeoKey */ +/* overrides the GCS or PCS setting. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF, GeogAngularUnitsGeoKey, &(psDefn->UOMAngle), 0, 1 ); + if( psDefn->UOMAngle != KvUserDefined ) + { + GTIFGetUOMAngleInfo( psDefn->UOMAngle, NULL, + &(psDefn->UOMAngleInDegrees) ); + } + +/* -------------------------------------------------------------------- */ +/* Check for a datum setting, and then use the datum to derive */ +/* an ellipsoid. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF, GeogGeodeticDatumGeoKey, &(psDefn->Datum), 0, 1 ); + + if( psDefn->Datum != KvUserDefined ) + { + GTIFGetDatumInfo( psDefn->Datum, NULL, &(psDefn->Ellipsoid) ); + } + +/* -------------------------------------------------------------------- */ +/* Check for an explicit ellipsoid. Use the ellipsoid to */ +/* derive the ellipsoid characteristics, if possible. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF, GeogEllipsoidGeoKey, &(psDefn->Ellipsoid), 0, 1 ); + + if( psDefn->Ellipsoid != KvUserDefined ) + { + GTIFGetEllipsoidInfo( psDefn->Ellipsoid, NULL, + &(psDefn->SemiMajor), &(psDefn->SemiMinor) ); + } + +/* -------------------------------------------------------------------- */ +/* Check for overridden ellipsoid parameters. It would be nice */ +/* to warn if they conflict with provided information, but for */ +/* now we just override. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF, GeogSemiMajorAxisGeoKey, &(psDefn->SemiMajor), 0, 1 ); + GTIFKeyGet(psGTIF, GeogSemiMinorAxisGeoKey, &(psDefn->SemiMinor), 0, 1 ); + + if( GTIFKeyGet(psGTIF, GeogInvFlatteningGeoKey, &dfInvFlattening, + 0, 1 ) == 1 ) + { + if( dfInvFlattening != 0.0 ) + psDefn->SemiMinor = + psDefn->SemiMajor * (1 - 1.0/dfInvFlattening); + else + psDefn->SemiMinor = psDefn->SemiMajor; + } + +/* -------------------------------------------------------------------- */ +/* Get the prime meridian info. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF, GeogPrimeMeridianGeoKey, &(psDefn->PM), 0, 1 ); + + if( psDefn->PM != KvUserDefined ) + { + GTIFGetPMInfo( psDefn->PM, NULL, &(psDefn->PMLongToGreenwich) ); + } + else + { + GTIFKeyGet(psGTIF, GeogPrimeMeridianLongGeoKey, + &(psDefn->PMLongToGreenwich), 0, 1 ); + + psDefn->PMLongToGreenwich = + GTIFAngleToDD( psDefn->PMLongToGreenwich, + psDefn->UOMAngle ); + } + +/* -------------------------------------------------------------------- */ +/* Have the projection units of measure been overridden? We */ +/* should likely be doing something about angular units too, */ +/* but these are very rarely not decimal degrees for actual */ +/* file coordinates. */ +/* -------------------------------------------------------------------- */ + GTIFKeyGet(psGTIF,ProjLinearUnitsGeoKey,&(psDefn->UOMLength),0,1); + + if( psDefn->UOMLength != KvUserDefined ) + { + GTIFGetUOMLengthInfo( psDefn->UOMLength, NULL, + &(psDefn->UOMLengthInMeters) ); + } + +/* -------------------------------------------------------------------- */ +/* Handle a variety of user defined transform types. */ +/* -------------------------------------------------------------------- */ + if( GTIFKeyGet(psGTIF,ProjCoordTransGeoKey, + &(psDefn->CTProjection),0,1) == 1) + { + GTIFFetchProjParms( psGTIF, psDefn ); + } + +/* -------------------------------------------------------------------- */ +/* Try to set the zoned map system information. */ +/* -------------------------------------------------------------------- */ + psDefn->MapSys = GTIFProjToMapSys( psDefn->ProjCode, &(psDefn->Zone) ); + +/* -------------------------------------------------------------------- */ +/* If this is UTM, and we were unable to extract the projection */ +/* parameters from the CSV file, just set them directly now, */ +/* since it's pretty easy, and a common case. */ +/* -------------------------------------------------------------------- */ + if( (psDefn->MapSys == MapSys_UTM_North + || psDefn->MapSys == MapSys_UTM_South) + && psDefn->CTProjection == KvUserDefined ) + { + psDefn->CTProjection = CT_TransverseMercator; + psDefn->nParms = 7; + psDefn->ProjParmId[0] = ProjNatOriginLatGeoKey; + psDefn->ProjParm[0] = 0.0; + + psDefn->ProjParmId[1] = ProjNatOriginLongGeoKey; + psDefn->ProjParm[1] = psDefn->Zone*6 - 183.0; + + psDefn->ProjParmId[4] = ProjScaleAtNatOriginGeoKey; + psDefn->ProjParm[4] = 0.9996; + + psDefn->ProjParmId[5] = ProjFalseEastingGeoKey; + psDefn->ProjParm[5] = 500000.0; + + psDefn->ProjParmId[6] = ProjFalseNorthingGeoKey; + + if( psDefn->MapSys == MapSys_UTM_North ) + psDefn->ProjParm[6] = 0.0; + else + psDefn->ProjParm[6] = 10000000.0; + } + +/* -------------------------------------------------------------------- */ +/* For now we forceable deaccess all CSV files to reduce the */ +/* chance of "leakage". Really, this should be application */ +/* controlled. */ +/* -------------------------------------------------------------------- */ + CSVDeaccess( NULL ); + + return TRUE; +} + +/************************************************************************/ +/* GTIFDecToDMS() */ +/* */ +/* Convenient function to translate decimal degrees to DMS */ +/* format for reporting to a user. */ +/************************************************************************/ + +const char *GTIFDecToDMS( double dfAngle, const char * pszAxis, + int nPrecision ) + +{ + int nDegrees, nMinutes; + double dfSeconds; + char szFormat[30]; + static char szBuffer[50]; + const char *pszHemisphere = NULL; + double dfRound; + int i; + + dfRound = 0.5/60; + for( i = 0; i < nPrecision; i++ ) + dfRound = dfRound * 0.1; + + nDegrees = (int) ABS(dfAngle); + nMinutes = (int) ((ABS(dfAngle) - nDegrees) * 60 + dfRound); + dfSeconds = ABS((ABS(dfAngle) * 3600 - nDegrees*3600 - nMinutes*60)); + + if( EQUAL(pszAxis,"Long") && dfAngle < 0.0 ) + pszHemisphere = "W"; + else if( EQUAL(pszAxis,"Long") ) + pszHemisphere = "E"; + else if( dfAngle < 0.0 ) + pszHemisphere = "S"; + else + pszHemisphere = "N"; + + sprintf( szFormat, "%%3dd%%2d\'%%%d.%df\"%s", + nPrecision+3, nPrecision, pszHemisphere ); + sprintf( szBuffer, szFormat, nDegrees, nMinutes, dfSeconds ); + + return( szBuffer ); +} + +/************************************************************************/ +/* GTIFPrintDefn() */ +/* */ +/* Report the contents of a GTIFDefn structure ... mostly for */ +/* debugging. */ +/************************************************************************/ + +void GTIFPrintDefn( GTIFDefn * psDefn, FILE * fp ) + +{ +/* -------------------------------------------------------------------- */ +/* Get the PCS name if possible. */ +/* -------------------------------------------------------------------- */ + if( psDefn->PCS != KvUserDefined ) + { + char *pszPCSName = NULL; + + GTIFGetPCSInfo( psDefn->PCS, &pszPCSName, NULL, NULL, NULL ); + if( pszPCSName == NULL ) + pszPCSName = CPLStrdup("name unknown"); + + fprintf( fp, "PCS = %d (%s)\n", psDefn->PCS, pszPCSName ); + CPLFree( pszPCSName ); + } + +/* -------------------------------------------------------------------- */ +/* Dump the projection code if possible. */ +/* -------------------------------------------------------------------- */ + if( psDefn->ProjCode != KvUserDefined ) + { + char *pszTRFName = NULL; + + GTIFGetProjTRFInfo( psDefn->ProjCode, &pszTRFName, NULL, NULL ); + if( pszTRFName == NULL ) + pszTRFName = CPLStrdup(""); + + fprintf( fp, "Projection = %d (%s)\n", + psDefn->ProjCode, pszTRFName ); + + CPLFree( pszTRFName ); + } + +/* -------------------------------------------------------------------- */ +/* Try to dump the projection method name, and parameters if possible.*/ +/* -------------------------------------------------------------------- */ + if( psDefn->CTProjection != KvUserDefined ) + { + char *pszName = GTIFValueName(ProjCoordTransGeoKey, + psDefn->CTProjection); + int i; + + if( pszName == NULL ) + pszName = "(unknown)"; + + fprintf( fp, "Projection Method: %s\n", pszName ); + + for( i = 0; i < psDefn->nParms; i++ ) + { + if( psDefn->ProjParmId[i] == 0 ) + continue; + + pszName = GTIFKeyName((geokey_t) psDefn->ProjParmId[i]); + if( pszName == NULL ) + pszName = "(unknown)"; + + if( i < 4 ) + { + char *pszAxisName; + + if( strstr(pszName,"Long") != NULL ) + pszAxisName = "Long"; + else if( strstr(pszName,"Lat") != NULL ) + pszAxisName = "Lat"; + else + pszAxisName = "?"; + + fprintf( fp, " %s: %f (%s)\n", + pszName, psDefn->ProjParm[i], + GTIFDecToDMS( psDefn->ProjParm[i], pszAxisName, 2 ) ); + } + else if( i == 4 ) + fprintf( fp, " %s: %f\n", pszName, psDefn->ProjParm[i] ); + else + fprintf( fp, " %s: %f m\n", pszName, psDefn->ProjParm[i] ); + } + } + +/* -------------------------------------------------------------------- */ +/* Report the GCS name, and number. */ +/* -------------------------------------------------------------------- */ + if( psDefn->GCS != KvUserDefined ) + { + char *pszName = NULL; + + GTIFGetGCSInfo( psDefn->GCS, &pszName, NULL, NULL, NULL ); + if( pszName == NULL ) + pszName = CPLStrdup("(unknown)"); + + fprintf( fp, "GCS: %d/%s\n", psDefn->GCS, pszName ); + CPLFree( pszName ); + } + +/* -------------------------------------------------------------------- */ +/* Report the datum name. */ +/* -------------------------------------------------------------------- */ + if( psDefn->Datum != KvUserDefined ) + { + char *pszName = NULL; + + GTIFGetDatumInfo( psDefn->Datum, &pszName, NULL ); + if( pszName == NULL ) + pszName = CPLStrdup("(unknown)"); + + fprintf( fp, "Datum: %d/%s\n", psDefn->Datum, pszName ); + CPLFree( pszName ); + } + +/* -------------------------------------------------------------------- */ +/* Report the ellipsoid. */ +/* -------------------------------------------------------------------- */ + if( psDefn->Ellipsoid != KvUserDefined ) + { + char *pszName = NULL; + + GTIFGetEllipsoidInfo( psDefn->Ellipsoid, &pszName, NULL, NULL ); + if( pszName == NULL ) + pszName = CPLStrdup("(unknown)"); + + fprintf( fp, "Ellipsoid: %d/%s (%.2f,%.2f)\n", + psDefn->Ellipsoid, pszName, + psDefn->SemiMajor, psDefn->SemiMinor ); + CPLFree( pszName ); + } + +/* -------------------------------------------------------------------- */ +/* Report the prime meridian. */ +/* -------------------------------------------------------------------- */ + if( psDefn->PM != KvUserDefined ) + { + char *pszName = NULL; + + GTIFGetPMInfo( psDefn->PM, &pszName, NULL ); + + if( pszName == NULL ) + pszName = CPLStrdup("(unknown)"); + + fprintf( fp, "Prime Meridian: %d/%s (%f/%s)\n", + psDefn->PM, pszName, + psDefn->PMLongToGreenwich, + GTIFDecToDMS( psDefn->PMLongToGreenwich, "Long", 2 ) ); + CPLFree( pszName ); + } + +/* -------------------------------------------------------------------- */ +/* Report the projection units of measure (currently just */ +/* linear). */ +/* -------------------------------------------------------------------- */ + if( psDefn->UOMLength != KvUserDefined ) + { + char *pszName = NULL; + + GTIFGetUOMLengthInfo( psDefn->UOMLength, &pszName, NULL ); + if( pszName == NULL ) + pszName = CPLStrdup( "(unknown)" ); + + fprintf( fp, "Projection Linear Units: %d/%s (%fm)\n", + psDefn->UOMLength, pszName, psDefn->UOMLengthInMeters ); + CPLFree( pszName ); + } + + CSVDeaccess( NULL ); +} + +/************************************************************************/ +/* GTIFFreeMemory() */ +/* */ +/* Externally visible function to free memory allocated within */ +/* geo_normalize.c. */ +/************************************************************************/ + +void GTIFFreeMemory( char * pMemory ) + +{ + if( pMemory != NULL ) + VSIFree( pMemory ); +} + +/************************************************************************/ +/* GTIFDeaccessCSV() */ +/* */ +/* Free all cached CSV info. */ +/************************************************************************/ + +void GTIFDeaccessCSV() + +{ + CSVDeaccess( NULL ); +} diff --git a/Utilities/otbgeotiff/geo_normalize.h b/Utilities/otbgeotiff/geo_normalize.h new file mode 100644 index 0000000000000000000000000000000000000000..900dc812cc2a79e41b48329788fd69d96e13de8f --- /dev/null +++ b/Utilities/otbgeotiff/geo_normalize.h @@ -0,0 +1,238 @@ +/****************************************************************************** + * $Id: geo_normalize.h,v 1.12 2005/08/26 16:08:14 fwarmerdam Exp $ + * + * Project: libgeotiff + * Purpose: Include file related to geo_normalize.c containing Code to + * normalize PCS and other composite codes in a GeoTIFF file. + * Author: Frank Warmerdam, warmerda@home.com + * + ****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: geo_normalize.h,v $ + * Revision 1.12 2005/08/26 16:08:14 fwarmerdam + * Include void in empty argument list for prototype. + * + * Revision 1.11 2004/02/03 17:19:50 warmerda + * export GTIFAngleToDD() - used by GDAL mrsiddataset.cpp + * + * Revision 1.10 2003/01/15 04:39:16 warmerda + * Added GTIFDeaccessCSV + * + * Revision 1.9 2003/01/15 03:37:40 warmerda + * added GTIFFreeMemory() + * + * Revision 1.8 2002/11/28 22:27:42 warmerda + * preliminary upgrade to EPSG 6.2.2 tables + * + * Revision 1.7 1999/09/17 00:55:26 warmerda + * added GTIFGetUOMAngleInfo(), and UOMAngle in GTIFDefn + * + * Revision 1.6 1999/05/04 03:13:42 warmerda + * Added prototype + * + * Revision 1.5 1999/04/29 23:02:55 warmerda + * added docs, and MapSys related stuff + * + * Revision 1.4 1999/03/18 21:35:19 geotiff + * Added PROJ.4 related stuff + * + * Revision 1.3 1999/03/17 20:44:04 geotiff + * added CPL_DLL related support + * + * Revision 1.2 1999/03/10 18:24:06 geotiff + * corrected to use int' + * + */ + +#ifndef GEO_NORMALIZE_H_INCLUDED +#define GEO_NORMALIZE_H_INCLUDED + +#include <stdio.h> +#include "geotiff.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file geo_normalize.h + * + * Include file for extended projection definition normalization api. + */ + +#define MAX_GTIF_PROJPARMS 10 + +/** + * Holds a definition of a coordinate system in normalized form. + */ + +typedef struct { + /** From GTModelTypeGeoKey tag. Can have the values ModelTypeGeographic + or ModelTypeProjected. */ + short Model; + + /** From ProjectedCSTypeGeoKey tag. For example PCS_NAD27_UTM_zone_3N.*/ + short PCS; + + /** From GeographicTypeGeoKey tag. For example GCS_WGS_84 or + GCS_Voirol_1875_Paris. Includes datum and prime meridian value. */ + short GCS; + + /** From ProjLinearUnitsGeoKey. For example Linear_Meter. */ + short UOMLength; + + /** One UOMLength = UOMLengthInMeters meters. */ + double UOMLengthInMeters; + + /** The angular units of the GCS. */ + short UOMAngle; + + /** One UOMAngle = UOMLengthInDegrees degrees. */ + double UOMAngleInDegrees; + + /** Datum from GeogGeodeticDatumGeoKey tag. For example Datum_WGS84 */ + short Datum; + + /** Prime meridian from GeogPrimeMeridianGeoKey. For example PM_Greenwich + or PM_Paris. */ + short PM; + + /** Decimal degrees of longitude between this prime meridian and + Greenwich. Prime meridians to the west of Greenwich are negative. */ + double PMLongToGreenwich; + + /** Ellipsoid identifier from GeogELlipsoidGeoKey. For example + Ellipse_Clarke_1866. */ + short Ellipsoid; + + /** The length of the semi major ellipse axis in meters. */ + double SemiMajor; + + /** The length of the semi minor ellipse axis in meters. */ + double SemiMinor; + + /** Projection id from ProjectionGeoKey. For example Proj_UTM_11S. */ + short ProjCode; + + /** EPSG identifier for underlying projection method. From the EPSG + TRF_METHOD table. */ + short Projection; + + /** GeoTIFF identifier for underlying projection method. While some of + these values have corresponding vlaues in EPSG (Projection field), + others do not. For example CT_TransverseMercator. */ + short CTProjection; + + /** Number of projection parameters in ProjParm and ProjParmId. */ + int nParms; + + /** Projection parameter value. The identify of this parameter + is established from the corresponding entry in ProjParmId. The + value will be measured in meters, or decimal degrees if it is a + linear or angular measure. */ + double ProjParm[MAX_GTIF_PROJPARMS]; + + /** Projection parameter identifier. For example ProjFalseEastingGeoKey. + The value will be 0 for unused table entries. */ + int ProjParmId[MAX_GTIF_PROJPARMS]; /* geokey identifier, + eg. ProjFalseEastingGeoKey*/ + + /** Special zone map system code (MapSys_UTM_South, MapSys_UTM_North, + MapSys_State_Plane or KvUserDefined if none apply. */ + int MapSys; + + /** UTM, or State Plane Zone number, zero if not known. */ + int Zone; + +} GTIFDefn; + +int CPL_DLL GTIFGetPCSInfo( int nPCSCode, char **ppszEPSGName, + short *pnProjOp, + short *pnUOMLengthCode, short *pnGeogCS ); +int CPL_DLL GTIFGetProjTRFInfo( int nProjTRFCode, + char ** ppszProjTRFName, + short * pnProjMethod, + double * padfProjParms ); +int CPL_DLL GTIFGetGCSInfo( int nGCSCode, char **ppszName, + short *pnDatum, short *pnPM, short *pnUOMAngle ); +int CPL_DLL GTIFGetDatumInfo( int nDatumCode, char **ppszName, + short * pnEllipsoid ); +int CPL_DLL GTIFGetEllipsoidInfo( int nEllipsoid, char ** ppszName, + double * pdfSemiMajor, + double * pdfSemiMinor ); +int CPL_DLL GTIFGetPMInfo( int nPM, char **ppszName, + double * pdfLongToGreenwich ); + +double CPL_DLL GTIFAngleStringToDD( const char *pszAngle, int nUOMAngle ); +int CPL_DLL GTIFGetUOMLengthInfo( int nUOMLengthCode, + char **ppszUOMName, + double * pdfInMeters ); +int CPL_DLL GTIFGetUOMAngleInfo( int nUOMAngleCode, + char **ppszUOMName, + double * pdfInDegrees ); +double CPL_DLL GTIFAngleToDD( double dfAngle, int nUOMAngle ); + + +/* this should be used to free strings returned by GTIFGet... funcs */ +void CPL_DLL GTIFFreeMemory( char * ); +void CPL_DLL GTIFDeaccessCSV( void ); + +int CPL_DLL GTIFGetDefn( GTIF *psGTIF, GTIFDefn * psDefn ); +void CPL_DLL GTIFPrintDefn( GTIFDefn *, FILE * ); +void CPL_DLL GTIFFreeDefn( GTIF * ); + +void CPL_DLL SetCSVFilenameHook( const char *(*CSVFileOverride)(const char *) ); + +const char CPL_DLL *GTIFDecToDMS( double, const char *, int ); + +/* + * These are useful for recognising UTM and State Plane, with or without + * CSV files being found. + */ + +#define MapSys_UTM_North -9001 +#define MapSys_UTM_South -9002 +#define MapSys_State_Plane_27 -9003 +#define MapSys_State_Plane_83 -9004 + +int CPL_DLL GTIFMapSysToPCS( int MapSys, int Datum, int nZone ); +int CPL_DLL GTIFMapSysToProj( int MapSys, int nZone ); +int CPL_DLL GTIFPCSToMapSys( int PCSCode, int * pDatum, int * pZone ); +int CPL_DLL GTIFProjToMapSys( int ProjCode, int * pZone ); + +/* + * These are only useful if using libgeotiff with libproj (PROJ.4+). + */ +char CPL_DLL *GTIFGetProj4Defn( GTIFDefn * ); +int CPL_DLL GTIFProj4ToLatLong( GTIFDefn *, int, double *, double * ); +int CPL_DLL GTIFProj4FromLatLong( GTIFDefn *, int, double *, double * ); + +#if defined(HAVE_LIBPROJ) && defined(HAVE_PROJECTS_H) +# define HAVE_GTIFPROJ4 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ndef GEO_NORMALIZE_H_INCLUDED */ diff --git a/Utilities/otbgeotiff/geo_print.c b/Utilities/otbgeotiff/geo_print.c new file mode 100644 index 0000000000000000000000000000000000000000..4b969432e0fb2bc97900054fbddc7cd082074f7f --- /dev/null +++ b/Utilities/otbgeotiff/geo_print.c @@ -0,0 +1,517 @@ +/********************************************************************** + * + * geo_print.c -- Key-dumping routines for GEOTIFF files. + * + * Written By: Niles D. Ritter. + * + * copyright (c) 1995 Niles D. Ritter + * + * Permission granted to use this software, so long as this copyright + * notice accompanies any products derived therefrom. + * + * Revision History; + * + * 20 June, 1995 Niles D. Ritter New + * 7 July, 1995 NDR Fix indexing + * 27 July, 1995 NDR Added Import utils + * 28 July, 1995 NDR Made parser more strict. + * 29 Sep, 1995 NDR Fixed matrix printing. + * + * $Log: geo_print.c,v $ + * Revision 1.9 2004/10/19 14:24:09 fwarmerdam + * dynamically allocate tag list so large lists work: Oliver Colin + * + * Revision 1.8 2004/04/27 21:31:31 warmerda + * avoid crash if gt_tif is NULL + * + * Revision 1.7 2003/10/21 19:19:53 warmerda + * fixed bug with large message texts sometimes causing a crash + * + * Revision 1.6 2003/09/23 18:27:30 warmerda + * fixed bug with long datum names: bug 399 + * + * Revision 1.5 2003/07/08 17:31:30 warmerda + * cleanup various warnings + * + * Revision 1.4 2002/05/31 14:27:26 warmerda + * added escaping in metadata for string key values + * + * Revision 1.3 1999/05/04 03:14:35 warmerda + * avoid warnings + * + * Revision 1.2 1999/05/03 17:50:31 warmerda + * avoid warnings on IRIX + * + * + **********************************************************************/ + +#include "geotiff.h" /* public interface */ +#include "geo_tiffp.h" /* external TIFF interface */ +#include "geo_keyp.h" /* private interface */ +#include "geokeys.h" + +#include <stdio.h> /* for sprintf */ + +#define FMT_GEOTIFF "Geotiff_Information:" +#define FMT_VERSION "Version: %hd" +#define FMT_REV "Key_Revision: %1hd.%hd" +#define FMT_TAGS "Tagged_Information:" +#define FMT_TAGEND "End_Of_Tags." +#define FMT_KEYS "Keyed_Information:" +#define FMT_KEYEND "End_Of_Keys." +#define FMT_GEOEND "End_Of_Geotiff." +#define FMT_DOUBLE "%-17.9g" +#define FMT_SHORT "%-11hd" + +static void DefaultPrint(char *string, void *aux); +static void PrintKey(GeoKey *key, GTIFPrintMethod print,void *aux); +static void PrintGeoTags(GTIF *gtif,GTIFReadMethod scan,void *aux); +static void PrintTag(int tag, int nrows, double *data, int ncols, + GTIFPrintMethod print,void *aux); +static void DefaultRead(char *string, void *aux); +static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux); +static int ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux); + +/* + * Print off the directory info, using whatever method is specified + * (defaults to fprintf if null). The "aux" parameter is provided for user + * defined method for passing parameters or whatever. + * + * The output format is a "GeoTIFF meta-data" file, which may be + * used to import information with the GTIFFImport() routine. + */ + +void GTIFPrint(GTIF *gtif, GTIFPrintMethod print,void *aux) +{ + int i; + int numkeys = gtif->gt_num_keys; + GeoKey *key = gtif->gt_keys; + char message[1024]; + + if (!print) print = (GTIFPrintMethod) &DefaultPrint; + if (!aux) aux=stdout; + + sprintf(message,FMT_GEOTIFF "\n"); + print(message,aux); + sprintf(message, "Version: %hd" ,gtif->gt_version); + sprintf(message, FMT_VERSION,gtif->gt_version); + print(" ",aux); print(message,aux); print("\n",aux); + sprintf(message, FMT_REV,gtif->gt_rev_major, + gtif->gt_rev_minor); + print(" ",aux); print(message,aux); print("\n",aux); + + sprintf(message," %s\n",FMT_TAGS); print(message,aux); + PrintGeoTags(gtif,print,aux); + sprintf(message," %s\n",FMT_TAGEND); print(message,aux); + + sprintf(message," %s\n",FMT_KEYS); print(message,aux); + for (i=0; i<numkeys; i++) + PrintKey(++key,print,aux); + sprintf(message," %s\n",FMT_KEYEND); print(message,aux); + + sprintf(message," %s\n",FMT_GEOEND); print(message,aux); +} + +static void PrintGeoTags(GTIF *gt, GTIFPrintMethod print,void *aux) +{ + double *data; + int count; + tiff_t *tif=gt->gt_tif; + + if( tif == NULL ) + return; + + if ((gt->gt_methods.get)(tif, GTIFF_TIEPOINTS, &count, &data )) + PrintTag(GTIFF_TIEPOINTS,count/3, data, 3, print, aux); + if ((gt->gt_methods.get)(tif, GTIFF_PIXELSCALE, &count, &data )) + PrintTag(GTIFF_PIXELSCALE,count/3, data, 3, print, aux); + if ((gt->gt_methods.get)(tif, GTIFF_TRANSMATRIX, &count, &data )) + PrintTag(GTIFF_TRANSMATRIX,count/4, data, 4, print, aux); +} + +static void PrintTag(int tag, int nrows, double *dptr, int ncols, + GTIFPrintMethod print,void *aux) +{ + int i,j; + double *data=dptr; + char message[1024]; + + print(" ",aux); + print(GTIFTagName(tag),aux); + sprintf(message," (%d,%d):\n",nrows,ncols); + print(message,aux); + for (i=0;i<nrows;i++) + { + print(" ",aux); + for (j=0;j<ncols;j++) + { + sprintf(message,FMT_DOUBLE,*data++); + print(message,aux); + } + print("\n",aux); + } + _GTIFFree(dptr); /* free up the allocated memory */ +} + + +static void PrintKey(GeoKey *key, GTIFPrintMethod print, void *aux) +{ + char *data; + geokey_t keyid = (geokey_t) key->gk_key; + int count = key->gk_count; + int vals_now,i; + pinfo_t *sptr; + double *dptr; + char message[40]; + + print(" ",aux); + print(GTIFKeyName(keyid),aux); + + sprintf(message," (%s,%d): ",GTIFTypeName(key->gk_type),count); + print(message,aux); + + if (key->gk_type==TYPE_SHORT && count==1) + data = (char *)&key->gk_data; + else + data = key->gk_data; + + switch (key->gk_type) + { + case TYPE_ASCII: + { + int in_char, out_char; + + print("\"",aux); + + in_char = 0; + out_char = 0; + while( in_char < count-1 ) + { + char ch = ((char *) data)[in_char++]; + + if( ch == '\n' ) + { + message[out_char++] = '\\'; + message[out_char++] = 'n'; + } + else if( ch == '\\' ) + { + message[out_char++] = '\\'; + message[out_char++] = '\\'; + } + else + message[out_char++] = ch; + + /* flush message if buffer full */ + if( out_char >= sizeof(message)-3 ) + { + message[out_char] = '\0'; + print(message,aux); + out_char = 0; + } + } + + message[out_char]='\0'; + print(message,aux); + + print("\"\n",aux); + } + break; + + case TYPE_DOUBLE: + for (dptr = (double *)data; count > 0; count-= vals_now) + { + vals_now = count > 3? 3: count; + for (i=0; i<vals_now; i++,dptr++) + { + sprintf(message,FMT_DOUBLE ,*dptr); + print(message,aux); + } + print("\n",aux); + } + break; + + case TYPE_SHORT: + sptr = (pinfo_t *)data; + if (count==1) + { + print( GTIFValueName(keyid,*sptr), aux ); + print( "\n", aux ); + } + else + for (; count > 0; count-= vals_now) + { + vals_now = count > 3? 3: count; + for (i=0; i<vals_now; i++,sptr++) + { + sprintf(message,FMT_SHORT,*sptr); + print(message,aux); + } + print("\n",aux); + } + break; + + default: + sprintf(message, "Unknown Type (%d)\n",key->gk_type); + print(message,aux); + break; + } +} + +static void DefaultPrint(char *string, void *aux) +{ + /* Pretty boring */ + fprintf((FILE *)aux,string); +} + + +/* + * Importing metadata file + */ + +/* + * Import the directory info, using whatever method is specified + * (defaults to fscanf if null). The "aux" parameter is provided for user + * defined method for passing file or whatever. + * + * The input format is a "GeoTIFF meta-data" file, which may be + * generated by the GTIFFPrint() routine. + */ + +int GTIFImport(GTIF *gtif, GTIFReadMethod scan,void *aux) +{ + int status; + char message[1024]; + + if (!scan) scan = (GTIFReadMethod) &DefaultRead; + if (!aux) aux=stdin; + + scan(message,aux); + if (strncmp(message,FMT_GEOTIFF,8)) return 0; + scan(message,aux); + if (!sscanf(message,FMT_VERSION,>if->gt_version)) return 0; + scan(message,aux); + if (sscanf(message,FMT_REV,>if->gt_rev_major, + >if->gt_rev_minor) !=2) return 0; + + scan(message,aux); + if (strncmp(message,FMT_TAGS,8)) return 0; + while ((status=ReadTag(gtif,scan,aux))>0); + if (status < 0) return 0; + + scan(message,aux); + if (strncmp(message,FMT_KEYS,8)) return 0; + while ((status=ReadKey(gtif,scan,aux))>0); + + return (status==0); /* success */ +} + +static int StringError(char *string) +{ + fprintf(stderr,"Parsing Error at \'%s\'\n",string); + return -1; +} + +#define SKIPWHITE(vptr) \ + while (*vptr && (*vptr==' '||*vptr=='\t')) vptr++ +#define FINDCHAR(vptr,c) \ + while (*vptr && *vptr!=(c)) vptr++ + +static int ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux) +{ + int i,j,tag; + char *vptr; + char tagname[100]; + double *data,*dptr; + int count,nrows,ncols,num; + char message[1024]; + + scan(message,aux); + if (!strncmp(message,FMT_TAGEND,8)) return 0; + + num=sscanf(message,"%[^( ] (%d,%d):\n",tagname,&nrows,&ncols); + if (num!=3) return StringError(message); + + tag = GTIFTagCode(tagname); + if (tag < 0) return StringError(tagname); + + count = nrows*ncols; + + data = (double *) _GTIFcalloc(count * sizeof(double)); + dptr = data; + + for (i=0;i<nrows;i++) + { + scan(message,aux); + vptr = message; + for (j=0;j<ncols;j++) + { + if (!sscanf(vptr,"%lg",dptr++)) + return StringError(vptr); + FINDCHAR(vptr,' '); + SKIPWHITE(vptr); + } + } + (gt->gt_methods.set)(gt->gt_tif, (pinfo_t) tag, count, data ); + + _GTIFFree( data ); + + return 1; +} + + +static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux) +{ + tagtype_t ktype; + int count,outcount; + int vals_now,i; + geokey_t key; + int icode; + pinfo_t code; + short *sptr; + char name[1000]; + char type[20]; + double data[100]; + double *dptr; + char *vptr; + int num; + char message[2048]; + + scan(message,aux); + if (!strncmp(message,FMT_KEYEND,8)) return 0; + + num=sscanf(message,"%[^( ] (%[^,],%d):\n",name,type,&count); + if (num!=3) return StringError(message); + + vptr = message; + FINDCHAR(vptr,':'); + if (!*vptr) return StringError(message); + vptr+=2; + + if( GTIFKeyCode(name) < 0 ) + return StringError(name); + else + key = (geokey_t) GTIFKeyCode(name); + + if( GTIFTypeCode(type) < 0 ) + return StringError(type); + else + ktype = (tagtype_t) GTIFTypeCode(type); + + /* skip white space */ + SKIPWHITE(vptr); + if (!*vptr) return StringError(message); + + switch (ktype) + { + case TYPE_ASCII: + { + char *cdata; + int out_char = 0; + + FINDCHAR(vptr,'"'); + if (!*vptr) return StringError(message); + + cdata = (char *) _GTIFcalloc( count+1 ); + + vptr++; + while( out_char < count-1 ) + { + if( *vptr == '\0' ) + break; + + else if( vptr[0] == '\\' && vptr[1] == 'n' ) + { + cdata[out_char++] = '\n'; + vptr += 2; + } + else if( vptr[0] == '\\' && vptr[1] == '\\' ) + { + cdata[out_char++] = '\\'; + vptr += 2; + } + else + cdata[out_char++] = *(vptr++); + } + + if( out_char < count-1 ) return StringError(message); + if( *vptr != '"' ) return StringError(message); + + cdata[count-1] = '\0'; + GTIFKeySet(gt,key,ktype,count,cdata); + + _GTIFFree( cdata ); + } + break; + + case TYPE_DOUBLE: + outcount = count; + for (dptr = data; count > 0; count-= vals_now) + { + vals_now = count > 3? 3: count; + for (i=0; i<vals_now; i++,dptr++) + { + if (!sscanf(vptr,"%lg" ,dptr)) + StringError(vptr); + FINDCHAR(vptr,' '); + SKIPWHITE(vptr); + } + if (vals_now<count) + { + scan(message,aux); + vptr = message; + } + } + if (outcount==1) + GTIFKeySet(gt,key,ktype,outcount,data[0]); + else + GTIFKeySet(gt,key,ktype,outcount,data); + break; + + case TYPE_SHORT: + if (count==1) + { + icode = GTIFValueCode(key,vptr); + if (icode < 0) return StringError(vptr); + code = (pinfo_t) icode; + GTIFKeySet(gt,key,ktype,count,code); + } + else /* multi-valued short - no such thing yet */ + { + sptr = (short *)data; + outcount = count; + for (; count > 0; count-= vals_now) + { + vals_now = count > 3? 3: count; + for (i=0; i<vals_now; i++,sptr++) + { + int work_int; + + /* note: FMT_SHORT (%11hd) not supported on IRIX */ + sscanf(message,"%11d",&work_int); + *sptr = (short) work_int; + scan(message,aux); + } + if (vals_now<count) + { + scan(message,aux); + vptr = message; + } + } + GTIFKeySet(gt,key,ktype,outcount,sptr); + } + break; + + default: + return -1; + } + return 1; +} + + +static void DefaultRead(char *string, void *aux) +{ + /* Pretty boring */ + fscanf((FILE *)aux,"%[^\n]\n",string); +} + diff --git a/Utilities/otbgeotiff/geo_set.c b/Utilities/otbgeotiff/geo_set.c new file mode 100644 index 0000000000000000000000000000000000000000..48831796a9ae7c69e92a78d7e4223be5c8205918 --- /dev/null +++ b/Utilities/otbgeotiff/geo_set.c @@ -0,0 +1,262 @@ +/********************************************************************** + * + * geo_set.c -- Public routines for GEOTIFF GeoKey access. + * + * Written By: Niles D. Ritter. + * + * copyright (c) 1995 Niles D. Ritter + * + * Permission granted to use this software, so long as this copyright + * notice accompanies any products derived therefrom. + * + * $Log: geo_set.c,v $ + * Revision 1.11 2004/04/27 21:32:33 warmerda + * reformat for clarity + * + * Revision 1.10 2003/07/08 17:31:30 warmerda + * cleanup various warnings + * + * Revision 1.9 2003/01/15 03:37:19 warmerda + * avoid warning + * + * Revision 1.8 2002/09/27 13:05:33 warmerda + * allow dynamic set/delete of ASCII tags. ASCIIPARAMS now kept split + * + * Revision 1.7 2001/05/02 16:48:22 warmerda + * fixed a couple bugs in delete code + * + * Revision 1.6 2001/05/02 13:54:34 warmerda + * updated geo_set.c to support deleting tags + * + * Revision 1.5 1999/05/04 03:09:33 warmerda + * avoid warnings + * + * Revision 1.4 1999/05/03 17:50:31 warmerda + * avoid warnings on IRIX + * + * Revision 1.3 1999/04/28 19:59:38 warmerda + * added some doxygen style documentation + * + * Revision 1.2 1999/03/11 17:39:38 geotiff + * Added fix for case where a key is being overwritten. + * + **********************************************************************/ + +#include "geotiff.h" /* public interface */ +#include "geo_tiffp.h" /* external TIFF interface */ +#include "geo_keyp.h" /* private interface */ + +#include <assert.h> + +/** +This function writes a geokey_t value to a GeoTIFF file. + +@param gtif The geotiff information handle from GTIFNew(). + +@param keyID The geokey_t name (such as ProjectedCSTypeGeoKey). +This must come from the list of legal geokey_t values +(an enumeration) listed below. + +@param val The <b>val</b> argument is a pointer to the +variable into which the value should be read. The type of the variable +varies depending on the geokey_t given. While there is no ready mapping +of geokey_t values onto types, in general code values are of type <i>short</i>, +citations are strings, and everything else is of type <i>double</i>. Note +that pointer's to <i>int</i> should never be passed to GTIFKeyGet() for +integer values as they will be shorts, and the int's may not be properly +initialized (and will be grossly wrong on MSB systems). + +@param index Indicates how far into the list of values +for this geokey to offset. Should normally be zero. + +@param count Indicates how many values +to read. At this time all keys except for strings have only one value, +so <b>index</b> should be zero, and <b>count</b> should be one.<p> + +The <b>key</b> indicates the key name to be written to the +file and should from the geokey_t enumeration +(eg. <tt>ProjectedCSTypeGeoKey</tt>). The full list of possible geokey_t +values can be found in geokeys.inc, or in the online documentation for +GTIFKeyGet().<p> + +The <b>type</b> should be one of TYPE_SHORT, TYPE_ASCII, or TYPE_DOUBLE and +will indicate the type of value being passed at the end of the argument +list (the key value). The <b>count</b> should be one except for strings +when it should be the length of the string (or zero to for this to be +computed internally). As a special case a <b>count</b> of -1 can be +used to request an existing key be deleted, in which no value is passed.<p> + +The actual value is passed at the end of the argument list, and should be +a short, a double, or a char * value. Note that short and double values +are passed as is, not as pointers.<p> + +Note that key values aren't actually flushed to the file until +GTIFWriteKeys() is called. Till then +the new values are just kept with the GTIF structure.<p> + +<b>Example:</b><p> + +<pre> + GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, + RasterPixelIsArea); + GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 0, + "UTM 11 North / NAD27" ); +</pre> + + */ + +int GTIFKeySet(GTIF *gtif, geokey_t keyID, tagtype_t type, int count,...) +{ + va_list ap; + int index = gtif->gt_keyindex[ keyID ]; + int newvalues = 0; + GeoKey *key; + char *data = NULL; + char *val = NULL; + pinfo_t sval; + double dval; + + va_start(ap, count); + /* pass singleton keys by value */ + if (count>1 && type!=TYPE_ASCII) + { + val = va_arg(ap, char*); + } + else if( count == -1 ) + { + /* delete the indicated tag */ + va_end(ap); + + if( index < 1 ) + return 0; + + if (gtif->gt_keys[index].gk_type == TYPE_ASCII) + { + _GTIFFree (gtif->gt_keys[index].gk_data); + } + + while( index < gtif->gt_num_keys ) + { + _GTIFmemcpy( gtif->gt_keys + index, + gtif->gt_keys + index + 1, + sizeof(GeoKey) ); + gtif->gt_keyindex[gtif->gt_keys[index].gk_key] = index; + index++; + } + + gtif->gt_num_keys--; + gtif->gt_nshorts -= sizeof(KeyEntry)/sizeof(pinfo_t); + gtif->gt_keyindex[keyID] = 0; + gtif->gt_flags |= FLAG_FILE_MODIFIED; + + return 1; + } + else switch (type) + { + case TYPE_SHORT: sval=(pinfo_t) va_arg(ap, int); val=(char *)&sval; break; + case TYPE_DOUBLE: dval=va_arg(ap, dblparam_t); val=(char *)&dval; break; + case TYPE_ASCII: + val=va_arg(ap, char*); + count = strlen(val) + 1; /* force = string length */ + break; + default: + assert( FALSE ); + break; + } + va_end(ap); + + /* We assume here that there are no multi-valued SHORTS ! */ + if (index) + { + /* Key already exists */ + key = gtif->gt_keys+index; + if (type!=key->gk_type || count > key->gk_count) + { + /* need to reset data pointer */ + key->gk_type = type; + key->gk_count = count; + key->gk_size = _gtiff_size[ type ]; + newvalues = 1; + } + } + else + { + /* We need to create the key */ + if (gtif->gt_num_keys == MAX_KEYS) return 0; + key = gtif->gt_keys + ++gtif->gt_num_keys; + index = gtif->gt_num_keys; + gtif->gt_keyindex[ keyID ] = index; + key->gk_key = keyID; + key->gk_type = type; + key->gk_count = count; + key->gk_size = _gtiff_size[ type ]; + if (gtif->gt_keymin > keyID) gtif->gt_keymin=keyID; + if (gtif->gt_keymax < keyID) gtif->gt_keymax=keyID; + newvalues = 1; + } + + if (newvalues) + { + switch (type) + { + case TYPE_SHORT: + if (count > 1) return 0; + data = (char *)&key->gk_data; /* store value *in* data */ + break; + case TYPE_DOUBLE: + key->gk_data = (char *)(gtif->gt_double + gtif->gt_ndoubles); + data = key->gk_data; + gtif->gt_ndoubles += count; + break; + case TYPE_ASCII: + break; + default: + va_end(ap); + return 0; + } + gtif->gt_nshorts += sizeof(KeyEntry)/sizeof(pinfo_t); + } + + /* this fixes a bug where if a request is made to write a duplicate + key, we must initialize the data to a valid value. + Bryan Wells (bryan@athena.bangor.autometric.com) */ + + else /* no new values, but still have something to write */ + { + switch (type) + { + case TYPE_SHORT: + if (count > 1) return 0; + data = (char *)&key->gk_data; /* store value *in* data */ + break; + case TYPE_DOUBLE: + data = key->gk_data; + break; + case TYPE_ASCII: + break; + default: + return 0; + } + } + + switch (type) + { + case TYPE_ASCII: + /* throw away existing data and allocate room for new data */ + if (key->gk_data != 0) + { + _GTIFFree(key->gk_data); + } + key->gk_data = (char *)_GTIFcalloc(count); + key->gk_count = count; + data = key->gk_data; + break; + default: + break; + } + + _GTIFmemcpy(data, val, count*key->gk_size); + + gtif->gt_flags |= FLAG_FILE_MODIFIED; + return 1; +} diff --git a/Utilities/otbgeotiff/geo_tiffp.c b/Utilities/otbgeotiff/geo_tiffp.c new file mode 100644 index 0000000000000000000000000000000000000000..75de1dfe4f14431d572b408b9dae57cca9d8ff63 --- /dev/null +++ b/Utilities/otbgeotiff/geo_tiffp.c @@ -0,0 +1,140 @@ +/********************************************************************** + * + * geo_tiffp.c Private TIFF interface module for GEOTIFF + * + * This module implements the interface between the GEOTIFF + * tag parser and the TIFF i/o module. The current setup + * relies on the "libtiff" code, but if you use your own + * TIFF reader software, you may replace the module implementations + * here with your own calls. No "libtiff" dependencies occur + * anywhere else in this code. + * + **********************************************************************/ + +#include "geotiff.h" /* public GTIFF interface */ + +#include "geo_tiffp.h" /* Private TIFF interface */ +#include "geo_keyp.h" /* Private GTIFF interface */ + +/* tiff size array global */ +gsize_t _gtiff_size[] = { 0, 1, 2, 4, 8, 1, 4, 8, 1, 2, 4, 1 }; + +static int _GTIFGetField (tiff_t *tif, pinfo_t tag, int *count, void *value ); +static int _GTIFSetField (tiff_t *tif, pinfo_t tag, int count, void *value ); +static tagtype_t _GTIFTagType (tiff_t *tif, pinfo_t tag); + +/* + * Set up default TIFF handlers. + */ +void _GTIFSetDefaultTIFF(TIFFMethod *method) +{ + if (!method) return; + + method->get = _GTIFGetField; + method->set = _GTIFSetField; + method->type = _GTIFTagType; +} + +gdata_t _GTIFcalloc(gsize_t size) +{ + gdata_t data=(gdata_t)_TIFFmalloc((tsize_t)size); + if (data) _TIFFmemset((tdata_t)data,0,(tsize_t)size); + return data; +} + +gdata_t _GTIFrealloc(gdata_t ptr, gsize_t size) +{ + return( _TIFFrealloc((tdata_t)ptr, (tsize_t) size) ); +} + +void _GTIFmemcpy(gdata_t out,gdata_t in,gsize_t size) +{ + _TIFFmemcpy((tdata_t)out,(tdata_t)in,(tsize_t)size); +} + +void _GTIFFree(gdata_t data) +{ + if (data) _TIFFfree((tdata_t)data); +} + + + +/* returns the value of TIFF tag <tag>, or if + * the value is an array, returns an allocated buffer + * containing the values. Allocate a copy of the actual + * buffer, sized up for updating. + */ +static int _GTIFGetField (tiff_t *tif, pinfo_t tag, int *count, void *val ) +{ + int status; + unsigned short scount=0; + char *tmp; + char *value; + gsize_t size = _gtiff_size[_GTIFTagType (tif,tag)]; + + if (_GTIFTagType(tif, tag) == TYPE_ASCII) + { + status = TIFFGetField((TIFF *)tif,tag,&tmp); + if (!status) return status; + scount = (unsigned short) (strlen(tmp)+1); + } + else status = TIFFGetField((TIFF *)tif,tag,&scount,&tmp); + if (!status) return status; + + *count = scount; + + value = (char *)_GTIFcalloc( (scount+MAX_VALUES)*size); + if (!value) return 0; + + _TIFFmemcpy( value, tmp, size * scount); + + *(char **)val = value; + return status; +} + +/* + * Set a GeoTIFF TIFF field. + */ +static int _GTIFSetField (tiff_t *tif, pinfo_t tag, int count, void *value ) +{ + int status; + unsigned short scount = (unsigned short) count; + + /* libtiff ASCII uses null-delimiter */ + if (_GTIFTagType(tif, tag) == TYPE_ASCII) + status = TIFFSetField((TIFF *)tif,tag,value); + else + status = TIFFSetField((TIFF *)tif,tag,scount,value); + return status; +} + + +/* + * This routine is supposed to return the TagType of the <tag> + * TIFF tag. Unfortunately, "libtiff" does not provide this + * service by default, so we just have to "know" what type of tags + * we've got, and how many. We only define the ones Geotiff + * uses here, and others return UNKNOWN. The "tif" parameter + * is provided for those TIFF implementations that provide + * for tag-type queries. + */ +static tagtype_t _GTIFTagType (tiff_t *tif, pinfo_t tag) +{ + tagtype_t ttype; + + (void) tif; /* dummy reference */ + + switch (tag) + { + case GTIFF_ASCIIPARAMS: ttype=TYPE_ASCII; break; + case GTIFF_PIXELSCALE: + case GTIFF_TRANSMATRIX: + case GTIFF_TIEPOINTS: + case GTIFF_DOUBLEPARAMS: ttype=TYPE_DOUBLE; break; + case GTIFF_GEOKEYDIRECTORY: ttype=TYPE_SHORT; break; + default: ttype = TYPE_UNKNOWN; + } + + return ttype; +} + diff --git a/Utilities/otbgeotiff/geo_tiffp.h b/Utilities/otbgeotiff/geo_tiffp.h new file mode 100644 index 0000000000000000000000000000000000000000..8b065b8ddeeb244e6354f412269a367c889be8f4 --- /dev/null +++ b/Utilities/otbgeotiff/geo_tiffp.h @@ -0,0 +1,114 @@ +/********************************************************************** + * + * geo_tiffp.h - Private interface for TIFF tag parsing. + * + * Written by: Niles D. Ritter + * + * This interface file encapsulates the interface to external TIFF + * file-io routines and definitions. The current configuration + * assumes that the "libtiff" module is used, but if you have your + * own TIFF reader, you may replace the definitions with your own + * here, and replace the implementations in geo_tiffp.c. No other + * modules have any explicit dependence on external TIFF modules. + * + * Revision History; + * + * 20 June, 1995 Niles D. Ritter New + * 6 July, 1995 Niles D. Ritter Fix prototypes + * + **********************************************************************/ + +#ifndef __geo_tiffp_h_ +#define __geo_tiffp_h_ + +/********************************************************************** + * + * Private includes + * + * If you are not using libtiff and XTIFF, replace this include file + * with the appropriate one for your own TIFF parsing routines. + * + * Revision History + * + * 19 September 1995 ndr Demoted Intergraph trans matrix. + * + **********************************************************************/ + +#include "geotiff.h" +#include "xtiffio.h" +#include "cpl_serv.h" + +/* + * dblparam_t is the type that a double precision + * floating point value will have on the parameter + * stack (when coerced by the compiler). You shouldn't + * have to change this. + */ +#ifdef applec +typedef extended dblparam_t; +#else +typedef double dblparam_t; +#endif + + +/********************************************************************** + * + * Private defines + * + * If you are not using "libtiff"/LIBXTIFF, replace these definitions + * with the appropriate definitions to access the geo-tags + * + **********************************************************************/ + +typedef unsigned short pinfo_t; /* SHORT ProjectionInfo tag type */ +typedef TIFF tiff_t; /* TIFF file descriptor */ +typedef tdata_t gdata_t; /* pointer to data */ +typedef tsize_t gsize_t; /* data allocation size */ + +#define GTIFF_GEOKEYDIRECTORY TIFFTAG_GEOKEYDIRECTORY /* from xtiffio.h */ +#define GTIFF_DOUBLEPARAMS TIFFTAG_GEODOUBLEPARAMS +#define GTIFF_ASCIIPARAMS TIFFTAG_GEOASCIIPARAMS +#define GTIFF_PIXELSCALE TIFFTAG_GEOPIXELSCALE +#define GTIFF_TRANSMATRIX TIFFTAG_GEOTRANSMATRIX +#define GTIFF_INTERGRAPH_MATRIX TIFFTAG_INTERGRAPH_MATRIX +#define GTIFF_TIEPOINTS TIFFTAG_GEOTIEPOINTS +#define GTIFF_LOCAL 0 + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * Method function pointer types + */ +typedef int (*GTGetFunction) (tiff_t *tif, pinfo_t tag, int *count, void *value ); +typedef int (*GTSetFunction) (tiff_t *tif, pinfo_t tag, int count, void *value ); +typedef tagtype_t (*GTTypeFunction) (tiff_t *tif, pinfo_t tag); +typedef struct _TIFFMethod { + GTGetFunction get; + GTSetFunction set; + GTTypeFunction type; +} TIFFMethod; + +/********************************************************************** + * + * Protected Function Declarations + * + * These routines are exposed implementations, and should not + * be used by external GEOTIFF client programs. + * + **********************************************************************/ + +extern gsize_t _gtiff_size[]; /* TIFF data sizes */ +extern void CPL_DLL _GTIFSetDefaultTIFF(TIFFMethod *method); +extern gdata_t CPL_DLL _GTIFcalloc(gsize_t); +extern gdata_t CPL_DLL _GTIFrealloc(gdata_t,gsize_t); +extern void CPL_DLL _GTIFFree(gdata_t data); +extern void CPL_DLL _GTIFmemcpy(gdata_t out,gdata_t in,gsize_t size); + +#if defined(__cplusplus) +} +#endif + + +#endif /* __geo_tiffp_h_ */ diff --git a/Utilities/otbgeotiff/geo_trans.c b/Utilities/otbgeotiff/geo_trans.c new file mode 100644 index 0000000000000000000000000000000000000000..590f55efdde75418990ea1b237c44b250acf6e42 --- /dev/null +++ b/Utilities/otbgeotiff/geo_trans.c @@ -0,0 +1,334 @@ +/****************************************************************************** + * $Id: geo_trans.c,v 1.10 2003/07/08 17:31:30 warmerda Exp $ + * + * Project: libgeotiff + * Purpose: Code to abstract translation between pixel/line and PCS + * coordinates. + * Author: Frank Warmerdam, warmerda@home.com + * + ****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: geo_trans.c,v $ + * Revision 1.10 2003/07/08 17:31:30 warmerda + * cleanup various warnings + * + * Revision 1.9 2001/11/28 14:20:30 warmerda + * fixed transform memory leak in GTIFPCSToImage + * + * Revision 1.8 2001/04/06 16:56:22 warmerda + * added support for PCSToImage with matrix + * + * Revision 1.7 2001/03/05 03:25:23 warmerda + * restructure cleanup, and apply to GTIFPCSToImage() + * + * Revision 1.6 2001/03/04 22:37:39 warmerda + * fixed memory leak for fields fetched with gt_methods.get - Alan Gray + * + * Revision 1.5 2000/08/22 03:32:46 warmerda + * removed GTIFTiepointTranslate code + * + * Revision 1.4 1999/09/17 01:19:51 warmerda + * Fixed bug in use of transform matrix. + * + * Revision 1.3 1999/09/16 21:25:40 warmerda + * Added tiepoint, and transformation matrix based translation. Note + * that we don't try to invert the transformation matrix for + * GTIFPCSToImage(). + * + * Revision 1.2 1999/09/07 20:00:40 warmerda + * Fixed count/tiepoint_count bug in GTIFPCSToImage(). + * + * Revision 1.1 1999/05/04 03:07:57 warmerda + * New + * + */ + +#include "geotiff.h" +#include "geo_tiffp.h" /* external TIFF interface */ +#include "geo_keyp.h" /* private interface */ +#include "geokeys.h" + +/************************************************************************/ +/* inv_geotransform() */ +/* */ +/* Invert a 6 term geotransform style matrix. */ +/************************************************************************/ + +static int inv_geotransform( double *gt_in, double *gt_out ) + +{ + double det, inv_det; + + /* we assume a 3rd row that is [0 0 1] */ + + /* Compute determinate */ + + det = gt_in[0] * gt_in[4] - gt_in[1] * gt_in[3]; + + if( fabs(det) < 0.000000000000001 ) + return 0; + + inv_det = 1.0 / det; + + /* compute adjoint, and devide by determinate */ + + gt_out[0] = gt_in[4] * inv_det; + gt_out[3] = -gt_in[3] * inv_det; + + gt_out[1] = -gt_in[1] * inv_det; + gt_out[4] = gt_in[0] * inv_det; + + gt_out[2] = ( gt_in[1] * gt_in[5] - gt_in[2] * gt_in[4]) * inv_det; + gt_out[5] = (-gt_in[0] * gt_in[5] + gt_in[2] * gt_in[3]) * inv_det; + + return 1; +} + +/************************************************************************/ +/* GTIFTiepointTranslate() */ +/************************************************************************/ + +int GTIFTiepointTranslate( int gcp_count, double * gcps_in, double * gcps_out, + double x_in, double y_in, + double *x_out, double *y_out ) + +{ + (void) gcp_count; + (void) gcps_in; + (void) gcps_out; + (void) x_in; + (void) y_in; + (void) x_out; + (void) y_out; + + /* I would appreciate a _brief_ block of code for doing second order + polynomial regression here! */ + return FALSE; +} + + +/************************************************************************/ +/* GTIFImageToPCS() */ +/************************************************************************/ + +/** + * Translate a pixel/line coordinate to projection coordinates. + * + * At this time this function does not support image to PCS translations for + * tiepoints-only definitions, only pixelscale and transformation matrix + * formulations. + * + * @param gtif The handle from GTIFNew() indicating the target file. + * @param x A pointer to the double containing the pixel offset on input, + * and into which the easting/longitude will be put on completion. + * @param y A pointer to the double containing the line offset on input, + * and into which the northing/latitude will be put on completion. + * + * @return TRUE if the transformation succeeds, or FALSE if it fails. It may + * fail if the file doesn't have properly setup transformation information, + * or it is in a form unsupported by this function. + */ + +int GTIFImageToPCS( GTIF *gtif, double *x, double *y ) + +{ + int res = FALSE; + int tiepoint_count, count, transform_count; + tiff_t *tif=gtif->gt_tif; + double *tiepoints = 0; + double *pixel_scale = 0; + double *transform = 0; + + + if (!(gtif->gt_methods.get)(tif, GTIFF_TIEPOINTS, + &tiepoint_count, &tiepoints )) + tiepoint_count = 0; + + if (!(gtif->gt_methods.get)(tif, GTIFF_PIXELSCALE, &count, &pixel_scale )) + count = 0; + + if (!(gtif->gt_methods.get)(tif, GTIFF_TRANSMATRIX, + &transform_count, &transform )) + transform_count = 0; + +/* -------------------------------------------------------------------- */ +/* If the pixelscale count is zero, but we have tiepoints use */ +/* the tiepoint based approach. */ +/* -------------------------------------------------------------------- */ + if( tiepoint_count > 6 && count == 0 ) + { + res = GTIFTiepointTranslate( tiepoint_count / 6, + tiepoints, tiepoints + 3, + *x, *y, x, y ); + } + +/* -------------------------------------------------------------------- */ +/* If we have a transformation matrix, use it. */ +/* -------------------------------------------------------------------- */ + else if( transform_count == 16 ) + { + double x_in = *x, y_in = *y; + + *x = x_in * transform[0] + y_in * transform[1] + transform[3]; + *y = x_in * transform[4] + y_in * transform[5] + transform[7]; + + res = TRUE; + } + +/* -------------------------------------------------------------------- */ +/* For now we require one tie point, and a valid pixel scale. */ +/* -------------------------------------------------------------------- */ + else if( count < 3 || tiepoint_count < 6 ) + { + res = FALSE; + } + + else + { + *x = (*x - tiepoints[0]) * pixel_scale[0] + tiepoints[3]; + *y = (*y - tiepoints[1]) * (-1 * pixel_scale[1]) + tiepoints[4]; + + res = TRUE; + } + +/* -------------------------------------------------------------------- */ +/* Cleanup */ +/* -------------------------------------------------------------------- */ + if(tiepoints) + _GTIFFree(tiepoints); + if(pixel_scale) + _GTIFFree(pixel_scale); + if(transform) + _GTIFFree(transform); + + return res; +} + +/************************************************************************/ +/* GTIFPCSToImage() */ +/************************************************************************/ + +/** + * Translate a projection coordinate to pixel/line coordinates. + * + * At this time this function does not support PCS to image translations for + * tiepoints-only based definitions, only matrix and pixelscale/tiepoints + * formulations are supposed. + * + * @param gtif The handle from GTIFNew() indicating the target file. + * @param x A pointer to the double containing the pixel offset on input, + * and into which the easting/longitude will be put on completion. + * @param y A pointer to the double containing the line offset on input, + * and into which the northing/latitude will be put on completion. + * + * @return TRUE if the transformation succeeds, or FALSE if it fails. It may + * fail if the file doesn't have properly setup transformation information, + * or it is in a form unsupported by this function. + */ + +int GTIFPCSToImage( GTIF *gtif, double *x, double *y ) + +{ + double *tiepoints = NULL; + int tiepoint_count, count, transform_count = 0; + double *pixel_scale = NULL; + double *transform = NULL; + tiff_t *tif=gtif->gt_tif; + int result = FALSE; + +/* -------------------------------------------------------------------- */ +/* Fetch tiepoints and pixel scale. */ +/* -------------------------------------------------------------------- */ + if (!(gtif->gt_methods.get)(tif, GTIFF_TIEPOINTS, + &tiepoint_count, &tiepoints )) + tiepoint_count = 0; + + if (!(gtif->gt_methods.get)(tif, GTIFF_PIXELSCALE, &count, &pixel_scale )) + count = 0; + + if (!(gtif->gt_methods.get)(tif, GTIFF_TRANSMATRIX, + &transform_count, &transform )) + transform_count = 0; + +/* -------------------------------------------------------------------- */ +/* If the pixelscale count is zero, but we have tiepoints use */ +/* the tiepoint based approach. */ +/* -------------------------------------------------------------------- */ + if( tiepoint_count > 6 && count == 0 ) + { + result = GTIFTiepointTranslate( tiepoint_count / 6, + tiepoints + 3, tiepoints, + *x, *y, x, y ); + } + +/* -------------------------------------------------------------------- */ +/* Handle matrix - convert to "geotransform" format, invert and */ +/* apply. */ +/* -------------------------------------------------------------------- */ + else if( transform_count == 16 ) + { + double x_in = *x, y_in = *y; + double gt_in[6], gt_out[6]; + + gt_in[0] = transform[0]; + gt_in[1] = transform[1]; + gt_in[2] = transform[3]; + gt_in[3] = transform[4]; + gt_in[4] = transform[5]; + gt_in[5] = transform[7]; + + if( !inv_geotransform( gt_in, gt_out ) ) + result = FALSE; + else + { + *x = x_in * gt_out[0] + y_in * gt_out[1] + gt_out[2]; + *y = x_in * gt_out[3] + y_in * gt_out[4] + gt_out[5]; + + result = TRUE; + } + } + +/* -------------------------------------------------------------------- */ +/* For now we require one tie point, and a valid pixel scale. */ +/* -------------------------------------------------------------------- */ + else if( count >= 3 && tiepoint_count >= 6 ) + { + *x = (*x - tiepoints[3]) / pixel_scale[0] + tiepoints[0]; + *y = (*y - tiepoints[4]) / (-1 * pixel_scale[1]) + tiepoints[1]; + + result = TRUE; + } + +/* -------------------------------------------------------------------- */ +/* Cleanup. */ +/* -------------------------------------------------------------------- */ + if(tiepoints) + _GTIFFree(tiepoints); + if(pixel_scale) + _GTIFFree(pixel_scale); + if(transform) + _GTIFFree(transform); + + return result; +} + diff --git a/Utilities/otbgeotiff/geo_write.c b/Utilities/otbgeotiff/geo_write.c new file mode 100644 index 0000000000000000000000000000000000000000..0e94d53dcbd4fdda89e158c185d3f469e0f28c32 --- /dev/null +++ b/Utilities/otbgeotiff/geo_write.c @@ -0,0 +1,193 @@ +/********************************************************************** + * + * geo_write.c -- Public routines for GEOTIFF GeoKey access. + * + * Written By: Niles D. Ritter. + * + * copyright (c) 1995 Niles D. Ritter + * + * Permission granted to use this software, so long as this copyright + * notice accompanies any source code derived therefrom. + * + **********************************************************************/ + +#include "geotiffio.h" /* public interface */ +#include "geo_tiffp.h" /* external TIFF interface */ +#include "geo_keyp.h" /* private interface */ + +static int WriteKey(GTIF* gt, TempKeyData* tempData, + KeyEntry* entptr, GeoKey* keyptr); +static int SortKeys(GTIF* gt,int *sortkeys); + + +/** +This function flushes all the GeoTIFF keys that have been set with the +GTIFKeySet() function into the associated +TIFF file. + +@param gt The GeoTIFF handle returned by GTIFNew. + +GTIFWriteKeys() should be called before +GTIFFree() is used to deallocate a GeoTIFF access handle. + */ + +int GTIFWriteKeys(GTIF *gt) +{ + int i; + GeoKey *keyptr; + KeyEntry *entptr; + KeyHeader *header; + TempKeyData tempData; + int sortkeys[MAX_KEYS]; + + if (!(gt->gt_flags & FLAG_FILE_MODIFIED)) return 1; + + if( gt->gt_tif == NULL ) + return 0; + + tempData.tk_asciiParams = 0; + tempData.tk_asciiParamsLength = 0; + tempData.tk_asciiParamsOffset = 0; + + /* Sort the Keys into numerical order */ + if (!SortKeys(gt,sortkeys)) + { + /* XXX error: a key was not recognized */ + } + + /* Set up header of ProjectionInfo tag */ + header = (KeyHeader *)gt->gt_short; + header->hdr_num_keys = (pinfo_t) gt->gt_num_keys; + header->hdr_version = GvCurrentVersion; + header->hdr_rev_major = GvCurrentRevision; + header->hdr_rev_minor = GvCurrentMinorRev; + + /* Sum up the ASCII tag lengths */ + for (i = 0; i < gt->gt_num_keys; i++) + { + keyptr = gt->gt_keys + sortkeys[i]; + if (keyptr->gk_type == TYPE_ASCII) + { + tempData.tk_asciiParamsLength += keyptr->gk_count; + } + } + if (tempData.tk_asciiParamsLength > 0) + { + tempData.tk_asciiParams = + (char *)_GTIFcalloc(tempData.tk_asciiParamsLength + 1); + tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0'; + } + + /* Set up the rest of SHORT array properly */ + keyptr = gt->gt_keys; + entptr = (KeyEntry*)(gt->gt_short + 4); + for (i=0; i< gt->gt_num_keys; i++,entptr++) + { + if (!WriteKey(gt,&tempData,entptr,keyptr+sortkeys[i])) return 0; + } + + /* Write out the Key Directory */ + (gt->gt_methods.set)(gt->gt_tif, GTIFF_GEOKEYDIRECTORY, gt->gt_nshorts, gt->gt_short ); + + /* Write out the params directories */ + if (gt->gt_ndoubles) + (gt->gt_methods.set)(gt->gt_tif, GTIFF_DOUBLEPARAMS, gt->gt_ndoubles, gt->gt_double ); + if (tempData.tk_asciiParamsLength > 0) + { + /* just to be safe */ + tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0'; + (gt->gt_methods.set)(gt->gt_tif, + GTIFF_ASCIIPARAMS, 0, tempData.tk_asciiParams); + } + + gt->gt_flags &= ~FLAG_FILE_MODIFIED; + + if (tempData.tk_asciiParamsLength > 0) + { + _GTIFFree (tempData.tk_asciiParams); + } + return 1; +} + +/********************************************************************** + * + * Private Routines + * + **********************************************************************/ + +/* + * Given GeoKey, write out the KeyEntry entries, returning 0 if failure. + * This is the exact complement of ReadKey(). + */ + +static int WriteKey(GTIF* gt, TempKeyData* tempData, + KeyEntry* entptr, GeoKey* keyptr) +{ + int count; + + entptr->ent_key = (pinfo_t) keyptr->gk_key; + entptr->ent_count = (pinfo_t) keyptr->gk_count; + count = entptr->ent_count; + + if (count==1 && keyptr->gk_type==TYPE_SHORT) + { + entptr->ent_location = GTIFF_LOCAL; + entptr->ent_val_offset = *(pinfo_t*)&keyptr->gk_data; + return 1; + } + + switch (keyptr->gk_type) + { + case TYPE_SHORT: + entptr->ent_location = GTIFF_GEOKEYDIRECTORY; + entptr->ent_val_offset = (pinfo_t) + ((pinfo_t*)keyptr->gk_data - gt->gt_short); + break; + case TYPE_DOUBLE: + entptr->ent_location = GTIFF_DOUBLEPARAMS; + entptr->ent_val_offset = (pinfo_t) + ((double*)keyptr->gk_data - gt->gt_double); + break; + case TYPE_ASCII: + entptr->ent_location = GTIFF_ASCIIPARAMS; + entptr->ent_val_offset = (pinfo_t) tempData->tk_asciiParamsOffset; + _GTIFmemcpy (tempData->tk_asciiParams + tempData->tk_asciiParamsOffset + , keyptr->gk_data, keyptr->gk_count); + tempData->tk_asciiParams[tempData->tk_asciiParamsOffset+keyptr->gk_count-1] = '|'; + tempData->tk_asciiParamsOffset += keyptr->gk_count; + break; + default: + return 0; /* failure */ + } + + return 1; /* success */ +} + + +/* + * Numerically sort the GeoKeys. + * We just do a linear search through + * the list and pull out the keys that were set. + */ + +static int SortKeys(GTIF* gt,int *sortkeys) +{ + int loc; + int nkeys=0; + geokey_t key,kmin,kmax; + int *index = gt->gt_keyindex; + + kmin = (geokey_t) gt->gt_keymin; + kmax = (geokey_t) gt->gt_keymax; + for (key=kmin; key<=kmax; key++) + { + if ( (loc=index[key]) != 0 ) + { + sortkeys[nkeys] = loc; + nkeys++; + } + } + + return nkeys==gt->gt_num_keys; +} + diff --git a/Utilities/otbgeotiff/geokeys.h b/Utilities/otbgeotiff/geokeys.h new file mode 100644 index 0000000000000000000000000000000000000000..f3e47c14b3519253085695a553d58efe1bb6b913 --- /dev/null +++ b/Utilities/otbgeotiff/geokeys.h @@ -0,0 +1,54 @@ +/********************************************************************** + * + * geokeys.h - Public registry for valid GEOTIFF GeoKeys. + * + * Written By: Niles D. Ritter + * + * Revision History: + * + * Rev.# Author M/D/Y Date Key Changes/Additions + * ----- ------ ---------- ------------------------------------- + * 0 ndr 06/10/95 Inital Beta Release + * 1 ndr 09/18/95 Final 1.0 Release + * + **********************************************************************/ + +#ifndef __geokeys_h_ +#define __geokeys_h_ + +/* The GvCurrentRevision number should be incremented whenever a + * new set of Keys are defined or modified in "geokeys.inc", and comments + * added to the "Revision History" section above. If only code + * _values_ are augmented, the "GvCurrentMinorRev" number should + * be incremented instead (see "geovalues.h"). Whenever the + * GvCurrentRevision is incremented, the GvCurrentMinorRev should + * be reset to zero. + * + * + * The Section Numbers below refer to the GeoTIFF Spec sections + * in which these values are documented. + * + */ +#define GvCurrentRevision 1 /* Final 1.0 Release */ + +#ifdef ValuePair +# undef ValuePair +#endif +#define ValuePair(name,value) name = value, + +typedef enum { + BaseGeoKey = 1024, /* First valid code */ + +# include "geokeys.inc" /* geokey database */ + + ReservedEndGeoKey = 32767, + + /* Key space available for Private or internal use */ + PrivateBaseGeoKey = 32768, /* Consistent with TIFF Private tags */ + PrivateEndGeoKey = 65535, + + EndGeoKey = 65535 /* Largest Possible GeoKey ID */ +} geokey_t; + + +#endif /* __geokeys_h_ */ diff --git a/Utilities/otbgeotiff/geokeys.inc b/Utilities/otbgeotiff/geokeys.inc new file mode 100644 index 0000000000000000000000000000000000000000..286c23c2bd4cbc1a262eec1bc79b14296f2bebd9 --- /dev/null +++ b/Utilities/otbgeotiff/geokeys.inc @@ -0,0 +1,76 @@ +/* GeoTIFF GeoKey Database */ + +/* Note: Any changes/additions to this database require */ +/* a change in the revision value in geokeys.h */ + +/* C database for Geotiff include files. */ +/* the macro ValuePair() must be defined */ +/* by the enclosing include file */ + +/* Revised 28 Sep 1995 NDR -- Added Rev. 1.0 aliases. */ + +/* 6.2.1 GeoTIFF Configuration Keys */ + +ValuePair( GTModelTypeGeoKey, 1024) /* Section 6.3.1.1 Codes */ +ValuePair( GTRasterTypeGeoKey, 1025) /* Section 6.3.1.2 Codes */ +ValuePair( GTCitationGeoKey, 1026) /* documentation */ + +/* 6.2.2 Geographic CS Parameter Keys */ + +ValuePair( GeographicTypeGeoKey, 2048) /* Section 6.3.2.1 Codes */ +ValuePair( GeogCitationGeoKey, 2049) /* documentation */ +ValuePair( GeogGeodeticDatumGeoKey, 2050) /* Section 6.3.2.2 Codes */ +ValuePair( GeogPrimeMeridianGeoKey, 2051) /* Section 6.3.2.4 codes */ +ValuePair( GeogLinearUnitsGeoKey, 2052) /* Section 6.3.1.3 Codes */ +ValuePair( GeogLinearUnitSizeGeoKey, 2053) /* meters */ +ValuePair( GeogAngularUnitsGeoKey, 2054) /* Section 6.3.1.4 Codes */ +ValuePair( GeogAngularUnitSizeGeoKey, 2055) /* radians */ +ValuePair( GeogEllipsoidGeoKey, 2056) /* Section 6.3.2.3 Codes */ +ValuePair( GeogSemiMajorAxisGeoKey, 2057) /* GeogLinearUnits */ +ValuePair( GeogSemiMinorAxisGeoKey, 2058) /* GeogLinearUnits */ +ValuePair( GeogInvFlatteningGeoKey, 2059) /* ratio */ +ValuePair( GeogAzimuthUnitsGeoKey, 2060) /* Section 6.3.1.4 Codes */ +ValuePair( GeogPrimeMeridianLongGeoKey, 2061) /* GeoAngularUnit */ + +/* 6.2.3 Projected CS Parameter Keys */ +/* Several keys have been renamed,*/ +/* and the deprecated names aliased for backward compatibility */ + +ValuePair( ProjectedCSTypeGeoKey, 3072) /* Section 6.3.3.1 codes */ +ValuePair( PCSCitationGeoKey, 3073) /* documentation */ +ValuePair( ProjectionGeoKey, 3074) /* Section 6.3.3.2 codes */ +ValuePair( ProjCoordTransGeoKey, 3075) /* Section 6.3.3.3 codes */ +ValuePair( ProjLinearUnitsGeoKey, 3076) /* Section 6.3.1.3 codes */ +ValuePair( ProjLinearUnitSizeGeoKey, 3077) /* meters */ +ValuePair( ProjStdParallel1GeoKey, 3078) /* GeogAngularUnit */ +ValuePair( ProjStdParallelGeoKey,ProjStdParallel1GeoKey) /* ** alias ** */ +ValuePair( ProjStdParallel2GeoKey, 3079) /* GeogAngularUnit */ +ValuePair( ProjNatOriginLongGeoKey, 3080) /* GeogAngularUnit */ +ValuePair( ProjOriginLongGeoKey,ProjNatOriginLongGeoKey) /* ** alias ** */ +ValuePair( ProjNatOriginLatGeoKey, 3081) /* GeogAngularUnit */ +ValuePair( ProjOriginLatGeoKey,ProjNatOriginLatGeoKey) /* ** alias ** */ +ValuePair( ProjFalseEastingGeoKey, 3082) /* ProjLinearUnits */ +ValuePair( ProjFalseNorthingGeoKey, 3083) /* ProjLinearUnits */ +ValuePair( ProjFalseOriginLongGeoKey, 3084) /* GeogAngularUnit */ +ValuePair( ProjFalseOriginLatGeoKey, 3085) /* GeogAngularUnit */ +ValuePair( ProjFalseOriginEastingGeoKey, 3086) /* ProjLinearUnits */ +ValuePair( ProjFalseOriginNorthingGeoKey, 3087) /* ProjLinearUnits */ +ValuePair( ProjCenterLongGeoKey, 3088) /* GeogAngularUnit */ +ValuePair( ProjCenterLatGeoKey, 3089) /* GeogAngularUnit */ +ValuePair( ProjCenterEastingGeoKey, 3090) /* ProjLinearUnits */ +ValuePair( ProjCenterNorthingGeoKey, 3091) /* ProjLinearUnits */ +ValuePair( ProjScaleAtNatOriginGeoKey, 3092) /* ratio */ +ValuePair( ProjScaleAtOriginGeoKey,ProjScaleAtNatOriginGeoKey) /* ** alias ** */ +ValuePair( ProjScaleAtCenterGeoKey, 3093) /* ratio */ +ValuePair( ProjAzimuthAngleGeoKey, 3094) /* GeogAzimuthUnit */ +ValuePair( ProjStraightVertPoleLongGeoKey, 3095) /* GeogAngularUnit */ +ValuePair( ProjRectifiedGridAngleGeoKey, 3096) /* GeogAngularUnit */ + +/* 6.2.4 Vertical CS Keys */ + +ValuePair( VerticalCSTypeGeoKey, 4096) /* Section 6.3.4.1 codes */ +ValuePair( VerticalCitationGeoKey, 4097) /* documentation */ +ValuePair( VerticalDatumGeoKey, 4098) /* Section 6.3.4.2 codes */ +ValuePair( VerticalUnitsGeoKey, 4099) /* Section 6.3.1 (.x) codes */ + +/* End of Data base */ diff --git a/Utilities/otbgeotiff/geonames.h b/Utilities/otbgeotiff/geonames.h new file mode 100644 index 0000000000000000000000000000000000000000..ccedc7df32f2f719dcceb8cb4f4350d3f5f45cdc --- /dev/null +++ b/Utilities/otbgeotiff/geonames.h @@ -0,0 +1,146 @@ +/* + * geonames.h + * + * This encapsulates all of the value-naming mechanism of + * libgeotiff. + * + * Written By: Niles Ritter + * + * Revision History: + * + * Author Date Key Changes/Additions + * ------ ---------- ------------------------------------- + * ndr 10 Jun 95 Inital Beta Release + * ndr 28 Jul 95 Added ModelType aliases, Kv aliases. + */ + +#ifndef __geonames_h +#define __geonames_h + +struct _KeyInfo { + int ki_key; + char *ki_name; +}; +typedef struct _KeyInfo KeyInfo; + +/* If memory is a premium, then omitting the + * long name lists may save some space; simply + * #define OMIT_GEOTIFF_NAMES in the compile statement + * to remove all key->string translation. + */ +#ifdef ValuePair +# undef ValuePair +#endif + +#ifndef OMIT_GEOTIFF_NAMES +#define ValuePair(token,value) {token,#token}, +#else +#define ValuePair(token,value) +#endif + +#define END_LIST { -1, (char *)0} + +/************************************************************ + * 6.2.x GeoTIFF Keys + ************************************************************/ + +static KeyInfo _keyInfo[] = { +# include "geokeys.inc" /* geokey database */ + END_LIST +}; + +#define COMMON_VALUES \ + {KvUndefined, "Undefined"}, \ + {KvUserDefined,"User-Defined"}, \ + ValuePair(KvUndefined,KvUndefined) \ + ValuePair(KvUserDefined,KvUserDefined) + +static KeyInfo _csdefaultValue[] = { + COMMON_VALUES + END_LIST +}; + +/************************************************************ + * 6.3.x GeoTIFF Key Values + ************************************************************/ + +static KeyInfo _modeltypeValue[] = { + COMMON_VALUES + ValuePair(ModelTypeProjected,1) + ValuePair(ModelTypeGeographic,2) + ValuePair(ModelTypeGeocentric,3) + ValuePair(ModelProjected,1) /* aliases */ + ValuePair(ModelGeographic,2) /* aliases */ + ValuePair(ModelGeocentric,3) /* aliases */ + END_LIST +}; + +static KeyInfo _rastertypeValue[] = { + COMMON_VALUES + ValuePair(RasterPixelIsArea,1) + ValuePair(RasterPixelIsPoint,2) + END_LIST +}; + +static KeyInfo _geounitsValue[] = { + COMMON_VALUES +# include "epsg_units.inc" + END_LIST +}; + +static KeyInfo _geographicValue[] = { + COMMON_VALUES +# include "epsg_gcs.inc" + END_LIST +}; + +static KeyInfo _geodeticdatumValue[] = { + COMMON_VALUES +# include "epsg_datum.inc" + END_LIST +}; + +static KeyInfo _ellipsoidValue[] = { + COMMON_VALUES +# include "epsg_ellipse.inc" + END_LIST +}; + +static KeyInfo _primemeridianValue[] = { + COMMON_VALUES +# include "epsg_pm.inc" + END_LIST +}; + +static KeyInfo _pcstypeValue[] = { + COMMON_VALUES +# include "epsg_pcs.inc" + END_LIST +}; + +static KeyInfo _projectionValue[] = { + COMMON_VALUES +# include "epsg_proj.inc" + END_LIST +}; + +static KeyInfo _coordtransValue[] = { + COMMON_VALUES +# include "geo_ctrans.inc" + END_LIST +}; + +static KeyInfo _vertcstypeValue[] = { + COMMON_VALUES +# include "epsg_vertcs.inc" + END_LIST +}; + +static KeyInfo _vdatumValue[] = { + COMMON_VALUES + ValuePair(VDatumBase,1) + END_LIST +}; + +#endif /* __geonames_h */ + diff --git a/Utilities/otbgeotiff/geotiff.h b/Utilities/otbgeotiff/geotiff.h new file mode 100644 index 0000000000000000000000000000000000000000..0af6883e9ba54eca7d859ac4fdee946a2a70b14a --- /dev/null +++ b/Utilities/otbgeotiff/geotiff.h @@ -0,0 +1,117 @@ +/********************************************************************** + * + * geotiff.h - Public interface for Geotiff tag parsing. + * + * + * Written By: Niles D. Ritter + * + **********************************************************************/ + +#ifndef __geotiff_h_ +#define __geotiff_h_ + +/** + * \file geotiff.h + * + * Primary libgeotiff include file. + * + * This is the defacto registry for valid GEOTIFF GeoKeys + * and their associated symbolic values. This is also the only file + * of the GeoTIFF library which needs to be included in client source + * code. + */ + +/* This Version code should only change if a drastic + * alteration is made to the GeoTIFF key structure. Readers + * encountering a larger value should give up gracefully. + */ +#define GvCurrentVersion 1 + +#define LIBGEOTIFF_VERSION 1240 + +#include "geo_config.h" +#include "geokeys.h" + +/********************************************************************** + * Do we want to build as a DLL on windows? + **********************************************************************/ +#if !defined(CPL_DLL) +# if defined(_WIN32) && defined(BUILD_AS_DLL) +# define CPL_DLL __declspec(dllexport) +# else +# define CPL_DLL +# endif +#endif + +/********************************************************************** + * + * Public Structures & Definitions + * + **********************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +typedef struct gtiff GTIF; /* struct gtiff is private */ +typedef unsigned short tifftag_t; +typedef unsigned short geocode_t; +typedef int (*GTIFPrintMethod)(char *string, void *aux); +typedef int (*GTIFReadMethod)(char *string, void *aux); + +typedef enum { + TYPE_BYTE=1, + TYPE_SHORT=2, + TYPE_LONG=3, + TYPE_RATIONAL=4, + TYPE_ASCII=5, + TYPE_FLOAT=6, + TYPE_DOUBLE=7, + TYPE_SBYTE=8, + TYPE_SSHORT=9, + TYPE_SLONG=10, + TYPE_UNKNOWN=11 +} tagtype_t; + + +/********************************************************************** + * + * Public Function Declarations + * + **********************************************************************/ + +/* TIFF-level interface */ +GTIF CPL_DLL *GTIFNew(void *tif); +void CPL_DLL GTIFFree(GTIF *gtif); +int CPL_DLL GTIFWriteKeys(GTIF *gtif); +void CPL_DLL GTIFDirectoryInfo(GTIF *gtif, int *versions, int *keycount); + +/* GeoKey Access */ +int CPL_DLL GTIFKeyInfo(GTIF *gtif, geokey_t key, int *size, tagtype_t* type); +int CPL_DLL GTIFKeyGet(GTIF *gtif, geokey_t key, void *val, int index, + int count); +int CPL_DLL GTIFKeySet(GTIF *gtif, geokey_t keyID, tagtype_t type, + int count,...); + +/* Metadata Import-Export utilities */ +void CPL_DLL GTIFPrint(GTIF *gtif, GTIFPrintMethod print, void *aux); +int CPL_DLL GTIFImport(GTIF *gtif, GTIFReadMethod scan, void *aux); +char CPL_DLL *GTIFKeyName(geokey_t key); +char CPL_DLL *GTIFValueName(geokey_t key,int value); +char CPL_DLL *GTIFTypeName(tagtype_t type); +char CPL_DLL *GTIFTagName(int tag); +int CPL_DLL GTIFKeyCode(char * key); +int CPL_DLL GTIFValueCode(geokey_t key,char *value); +int CPL_DLL GTIFTypeCode(char *type); +int CPL_DLL GTIFTagCode(char *tag); + +/* Translation between image/PCS space */ + +int CPL_DLL GTIFImageToPCS( GTIF *gtif, double *x, double *y ); +int CPL_DLL GTIFPCSToImage( GTIF *gtif, double *x, double *y ); + +#if defined(__cplusplus) +} +#endif + +#endif /* __geotiff_h_ */ diff --git a/Utilities/otbgeotiff/geotiff_proj4.c b/Utilities/otbgeotiff/geotiff_proj4.c new file mode 100644 index 0000000000000000000000000000000000000000..270bd6d09c9e9ca5eba9b53eeb0ab341dfbfb9d4 --- /dev/null +++ b/Utilities/otbgeotiff/geotiff_proj4.c @@ -0,0 +1,725 @@ +/****************************************************************************** + * $Id: geotiff_proj4.c,v 1.23 2007/03/13 18:04:33 fwarmerdam Exp $ + * + * Project: libgeotiff + * Purpose: Code to convert a normalized GeoTIFF definition into a PROJ.4 + * (OGDI) compatible projection string. + * Author: Frank Warmerdam, warmerda@home.com + * + ****************************************************************************** + * Copyright (c) 1999, Frank Warmerdam + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + ****************************************************************************** + * + * $Log: geotiff_proj4.c,v $ + * Revision 1.23 2007/03/13 18:04:33 fwarmerdam + * added new zealand map grid support per bug 1519 + * + * Revision 1.22 2005/03/04 04:32:37 fwarmerdam + * added cylindricalequalarea support + * + * Revision 1.21 2003/08/21 18:42:39 warmerda + * fixed support for ModelTypeGeographic as per email from Young Su, Cha + * + * Revision 1.20 2003/07/08 17:31:30 warmerda + * cleanup various warnings + * + * Revision 1.19 2002/11/29 20:57:09 warmerda + * added LCC1SP mapping + * + * Revision 1.18 2002/07/09 14:47:53 warmerda + * fixed translation of polar stereographic + * + * Revision 1.17 2001/11/23 19:53:56 warmerda + * free PROJ.4 definitions after use + * + * Revision 1.16 2000/12/05 19:21:45 warmerda + * added cassini support + * + * Revision 1.15 2000/12/05 17:44:41 warmerda + * Use +R_A for Miller and VanDerGrinten + * + * Revision 1.14 2000/10/13 18:06:51 warmerda + * added econic support for PROJ.4 translation + * + * Revision 1.13 2000/09/15 19:30:48 warmerda + * *** empty log message *** + * + * Revision 1.12 2000/09/15 18:21:07 warmerda + * Fixed order of parameters for LCC 2SP. When parameters + * were read from EPSG CSV files the standard parallels and origin + * were mixed up. This affects alot of state plane zones! + * + * Revision 1.11 2000/06/06 17:39:45 warmerda + * Modify to work with projUV version of library. + * + * Revision 1.10 1999/07/06 15:05:51 warmerda + * Fixed up LCC_1SP notes. + * + * Revision 1.9 1999/05/04 16:24:49 warmerda + * Fixed projection string formating with zones. + * + * Revision 1.8 1999/05/04 12:27:01 geotiff + * only emit proj unsupported warning if DEBUG defined + * + * Revision 1.7 1999/05/04 03:14:59 warmerda + * fixed use of foot instead of ft for units + * + * Revision 1.6 1999/05/03 17:50:31 warmerda + * avoid warnings on IRIX + * + * Revision 1.5 1999/04/29 23:02:24 warmerda + * added mapsys utm test. + * + * Revision 1.4 1999/03/18 21:35:42 geotiff + * Added reprojection functions + * + * Revision 1.3 1999/03/10 18:11:17 geotiff + * Removed comment about this not being the master ... now it is. + * + * Revision 1.2 1999/03/10 18:10:27 geotiff + * Avoid use of cpl_serv.h and CPLStrdup(). + * + * Revision 1.1 1999/03/10 15:20:43 geotiff + * New + * + */ + +#include "cpl_serv.h" +#include "geotiff.h" +#include "geo_normalize.h" +#include "geovalues.h" + +/************************************************************************/ +/* GTIFGetProj4Defn() */ +/************************************************************************/ + +char * GTIFGetProj4Defn( GTIFDefn * psDefn ) + +{ + char szProjection[512]; + char szUnits[24]; + double dfFalseEasting, dfFalseNorthing; + + szProjection[0] = '\0'; + +/* ==================================================================== */ +/* Translate the units of measure. */ +/* */ +/* Note that even with a +units, or +to_meter in effect, it is */ +/* still assumed that all the projection parameters are in */ +/* meters. */ +/* ==================================================================== */ + if( psDefn->UOMLength == Linear_Meter ) + { + strcpy( szUnits, "+units=m " ); + } + else if( psDefn->UOMLength == Linear_Foot ) + { + strcpy( szUnits, "+units=ft " ); + } + else if( psDefn->UOMLength == Linear_Foot_US_Survey ) + { + strcpy( szUnits, "+units=us-ft " ); + } + else if( psDefn->UOMLength == Linear_Foot_Indian ) + { + strcpy( szUnits, "+units=ind-ft " ); + } + else if( psDefn->UOMLength == Linear_Link ) + { + strcpy( szUnits, "+units=link " ); + } + else if( psDefn->UOMLength == Linear_Yard_Indian) + { + strcpy( szUnits, "+units=ind-yd " ); + } + else if( psDefn->UOMLength == Linear_Fathom ) + { + strcpy( szUnits, "+units=fath " ); + } + else if( psDefn->UOMLength == Linear_Mile_International_Nautical ) + { + strcpy( szUnits, "+units=kmi " ); + } + else + { + sprintf( szUnits, "+to_meter=%.10f", psDefn->UOMLengthInMeters ); + } + +/* -------------------------------------------------------------------- */ +/* false easting and northing are in meters and that is what */ +/* PROJ.4 wants regardless of the linear units. */ +/* -------------------------------------------------------------------- */ + dfFalseEasting = psDefn->ProjParm[5]; + dfFalseNorthing = psDefn->ProjParm[6]; + +/* ==================================================================== */ +/* Handle general projection methods. */ +/* ==================================================================== */ + +/* -------------------------------------------------------------------- */ +/* Geographic. */ +/* -------------------------------------------------------------------- */ + if(psDefn->Model==ModelTypeGeographic) + { + sprintf(szProjection+strlen(szProjection),"+proj=latlong "); + + } + +/* -------------------------------------------------------------------- */ +/* UTM - special case override on transverse mercator so things */ +/* will be more meaningful to the user. */ +/* -------------------------------------------------------------------- */ + else if( psDefn->MapSys == MapSys_UTM_North ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=utm +zone=%d ", + psDefn->Zone ); + } + +/* -------------------------------------------------------------------- */ +/* Transverse Mercator */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_TransverseMercator ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=tmerc +lat_0=%.9f +lon_0=%.9f +k=%f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[4], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Mercator */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Mercator ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=merc +lat_ts=%.9f +lon_0=%.9f +k=%f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[4], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Cassini/Soldner */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_CassiniSoldner ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=cass +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Oblique Stereographic - Should this really map onto */ +/* Stereographic? */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_ObliqueStereographic ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=stere +lat_0=%.9f +lon_0=%.9f +k=%f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[4], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Stereographic */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Stereographic ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=stere +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Polar Stereographic */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_PolarStereographic ) + { + if( psDefn->ProjParm[0] > 0.0 ) + sprintf( szProjection+strlen(szProjection), + "+proj=stere +lat_0=90 +lat_ts=%.9f +lon_0=%.9f " + "+k=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[4], + dfFalseEasting, + dfFalseNorthing ); + else + sprintf( szProjection+strlen(szProjection), + "+proj=stere +lat_0=-90 +lat_ts=%.9f +lon_0=%.9f " + "+k=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[4], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Equirectangular */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Equirectangular ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=eqc +lat_ts=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Gnomonic */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Gnomonic ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=gnom +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Orthographic */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Orthographic ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=ortho +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Lambert Azimuthal Equal Area */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_LambertAzimEqualArea ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=laea +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Azimuthal Equidistant */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_AzimuthalEquidistant ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=aeqd +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Miller Cylindrical */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_MillerCylindrical ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=mill +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f +R_A ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Polyconic */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Polyconic ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=poly +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* AlbersEqualArea */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_AlbersEqualArea ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=aea +lat_1=%.9f +lat_2=%.9f +lat_0=%.9f +lon_0=%.9f" + " +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[2], + psDefn->ProjParm[3], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* EquidistantConic */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_EquidistantConic ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=eqdc +lat_1=%.9f +lat_2=%.9f +lat_0=%.9f +lon_0=%.9f" + " +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[2], + psDefn->ProjParm[3], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Robinson */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Robinson ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=robin +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* VanDerGrinten */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_VanDerGrinten ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=vandg +lon_0=%.9f +x_0=%.3f +y_0=%.3f +R_A ", + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* Sinusoidal */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_Sinusoidal ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=sinu +lon_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[1], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* LambertConfConic_2SP */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_LambertConfConic_2SP ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=lcc +lat_0=%.9f +lon_0=%.9f +lat_1=%.9f +lat_2=%.9f " + " +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[2], + psDefn->ProjParm[3], + dfFalseEasting, + dfFalseNorthing ); + } + +/* -------------------------------------------------------------------- */ +/* LambertConfConic_1SP */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_LambertConfConic_1SP ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=lcc +lat_0=%.9f +lat_1=%.9f +lon_0=%.9f" + " +k_0=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[4], + psDefn->ProjParm[5], + psDefn->ProjParm[6] ); + } + +/* -------------------------------------------------------------------- */ +/* CT_CylindricalEqualArea */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_CylindricalEqualArea ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=cea +lat_ts=%.9f +lon_0=%.9f " + " +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[5], + psDefn->ProjParm[6] ); + } + +/* -------------------------------------------------------------------- */ +/* NewZealandMapGrid */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_NewZealandMapGrid ) + { + sprintf( szProjection+strlen(szProjection), + "+proj=nzmg +lat_0=%.9f +lon_0=%.9f" + " +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[5], + psDefn->ProjParm[6] ); + } + +/* -------------------------------------------------------------------- */ +/* Transverse Mercator - south oriented. */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_TransvMercator_SouthOriented ) + { + /* this appears to be an unsupported formulation with PROJ.4 */ + } + +/* -------------------------------------------------------------------- */ +/* ObliqueMercator (Hotine) */ +/* -------------------------------------------------------------------- */ + else if( psDefn->CTProjection == CT_ObliqueMercator ) + { + /* not clear how ProjParm[3] - angle from rectified to skewed grid - + should be applied ... see the +not_rot flag for PROJ.4. + Just ignoring for now. */ + + sprintf( szProjection+strlen(szProjection), + "+proj=omerc +lat_0=%.9f +lonc=%.9f +alpha=%.9f" + " +k=%.9f +x_0=%.3f +y_0=%.3f ", + psDefn->ProjParm[0], + psDefn->ProjParm[1], + psDefn->ProjParm[2], + psDefn->ProjParm[4], + psDefn->ProjParm[5], + psDefn->ProjParm[6] ); + } + +/* ==================================================================== */ +/* Handle ellipsoid information. */ +/* ==================================================================== */ + if( psDefn->Ellipsoid == Ellipse_WGS_84 ) + strcat( szProjection, "+ellps=WGS84 " ); + else if( psDefn->Ellipsoid == Ellipse_Clarke_1866 ) + strcat( szProjection, "+ellps=clrk66 " ); + else if( psDefn->Ellipsoid == Ellipse_Clarke_1880 ) + strcat( szProjection, "+ellps=clrk80 " ); + else if( psDefn->Ellipsoid == Ellipse_GRS_1980 ) + strcat( szProjection, "+ellps=GRS80 " ); + else + { + if( psDefn->SemiMajor != 0.0 && psDefn->SemiMinor != 0.0 ) + { + sprintf( szProjection+strlen(szProjection), + "+a=%.3f +b=%.3f ", + psDefn->SemiMajor, + psDefn->SemiMinor ); + } + } + + strcat( szProjection, szUnits ); + + return( strdup( szProjection ) ); +} + +#if !defined(HAVE_LIBPROJ) || !defined(HAVE_PROJECTS_H) + +int GTIFProj4ToLatLong( GTIFDefn * psDefn, int nPoints, + double *padfX, double *padfY ) +{ + (void) psDefn; + (void) nPoints; + (void) padfX; + (void) padfY; +#ifdef DEBUG + fprintf( stderr, + "GTIFProj4ToLatLong() - PROJ.4 support not compiled in.\n" ); +#endif + return FALSE; +} + +int GTIFProj4FromLatLong( GTIFDefn * psDefn, int nPoints, + double *padfX, double *padfY ) +{ + (void) psDefn; + (void) nPoints; + (void) padfX; + (void) padfY; +#ifdef DEBUG + fprintf( stderr, + "GTIFProj4FromLatLong() - PROJ.4 support not compiled in.\n" ); +#endif + return FALSE; +} +#else + +#include "projects.h" + +#ifdef USE_PROJUV +# define UV projUV +#endif + +/************************************************************************/ +/* GTIFProj4FromLatLong() */ +/* */ +/* Convert lat/long values to projected coordinate for a */ +/* particular definition. */ +/************************************************************************/ + +int GTIFProj4FromLatLong( GTIFDefn * psDefn, int nPoints, + double *padfX, double *padfY ) + +{ + char *pszProjection, **papszArgs; + PJ *psPJ; + int i; + +/* -------------------------------------------------------------------- */ +/* Get a projection definition. */ +/* -------------------------------------------------------------------- */ + pszProjection = GTIFGetProj4Defn( psDefn ); + + if( pszProjection == NULL ) + return FALSE; + +/* -------------------------------------------------------------------- */ +/* Parse into tokens for pj_init(), and initialize the projection. */ +/* -------------------------------------------------------------------- */ + + papszArgs = CSLTokenizeStringComplex( pszProjection, " +", TRUE, FALSE ); + free( pszProjection ); + + psPJ = pj_init( CSLCount(papszArgs), papszArgs ); + + CSLDestroy( papszArgs ); + + if( psPJ == NULL ) + { + return FALSE; + } + +/* -------------------------------------------------------------------- */ +/* Process each of the points. */ +/* -------------------------------------------------------------------- */ + for( i = 0; i < nPoints; i++ ) + { + UV sUV; + + sUV.u = padfX[i] * DEG_TO_RAD; + sUV.v = padfY[i] * DEG_TO_RAD; + + sUV = pj_fwd( sUV, psPJ ); + + padfX[i] = sUV.u; + padfY[i] = sUV.v; + } + + pj_free( psPJ ); + + return TRUE; +} + +/************************************************************************/ +/* GTIFProj4ToLatLong() */ +/* */ +/* Convert projection coordinates to lat/long for a particular */ +/* definition. */ +/************************************************************************/ + +int GTIFProj4ToLatLong( GTIFDefn * psDefn, int nPoints, + double *padfX, double *padfY ) + +{ + char *pszProjection, **papszArgs; + PJ *psPJ; + int i; + +/* -------------------------------------------------------------------- */ +/* Get a projection definition. */ +/* -------------------------------------------------------------------- */ + pszProjection = GTIFGetProj4Defn( psDefn ); + + if( pszProjection == NULL ) + return FALSE; + +/* -------------------------------------------------------------------- */ +/* Parse into tokens for pj_init(), and initialize the projection. */ +/* -------------------------------------------------------------------- */ + + papszArgs = CSLTokenizeStringComplex( pszProjection, " +", TRUE, FALSE ); + free( pszProjection ); + + psPJ = pj_init( CSLCount(papszArgs), papszArgs ); + + CSLDestroy( papszArgs ); + + if( psPJ == NULL ) + { + return FALSE; + } + +/* -------------------------------------------------------------------- */ +/* Process each of the points. */ +/* -------------------------------------------------------------------- */ + for( i = 0; i < nPoints; i++ ) + { + UV sUV; + + sUV.u = padfX[i]; + sUV.v = padfY[i]; + + sUV = pj_inv( sUV, psPJ ); + + padfX[i] = sUV.u * RAD_TO_DEG; + padfY[i] = sUV.v * RAD_TO_DEG; + } + + pj_free( psPJ ); + + return TRUE; +} + + +#endif /* has projects.h and -lproj */ + diff --git a/Utilities/otbgeotiff/geotiffio.h b/Utilities/otbgeotiff/geotiffio.h new file mode 100644 index 0000000000000000000000000000000000000000..72442b444044498552f4308d7205042b23a93c06 --- /dev/null +++ b/Utilities/otbgeotiff/geotiffio.h @@ -0,0 +1,16 @@ +/* + * geotiffio.h + * + * Standard include file for geotiff, including all + * key and code definitions. + */ + + +#ifndef __geotiffio_h +#define __geotiffio_h + +#include "geotiff.h" /* public key interface */ +#include "geovalues.h" /* key code definitions */ + +#endif /* __geotiffio_h */ + diff --git a/Utilities/otbgeotiff/geovalues.h b/Utilities/otbgeotiff/geovalues.h new file mode 100644 index 0000000000000000000000000000000000000000..625d33a31a63263b04beea3e6abeba5aa07caadc --- /dev/null +++ b/Utilities/otbgeotiff/geovalues.h @@ -0,0 +1,120 @@ +/********************************************************************** + * + * geovalues.h - Public registry for valid GEOTIFF key-values. + * + * Written By: Niles D. Ritter + * + * Revision History: + * + * Rev.# Author Date Key Changes/Additions + * ----- ------ ---------- ------------------------------------- + * 0.1 ndr 10 Jun 95 Inital Beta Release + * 0.2 ndr 12 Jul 95 New EPSG Tables installed. + * 0.2.1 ndr 28 Jul 95 Added ModelType aliases to Model's + * 1.0 ndr 18 Sep 95 Promoted to Revision 1.0 + * + **********************************************************************/ + +#ifndef __geovalues_h_ +#define __geovalues_h_ + +/* If code values are added or modified, the "GvCurrentMinorRev" + * number should be incremented here. If new Keys are added, then the + * GvCurrentRevision number should be incremented instead, and the + * GvCurrentMinorRev should be reset to zero (see "geokeys.h"). + * + * In addition, any changes here should be reflected in "geo_names.c" + * + */ + +#define GvCurrentMinorRev 0 /* First Major Rev EPSG Code Release */ + + +/* + * Universal key values -- defined for consistency + */ +#define KvUndefined 0 +#define KvUserDefined 32767 + +#ifdef ValuePair +# undef ValuePair +#endif +#define ValuePair(name,value) name = value, + +/* + * The section numbers refer to the GeoTIFF Specification section + * in which the code values are documented. + */ + +/************************************************************ + * 6.3.1 GeoTIFF General Codes + ************************************************************/ + +/* 6.3.1.1 Model Type Codes */ +typedef enum { + ModelTypeProjected = 1, /* Projection Coordinate System */ + ModelTypeGeographic = 2, /* Geographic latitude-longitude System */ + ModelTypeGeocentric = 3, /* Geocentric (X,Y,Z) Coordinate System */ + ModelProjected = ModelTypeProjected, /* alias */ + ModelGeographic = ModelTypeGeographic, /* alias */ + ModelGeocentric = ModelTypeGeocentric /* alias */ +} modeltype_t; + +/* 6.3.1.2 Raster Type Codes */ +typedef enum { + RasterPixelIsArea = 1, /* Standard pixel-fills-grid-cell */ + RasterPixelIsPoint = 2 /* Pixel-at-grid-vertex */ +} rastertype_t; + +typedef enum { +# include "epsg_gcs.inc" + geographic_end +} geographic_t; + +typedef enum { +# include "epsg_datum.inc" + geodeticdatum_end +} geodeticdatum_t; + +typedef enum { +# include "epsg_units.inc" + Unit_End +} geounits_t; + +typedef enum { +# include "epsg_ellipse.inc" + ellipsoid_end +} ellipsoid_t; + +typedef enum { +# include "epsg_pm.inc" + primemeridian_end +} primemeridian_t; + +typedef enum { +# include "epsg_pcs.inc" + pcstype_end +} pcstype_t; + +typedef enum { +# include "epsg_proj.inc" + projection_end +} projection_t; + +typedef enum { +# include "geo_ctrans.inc" + coordtrans_end +} coordtrans_t; + +typedef enum { +# include "epsg_vertcs.inc" + vertcs_end +} vertcstype_t; + + +typedef enum { + VDatumBase = 1 +} vdatum_t; + +#endif /* __geovalues_h_ */ + diff --git a/Utilities/otbgeotiff/libxtiff/CMakeLists.txt b/Utilities/otbgeotiff/libxtiff/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..690f2a25ed4fe96e8d17fa3ee7bb5d26df92987f --- /dev/null +++ b/Utilities/otbgeotiff/libxtiff/CMakeLists.txt @@ -0,0 +1,17 @@ +PROJECT(libxtiff) + +FILE(GLOB libxtiff_SRCS "*.c") +FILE(GLOB libxtiff_HDRS "*.h") + +ADD_LIBRARY(otbxtiff ${libxtiff_SRCS}) +TARGET_LINK_LIBRARIES(otbxtiff) + +INSTALL(TARGETS otbxtiff +RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries +LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries +ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR} COMPONENT Development) + +INSTALL(FILES ${libxtiff_HDRS_HDRS} + DESTINATION ${OTB_INSTALL_INCLUDE_DIR}/Utilities/otbxtiff + COMPONENT Development) + diff --git a/Utilities/otbgeotiff/libxtiff/xtiff.c b/Utilities/otbgeotiff/libxtiff/xtiff.c new file mode 100644 index 0000000000000000000000000000000000000000..5e679dcc4ee60d6c8713c9d5648c0a6593d15c58 --- /dev/null +++ b/Utilities/otbgeotiff/libxtiff/xtiff.c @@ -0,0 +1,205 @@ +/* + * xtiff.c + * + * Extended TIFF Directory GEO Tag Support. + * + * You may use this file as a template to add your own + * extended tags to the library. Only the parts of the code + * marked with "XXX" require modification. + * + * Author: Niles D. Ritter + * + * Revisions: + * 18 Sep 1995 -- Deprecated Integraph Matrix tag with new one. + * Backward compatible support provided. --NDR. + */ + +#include "xtiffio.h" +#include <stdio.h> +#include "cpl_serv.h" + +/* Tiff info structure. + * + * Entry format: + * { TAGNUMBER, ReadCount, WriteCount, DataType, FIELDNUM, + * OkToChange, PassDirCountOnSet, AsciiName } + * + * For ReadCount, WriteCount, -1 = unknown. + */ + +static const TIFFFieldInfo xtiffFieldInfo[] = { + + /* XXX Insert Your tags here */ + { TIFFTAG_GEOPIXELSCALE, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM, + TRUE, TRUE, "GeoPixelScale" }, + { TIFFTAG_INTERGRAPH_MATRIX,-1,-1, TIFF_DOUBLE, FIELD_CUSTOM, + TRUE, TRUE, "Intergraph TransformationMatrix" }, + { TIFFTAG_GEOTRANSMATRIX, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM, + TRUE, TRUE, "GeoTransformationMatrix" }, + { TIFFTAG_GEOTIEPOINTS, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM, + TRUE, TRUE, "GeoTiePoints" }, + { TIFFTAG_GEOKEYDIRECTORY,-1,-1, TIFF_SHORT, FIELD_CUSTOM, + TRUE, TRUE, "GeoKeyDirectory" }, + { TIFFTAG_GEODOUBLEPARAMS, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM, + TRUE, TRUE, "GeoDoubleParams" }, + { TIFFTAG_GEOASCIIPARAMS, -1,-1, TIFF_ASCII, FIELD_CUSTOM, + TRUE, FALSE, "GeoASCIIParams" }, +#ifdef JPL_TAG_SUPPORT + { TIFFTAG_JPL_CARTO_IFD, 1, 1, TIFF_LONG, FIELD_CUSTOM, + TRUE, TRUE, "JPL Carto IFD offset" }, /** Don't use this! **/ +#endif +}; + +#define N(a) (sizeof (a) / sizeof (a[0])) +static void _XTIFFLocalDefaultDirectory(TIFF *tif) +{ + /* Install the extended Tag field info */ + TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo)); +} + + +/********************************************************************** + * Nothing below this line should need to be changed. + **********************************************************************/ + +static TIFFExtendProc _ParentExtender; + +/* + * This is the callback procedure, and is + * called by the DefaultDirectory method + * every time a new TIFF directory is opened. + */ + +static void +_XTIFFDefaultDirectory(TIFF *tif) +{ + /* set up our own defaults */ + _XTIFFLocalDefaultDirectory(tif); + + /* Since an XTIFF client module may have overridden + * the default directory method, we call it now to + * allow it to set up the rest of its own methods. + */ + + if (_ParentExtender) + (*_ParentExtender)(tif); +} + + +/** +Registers an extension with libtiff for adding GeoTIFF tags. +After this one-time intialization, any TIFF open function may be called in +the usual manner to create a TIFF file that compatible with libgeotiff. +The XTIFF open functions are simply for convenience: they call this +and then pass their parameters on to the appropriate TIFF open function. + +<p>This function may be called any number of times safely, since it will +only register the extension the first time it is called. +**/ + +void XTIFFInitialize(void) +{ + static int first_time=1; + + if (! first_time) return; /* Been there. Done that. */ + first_time = 0; + + /* Grab the inherited method and install */ + _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory); +} + + +/** + * GeoTIFF compatible TIFF file open function. + * + * @param name The filename of a TIFF file to open. + * @param mode The open mode ("r", "w" or "a"). + * + * @return a TIFF * for the file, or NULL if the open failed. + * +This function is used to open GeoTIFF files instead of TIFFOpen() from +libtiff. Internally it calls TIFFOpen(), but sets up some extra hooks +so that GeoTIFF tags can be extracted from the file. If XTIFFOpen() isn't +used, GTIFNew() won't work properly. Files opened +with XTIFFOpen() should be closed with XTIFFClose(). + +The name of the file to be opened should be passed as <b>name</b>, and an +opening mode ("r", "w" or "a") acceptable to TIFFOpen() should be passed as the +<b>mode</b>.<p> + +If XTIFFOpen() fails it will return NULL. Otherwise, normal TIFFOpen() +error reporting steps will have already taken place.<p> + */ + +TIFF* +XTIFFOpen(const char* name, const char* mode) +{ + TIFF *tif; + + /* Set up the callback */ + XTIFFInitialize(); + + /* Open the file; the callback will set everything up + */ + tif = TIFFOpen(name, mode); + if (!tif) return tif; + + return tif; +} + +TIFF* +XTIFFFdOpen(int fd, const char* name, const char* mode) +{ + TIFF *tif; + + /* Set up the callback */ + XTIFFInitialize(); + + /* Open the file; the callback will set everything up + */ + tif = TIFFFdOpen(fd, name, mode); + if (!tif) return tif; + + return tif; +} + +TIFF* +XTIFFClientOpen(const char* name, const char* mode, thandle_t thehandle, + TIFFReadWriteProc RWProc, TIFFReadWriteProc RWProc2, + TIFFSeekProc SProc, TIFFCloseProc CProc, + TIFFSizeProc SzProc, + TIFFMapFileProc MFProvc, TIFFUnmapFileProc UMFProc ) +{ + TIFF *tif; + + /* Set up the callback */ + XTIFFInitialize(); + + /* Open the file; the callback will set everything up + */ + tif = TIFFClientOpen(name, mode, thehandle, + RWProc, RWProc2, + SProc, CProc, + SzProc, + MFProvc, UMFProc); + + if (!tif) return tif; + + return tif; +} + +/** + * Close a file opened with XTIFFOpen(). + * + * @param tif The file handle returned by XTIFFOpen(). + * + * If a GTIF structure was created with GTIFNew() + * for this file, it should be freed with GTIFFree() + * <i>before</i> calling XTIFFClose(). +*/ + +void +XTIFFClose(TIFF *tif) +{ + TIFFClose(tif); +} diff --git a/Utilities/otbgeotiff/libxtiff/xtiffio.h b/Utilities/otbgeotiff/libxtiff/xtiffio.h new file mode 100644 index 0000000000000000000000000000000000000000..a26708742e0c8d1f6602ffcf59502d1be50a51f6 --- /dev/null +++ b/Utilities/otbgeotiff/libxtiff/xtiffio.h @@ -0,0 +1,84 @@ +/* + * xtiffio.h -- Public interface to Extended GEO TIFF tags + * + * written by: Niles D. Ritter + */ + +#ifndef __xtiffio_h +#define __xtiffio_h + +#include "tiffio.h" +#include "geo_config.h" + +/** + * \file xtiffio.h + * + * Definitions relating GeoTIFF functions from geotiff.h to the TIFF + * library (usually libtiff). + */ + +/* + * Define public Tag names and values here + */ + +/* tags 33550 is a private tag registered to SoftDesk, Inc */ +#define TIFFTAG_GEOPIXELSCALE 33550 +/* tags 33920-33921 are private tags registered to Intergraph, Inc */ +#define TIFFTAG_INTERGRAPH_MATRIX 33920 /* $use TIFFTAG_GEOTRANSMATRIX ! */ +#define TIFFTAG_GEOTIEPOINTS 33922 +/* tags 34263-34264 are private tags registered to NASA-JPL Carto Group */ +#ifdef JPL_TAG_SUPPORT +#define TIFFTAG_JPL_CARTO_IFD 34263 /* $use GeoProjectionInfo ! */ +#endif +#define TIFFTAG_GEOTRANSMATRIX 34264 /* New Matrix Tag replaces 33920 */ +/* tags 34735-3438 are private tags registered to SPOT Image, Inc */ +#define TIFFTAG_GEOKEYDIRECTORY 34735 +#define TIFFTAG_GEODOUBLEPARAMS 34736 +#define TIFFTAG_GEOASCIIPARAMS 34737 + +/* + * Define Printing method flags. These + * flags may be passed in to TIFFPrintDirectory() to + * indicate that those particular field values should + * be printed out in full, rather than just an indicator + * of whether they are present or not. + */ +#define TIFFPRINT_GEOKEYDIRECTORY 0x80000000 +#define TIFFPRINT_GEOKEYPARAMS 0x40000000 + +/********************************************************************** + * Nothing below this line should need to be changed by the user. + **********************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/********************************************************************** + * Do we want to build as a DLL on windows? + **********************************************************************/ +#if !defined(CPL_DLL) +# if defined(_WIN32) && defined(BUILD_AS_DLL) +# define CPL_DLL __declspec(dllexport) +# else +# define CPL_DLL +# endif +#endif + +extern void CPL_DLL XTIFFInitialize(); +extern TIFF CPL_DLL * XTIFFOpen(const char* name, const char* mode); +extern TIFF CPL_DLL * XTIFFFdOpen(int fd, const char* name, const char* mode); +extern void CPL_DLL XTIFFClose(TIFF *tif); + +extern TIFF CPL_DLL * XTIFFClientOpen(const char* name, const char* mode, + thandle_t thehandle, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, + TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); +#if defined(__cplusplus) +} +#endif + +#endif /* __xtiffio_h */ + diff --git a/otbIncludeDirectories.cmake b/otbIncludeDirectories.cmake index bec3c603eae07bc6e305e46a39e9e6ca86a8f4ae..45536087fdadc749384a0212fb6f3b55b330dd41 100644 --- a/otbIncludeDirectories.cmake +++ b/otbIncludeDirectories.cmake @@ -32,6 +32,8 @@ SET(OTB_INCLUDE_DIRS_BUILD_TREE ${OTB_INCLUDE_DIRS_BUILD_TREE} ${OTB_SOURCE_DIR}/Utilities/dxflib ${OTB_SOURCE_DIR}/Utilities/InsightJournal ${OTB_SOURCE_DIR}/Utilities/otb6S + ${OTB_SOURCE_DIR}/Utilities/otbgeotiff + ${OTB_SOURCE_DIR}/Utilities/otbgeotiff/libxtiff ) #----------------------------------------------------------------------------- @@ -118,6 +120,8 @@ SET(OTB_INCLUDE_DIRS_INSTALL_TREE ${OTB_INCLUDE_DIRS_INSTALL_TREE} ${OTB_INSTALL_INCLUDE_DIR}/Utilities/otbossim/include/ossim ${OTB_INSTALL_INCLUDE_DIR}/Utilities/InsightJournal ${OTB_INSTALL_INCLUDE_DIR}/Utilities/otb6S + ${OTB_INSTALL_INCLUDE_DIR}/Utilities/otbgeotiff + ${OTB_INSTALL_INCLUDE_DIR}/Utilities/otbgeotiff/libxtiff ) SET(OTB_INCLUDE_DIRS_INSTALL_TREE ${OTB_INCLUDE_DIRS_INSTALL_TREE}