23 #include <QTemporaryFile> 
   25 #include <QDomElement> 
   28 #include <QTextStream> 
   42 #include <ogr_srs_api.h> 
   43 #include <cpl_error.h> 
   54     , mMapUnits( 
QGis::UnknownUnit )
 
   57     , mValidationHint( 
"" )
 
   58     , mAxisInverted( false )
 
   60   mCRS = OSRNewSpatialReference( NULL );
 
   66     , mMapUnits( 
QGis::UnknownUnit )
 
   69     , mValidationHint( 
"" )
 
   70     , mAxisInverted( false )
 
   72   mCRS = OSRNewSpatialReference( NULL );
 
   80     , mMapUnits( 
QGis::UnknownUnit )
 
   83     , mValidationHint( 
"" )
 
   84     , mAxisInverted( false )
 
   86   mCRS = OSRNewSpatialReference( NULL );
 
   92   OSRDestroySpatialReference( mCRS );
 
  119   QRegExp reCrsId( 
"^(epsg|postgis|internal)\\:(\\d+)$", Qt::CaseInsensitive );
 
  120   if ( reCrsId.indexIn( theDefinition ) == 0 )
 
  122     QString authName = reCrsId.cap( 1 ).toLower();
 
  124     if ( authName == 
"epsg" )
 
  126     if ( authName == 
"postgis" )
 
  128     long id = reCrsId.cap( 2 ).toLong();
 
  133     QRegExp reCrsStr( 
"^(?:(wkt|proj4)\\:)?(.+)$", Qt::CaseInsensitive );
 
  134     if ( reCrsStr.indexIn( theDefinition ) == 0 )
 
  136       if ( reCrsStr.cap( 1 ).toLower() == 
"proj4" )
 
  145           QString myName = QString( 
" * %1 (%2)" )
 
  146                            .arg( 
QObject::tr( 
"Generated CRS", 
"A CRS automatically generated from layer info get this prefix for description" ) )
 
  167 #if GDAL_VERSION_NUM >= 1900 
  168   if ( theDefinition.startsWith( 
"ESRI::" ) )
 
  174   if ( OSRSetFromUserInput( crs, theDefinition.toLocal8Bit().constData() ) == OGRERR_NONE )
 
  176     if ( OSRExportToWkt( crs, &wkt ) == OGRERR_NONE )
 
  181     OSRDestroySpatialReference( crs );
 
  191 #if GDAL_VERSION_NUM >= 1900 
  192   const char* configOld = CPLGetConfigOption( 
"GDAL_FIX_ESRI_WKT", 
"" );
 
  193   const char* configNew = 
"GEOGCS";
 
  195   if ( strcmp( configOld, 
"" ) == 0 )
 
  197     CPLSetConfigOption( 
"GDAL_FIX_ESRI_WKT", configNew );
 
  198     if ( strcmp( configNew, CPLGetConfigOption( 
"GDAL_FIX_ESRI_WKT", 
"" ) ) != 0 )
 
  200                           .arg( configNew ).arg( CPLGetConfigOption( 
"GDAL_FIX_ESRI_WKT", 
"" ) ) );
 
  201     QgsDebugMsg( QString( 
"set GDAL_FIX_ESRI_WKT : %1" ).arg( configNew ) );
 
  205     QgsDebugMsg( QString( 
"GDAL_FIX_ESRI_WKT was already set : %1" ).arg( configNew ) );
 
  212   QRegExp re( 
"urn:ogc:def:crs:([^:]+).+([^:]+)", Qt::CaseInsensitive );
 
  213   if ( re.exactMatch( theCrs ) )
 
  215     theCrs = re.cap( 1 ) + 
":" + re.cap( 2 );
 
  219     re.setPattern( 
"(user|custom|qgis):(\\d+)" );
 
  220     if ( re.exactMatch( theCrs ) && 
createFromSrsId( re.cap( 2 ).toInt() ) )
 
  230   if ( theCrs.compare( 
"CRS:27", Qt::CaseInsensitive ) == 0 ||
 
  231        theCrs.compare( 
"OGC:CRS27", Qt::CaseInsensitive ) == 0 )
 
  238   if ( theCrs.compare( 
"CRS:83", Qt::CaseInsensitive ) == 0 ||
 
  239        theCrs.compare( 
"OGC:CRS83", Qt::CaseInsensitive ) == 0 )
 
  246   if ( theCrs.compare( 
"CRS:84", Qt::CaseInsensitive ) == 0 ||
 
  247        theCrs.compare( 
"OGC:CRS84", Qt::CaseInsensitive ) == 0 )
 
  259   mCRS = OSRNewSpatialReference( NULL );
 
  269     mDescription = srs.mDescription;
 
  270     mProjectionAcronym = srs.mProjectionAcronym;
 
  271     mEllipsoidAcronym = srs.mEllipsoidAcronym;
 
  272     mGeoFlag = srs.mGeoFlag;
 
  273     mAxisInverted = srs.mAxisInverted;
 
  274     mMapUnits = srs.mMapUnits;
 
  276     mAuthId = srs.mAuthId;
 
  277     mIsValidFlag = srs.mIsValidFlag;
 
  278     mValidationHint = srs.mValidationHint;
 
  283       OSRDestroySpatialReference( mCRS );
 
  284       mCRS = OSRClone( srs.mCRS );
 
  299   if ( mCustomSrsValidation )
 
  300     mCustomSrsValidation( *
this );
 
  317                      "srs_id", QString::number( 
id ) );
 
  320 bool QgsCoordinateReferenceSystem::loadFromDb( QString db, QString expression, QString value )
 
  322   QgsDebugMsgLevel( 
"load CRS from " + db + 
" where " + expression + 
" is " + value, 3 );
 
  323   mIsValidFlag = 
false;
 
  326   QFileInfo myInfo( db );
 
  327   if ( !myInfo.exists() )
 
  329     QgsDebugMsg( 
"failed : " + db + 
" does not exist!" );
 
  335   sqlite3_stmt *myPreparedStatement;
 
  338   myResult = openDb( db, &myDatabase );
 
  339   if ( myResult != SQLITE_OK )
 
  341     QgsDebugMsg( 
"failed : " + db + 
" could not be opened!" );
 
  357   QString mySql = 
"select srs_id,description,projection_acronym," 
  358                   "ellipsoid_acronym,parameters,srid,auth_name||':'||auth_id,is_geo " 
  359                   "from tbl_srs where " + expression + 
