23 #include <QTemporaryFile>
25 #include <QDomElement>
28 #include <QTextStream>
43 #include <ogr_srs_api.h>
44 #include <cpl_error.h>
55 , mMapUnits(
QGis::UnknownUnit )
58 , mValidationHint(
"" )
59 , mAxisInverted( false )
61 mCRS = OSRNewSpatialReference( NULL );
67 , mMapUnits(
QGis::UnknownUnit )
70 , mValidationHint(
"" )
71 , mAxisInverted( false )
73 mCRS = OSRNewSpatialReference( NULL );
81 , mMapUnits(
QGis::UnknownUnit )
84 , mValidationHint(
"" )
85 , mAxisInverted( false )
87 mCRS = OSRNewSpatialReference( NULL );
93 OSRDestroySpatialReference( mCRS );
120 QRegExp reCrsId(
"^(epsg|postgis|internal)\\:(\\d+)$", Qt::CaseInsensitive );
121 if ( reCrsId.
indexIn( theDefinition ) == 0 )
125 if ( authName ==
"epsg" )
127 if ( authName ==
"postgis" )
134 QRegExp reCrsStr(
"^(?:(wkt|proj4)\\:)?(.+)$", Qt::CaseInsensitive );
135 if ( reCrsStr.
indexIn( theDefinition ) == 0 )
147 .
arg(
QObject::tr(
"Generated CRS",
"A CRS automatically generated from layer info get this prefix for description" ) )
168 #if GDAL_VERSION_NUM >= 1900
177 if ( OSRExportToWkt( crs, &wkt ) == OGRERR_NONE )
182 OSRDestroySpatialReference( crs );
192 #if GDAL_VERSION_NUM >= 1900
193 const char* configOld = CPLGetConfigOption(
"GDAL_FIX_ESRI_WKT",
"" );
194 const char* configNew =
"GEOGCS";
196 if ( strcmp( configOld,
"" ) == 0 )
198 CPLSetConfigOption(
"GDAL_FIX_ESRI_WKT", configNew );
199 if ( strcmp( configNew, CPLGetConfigOption(
"GDAL_FIX_ESRI_WKT",
"" ) ) != 0 )
201 .arg( configNew ).arg( CPLGetConfigOption(
"GDAL_FIX_ESRI_WKT",
"" ) ) );
213 QRegExp re(
"urn:ogc:def:crs:([^:]+).+([^:]+)", Qt::CaseInsensitive );
216 theCrs = re.
cap( 1 ) +
":" + re.
cap( 2 );
231 if ( theCrs.
compare(
"CRS:27", Qt::CaseInsensitive ) == 0 ||
232 theCrs.
compare(
"OGC:CRS27", Qt::CaseInsensitive ) == 0 )
239 if ( theCrs.
compare(
"CRS:83", Qt::CaseInsensitive ) == 0 ||
240 theCrs.
compare(
"OGC:CRS83", Qt::CaseInsensitive ) == 0 )
247 if ( theCrs.
compare(
"CRS:84", Qt::CaseInsensitive ) == 0 ||
248 theCrs.
compare(
"OGC:CRS84", Qt::CaseInsensitive ) == 0 )
260 mCRS = OSRNewSpatialReference( NULL );
270 mDescription = srs.mDescription;
271 mProjectionAcronym = srs.mProjectionAcronym;
272 mEllipsoidAcronym = srs.mEllipsoidAcronym;
273 mGeoFlag = srs.mGeoFlag;
274 mAxisInverted = srs.mAxisInverted;
275 mMapUnits = srs.mMapUnits;
277 mAuthId = srs.mAuthId;
278 mIsValidFlag = srs.mIsValidFlag;
279 mValidationHint = srs.mValidationHint;
284 OSRDestroySpatialReference( mCRS );
285 mCRS = OSRClone( srs.mCRS );
300 if ( mCustomSrsValidation )
301 mCustomSrsValidation( *
this );
323 QgsDebugMsgLevel(
"load CRS from " + db +
" where " + expression +
" is " + value, 3 );
324 mIsValidFlag =
false;
328 if ( !myInfo.exists() )
330 QgsDebugMsg(
"failed : " + db +
" does not exist!" );
336 sqlite3_stmt *myPreparedStatement;
339 myResult = openDb( db, &myDatabase );
340 if ( myResult != SQLITE_OK )
342 QgsDebugMsg(
"failed : " + db +
" could not be opened!" );
358 QString mySql =
"select srs_id,description,projection_acronym,"
359 "ellipsoid_acronym,parameters,srid,auth_name||':'||auth_id,is_geo "
360 "from tbl_srs where " + expression +
"=" + quotedValue( value ) +
" order by deprecated";
361 myResult = sqlite3_prepare( myDatabase, mySql.
toUtf8(),
363 &myPreparedStatement, &myTail );
365 if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
368 myPreparedStatement, 0 ) ).
toLong();
370 myPreparedStatement, 1 ) );
371 mProjectionAcronym =
QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, 2 ) );
372 mEllipsoidAcronym =
QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, 3 ) );
373 mProj4 =
QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, 4 ) );
375 mAuthId =
QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, 6 ) );
383 else if ( mAuthId.
startsWith(
"EPSG:", Qt::CaseInsensitive ) )
385 OSRDestroySpatialReference( mCRS );
386 mCRS = OSRNewSpatialReference( NULL );
387 mIsValidFlag = OSRSetFromUserInput( mCRS, mAuthId.
toLower().
toAscii() ) == OGRERR_NONE;
393 setProj4String( mProj4 );
400 sqlite3_finalize( myPreparedStatement );
401 sqlite3_close( myDatabase );
407 if ( mAxisInverted == -1 )
409 OGRAxisOrientation orientation;
410 OSRGetAxis( mCRS, OSRIsGeographic( mCRS ) ?
"GEOGCS" :
"PROJCS", 0, &orientation );
413 if ( orientation == OAO_Other && mAuthId.
startsWith(
"EPSG:", Qt::CaseInsensitive ) )
417 if ( OSRImportFromEPSGA( crs, mAuthId.
mid( 5 ).
toInt() ) == OGRERR_NONE )
419 OSRGetAxis( crs, OSRIsGeographic( crs ) ?
"GEOGCS" :
"PROJCS", 0, &orientation );
422 OSRDestroySpatialReference( crs );
425 mAxisInverted = orientation == OAO_North;
428 return mAxisInverted != 0;
433 mIsValidFlag =
false;
439 QgsDebugMsg(
"theWkt is uninitialised, operation failed" );
444 const char *pWkt = ba.
data();
446 OGRErr myInputResult = OSRImportFromWkt( mCRS, (
char ** ) & pWkt );
448 if ( myInputResult != OGRERR_NONE )
450 QgsDebugMsg(
"\n---------------------------------------------------------------" );
451 QgsDebugMsg(
"This CRS could *** NOT *** be set from the supplied Wkt " );
454 QgsDebugMsg(
"---------------------------------------------------------------\n" );
458 if ( OSRAutoIdentifyEPSG( mCRS ) == OGRERR_NONE )
461 .
arg( OSRGetAuthorityName( mCRS, NULL ) )
462 .
arg( OSRGetAuthorityCode( mCRS, NULL ) );
472 char *proj4src = NULL;
473 OSRExportToProj4( mCRS, &proj4src );
485 OSRExportToProj4( mCRS, &proj4src );
496 .
arg(
QObject::tr(
"Generated CRS",
"A CRS automatically generated from layer info get this prefix for description" ) )
524 mIsValidFlag =
false;
527 QRegExp myProjRegExp(
"\\+proj=(\\S+)" );
528 int myStart = myProjRegExp.
indexIn( myProj4String );
531 QgsDebugMsg(
"proj string supplied has no +proj argument" );
535 mProjectionAcronym = myProjRegExp.
cap( 1 );
537 QRegExp myEllipseRegExp(
"\\+ellps=(\\S+)" );
538 myStart = myEllipseRegExp.
indexIn( myProj4String );
541 QgsDebugMsg(
"proj string supplied has no +ellps argument" );
542 mEllipsoidAcronym =
"";
546 mEllipsoidAcronym = myEllipseRegExp.
cap( 1 );
549 QRegExp myAxisRegExp(
"\\+a=(\\S+)" );
550 myStart = myAxisRegExp.
indexIn( myProj4String );
553 QgsDebugMsg(
"proj string supplied has no +a argument" );
571 myRecord = getRecord(
"select * from tbl_srs where parameters=" + quotedValue( myProj4String ) +
" order by deprecated" );
572 if ( myRecord.
empty() )
577 QRegExp myLat1RegExp(
"\\+lat_1=\\S+" );
578 QRegExp myLat2RegExp(
"\\+lat_2=\\S+" );
585 myStart1 = myLat1RegExp.
indexIn( myProj4String, myStart1 );
586 myStart2 = myLat2RegExp.
indexIn( myProj4String, myStart2 );
587 if ( myStart1 != -1 && myStart2 != -1 )
595 if ( lat1Str !=
"" && lat2Str !=
"" )
598 QString theProj4StringModified = myProj4String;
603 myStart2 = myLat2RegExp.
indexIn( theProj4String, myStart2 );
605 QgsDebugMsg(
"trying proj4string match with swapped lat_1,lat_2" );
606 myRecord = getRecord(
"select * from tbl_srs where parameters=" + quotedValue( theProj4StringModified.
trimmed() ) +
" order by deprecated" );
610 if ( myRecord.
empty() )
617 QString sql =
"SELECT * FROM tbl_srs WHERE ";
625 foreach (
QString param, myProj4String.
split(
QRegExp(
"\\s+(?=\\+)" ), QString::SkipEmptyParts ) )
642 myRecord = getRecord( sql + delim + datum +
" order by deprecated" );
645 if ( myRecord.
empty() )
648 myRecord = getRecord( sql +
" order by deprecated" );
651 if ( !myRecord.
empty() )
655 foreach (
QString param, myRecord[
"parameters"].split(
QRegExp(
"\\s+(?=\\+)" ), QString::SkipEmptyParts ) )
658 foundParams << param.
trimmed();
664 if ( myParams != foundParams )
671 if ( !myRecord.
empty() )
673 mySrsId = myRecord[
"srs_id"].toLong();
683 QgsDebugMsg(
"globbing search for srsid from this proj string" );
684 setProj4String( myProj4String );
693 mIsValidFlag =
false;
700 QgsDebugMsg(
"Projection is not found in databases." );
702 setProj4String( myProj4String );
717 sqlite3_stmt *myPreparedStatement;
724 if ( !myInfo.exists() )
726 QgsDebugMsg(
"failed : " + myDatabaseFileName +
" does not exist!" );
731 myResult = openDb( myDatabaseFileName, &myDatabase );
732 if ( myResult != SQLITE_OK )
737 myResult = sqlite3_prepare( myDatabase, theSql.
toUtf8(), theSql.
toUtf8().
length(), &myPreparedStatement, &myTail );
739 if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
742 int myColumnCount = sqlite3_column_count( myPreparedStatement );
744 for (
int myColNo = 0; myColNo < myColumnCount; myColNo++ )
746 myFieldName =
QString::fromUtf8((
char * )sqlite3_column_name( myPreparedStatement, myColNo ) );
747 myFieldValue =
QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, myColNo ) );
748 myMap[myFieldName] = myFieldValue;
750 if ( sqlite3_step( myPreparedStatement ) != SQLITE_DONE )
764 sqlite3_finalize( myPreparedStatement );
765 sqlite3_close( myDatabase );
769 myFileInfo.
setFile( myDatabaseFileName );
770 if ( !myFileInfo.
exists() )
777 myResult = openDb( myDatabaseFileName, &myDatabase );
778 if ( myResult != SQLITE_OK )
783 myResult = sqlite3_prepare( myDatabase, theSql.
toUtf8(), theSql.
toUtf8().
length(), &myPreparedStatement, &myTail );
785 if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
787 int myColumnCount = sqlite3_column_count( myPreparedStatement );
789 for (
int myColNo = 0; myColNo < myColumnCount; myColNo++ )
791 myFieldName =
QString::fromUtf8((
char * )sqlite3_column_name( myPreparedStatement, myColNo ) );
792 myFieldValue =
QString::fromUtf8((
char * )sqlite3_column_text( myPreparedStatement, myColNo ) );
793 myMap[myFieldName] = myFieldValue;
796 if ( sqlite3_step( myPreparedStatement ) != SQLITE_DONE )
807 sqlite3_finalize( myPreparedStatement );
808 sqlite3_close( myDatabase );
813 for ( it = myMap.
begin(); it != myMap.
end(); ++it )
841 if ( mDescription.
isNull() )
853 if ( mProjectionAcronym.
isNull() )
859 return mProjectionAcronym;
865 if ( mEllipsoidAcronym.
isNull() )
871 return mEllipsoidAcronym;
883 char *proj4src = NULL;
884 OSRExportToProj4( mCRS, &proj4src );
906 void QgsCoordinateReferenceSystem::setInternalId(
long theSrsId )
910 void QgsCoordinateReferenceSystem::setAuthId(
QString authId )
914 void QgsCoordinateReferenceSystem::setSrid(
long theSrid )
918 void QgsCoordinateReferenceSystem::setDescription(
QString theDescription )
920 mDescription = theDescription;
922 void QgsCoordinateReferenceSystem::setProj4String(
QString theProj4String )
924 mProj4 = theProj4String;
928 OSRDestroySpatialReference( mCRS );
929 mCRS = OSRNewSpatialReference( NULL );
934 #if defined(QGISDEBUG) && QGISDEBUG>=3
938 void QgsCoordinateReferenceSystem::setGeographicFlag(
bool theGeoFlag )
940 mGeoFlag = theGeoFlag;
942 void QgsCoordinateReferenceSystem::setEpsg(
long theEpsg )
944 mAuthId =
QString(
"EPSG:%1" ).
arg( theEpsg );
946 void QgsCoordinateReferenceSystem::setProjectionAcronym(
QString theProjectionAcronym )
948 mProjectionAcronym = theProjectionAcronym;
950 void QgsCoordinateReferenceSystem::setEllipsoidAcronym(
QString theEllipsoidAcronym )
952 mEllipsoidAcronym = theEllipsoidAcronym;
955 void QgsCoordinateReferenceSystem::setMapUnits()
969 if ( OSRIsProjected( mCRS ) )
971 double toMeter = OSRGetLinearUnits( mCRS, &unitName );
979 static const double feetToMeter = 0.3048;
980 static const double smallNum = 1e-3;
982 if ( qAbs( toMeter - feetToMeter ) < smallNum )
985 QgsDebugMsg(
"Projection has linear units of " + unit );
989 else if ( unit ==
"Foot" )
999 OSRGetAngularUnits( mCRS, &unitName );
1001 if ( unit ==
"degree" )
1005 QgsDebugMsg(
"Unsupported map units of " + unit );
1024 if ( mEllipsoidAcronym.
isNull() || mProjectionAcronym.
isNull()
1027 QgsDebugMsg(
"QgsCoordinateReferenceSystem::findMatchingProj will only "
1028 "work if prj acr ellipsoid acr and proj4string are set"
1029 " and the current projection is valid!" );
1035 sqlite3_stmt *myPreparedStatement;
1040 QString mySql =
QString(
"select srs_id,parameters from tbl_srs where "
1041 "projection_acronym=%1 and ellipsoid_acronym=%2 order by deprecated" )
1042 .
arg( quotedValue( mProjectionAcronym ) )
1043 .
arg( quotedValue( mEllipsoidAcronym ) );
1048 myResult = openDb( myDatabaseFileName, &myDatabase );
1049 if ( myResult != SQLITE_OK )
1054 myResult = sqlite3_prepare( myDatabase, mySql.
toUtf8(), mySql.
toUtf8().
length(), &myPreparedStatement, &myTail );
1056 if ( myResult == SQLITE_OK )
1059 while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
1065 QgsDebugMsg(
"-------> MATCH FOUND in srs.db srsid: " + mySrsId );
1067 sqlite3_finalize( myPreparedStatement );
1068 sqlite3_close( myDatabase );
1077 QgsDebugMsg(
"no match found in srs.db, trying user db now!" );
1079 sqlite3_finalize( myPreparedStatement );
1080 sqlite3_close( myDatabase );
1087 myResult = openDb( myDatabaseFileName, &myDatabase );
1088 if ( myResult != SQLITE_OK )
1093 myResult = sqlite3_prepare( myDatabase, mySql.
toUtf8(), mySql.
toUtf8().
length(), &myPreparedStatement, &myTail );
1095 if ( myResult == SQLITE_OK )
1098 while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
1104 QgsDebugMsg(
"-------> MATCH FOUND in user qgis.db srsid: " + mySrsId );
1106 sqlite3_finalize( myPreparedStatement );
1107 sqlite3_close( myDatabase );
1119 sqlite3_finalize( myPreparedStatement );
1120 sqlite3_close( myDatabase );
1126 return ( !mIsValidFlag && !theSrs.mIsValidFlag ) ||
1127 ( mIsValidFlag && theSrs.mIsValidFlag && theSrs.
authid() ==
authid() );
1132 return !( *
this == theSrs );
1140 if ( OSRExportToWkt( mCRS, &wkt ) == OGRERR_NONE )
1151 QgsDebugMsg(
"Reading Spatial Ref Sys from xml ------------------------!" );
1154 if ( ! srsNode.
isNull() )
1156 bool initialized =
false;
1189 QgsDebugMsg(
"Ignoring authid/epsg for user crs." );
1207 QgsDebugMsg(
"Setting from elements one by one" );
1213 setInternalId( myNode.toElement().text().toLong() );
1216 setSrid( myNode.toElement().text().toLong() );
1219 setAuthId( myNode.toElement().text() );
1221 myNode = srsNode.
namedItem(
"description" );
1222 setDescription( myNode.toElement().text() );
1224 myNode = srsNode.
namedItem(
"projectionacronym" );
1225 setProjectionAcronym( myNode.toElement().text() );
1227 myNode = srsNode.
namedItem(
"ellipsoidacronym" );
1228 setEllipsoidAcronym( myNode.toElement().text() );
1230 myNode = srsNode.
namedItem(
"geographicflag" );
1231 if ( myNode.toElement().text().compare(
"true" ) )
1233 setGeographicFlag(
true );
1237 setGeographicFlag(
false );
1244 mIsValidFlag =
true;
1253 .
arg(
QObject::tr(
"Generated CRS",
"A CRS automatically generated from layer info get this prefix for description" ) )
1296 mySrsElement.
appendChild( myProjectionAcronymElement );
1300 mySrsElement.
appendChild( myEllipsoidAcronymElement );
1303 QString myGeoFlagText =
"false";
1306 myGeoFlagText =
"true";
1310 mySrsElement.
appendChild( myGeographicFlagElement );
1326 QString QgsCoordinateReferenceSystem::proj4FromSrsId(
const int theSrsId )
1331 QString mySql =
QString(
"select parameters from tbl_srs where srs_id = %1 order by deprecated" ).
arg( theSrsId );
1345 myFileInfo.
setFile( myDatabaseFileName );
1346 if ( !myFileInfo.
exists() )
1360 rc = openDb( myDatabaseFileName, &db );
1367 sqlite3_stmt *ppStmt;
1369 rc = sqlite3_prepare( db, mySql.
toUtf8(), mySql.
toUtf8().
length(), &ppStmt, &pzTail );
1372 if ( rc == SQLITE_OK )
1374 if ( sqlite3_step( ppStmt ) == SQLITE_ROW )
1380 sqlite3_finalize( ppStmt );
1382 sqlite3_close( db );
1385 return myProjString;
1388 int QgsCoordinateReferenceSystem::openDb(
QString path,
sqlite3 **db,
bool readonly )
1391 int myResult = readonly
1392 ? sqlite3_open_v2( path.
toUtf8().
data(), db, SQLITE_OPEN_READONLY, NULL )
1395 if ( myResult != SQLITE_OK )
1404 .arg( sqlite3_errmsg( *db ) ),
QObject::tr(
"CRS" ) );
1411 mCustomSrsValidation = f;
1416 return mCustomSrsValidation;
1419 void QgsCoordinateReferenceSystem::debugPrint()
1443 mValidationHint = html;
1448 return mValidationHint;
1456 if ( ! mIsValidFlag )
1474 if ( getRecordCount() == 0 )
1476 mySql =
"insert into tbl_srs (srs_id,description,projection_acronym,ellipsoid_acronym,parameters,is_geo) values ("
1478 +
"," + quotedValue( name )
1481 +
"," + quotedValue(
toProj4() )
1486 mySql =
"insert into tbl_srs (description,projection_acronym,ellipsoid_acronym,parameters,is_geo) values ("
1487 + quotedValue( name )
1490 +
"," + quotedValue(
toProj4() )
1495 sqlite3_stmt *myPreparedStatement;
1499 if ( myResult != SQLITE_OK )
1503 .arg( sqlite3_errmsg( myDatabase ) ) );
1507 myResult = sqlite3_prepare( myDatabase, mySql.
toUtf8(), mySql.
toUtf8().
length(), &myPreparedStatement, &myTail );
1510 if ( myResult == SQLITE_OK && sqlite3_step( myPreparedStatement ) == SQLITE_DONE )
1514 return_id = sqlite3_last_insert_rowid( myDatabase );
1515 setInternalId( return_id );
1526 settings.
setValue(
"/UI/recentProjectionsProj4", projectionsProj4 );
1527 settings.
setValue(
"/UI/recentProjectionsAuthId", projectionsAuthId );
1535 long QgsCoordinateReferenceSystem::getRecordCount()
1539 sqlite3_stmt *myPreparedStatement;
1541 long myRecordCount = 0;
1544 if ( myResult != SQLITE_OK )
1546 QgsDebugMsg(
QString(
"Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
1550 QString mySql =
"select count(*) from tbl_srs";
1551 myResult = sqlite3_prepare( myDatabase, mySql.
toUtf8(), mySql.
toUtf8().
length(), &myPreparedStatement, &myTail );
1553 if ( myResult == SQLITE_OK )
1555 if ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
1558 myRecordCount = myRecordCountString.
toLong();
1562 sqlite3_finalize( myPreparedStatement );
1563 sqlite3_close( myDatabase );
1564 return myRecordCount;
1567 QString QgsCoordinateReferenceSystem::quotedValue(
QString value )
1574 bool QgsCoordinateReferenceSystem::loadWkts(
QHash<int, QString> &wkts,
const char *filename )
1576 qDebug(
"Loading %s", filename );
1577 const char *pszFilename = CPLFindFile(
"gdal", filename );
1581 QFile csv( pszFilename );
1582 if ( !csv.open( QIODevice::ReadOnly ) )
1589 QString line = lines.readLine();
1599 if ( !loadWkts( wkts, line.
mid( 8 ).
toUtf8() ) )
1604 int pos = line.
indexOf(
"," );
1609 int epsg = line.
left( pos ).
toInt( &ok );
1613 wkts.
insert( epsg, line.
mid( pos + 1 ) );
1626 foreach (
QString csv,
QStringList() <<
"gcs.csv" <<
"pcs.csv" <<
"vertcs.csv" <<
"compdcs.csv" <<
"geoccs.csv" )
1630 QFile f( filename );
1631 if ( !f.open( QIODevice::ReadOnly ) )
1641 QString line = lines.readLine();
1645 int pos = line.
indexOf(
"," );
1650 int epsg = line.
left( pos ).
toInt( &ok );
1655 if ( epsg == 2218 || epsg == 2221 || epsg == 2296 || epsg == 2297 || epsg == 2298 || epsg == 2299 || epsg == 2300 || epsg == 2301 || epsg == 2302 ||
1656 epsg == 2303 || epsg == 2304 || epsg == 2305 || epsg == 2306 || epsg == 2307 || epsg == 2963 || epsg == 2985 || epsg == 2986 || epsg == 3052 ||
1657 epsg == 3053 || epsg == 3139 || epsg == 3144 || epsg == 3145 || epsg == 3173 || epsg == 3295 || epsg == 3993 || epsg == 4087 || epsg == 4088 ||
1658 epsg == 5017 || epsg == 5221 || epsg == 5224 || epsg == 5225 || epsg == 5514 || epsg == 5515 || epsg == 5516 || epsg == 5819 || epsg == 5820 ||
1659 epsg == 5821 || epsg == 32600 || epsg == 32663 || epsg == 32700 )
1662 if ( OSRImportFromEPSG( crs, epsg ) != OGRERR_NONE )
1664 qDebug(
"EPSG %d: not imported", epsg );
1669 if ( OSRExportToWkt( crs, &wkt ) != OGRERR_NONE )
1671 qWarning(
"EPSG %d: not exported to WKT", epsg );
1675 wkts.
insert( epsg, wkt );
1683 qDebug(
"Loaded %d/%d from %s", n, l, filename.
toUtf8().
constData() );
1686 OSRDestroySpatialReference( crs );
1694 syncDatumTransform( dbFilePath );
1696 int inserted = 0, updated = 0, deleted = 0, errors = 0;
1701 if ( sqlite3_open( dbFilePath.
toUtf8().
constData(), &database ) != SQLITE_OK )
1707 if ( sqlite3_exec( database,
"BEGIN TRANSACTION", 0, 0, 0 ) != SQLITE_OK )
1709 qCritical(
"Could not begin transaction: %s [%s]\n",
QgsApplication::srsDbFilePath().toLocal8Bit().constData(), sqlite3_errmsg( database ) );
1714 if ( sqlite3_exec( database,
"alter table tbl_srs add noupdate boolean", 0, 0, 0 ) == SQLITE_OK )
1715 ( 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 );
1717 ( void )sqlite3_exec( database,
"UPDATE tbl_srs SET srid=141001 WHERE srid=41001 AND auth_name='OSGEO' AND auth_id='41001'", 0, 0, 0 );
1721 sqlite3_stmt *select;
1722 char *errMsg = NULL;
1728 loadWkts( wkts,
"epsg.wkt" );
1730 qDebug(
"%d WKTs loaded", wkts.
count() );
1735 char *psz = ba.
data();
1736 OGRErr ogrErr = OSRImportFromWkt( crs, &psz );
1737 if ( ogrErr != OGRERR_NONE )
1740 if ( OSRExportToProj4( crs, &psz ) != OGRERR_NONE )
1751 sql =
QString(
"SELECT parameters,noupdate FROM tbl_srs WHERE auth_name='EPSG' AND auth_id='%1'" ).
arg( it.key() );
1752 if ( sqlite3_prepare( database, sql.
toAscii(), sql.
size(), &select, &tail ) != SQLITE_OK )
1754 qCritical(
"Could not prepare: %s [%s]\n", sql.
toAscii().
constData(), sqlite3_errmsg( database ) );
1759 if ( sqlite3_step( select ) == SQLITE_ROW )
1761 srsProj4 = (
const char * ) sqlite3_column_text( select, 0 );
1763 if (
QString::fromUtf8((
char * )sqlite3_column_text( select, 1 ) ).toInt() != 0 )
1767 sqlite3_finalize( select );
1771 if ( proj4 != srsProj4 )
1774 sql =
QString(
"UPDATE tbl_srs SET parameters=%1 WHERE auth_name='EPSG' AND auth_id=%2" ).
arg( quotedValue( proj4 ) ).
arg( it.key() );
1776 if ( sqlite3_exec( database, sql.
toUtf8(), 0, 0, &errMsg ) != SQLITE_OK )
1778 qCritical(
"Could not execute: %s [%s/%s]\n",
1780 sqlite3_errmsg( database ),
1781 errMsg ? errMsg :
"(unknown error)" );
1793 QRegExp projRegExp(
"\\+proj=(\\S+)" );
1794 if ( projRegExp.
indexIn( proj4 ) < 0 )
1796 QgsDebugMsg(
QString(
"EPSG %1: no +proj argument found [%2]" ).arg( it.key() ).arg( proj4 ) );
1800 QRegExp ellipseRegExp(
"\\+ellps=(\\S+)" );
1802 if ( ellipseRegExp.
indexIn( proj4 ) >= 0 )
1804 ellps = ellipseRegExp.
cap( 1 );
1807 QString name( OSRIsGeographic( crs ) ? OSRGetAttrValue( crs,
"GEOCS", 0 ) : OSRGetAttrValue( crs,
"PROJCS", 0 ) );
1811 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)" )
1812 .
arg( quotedValue( name ) )
1813 .
arg( quotedValue( projRegExp.
cap( 1 ) ) )
1814 .
arg( quotedValue( ellps ) )
1815 .
arg( quotedValue( proj4 ) )
1817 .arg( OSRIsGeographic( crs ) );
1820 if ( sqlite3_exec( database, sql.
toUtf8(), 0, 0, &errMsg ) == SQLITE_OK )
1826 qCritical(
"Could not execute: %s [%s/%s]\n",
1828 sqlite3_errmsg( database ),
1829 errMsg ? errMsg :
"(unknown error)" );
1833 sqlite3_free( errMsg );
1838 sql =
"DELETE FROM tbl_srs WHERE auth_name='EPSG' AND NOT auth_id IN (";
1840 foreach (
int i, wkts.
keys() )
1845 sql +=
") AND NOT noupdate";
1847 if ( sqlite3_exec( database, sql.
toUtf8(), 0, 0, 0 ) == SQLITE_OK )
1849 deleted = sqlite3_changes( database );
1854 qCritical(
"Could not execute: %s [%s]\n",
1856 sqlite3_errmsg( database ) );
1859 #if !defined(PJ_VERSION) || PJ_VERSION!=470
1860 sql =
QString(
"select auth_name,auth_id,parameters from tbl_srs WHERE auth_name<>'EPSG' AND NOT deprecated AND NOT noupdate" );
1861 if ( sqlite3_prepare( database, sql.
toAscii(), sql.
size(), &select, &tail ) == SQLITE_OK )
1863 while ( sqlite3_step( select ) == SQLITE_ROW )
1865 const char *auth_name = (
const char * ) sqlite3_column_text( select, 0 );
1866 const char *auth_id = (
const char * ) sqlite3_column_text( select, 1 );
1867 const char *params = (
const char * ) sqlite3_column_text( select, 2 );
1874 pj = pj_init_plus( input.
toAscii() );
1879 char *def = pj_get_def( pj, 0 );
1888 proj4 = proj4.
mid( input.
size() );
1892 if ( proj4 != params )
1894 sql =
QString(
"UPDATE tbl_srs SET parameters=%1 WHERE auth_name=%2 AND auth_id=%3" )
1895 .
arg( quotedValue( proj4 ) )
1896 .
arg( quotedValue( auth_name ) )
1897 .
arg( quotedValue( auth_id ) );
1899 if ( sqlite3_exec( database, sql.
toUtf8(), 0, 0, &errMsg ) == SQLITE_OK )
1906 qCritical(
"Could not execute: %s [%s/%s]\n",
1908 sqlite3_errmsg( database ),
1909 errMsg ? errMsg :
"(unknown error)" );
1916 QgsDebugMsg(
QString(
"could not retrieve proj string for %1 from PROJ" ).arg( input ) );
1930 qCritical(
"Could not execute: %s [%s]\n",
1932 sqlite3_errmsg( database ) );
1936 OSRDestroySpatialReference( crs );
1938 if ( sqlite3_exec( database,
"COMMIT", 0, 0, 0 ) != SQLITE_OK )
1940 qCritical(
"Could not commit transaction: %s [%s]\n",
QgsApplication::srsDbFilePath().toLocal8Bit().constData(), sqlite3_errmsg( database ) );
1944 sqlite3_close( database );
1946 qWarning(
"CRS update (inserted:%d updated:%d deleted:%d errors:%d)", inserted, updated, deleted, errors );
1951 return updated + inserted;
1954 bool QgsCoordinateReferenceSystem::syncDatumTransform(
const QString& dbPath )
1956 const char *filename = CSVFilename(
"datum_shift.csv" );
1957 FILE *fp = VSIFOpen( filename,
"rb" );
1963 char **fieldnames = CSVReadParseLine( fp );
1975 {
"SOURCE_CRS_CODE",
"source_crs_code", -1 },
1976 {
"TARGET_CRS_CODE",
"target_crs_code", -1 },
1977 {
"REMARKS",
"remarks", -1 },
1978 {
"COORD_OP_SCOPE",
"scope", -1 },
1979 {
"AREA_OF_USE_CODE",
"area_of_use_code", -1 },
1985 {
"DEPRECATED",
"deprecated", -1 },
1986 {
"COORD_OP_METHOD_CODE",
"coord_op_method_code", -1 },
1994 {
"PREFERRED",
"preferred", -1 },
1995 {
"COORD_OP_CODE",
"coord_op_code", -1 },
1998 QString update =
"UPDATE tbl_datum_transform SET ";
2001 int n = CSLCount( fieldnames );
2003 int idxid = -1, idxrx = -1, idxry = -1, idxrz = -1, idxmcode = -1;
2004 for (
unsigned int i = 0; i <
sizeof(
map ) /
sizeof( *map ); i++ )
2006 bool last = i ==
sizeof(
map ) /
sizeof( *map ) - 1;
2008 map[i].idx = CSLFindString( fieldnames, map[i].src );
2009 if ( map[i].idx < 0 )
2011 qWarning(
"field %s not found", map[i].src );
2012 CSLDestroy( fieldnames );
2017 if ( strcmp( map[i].src,
"COORD_OP_CODE" ) == 0 )
2019 if ( strcmp( map[i].src,
"RX" ) == 0 )
2021 if ( strcmp( map[i].src,
"RY" ) == 0 )
2023 if ( strcmp( map[i].src,
"RZ" ) == 0 )
2025 if ( strcmp( map[i].src,
"COORD_OP_METHOD_CODE" ) == 0 )
2035 update +=
" WHERE ";
2043 update +=
QString(
"%1=%%2" ).
arg( map[i].dst ).
arg( i + 1 );
2045 insert +=
map[i].dst;
2049 insert =
"INSERT INTO tbl_datum_transform(" + insert +
") VALUES (" + values +
")";
2054 CSLDestroy( fieldnames );
2056 Q_ASSERT( idxid >= 0 );
2057 Q_ASSERT( idxrx >= 0 );
2058 Q_ASSERT( idxry >= 0 );
2059 Q_ASSERT( idxrz >= 0 );
2063 if ( openResult != SQLITE_OK )
2069 if ( sqlite3_exec( db,
"BEGIN TRANSACTION", 0, 0, 0 ) != SQLITE_OK )
2072 sqlite3_close( db );
2078 v.
reserve(
sizeof( map ) /
sizeof( *map ) );
2080 while ( !feof( fp ) )
2082 char **values = CSVReadParseLine( fp );
2086 if ( CSLCount( values ) < n )
2088 qWarning(
"Only %d columns", CSLCount( values ) );
2092 for (
unsigned int i = 0; i <
sizeof(
map ) /
sizeof( *map ); i++ )
2094 int idx =
map[i].idx;
2095 Q_ASSERT( idx != -1 );
2096 Q_ASSERT( idx < n );
2097 v.
insert( i, *values[ idx ] ? quotedValue( values[idx] ) :
"NULL" );
2101 if ( v.
at( idxmcode ).compare(
QString(
"'9607'" ) ) == 0 )
2103 v[ idxmcode ] =
"'9606'";
2104 v[ idxrx ] =
"'" +
qgsDoubleToString( -( v[ idxrx ].
remove(
"'" ).toDouble() ) ) +
"'";
2105 v[ idxry ] =
"'" +
qgsDoubleToString( -( v[ idxry ].
remove(
"'" ).toDouble() ) ) +
"'";
2106 v[ idxrz ] =
"'" +
qgsDoubleToString( -( v[ idxrz ].
remove(
"'" ).toDouble() ) ) +
"'";
2112 QString sql =
QString(
"SELECT coord_op_code FROM tbl_datum_transform WHERE coord_op_code=%1" ).
arg( v[ idxid ] );
2113 int prepareRes = sqlite3_prepare( db, sql.
toAscii(), sql.
size(), &stmt, NULL );
2114 if ( prepareRes != SQLITE_OK )
2117 if ( sqlite3_step( stmt ) == SQLITE_ROW )
2119 cOpCode = (
const char * ) sqlite3_column_text( stmt, 0 );
2121 sqlite3_finalize( stmt );
2123 sql = cOpCode.
isEmpty() ? insert : update;
2124 for (
int i = 0; i < v.
size(); i++ )
2126 sql = sql.
arg( v[i] );
2129 if ( sqlite3_exec( db, sql.
toUtf8(), 0, 0, 0 ) != SQLITE_OK )
2132 qCritical(
"Error: %s", sqlite3_errmsg( db ) );
2136 if ( sqlite3_exec( db,
"COMMIT", 0, 0, 0 ) != SQLITE_OK )
2142 sqlite3_close( db );
2154 return OSRGetAuthorityName( mCRS,
"GEOGCS" ) +
QString(
":" ) + OSRGetAuthorityCode( mCRS,
"GEOGCS" );
2174 if ( projectionsAuthId.
size() >= projections.
size() )
2178 projections.
clear();
2179 for (
int i = 0; i < projectionsAuthId.
size(); i++ )
2193 if ( crs.
srsid() == 0 )
QgsCoordinateReferenceSystem()
Default constructor.
bool createFromSrid(const long theSrid)
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString cap(int nth) const
QString & append(QChar ch)
const QgsCoordinateReferenceSystem & crsByAuthId(const QString &authid)
Returns the CRS for authid, e.g.
iterator insert(const Key &key, const T &value)
void setValidationHint(QString html)
bool createFromWkt(const QString &theWkt)
QDomNode appendChild(const QDomNode &newChild)
QString geographicCRSAuthId() const
Returns auth id of related geographic CRS.
bool saveAsUserCRS(QString name)
Copied from QgsCustomProjectionDialog /// Please refactor into SQL handler !!! ///.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QString & prepend(QChar ch)
static void warning(const QString &msg)
Goes to qWarning.
void setFile(const QString &file)
const T & at(int i) const
bool createFromId(const long theId, CrsType theType=PostgisCrsId)
The QGis class provides global constants for use throughout the application.
bool axisInverted() const
static CUSTOM_CRS_VALIDATION customSrsValidation()
Gets custom function.
int count(const Key &key) const
QString tr(const char *sourceText, const char *disambiguation, int n)
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
bool createFromString(const QString &theDefinition)
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
static void setCustomSrsValidation(CUSTOM_CRS_VALIDATION f)
Sets custom function to force valid CRS QGIS uses implementation in QgisGui::customSrsValidation.
void setPattern(const QString &pattern)
QDomElement toElement() const
int matchedLength() const
void setValue(const QString &key, const QVariant &value)
int indexIn(const QString &str, int offset, CaretMode caretMode) const
bool createFromOgcWmsCrs(QString theCrs)
Set up this CRS from the given OGC CRS.
QString number(int n, int base)
bool createFromSrsId(const long theSrsId)
void append(const T &value)
QString fromUtf8(const char *str, int size)
const_iterator constEnd() const
#define QgsDebugMsgLevel(str, level)
static QStringList recentProjections()
Returns a list of recently used projections.
bool createFromUserInput(const QString &theDefinition)
int toInt(bool *ok, int base) const
const char * constData() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
const long GEOCRS_ID
Magic number for a geographic coord sys in QGIS srs.db tbl_srs.srs_id.
QgsCoordinateReferenceSystem & operator=(const QgsCoordinateReferenceSystem &srs)
Assignment operator.
const QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
QFuture< void > map(Sequence &sequence, MapFunction function)
QString ellipsoidAcronym() const
QList< Key > keys() const
~QgsCoordinateReferenceSystem()
QDomText createTextNode(const QString &value)
QByteArray toLocal8Bit() const
QDomNode namedItem(const QString &name) const
QString qgsDoubleToString(const double &a, const int &precision=17)
long toLong(bool *ok, int base) const
QString & replace(int position, int n, QChar after)
QVariant value(const QString &key, const QVariant &defaultValue) const
const_iterator constBegin() const
const int USER_CRS_START_ID
Magick number that determines whether a projection crsid is a system (srs.db) or user (~/...
bool writeXML(QDomNode &theNode, QDomDocument &theDoc) const
QByteArray toLatin1() const
QString mid(int position, int n) const
QStringList toStringList() const
QString projectionAcronym() const
void insert(int i, const T &value)
Class for storing a coordinate reference system (CRS)
static const QString srsDbFilePath()
Returns the path to the srs.db file.
const int LAT_PREFIX_LEN
The length of the string "+lat_1=".
UnitType
Map units that qgis supports.
QString left(int n) const
bool readXML(QDomNode &theNode)
QString description() const
bool operator!=(const QgsCoordinateReferenceSystem &theSrs) const
QDomElement createElement(const QString &tagName)
void(* CUSTOM_CRS_VALIDATION)(QgsCoordinateReferenceSystem &)
bool operator==(const QgsCoordinateReferenceSystem &theSrs) const
bool geographicFlag() const
int compare(const QString &other) const
static const QString qgisUserDbFilePath()
Returns the path to the user qgis.db file.
bool exactMatch(const QString &str) const
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
static QgsCRSCache * instance()
static void setupESRIWktFix()
QByteArray toAscii() const
bool createFromProj4(const QString &theProjString)
void * OGRSpatialReferenceH
QString toProj4() const
Get the Proj Proj4 string representation of this srs.
QByteArray toUtf8() const
QGis::UnitType mapUnits() const