|
32 | 32 | #include "qgis.h" //const vals declared here
|
33 | 33 |
|
34 | 34 | #include <sqlite3.h>
|
| 35 | +#include <proj_api.h> |
35 | 36 |
|
36 | 37 | //gdal and ogr includes (needed for == operator)
|
37 | 38 | #include <ogr_srs_api.h>
|
@@ -1353,3 +1354,139 @@ QString QgsCoordinateReferenceSystem::quotedValue( QString value )
|
1353 | 1354 | value.replace( "'", "''" );
|
1354 | 1355 | return value.prepend( "'" ).append( "'" );
|
1355 | 1356 | }
|
| 1357 | + |
| 1358 | +int QgsCoordinateReferenceSystem::syncDb() |
| 1359 | +{ |
| 1360 | + int updated = 0, errors = 0; |
| 1361 | + sqlite3 *database; |
| 1362 | + if ( sqlite3_open( QgsApplication::srsDbFilePath().toUtf8().constData(), &database ) != SQLITE_OK ) |
| 1363 | + { |
| 1364 | + qCritical( "Can't open database: %s [%s]\n", QgsApplication::srsDbFilePath().toLocal8Bit().constData(), sqlite3_errmsg( database ) ); |
| 1365 | + return -1; |
| 1366 | + } |
| 1367 | + |
| 1368 | + const char *tail; |
| 1369 | + sqlite3_stmt *select; |
| 1370 | + QString sql = "select auth_name,auth_id,parameters from tbl_srs WHERE auth_name IS NOT NULL AND auth_id IS NOT NULL"; |
| 1371 | + if ( sqlite3_prepare( database, sql.toAscii(), sql.size(), &select, &tail ) != SQLITE_OK ) |
| 1372 | + { |
| 1373 | + qCritical( "Could not prepare: %s [%s]\n", sql.toAscii().constData(), sqlite3_errmsg( database ) ); |
| 1374 | + sqlite3_close( database ); |
| 1375 | + return -1; |
| 1376 | + } |
| 1377 | + |
| 1378 | + OGRSpatialReferenceH crs = OSRNewSpatialReference( NULL ); |
| 1379 | + |
| 1380 | + while ( sqlite3_step( select ) == SQLITE_ROW ) |
| 1381 | + { |
| 1382 | + const char *auth_name = ( const char * ) sqlite3_column_text( select, 0 ); |
| 1383 | + const char *auth_id = ( const char * ) sqlite3_column_text( select, 1 ); |
| 1384 | + const char *params = ( const char * ) sqlite3_column_text( select, 2 ); |
| 1385 | + |
| 1386 | + QString proj4; |
| 1387 | + |
| 1388 | + if ( QString( auth_name ).compare( "epsg", Qt::CaseInsensitive ) == 0 ) |
| 1389 | + { |
| 1390 | + OGRErr ogrErr = OSRSetFromUserInput( crs, QString( "epsg:%1" ).arg( auth_id ).toAscii() ); |
| 1391 | + |
| 1392 | + if ( ogrErr == OGRERR_NONE ) |
| 1393 | + { |
| 1394 | + char *output = 0; |
| 1395 | + |
| 1396 | + if ( OSRExportToProj4( crs, &output ) == OGRERR_NONE ) |
| 1397 | + { |
| 1398 | + proj4 = output; |
| 1399 | + proj4 = proj4.trimmed(); |
| 1400 | + } |
| 1401 | + else |
| 1402 | + { |
| 1403 | + QgsDebugMsg( QString( "could not retrieve proj.4 string for epsg:%1 from OGR" ).arg( auth_id ) ); |
| 1404 | + } |
| 1405 | + |
| 1406 | + if ( output ) |
| 1407 | + CPLFree( output ); |
| 1408 | + } |
| 1409 | + } |
| 1410 | +#if !defined(PJ_VERSION) || PJ_VERSION!=470 |
| 1411 | + // 4.7.0 has a bug that crashes after 16 consecutive pj_init_plus with different strings |
| 1412 | + else |
| 1413 | + { |
| 1414 | + input = QString( "+init=%1:%2" ).arg( QString( auth_name ).toLower() ).arg( auth_id ); |
| 1415 | + projPJ pj = pj_init_plus( input.toAscii() ); |
| 1416 | + if ( !pj ) |
| 1417 | + { |
| 1418 | + input = QString( "+init=%1:%2" ).arg( QString( auth_name ).toUpper() ).arg( auth_id ); |
| 1419 | + pj = pj_init_plus( input.toAscii() ); |
| 1420 | + } |
| 1421 | + |
| 1422 | + if ( pj ) |
| 1423 | + { |
| 1424 | + char *def = pj_get_def( pj, 0 ); |
| 1425 | + if ( def ) |
| 1426 | + { |
| 1427 | + proj4 = def; |
| 1428 | + pj_dalloc( def ); |
| 1429 | + |
| 1430 | + input.prepend( ' ' ).append( ' ' ); |
| 1431 | + if ( proj4.startsWith( input ) ) |
| 1432 | + { |
| 1433 | + proj4 = proj4.mid( input.size() ); |
| 1434 | + } |
| 1435 | + } |
| 1436 | + else |
| 1437 | + { |
| 1438 | + QgsDebugMsg( QString( "could not retrieve proj string for %1 from PROJ" ).arg( input ) ); |
| 1439 | + } |
| 1440 | + } |
| 1441 | + else |
| 1442 | + { |
| 1443 | + QgsDebugMsgLevel( QString( "could not retrieve crs for %1 from PROJ" ).arg( input ), 3 ); |
| 1444 | + } |
| 1445 | + |
| 1446 | + pj_free( pj ); |
| 1447 | + } |
| 1448 | +#endif |
| 1449 | + |
| 1450 | + if ( proj4.isEmpty() ) |
| 1451 | + { |
| 1452 | + continue; |
| 1453 | + } |
| 1454 | + |
| 1455 | + if ( proj4 != params ) |
| 1456 | + { |
| 1457 | + char *errMsg = NULL; |
| 1458 | + |
| 1459 | + sql = QString( "UPDATE tbl_srs SET parameters=%1 WHERE auth_name=%2 AND auth_id=%3" ) |
| 1460 | + .arg( quotedValue( proj4 ) ) |
| 1461 | + .arg( quotedValue( auth_name ) ) |
| 1462 | + .arg( quotedValue( auth_id ) ); |
| 1463 | + |
| 1464 | + if ( sqlite3_exec( database, sql.toUtf8(), 0, 0, &errMsg ) != SQLITE_OK ) |
| 1465 | + { |
| 1466 | + qCritical( "Could not execute: %s [%s/%s]\n", |
| 1467 | + sql.toLocal8Bit().constData(), |
| 1468 | + sqlite3_errmsg( database ), |
| 1469 | + errMsg ? errMsg : "(unknown error)" ); |
| 1470 | + errors++; |
| 1471 | + } |
| 1472 | + else |
| 1473 | + { |
| 1474 | + updated++; |
| 1475 | + QgsDebugMsgLevel( QString( "SQL: %1\n OLD:%2\n NEW:%3" ).arg( sql ).arg( params ).arg( proj4 ), 3 ); |
| 1476 | + } |
| 1477 | + |
| 1478 | + if ( errMsg ) |
| 1479 | + sqlite3_free( errMsg ); |
| 1480 | + } |
| 1481 | + } |
| 1482 | + |
| 1483 | + OSRDestroySpatialReference( crs ); |
| 1484 | + |
| 1485 | + sqlite3_finalize( select ); |
| 1486 | + sqlite3_close( database ); |
| 1487 | + |
| 1488 | + if ( errors > 0 ) |
| 1489 | + return -errors; |
| 1490 | + else |
| 1491 | + return updated; |
| 1492 | +} |
0 commit comments