"=" + quotedValue( value ) + 
" order by deprecated";
 
  360   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(),
 
  361                               mySql.toUtf8().length(),
 
  362                               &myPreparedStatement, &myTail );
 
  364   if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
 
  366     mSrsId = QString::fromUtf8(( 
char * )sqlite3_column_text(
 
  367                                  myPreparedStatement, 0 ) ).toLong();
 
  368     mDescription = QString::fromUtf8(( 
char * )sqlite3_column_text(
 
  369                                        myPreparedStatement, 1 ) );
 
  370     mProjectionAcronym = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 2 ) );
 
  371     mEllipsoidAcronym = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 3 ) );
 
  372     mProj4 = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 4 ) );
 
  373     mSRID = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 5 ) ).toLong();
 
  374     mAuthId = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 6 ) );
 
  375     mGeoFlag = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 7 ) ).toInt() != 0;
 
  380       mAuthId = QString( 
"USER:%1" ).arg( mSrsId );
 
  382     else if ( mAuthId.startsWith( 
"EPSG:", Qt::CaseInsensitive ) )
 
  384       OSRDestroySpatialReference( mCRS );
 
  385       mCRS = OSRNewSpatialReference( NULL );
 
  386       mIsValidFlag = OSRSetFromUserInput( mCRS, mAuthId.toLower().toAscii() ) == OGRERR_NONE;
 
  392       setProj4String( mProj4 );
 
  399   sqlite3_finalize( myPreparedStatement );
 
  400   sqlite3_close( myDatabase );
 
  406   if ( mAxisInverted == -1 )
 
  408     OGRAxisOrientation orientation;
 
  409     OSRGetAxis( mCRS, OSRIsGeographic( mCRS ) ? 
"GEOGCS" : 
"PROJCS", 0, &orientation );
 
  412     if ( orientation == OAO_Other && mAuthId.startsWith( 
"EPSG:", Qt::CaseInsensitive ) )
 
  416       if ( OSRImportFromEPSGA( crs, mAuthId.mid( 5 ).toInt() ) == OGRERR_NONE )
 
  418         OSRGetAxis( crs, OSRIsGeographic( crs ) ? 
"GEOGCS" : 
"PROJCS", 0, &orientation );
 
  421       OSRDestroySpatialReference( crs );
 
  424     mAxisInverted = orientation == OAO_North;
 
  427   return mAxisInverted != 0;
 
  432   mIsValidFlag = 
false;
 
  436   if ( theWkt.isEmpty() )
 
  438     QgsDebugMsg( 
"theWkt is uninitialised, operation failed" );
 
  442   QByteArray ba = theWkt.toLatin1();
 
  443   const char *pWkt = ba.data();
 
  445   OGRErr myInputResult = OSRImportFromWkt( mCRS, ( 
char ** ) & pWkt );
 
  447   if ( myInputResult != OGRERR_NONE )
 
  449     QgsDebugMsg( 
"\n---------------------------------------------------------------" );
 
  450     QgsDebugMsg( 
"This CRS could *** NOT *** be set from the supplied Wkt " );
 
  452     QgsDebugMsg( QString( 
"UNUSED WKT: %1" ).arg( pWkt ) );
 
  453     QgsDebugMsg( 
"---------------------------------------------------------------\n" );
 
  457   if ( OSRAutoIdentifyEPSG( mCRS ) == OGRERR_NONE )
 
  459     QString 
authid = QString( 
"%1:%2" )
 
  460                      .arg( OSRGetAuthorityName( mCRS, NULL ) )
 
  461                      .arg( OSRGetAuthorityCode( mCRS, NULL ) );
 
  471   char *proj4src = NULL;
 
  472   OSRExportToProj4( mCRS, &proj4src );
 
  484     OSRExportToProj4( mCRS, &proj4src );
 
  494     QString myName = QString( 
" * %1 (%2)" )
 
  495                      .arg( 
QObject::tr( 
"Generated CRS", 
"A CRS automatically generated from layer info get this prefix for description" ) )
 
  521   QString myProj4String = theProj4String.trimmed();
 
  523   mIsValidFlag = 
false;
 
  526   QRegExp myProjRegExp( 
"\\+proj=(\\S+)" );
 
  527   int myStart = myProjRegExp.indexIn( myProj4String );
 
  530     QgsDebugMsg( 
"proj string supplied has no +proj argument" );
 
  534   mProjectionAcronym = myProjRegExp.cap( 1 );
 
  536   QRegExp myEllipseRegExp( 
"\\+ellps=(\\S+)" );
 
  537   myStart = myEllipseRegExp.indexIn( myProj4String );
 
  540     QgsDebugMsg( 
"proj string supplied has no +ellps argument" );
 
  541     mEllipsoidAcronym = 
"";
 
  545     mEllipsoidAcronym = myEllipseRegExp.cap( 1 );
 
  548   QRegExp myAxisRegExp( 
"\\+a=(\\S+)" );
 
  549   myStart = myAxisRegExp.indexIn( myProj4String );
 
  552     QgsDebugMsg( 
"proj string supplied has no +a argument" );
 
  564   QgsCoordinateReferenceSystem::RecordMap myRecord;
 
  570   myRecord = getRecord( 
"select * from tbl_srs where parameters=" + quotedValue( myProj4String ) + 
" order by deprecated" );
 
  571   if ( myRecord.empty() )
 
  576     QRegExp myLat1RegExp( 
"\\+lat_1=\\S+" );
 
  577     QRegExp myLat2RegExp( 
"\\+lat_2=\\S+" );
 
  582     QString lat1Str = 
"";
 
  583     QString lat2Str = 
"";
 
  584     myStart1 = myLat1RegExp.indexIn( myProj4String, myStart1 );
 
  585     myStart2 = myLat2RegExp.indexIn( myProj4String, myStart2 );
 
  586     if ( myStart1 != -1 && myStart2 != -1 )
 
  588       myLength1 = myLat1RegExp.matchedLength();
 
  589       myLength2 = myLat2RegExp.matchedLength();
 
  594     if ( lat1Str != 
"" && lat2Str != 
"" )
 
  597       QString theProj4StringModified = myProj4String;
 
  602       myStart2 = myLat2RegExp.indexIn( theProj4String, myStart2 );
 
  604       QgsDebugMsg( 
"trying proj4string match with swapped lat_1,lat_2" );
 
  605       myRecord = getRecord( 
"select * from tbl_srs where parameters=" + quotedValue( theProj4StringModified.trimmed() ) + 
" order by deprecated" );
 
  609   if ( myRecord.empty() )
 
  616     QString sql = 
"SELECT * FROM tbl_srs WHERE ";
 
  623     QStringList myParams;
 
  624     foreach ( QString param, myProj4String.split( QRegExp( 
"\\s+(?=\\+)" ), QString::SkipEmptyParts ) )
 
  626       QString arg = QString( 
"' '||parameters||' ' LIKE %1" ).arg( quotedValue( QString( 
"% %1 %" ).arg( param.trimmed() ) ) );
 
  627       if ( param.startsWith( 
"+datum=" ) )
 
  635         myParams << param.trimmed();
 
  639     if ( !datum.isEmpty() )
 
  641       myRecord = getRecord( sql + delim + datum + 
" order by deprecated" );
 
  644     if ( myRecord.empty() )
 
  647       myRecord = getRecord( sql + 
" order by deprecated" );
 
  650     if ( !myRecord.empty() )
 
  653       QStringList foundParams;
 
  654       foreach ( QString param, myRecord[
"parameters"].split( QRegExp( 
"\\s+(?=\\+)" ), QString::SkipEmptyParts ) )
 
  656         if ( !param.startsWith( 
"+datum=" ) )
 
  657           foundParams << param.trimmed();
 
  663       if ( myParams != foundParams )
 
  670   if ( !myRecord.empty() )
 
  672     mySrsId = myRecord[
"srs_id"].toLong();
 
  673     QgsDebugMsg( 
"proj4string param match search for srsid returned srsid: " + QString::number( mySrsId ) );
 
  682     QgsDebugMsg( 
"globbing search for srsid from this proj string" );
 
  683     setProj4String( myProj4String );
 
  685     QgsDebugMsg( 
"globbing search for srsid returned srsid: " + QString::number( mySrsId ) );
 
  692       mIsValidFlag = 
false;
 
  699     QgsDebugMsg( 
"Projection is not found in databases." );
 
  701     setProj4String( myProj4String );
 
  708 QgsCoordinateReferenceSystem::RecordMap QgsCoordinateReferenceSystem::getRecord( QString theSql )
 
  710   QString myDatabaseFileName;
 
  711   QgsCoordinateReferenceSystem::RecordMap myMap;
 
  713   QString myFieldValue;
 
  716   sqlite3_stmt *myPreparedStatement;
 
  722   QFileInfo myInfo( myDatabaseFileName );
 
  723   if ( !myInfo.exists() )
 
  725     QgsDebugMsg( 
"failed : " + myDatabaseFileName + 
" does not exist!" );
 
  730   myResult = openDb( myDatabaseFileName, &myDatabase );
 
  731   if ( myResult != SQLITE_OK )
 
  736   myResult = sqlite3_prepare( myDatabase, theSql.toUtf8(), theSql.toUtf8().length(), &myPreparedStatement, &myTail );
 
  738   if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
 
  741     int myColumnCount = sqlite3_column_count( myPreparedStatement );
 
  743     for ( 
int myColNo = 0; myColNo < myColumnCount; myColNo++ )
 
  745       myFieldName = QString::fromUtf8(( 
char * )sqlite3_column_name( myPreparedStatement, myColNo ) );
 
  746       myFieldValue = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, myColNo ) );
 
  747       myMap[myFieldName] = myFieldValue;
 
  749     if ( sqlite3_step( myPreparedStatement ) != SQLITE_DONE )
 
  763     sqlite3_finalize( myPreparedStatement );
 
  764     sqlite3_close( myDatabase );
 
  767     QFileInfo myFileInfo;
 
  768     myFileInfo.setFile( myDatabaseFileName );
 
  769     if ( !myFileInfo.exists() )
 
  776     myResult = openDb( myDatabaseFileName, &myDatabase );
 
  777     if ( myResult != SQLITE_OK )
 
  782     myResult = sqlite3_prepare( myDatabase, theSql.toUtf8(), theSql.toUtf8().length(), &myPreparedStatement, &myTail );
 
  784     if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
 
  786       int myColumnCount = sqlite3_column_count( myPreparedStatement );
 
  788       for ( 
int myColNo = 0; myColNo < myColumnCount; myColNo++ )
 
  790         myFieldName = QString::fromUtf8(( 
char * )sqlite3_column_name( myPreparedStatement, myColNo ) );
 
  791         myFieldValue = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, myColNo ) );
 
  792         myMap[myFieldName] = myFieldValue;
 
  795       if ( sqlite3_step( myPreparedStatement ) != SQLITE_DONE )
 
  806   sqlite3_finalize( myPreparedStatement );
 
  807   sqlite3_close( myDatabase );
 
  811   RecordMap::Iterator it;
 
  812   for ( it = myMap.begin(); it != myMap.end(); ++it )
 
  840   if ( mDescription.isNull() )
 
  852   if ( mProjectionAcronym.isNull() )
 
  858     return mProjectionAcronym;
 
  864   if ( mEllipsoidAcronym.isNull() )
 
  870     return mEllipsoidAcronym;
 
  879   if ( mProj4.isEmpty() )
 
  882     char *proj4src = NULL;
 
  883     OSRExportToProj4( mCRS, &proj4src );
 
  888   return mProj4.trimmed();
 
  905 void QgsCoordinateReferenceSystem::setInternalId( 
long theSrsId )
 
  909 void QgsCoordinateReferenceSystem::setAuthId( QString authId )
 
  913 void QgsCoordinateReferenceSystem::setSrid( 
long theSrid )
 
  917 void QgsCoordinateReferenceSystem::setDescription( QString theDescription )
 
  919   mDescription = theDescription;
 
  921 void QgsCoordinateReferenceSystem::setProj4String( QString theProj4String )
 
  923   mProj4 = theProj4String;
 
  924   char *oldlocale = setlocale( LC_NUMERIC, NULL );
 
  927     oldlocale = strdup( oldlocale );
 
  929   setlocale( LC_NUMERIC, 
"C" );
 
  930   OSRDestroySpatialReference( mCRS );
 
  931   mCRS = OSRNewSpatialReference( NULL );
 
  933     OSRImportFromProj4( mCRS, theProj4String.trimmed().toLatin1().constData() )
 
  938 #if defined(QGISDEBUG) && QGISDEBUG>=3 
  942   setlocale( LC_NUMERIC, oldlocale );
 
  945 void QgsCoordinateReferenceSystem::setGeographicFlag( 
bool theGeoFlag )
 
  947   mGeoFlag = theGeoFlag;
 
  949 void QgsCoordinateReferenceSystem::setEpsg( 
long theEpsg )
 
  951   mAuthId = QString( 
"EPSG:%1" ).arg( theEpsg );
 
  953 void  QgsCoordinateReferenceSystem::setProjectionAcronym( QString theProjectionAcronym )
 
  955   mProjectionAcronym = theProjectionAcronym;
 
  957 void  QgsCoordinateReferenceSystem::setEllipsoidAcronym( QString theEllipsoidAcronym )
 
  959   mEllipsoidAcronym = theEllipsoidAcronym;
 
  962 void QgsCoordinateReferenceSystem::setMapUnits()
 
  976   if ( OSRIsProjected( mCRS ) )
 
  978     double toMeter = OSRGetLinearUnits( mCRS, &unitName );
 
  979     QString unit( unitName );
 
  986     static const double feetToMeter = 0.3048;
 
  987     static const double smallNum = 1e-3;
 
  989     if ( qAbs( toMeter - feetToMeter ) < smallNum )
 
  992     QgsDebugMsg( 
"Projection has linear units of " + unit );
 
  996     else if ( unit == 
"Foot" )
 
 1000       QgsDebugMsg( 
"Unsupported map units of " + unit );
 
 1006     OSRGetAngularUnits( mCRS, &unitName );
 
 1007     QString unit( unitName );
 
 1008     if ( unit == 
"degree" )
 
 1012       QgsDebugMsg( 
"Unsupported map units of " + unit );
 
 1031   if ( mEllipsoidAcronym.isNull() ||  mProjectionAcronym.isNull()
 
 1034     QgsDebugMsg( 
"QgsCoordinateReferenceSystem::findMatchingProj will only " 
 1035                  "work if prj acr ellipsoid acr and proj4string are set" 
 1036                  " and the current projection is valid!" );
 
 1042   sqlite3_stmt *myPreparedStatement;
 
 1047   QString mySql = QString( 
"select srs_id,parameters from tbl_srs where " 
 1048                            "projection_acronym=%1 and ellipsoid_acronym=%2 order by deprecated" )
 
 1049                   .arg( quotedValue( mProjectionAcronym ) )
 
 1050                   .arg( quotedValue( mEllipsoidAcronym ) );
 
 1055   myResult = openDb( myDatabaseFileName, &myDatabase );
 
 1056   if ( myResult != SQLITE_OK )
 
 1061   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
 
 1063   if ( myResult == SQLITE_OK )
 
 1066     while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
 
 1068       QString mySrsId = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 0 ) );
 
 1069       QString myProj4String = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 1 ) );
 
 1070       if ( 
toProj4() == myProj4String.trimmed() )
 
 1072         QgsDebugMsg( 
"-------> MATCH FOUND in srs.db srsid: " + mySrsId );
 
 1074         sqlite3_finalize( myPreparedStatement );
 
 1075         sqlite3_close( myDatabase );
 
 1076         return mySrsId.toLong();
 
 1084   QgsDebugMsg( 
"no match found in srs.db, trying user db now!" );
 
 1086   sqlite3_finalize( myPreparedStatement );
 
 1087   sqlite3_close( myDatabase );
 
 1094   myResult = openDb( myDatabaseFileName, &myDatabase );
 
 1095   if ( myResult != SQLITE_OK )
 
 1100   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
 
 1102   if ( myResult == SQLITE_OK )
 
 1105     while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
 
 1107       QString mySrsId = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 0 ) );
 
 1108       QString myProj4String = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 1 ) );
 
 1109       if ( 
toProj4() == myProj4String.trimmed() )
 
 1111         QgsDebugMsg( 
"-------> MATCH FOUND in user qgis.db srsid: " + mySrsId );
 
 1113         sqlite3_finalize( myPreparedStatement );
 
 1114         sqlite3_close( myDatabase );
 
 1115         return mySrsId.toLong();
 
 1126   sqlite3_finalize( myPreparedStatement );
 
 1127   sqlite3_close( myDatabase );
 
 1133   return ( !mIsValidFlag && !theSrs.mIsValidFlag ) ||
 
 1134          ( mIsValidFlag && theSrs.mIsValidFlag && theSrs.
authid() == 
authid() );
 
 1139   return  !( *
this == theSrs );
 
 1144   if ( mWkt.isEmpty() )
 
 1147     if ( OSRExportToWkt( mCRS, &wkt ) == OGRERR_NONE )
 
 1158   QgsDebugMsg( 
"Reading Spatial Ref Sys from xml ------------------------!" );
 
 1159   QDomNode srsNode  = theNode.namedItem( 
"spatialrefsys" );
 
 1161   if ( ! srsNode.isNull() )
 
 1163     bool initialized = 
false;
 
 1165     long srsid = srsNode.namedItem( 
"srsid" ).toElement().text().toLong();
 
 1171       myNode = srsNode.namedItem( 
"authid" );
 
 1172       if ( !myNode.isNull() )
 
 1183         myNode = srsNode.namedItem( 
"epsg" );
 
 1184         if ( !myNode.isNull() )
 
 1196       QgsDebugMsg( 
"Ignoring authid/epsg for user crs." );
 
 1205       myNode = srsNode.namedItem( 
"proj4" );
 
 1214         QgsDebugMsg( 
"Setting from elements one by one" );
 
 1216         myNode = srsNode.namedItem( 
"proj4" );
 
 1217         setProj4String( myNode.toElement().text() );
 
 1219         myNode = srsNode.namedItem( 
"srsid" );
 
 1220         setInternalId( myNode.toElement().text().toLong() );
 
 1222         myNode = srsNode.namedItem( 
"srid" );
 
 1223         setSrid( myNode.toElement().text().toLong() );
 
 1225         myNode = srsNode.namedItem( 
"authid" );
 
 1226         setAuthId( myNode.toElement().text() );
 
 1228         myNode = srsNode.namedItem( 
"description" );
 
 1229         setDescription( myNode.toElement().text() );
 
 1231         myNode = srsNode.namedItem( 
"projectionacronym" );
 
 1232         setProjectionAcronym( myNode.toElement().text() );
 
 1234         myNode = srsNode.namedItem( 
"ellipsoidacronym" );
 
 1235         setEllipsoidAcronym( myNode.toElement().text() );
 
 1237         myNode = srsNode.namedItem( 
"geographicflag" );
 
 1238         if ( myNode.toElement().text().compare( 
"true" ) )
 
 1240           setGeographicFlag( 
true );
 
 1244           setGeographicFlag( 
false );
 
 1251         mIsValidFlag = 
true; 
 
 1259         QString myName = QString( 
" * %1 (%2)" )
 
 1260                          .arg( 
QObject::tr( 
"Generated CRS", 
"A CRS automatically generated from layer info get this prefix for description" ) )
 
 1278   QDomElement myLayerNode = theNode.toElement();
 
 1279   QDomElement mySrsElement  = theDoc.createElement( 
"spatialrefsys" );
 
 1281   QDomElement myProj4Element  = theDoc.createElement( 
"proj4" );
 
 1282   myProj4Element.appendChild( theDoc.createTextNode( 
toProj4() ) );
 
 1283   mySrsElement.appendChild( myProj4Element );
 
 1285   QDomElement mySrsIdElement  = theDoc.createElement( 
"srsid" );
 
 1286   mySrsIdElement.appendChild( theDoc.createTextNode( QString::number( 
srsid() ) ) );
 
 1287   mySrsElement.appendChild( mySrsIdElement );
 
 1289   QDomElement mySridElement  = theDoc.createElement( 
"srid" );
 
 1290   mySridElement.appendChild( theDoc.createTextNode( QString::number( 
postgisSrid() ) ) );
 
 1291   mySrsElement.appendChild( mySridElement );
 
 1293   QDomElement myEpsgElement  = theDoc.createElement( 
"authid" );
 
 1294   myEpsgElement.appendChild( theDoc.createTextNode( 
authid() ) );
 
 1295   mySrsElement.appendChild( myEpsgElement );
 
 1297   QDomElement myDescriptionElement  = theDoc.createElement( 
"description" );
 
 1298   myDescriptionElement.appendChild( theDoc.createTextNode( 
description() ) );
 
 1299   mySrsElement.appendChild( myDescriptionElement );
 
 1301   QDomElement myProjectionAcronymElement  = theDoc.createElement( 
"projectionacronym" );
 
 1302   myProjectionAcronymElement.appendChild( theDoc.createTextNode( 
projectionAcronym() ) );
 
 1303   mySrsElement.appendChild( myProjectionAcronymElement );
 
 1305   QDomElement myEllipsoidAcronymElement  = theDoc.createElement( 
"ellipsoidacronym" );
 
 1306   myEllipsoidAcronymElement.appendChild( theDoc.createTextNode( 
ellipsoidAcronym() ) );
 
 1307   mySrsElement.appendChild( myEllipsoidAcronymElement );
 
 1309   QDomElement myGeographicFlagElement  = theDoc.createElement( 
"geographicflag" );
 
 1310   QString myGeoFlagText = 
"false";
 
 1313     myGeoFlagText = 
"true";
 
 1316   myGeographicFlagElement.appendChild( theDoc.createTextNode( myGeoFlagText ) );
 
 1317   mySrsElement.appendChild( myGeographicFlagElement );
 
 1319   myLayerNode.appendChild( mySrsElement );
 
 1333 QString QgsCoordinateReferenceSystem::proj4FromSrsId( 
const int theSrsId )
 
 1336   QString myDatabaseFileName;
 
 1337   QString myProjString;
 
 1338   QString mySql = QString( 
"select parameters from tbl_srs where srs_id = %1 order by deprecated" ).arg( theSrsId );
 
 1340   QgsDebugMsg( 
"mySrsId = " + QString::number( theSrsId ) );
 
 1351     QFileInfo myFileInfo;
 
 1352     myFileInfo.setFile( myDatabaseFileName );
 
 1353     if ( !myFileInfo.exists() ) 
 
 1367   rc = openDb( myDatabaseFileName, &db );
 
 1374   sqlite3_stmt *ppStmt;
 
 1376   rc = sqlite3_prepare( db, mySql.toUtf8(), mySql.toUtf8().length(), &ppStmt, &pzTail );
 
 1379   if ( rc == SQLITE_OK )
 
 1381     if ( sqlite3_step( ppStmt ) == SQLITE_ROW )
 
 1383       myProjString = QString::fromUtf8(( 
char* )sqlite3_column_text( ppStmt, 0 ) );
 
 1387   sqlite3_finalize( ppStmt );
 
 1389   sqlite3_close( db );
 
 1392   return myProjString;
 
 1395 int QgsCoordinateReferenceSystem::openDb( QString path, 
sqlite3 **db, 
bool readonly )
 
 1398   int myResult = readonly
 
 1399                  ? sqlite3_open_v2( path.toUtf8().data(), db, SQLITE_OPEN_READONLY, NULL )
 
 1400                  : sqlite3_open( path.toUtf8().data(), db );
 
 1402   if ( myResult != SQLITE_OK )
 
 1404     QgsDebugMsg( 
"Can't open database: " + QString( sqlite3_errmsg( *db ) ) );
 
 1411                                .arg( sqlite3_errmsg( *db ) ), 
QObject::tr( 
"CRS" ) );
 
 1418   mCustomSrsValidation = f;
 
 1423   return mCustomSrsValidation;
 
 1426 void QgsCoordinateReferenceSystem::debugPrint()
 
 1429   QgsDebugMsg( 
"* Valid : " + ( mIsValidFlag ? QString( 
"true" ) : QString( 
"false" ) ) );
 
 1430   QgsDebugMsg( 
"* SrsId : " + QString::number( mSrsId ) );
 
 1450   mValidationHint = html;
 
 1455   return mValidationHint;
 
 1463   if ( ! mIsValidFlag )
 
 1471   QString proj4String = mProj4;
 
 1472   if ( proj4String.isEmpty() )
 
 1481   if ( getRecordCount() == 0 )
 
 1483     mySql = 
"insert into tbl_srs (srs_id,description,projection_acronym,ellipsoid_acronym,parameters,is_geo) values (" 
 1485             + 
"," + quotedValue( name )
 
 1488             + 
"," + quotedValue( 
toProj4() )
 
 1493     mySql = 
"insert into tbl_srs (description,projection_acronym,ellipsoid_acronym,parameters,is_geo) values (" 
 1494             + quotedValue( name )
 
 1497             + 
"," + quotedValue( 
toProj4() )
 
 1502   sqlite3_stmt *myPreparedStatement;
 
 1506   if ( myResult != SQLITE_OK )
 
 1508     QgsDebugMsg( QString( 
"Can't open or create database %1: %2" )
 
 1510                  .arg( sqlite3_errmsg( myDatabase ) ) );
 
 1513   QgsDebugMsg( QString( 
"Update or insert sql \n%1" ).arg( mySql ) );
 
 1514   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
 
 1517   if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_DONE )
 
 1521     return_id = sqlite3_last_insert_rowid( myDatabase );
 
 1522     setInternalId( return_id );
 
 1527     QStringList projectionsProj4 = settings.value( 
"/UI/recentProjectionsProj4" ).toStringList();
 
 1528     QStringList projectionsAuthId = settings.value( 
"/UI/recentProjectionsAuthId" ).toStringList();
 
 1531     projectionsProj4.append( 
toProj4() );
 
 1532     projectionsAuthId.append( 
authid() );
 
 1533     settings.setValue( 
"/UI/recentProjectionsProj4", projectionsProj4 );
 
 1534     settings.setValue( 
"/UI/recentProjectionsAuthId", projectionsAuthId );
 
 1542 long QgsCoordinateReferenceSystem::getRecordCount()
 
 1546   sqlite3_stmt *myPreparedStatement;
 
 1548   long          myRecordCount = 0;
 
 1551   if ( myResult != SQLITE_OK )
 
 1553     QgsDebugMsg( QString( 
"Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
 
 1557   QString mySql = 
"select count(*) from tbl_srs";
 
 1558   myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
 
 1560   if ( myResult == SQLITE_OK )
 
 1562     if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
 
 1564       QString myRecordCountString = QString::fromUtf8(( 
char * )sqlite3_column_text( myPreparedStatement, 0 ) );
 
 1565       myRecordCount = myRecordCountString.toLong();
 
 1569   sqlite3_finalize( myPreparedStatement );
 
 1570   sqlite3_close( myDatabase );
 
 1571   return myRecordCount;
 
 1574 QString QgsCoordinateReferenceSystem::quotedValue( QString value )
 
 1576   value.replace( 
"'", 
"''" );
 
 1577   return value.prepend( 
"'" ).append( 
"'" );
 
 1581 bool QgsCoordinateReferenceSystem::loadWkts( QHash<int, QString> &wkts, 
const char *filename )
 
 1583   qDebug( 
"Loading %s", filename );
 
 1584   const char *pszFilename = CPLFindFile( 
"gdal", filename );
 
 1588   QFile csv( pszFilename );
 
 1589   if ( !csv.open( QIODevice::ReadOnly ) )
 
 1592   QTextStream lines( &csv );
 
 1596     QString line = lines.readLine();
 
 1597     if ( line.isNull() )
 
 1600     if ( line.startsWith( 
'#' ) )
 
 1604     else if ( line.startsWith( 
"include " ) )
 
 1606       if ( !loadWkts( wkts, line.mid( 8 ).toUtf8() ) )
 
 1611       int pos = line.indexOf( 
"," );
 
 1616       int epsg = line.left( pos ).toInt( &ok );
 
 1620       wkts.insert( epsg, line.mid( pos + 1 ) );
 
 1629 bool QgsCoordinateReferenceSystem::loadIDs( QHash<int, QString> &wkts )
 
 1633   foreach ( QString csv, QStringList() << 
"gcs.csv" << 
"pcs.csv" << 
"vertcs.csv" << 
"compdcs.csv" << 
"geoccs.csv" )
 
 1635     QString filename = CPLFindFile( 
"gdal", csv.toUtf8() );
 
 1637     QFile f( filename );
 
 1638     if ( !f.open( QIODevice::ReadOnly ) )
 
 1641     QTextStream lines( &f );
 
 1648       QString line = lines.readLine();
 
 1649       if ( line.isNull() )
 
 1652       int pos = line.indexOf( 
"," );
 
 1657       int epsg = line.left( pos ).toInt( &ok );
 
 1662       if ( epsg == 2218 || epsg == 2221 || epsg == 2296 || epsg == 2297 || epsg == 2298 || epsg == 2299 || epsg == 2300 || epsg == 2301 || epsg == 2302 ||
 
 1663            epsg == 2303 || epsg == 2304 || epsg == 2305 || epsg == 2306 || epsg == 2307 || epsg == 2963 || epsg == 2985 || epsg == 2986 || epsg == 3052 ||
 
 1664            epsg == 3053 || epsg == 3139 || epsg == 3144 || epsg == 3145 || epsg == 3173 || epsg == 3295 || epsg == 3993 || epsg == 4087 || epsg == 4088 ||
 
 1665            epsg == 5017 || epsg == 5221 || epsg == 5224 || epsg == 5225 || epsg == 5514 || epsg == 5515 || epsg == 5516 || epsg == 5819 || epsg == 5820 ||
 
 1666            epsg == 5821 || epsg == 32600 || epsg == 32663 || epsg == 32700 )
 
 1669       if ( OSRImportFromEPSG( crs, epsg ) != OGRERR_NONE )
 
 1671         qDebug( 
"EPSG %d: not imported", epsg );
 
 1676       if ( OSRExportToWkt( crs, &wkt ) != OGRERR_NONE )
 
 1678         qWarning( 
"EPSG %d: not exported to WKT", epsg );
 
 1682       wkts.insert( epsg, wkt );
 
 1690     qDebug( 
"Loaded %d/%d from %s", n, l, filename.toUtf8().constData() );
 
 1693   OSRDestroySpatialReference( crs );
 
 1701   syncDatumTransform( dbFilePath );
 
 1703   int inserted = 0, updated = 0, deleted = 0, errors = 0;
 
 1708   if ( sqlite3_open( dbFilePath.toUtf8().constData(), &database ) != SQLITE_OK )
 
 1714   if ( sqlite3_exec( database, 
"BEGIN TRANSACTION", 0, 0, 0 ) != SQLITE_OK )
 
 1716     qCritical( 
"Could not begin transaction: %s [%s]\n", 
QgsApplication::srsDbFilePath().toLocal8Bit().constData(), sqlite3_errmsg( database ) );
 
 1721   if ( sqlite3_exec( database, 
"alter table tbl_srs add noupdate boolean", 0, 0, 0 ) == SQLITE_OK )
 
 1722     ( void )sqlite3_exec( database, 
"update tbl_srs set noupdate=(auth_name='EPSG' and auth_id in (5513,5514,5221,2065,102067,4156,4818))", 0, 0, 0 );
 
 1724   ( void )sqlite3_exec( database, 
"UPDATE tbl_srs SET srid=141001 WHERE srid=41001 AND auth_name='OSGEO' AND auth_id='41001'", 0, 0, 0 );
 
 1728   sqlite3_stmt *select;
 
 1729   char *errMsg = NULL;
 
 1733   QHash<int, QString> wkts;
 
 1735   loadWkts( wkts, 
"epsg.wkt" );
 
 1737   qDebug( 
"%d WKTs loaded", wkts.count() );
 
 1739   for ( QHash<int, QString>::const_iterator it = wkts.constBegin(); it != wkts.constEnd(); ++it )
 
 1741     QByteArray ba( it.value().toUtf8() );
 
 1742     char *psz = ba.data();
 
 1743     OGRErr ogrErr = OSRImportFromWkt( crs, &psz );
 
 1744     if ( ogrErr != OGRERR_NONE )
 
 1747     if ( OSRExportToProj4( crs, &psz ) != OGRERR_NONE )
 
 1751     proj4 = proj4.trimmed();
 
 1755     if ( proj4.isEmpty() )
 
 1758     sql = QString( 
"SELECT parameters,noupdate FROM tbl_srs WHERE auth_name='EPSG' AND auth_id='%1'" ).arg( it.key() );
 
 1759     if ( sqlite3_prepare( database, sql.toAscii(), sql.size(), &select, &tail ) != SQLITE_OK )
 
 1761       qCritical( 
"Could not prepare: %s [%s]\n", sql.toAscii().constData(), sqlite3_errmsg( database ) );
 
 1766     if ( sqlite3_step( select ) == SQLITE_ROW )
 
 1768       srsProj4 = ( 
const char * ) sqlite3_column_text( select, 0 );
 
 1770       if ( QString::fromUtf8(( 
char * )sqlite3_column_text( select, 1 ) ).toInt() != 0 )
 
 1774     sqlite3_finalize( select );
 
 1776     if ( !srsProj4.isEmpty() )
 
 1778       if ( proj4 != srsProj4 )
 
 1781         sql = QString( 
"UPDATE tbl_srs SET parameters=%1 WHERE auth_name='EPSG' AND auth_id=%2" ).arg( quotedValue( proj4 ) ).arg( it.key() );
 
 1783         if ( sqlite3_exec( database, sql.toUtf8(), 0, 0, &errMsg ) != SQLITE_OK )
 
 1785           qCritical( 
"Could not execute: %s [%s/%s]\n",
 
 1786                      sql.toLocal8Bit().constData(),
 
 1787                      sqlite3_errmsg( database ),
 
 1788                      errMsg ? errMsg : 
"(unknown error)" );
 
 1794           QgsDebugMsgLevel( QString( 
"SQL: %1\n OLD:%2\n NEW:%3" ).arg( sql ).arg( srsProj4 ).arg( proj4 ), 3 );
 
 1800       QRegExp projRegExp( 
"\\+proj=(\\S+)" );
 
 1801       if ( projRegExp.indexIn( proj4 ) < 0 )
 
 1803         QgsDebugMsg( QString( 
"EPSG %1: no +proj argument found [%2]" ).arg( it.key() ).arg( proj4 ) );
 
 1807       QRegExp ellipseRegExp( 
"\\+ellps=(\\S+)" );
 
 1809       if ( ellipseRegExp.indexIn( proj4 ) >= 0 )
 
 1811         ellps = ellipseRegExp.cap( 1 );
 
 1814       QString name( OSRIsGeographic( crs ) ? OSRGetAttrValue( crs, 
"GEOCS", 0 ) : OSRGetAttrValue( crs, 
"PROJCS", 0 ) );
 
 1815       if ( name.isEmpty() )
 
 1818       sql = QString( 
"INSERT INTO tbl_srs(description,projection_acronym,ellipsoid_acronym,parameters,srid,auth_name,auth_id,is_geo,deprecated) VALUES (%1,%2,%3,%4,%5,'EPSG',%5,%6,0)" )
 
 1819             .arg( quotedValue( name ) )
 
 1820             .arg( quotedValue( projRegExp.cap( 1 ) ) )
 
 1821             .arg( quotedValue( ellps ) )
 
 1822             .arg( quotedValue( proj4 ) )
 
 1824             .arg( OSRIsGeographic( crs ) );
 
 1827       if ( sqlite3_exec( database, sql.toUtf8(), 0, 0, &errMsg ) == SQLITE_OK )
 
 1833         qCritical( 
"Could not execute: %s [%s/%s]\n",
 
 1834                    sql.toLocal8Bit().constData(),
 
 1835                    sqlite3_errmsg( database ),
 
 1836                    errMsg ? errMsg : 
"(unknown error)" );
 
 1840           sqlite3_free( errMsg );
 
 1845   sql = 
"DELETE FROM tbl_srs WHERE auth_name='EPSG' AND NOT auth_id IN (";
 
 1847   foreach ( 
int i, wkts.keys() )
 
 1849     sql += delim + QString::number( i );
 
 1852   sql += 
") AND NOT noupdate";
 
 1854   if ( sqlite3_exec( database, sql.toUtf8(), 0, 0, 0 ) == SQLITE_OK )
 
 1856     deleted = sqlite3_changes( database );
 
 1861     qCritical( 
"Could not execute: %s [%s]\n",
 
 1862                sql.toLocal8Bit().constData(),
 
 1863                sqlite3_errmsg( database ) );
 
 1866 #if !defined(PJ_VERSION) || PJ_VERSION!=470 
 1867   sql = QString( 
"select auth_name,auth_id,parameters from tbl_srs WHERE auth_name<>'EPSG' AND NOT deprecated AND NOT noupdate" );
 
 1868   if ( sqlite3_prepare( database, sql.toAscii(), sql.size(), &select, &tail ) == SQLITE_OK )
 
 1870     while ( sqlite3_step( select ) == SQLITE_ROW )
 
 1872       const char *auth_name = ( 
const char * ) sqlite3_column_text( select, 0 );
 
 1873       const char *auth_id   = ( 
const char * ) sqlite3_column_text( select, 1 );
 
 1874       const char *params    = ( 
const char * ) sqlite3_column_text( select, 2 );
 
 1876       QString input = QString( 
"+init=%1:%2" ).arg( QString( auth_name ).toLower() ).arg( auth_id );
 
 1877       projPJ pj = pj_init_plus( input.toAscii() );
 
 1880         input = QString( 
"+init=%1:%2" ).arg( QString( auth_name ).toUpper() ).arg( auth_id );
 
 1881         pj = pj_init_plus( input.toAscii() );
 
 1886         char *def = pj_get_def( pj, 0 );
 
 1892           input.prepend( 
' ' ).append( 
' ' );
 
 1893           if ( proj4.startsWith( input ) )
 
 1895             proj4 = proj4.mid( input.size() );
 
 1896             proj4 = proj4.trimmed();
 
 1899           if ( proj4 != params )
 
 1901             sql = QString( 
"UPDATE tbl_srs SET parameters=%1 WHERE auth_name=%2 AND auth_id=%3" )
 
 1902                   .arg( quotedValue( proj4 ) )
 
 1903                   .arg( quotedValue( auth_name ) )
 
 1904                   .arg( quotedValue( auth_id ) );
 
 1906             if ( sqlite3_exec( database, sql.toUtf8(), 0, 0, &errMsg ) == SQLITE_OK )
 
 1909               QgsDebugMsgLevel( QString( 
"SQL: %1\n OLD:%2\n NEW:%3" ).arg( sql ).arg( params ).arg( proj4 ), 3 );
 
 1913               qCritical( 
"Could not execute: %s [%s/%s]\n",
 
 1914                          sql.toLocal8Bit().constData(),
 
 1915                          sqlite3_errmsg( database ),
 
 1916                          errMsg ? errMsg : 
"(unknown error)" );
 
 1923           QgsDebugMsg( QString( 
"could not retrieve proj string for %1 from PROJ" ).arg( input ) );
 
 1928         QgsDebugMsgLevel( QString( 
"could not retrieve crs for %1 from PROJ" ).arg( input ), 3 );
 
 1937     qCritical( 
"Could not execute: %s [%s]\n",
 
 1938                sql.toLocal8Bit().constData(),
 
 1939                sqlite3_errmsg( database ) );
 
 1943   OSRDestroySpatialReference( crs );
 
 1945   if ( sqlite3_exec( database, 
"COMMIT", 0, 0, 0 ) != SQLITE_OK )
 
 1947     qCritical( 
"Could not commit transaction: %s [%s]\n", 
QgsApplication::srsDbFilePath().toLocal8Bit().constData(), sqlite3_errmsg( database ) );
 
 1951   sqlite3_close( database );
 
 1953   qWarning( 
"CRS update (inserted:%d updated:%d deleted:%d errors:%d)", inserted, updated, deleted, errors );
 
 1958     return updated + inserted;
 
 1961 bool QgsCoordinateReferenceSystem::syncDatumTransform( 
const QString& dbPath )
 
 1963   const char *filename = CSVFilename( 
"datum_shift.csv" );
 
 1964   FILE *fp = VSIFOpen( filename, 
"rb" );
 
 1970   char **fieldnames = CSVReadParseLine( fp );
 
 1982     { 
"SOURCE_CRS_CODE", 
"source_crs_code", -1 },
 
 1983     { 
"TARGET_CRS_CODE", 
"target_crs_code", -1 },
 
 1984     { 
"REMARKS", 
"remarks", -1 },
 
 1985     { 
"COORD_OP_SCOPE", 
"scope", -1 },
 
 1986     { 
"AREA_OF_USE_CODE", 
"area_of_use_code", -1 },
 
 1992     { 
"DEPRECATED", 
"deprecated", -1 },
 
 1993     { 
"COORD_OP_METHOD_CODE", 
"coord_op_method_code", -1 },
 
 2001     { 
"PREFERRED", 
"preferred", -1 },
 
 2002     { 
"COORD_OP_CODE", 
"coord_op_code", -1 },
 
 2005   QString update = 
"UPDATE tbl_datum_transform SET ";
 
 2006   QString insert, values;
 
 2008   int n = CSLCount( fieldnames );
 
 2010   int idxid = -1, idxrx = -1, idxry = -1, idxrz = -1, idxmcode = -1;
 
 2011   for ( 
unsigned int i = 0; i < 
sizeof( map ) / 
sizeof( *map ); i++ )
 
 2013     bool last = i == 
sizeof( map ) / 
sizeof( *map ) - 1;
 
 2015     map[i].idx = CSLFindString( fieldnames, map[i].src );
 
 2016     if ( map[i].idx < 0 )
 
 2018       qWarning( 
"field %s not found", map[i].src );
 
 2019       CSLDestroy( fieldnames );
 
 2024     if ( strcmp( map[i].src, 
"COORD_OP_CODE" ) == 0 )
 
 2026     if ( strcmp( map[i].src, 
"RX" ) == 0 )
 
 2028     if ( strcmp( map[i].src, 
"RY" ) == 0 )
 
 2030     if ( strcmp( map[i].src, 
"RZ" ) == 0 )
 
 2032     if ( strcmp( map[i].src, 
"COORD_OP_METHOD_CODE" ) == 0 )
 
 2042         update += 
" WHERE ";
 
 2050     update += QString( 
"%1=%%2" ).arg( map[i].dst ).arg( i + 1 );
 
 2052     insert += map[i].dst;
 
 2053     values += QString( 
"%%1" ).arg( i + 1 );
 
 2056   insert = 
"INSERT INTO tbl_datum_transform(" + insert + 
") VALUES (" + values + 
")";
 
 2061   CSLDestroy( fieldnames );
 
 2063   Q_ASSERT( idxid >= 0 );
 
 2064   Q_ASSERT( idxrx >= 0 );
 
 2065   Q_ASSERT( idxry >= 0 );
 
 2066   Q_ASSERT( idxrz >= 0 );
 
 2069   int openResult = sqlite3_open( dbPath.toUtf8().constData(), &db );
 
 2070   if ( openResult != SQLITE_OK )
 
 2076   if ( sqlite3_exec( db, 
"BEGIN TRANSACTION", 0, 0, 0 ) != SQLITE_OK )
 
 2079     sqlite3_close( db );
 
 2085   v.reserve( 
sizeof( map ) / 
sizeof( *map ) );
 
 2087   while ( !feof( fp ) )
 
 2089     char **values = CSVReadParseLine( fp );
 
 2093     if ( CSLCount( values ) < n )
 
 2095       qWarning( 
"Only %d columns", CSLCount( values ) );
 
 2099     for ( 
unsigned int i = 0; i < 
sizeof( map ) / 
sizeof( *map ); i++ )
 
 2101       int idx = map[i].idx;
 
 2102       Q_ASSERT( idx != -1 );
 
 2103       Q_ASSERT( idx < n );
 
 2104       v.insert( i, *values[ idx ] ? quotedValue( values[idx] ) : 
"NULL" );
 
 2108     if ( v.at( idxmcode ).compare( QString( 
"'9607'" ) ) == 0 )
 
 2110       v[ idxmcode ] = 
"'9606'";
 
 2111       v[ idxrx ] = 
"'" + 
qgsDoubleToString( -( v[ idxrx ].
remove( 
"'" ).toDouble() ) ) + 
"'";
 
 2112       v[ idxry ] = 
"'" + 
qgsDoubleToString( -( v[ idxry ].
remove( 
"'" ).toDouble() ) ) + 
"'";
 
 2113       v[ idxrz ] = 
"'" + 
qgsDoubleToString( -( v[ idxrz ].
remove( 
"'" ).toDouble() ) ) + 
"'";
 
 2119     QString sql = QString( 
"SELECT coord_op_code FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( v[ idxid ] );
 
 2120     int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
 
 2121     if ( prepareRes != SQLITE_OK )
 
 2124     if ( sqlite3_step( stmt ) == SQLITE_ROW )
 
 2126       cOpCode = ( 
const char * ) sqlite3_column_text( stmt, 0 );
 
 2128     sqlite3_finalize( stmt );
 
 2130     sql = cOpCode.isEmpty() ? insert : update;
 
 2131     for ( 
int i = 0; i < v.size(); i++ )
 
 2133       sql = sql.arg( v[i] );
 
 2136     if ( sqlite3_exec( db, sql.toUtf8(), 0, 0, 0 ) != SQLITE_OK )
 
 2138       qCritical( 
"SQL: %s", sql.toUtf8().constData() );
 
 2139       qCritical( 
"Error: %s", sqlite3_errmsg( db ) );
 
 2143   if ( sqlite3_exec( db, 
"COMMIT", 0, 0, 0 ) != SQLITE_OK )
 
 2149   sqlite3_close( db );
 
 2161     return OSRGetAuthorityName( mCRS, 
"GEOGCS" ) + QString( 
":" ) + OSRGetAuthorityCode( mCRS, 
"GEOGCS" );
 
 2171   QStringList projections;
 
 2175   projections = settings.value( 
"/UI/recentProjections" ).toStringList();
 
 2179   QStringList projectionsProj4  = settings.value( 
"/UI/recentProjectionsProj4" ).toStringList();
 
 2180   QStringList projectionsAuthId = settings.value( 
"/UI/recentProjectionsAuthId" ).toStringList();
 
 2181   if ( projectionsAuthId.size() >= projections.size() )
 
 2185     projections.clear();
 
 2186     for ( 
int i = 0; i <  projectionsAuthId.size(); i++ )
 
 2194         if ( i >= projectionsProj4.size() || !crs.
createFromProj4( projectionsProj4.at( i ) ) )
 
 2200         if ( crs.
srsid() == 0 )
 
 2205       projections << QString::number( crs.
srsid() );