Skip to content

Commit 18274a2

Browse files
committed
datum transformations:
- copy descriptions, preference and deprecation from GDAL - remember position of dialog - allow hiding of deprecated transformations SQL: ALTER TABLE tbl_datum_transform ADD remarks varchar; ALTER TABLE tbl_datum_transform ADD scope varchar; ALTER TABLE tbl_datum_transform ADD preferred boolean; ALTER TABLE tbl_datum_transform ADD deprecated boolean; ALTER TABLE tbl_datum_transform ADD area_of_use_code varchar;
1 parent a47baba commit 18274a2

7 files changed

+245
-109
lines changed

resources/srs.db

1 KB
Binary file not shown.

src/core/qgscoordinatereferencesystem.cpp

+130-58
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <ogr_srs_api.h>
4343
#include <cpl_error.h>
4444
#include <cpl_conv.h>
45+
#include <cpl_csv.h>
4546

4647
CUSTOM_CRS_VALIDATION QgsCoordinateReferenceSystem::mCustomSrsValidation = NULL;
4748

@@ -195,8 +196,8 @@ void QgsCoordinateReferenceSystem::setupESRIWktFix( )
195196
{
196197
CPLSetConfigOption( "GDAL_FIX_ESRI_WKT", configNew );
197198
if ( strcmp( configNew, CPLGetConfigOption( "GDAL_FIX_ESRI_WKT", "" ) ) != 0 )
198-
QgsLogger::warning( QString( "GDAL_FIX_ESRI_WKT could not be set to %1 : %2"
199-
).arg( configNew ).arg( CPLGetConfigOption( "GDAL_FIX_ESRI_WKT", "" ) ) ) ;
199+
QgsLogger::warning( QString( "GDAL_FIX_ESRI_WKT could not be set to %1 : %2" )
200+
.arg( configNew ).arg( CPLGetConfigOption( "GDAL_FIX_ESRI_WKT", "" ) ) ) ;
200201
QgsDebugMsg( QString( "set GDAL_FIX_ESRI_WKT : %1" ).arg( configNew ) );
201202
}
202203
else
@@ -1945,107 +1946,178 @@ int QgsCoordinateReferenceSystem::syncDb()
19451946

19461947
bool QgsCoordinateReferenceSystem::syncDatumTransform( const QString& dbPath )
19471948
{
1948-
QString filename = CPLFindFile( "gdal", "datum_shift.csv" );
1949-
1950-
QFile f( filename );
1951-
if ( !f.open( QIODevice::ReadOnly ) )
1949+
const char *filename = CSVFilename( "datum_shift.csv" );
1950+
FILE *fp = VSIFOpen( filename, "rb" );
1951+
if ( !fp )
19521952
{
19531953
return false;
19541954
}
19551955

1956-
sqlite3* db;
1956+
char **fieldnames = CSVReadParseLine( fp );
1957+
1958+
// "SEQ_KEY","COORD_OP_CODE","SOURCE_CRS_CODE","TARGET_CRS_CODE","REMARKS","COORD_OP_SCOPE","AREA_OF_USE_CODE","AREA_SOUTH_BOUND_LAT","AREA_NORTH_BOUND_LAT","AREA_WEST_BOUND_LON","AREA_EAST_BOUND_LON","SHOW_OPERATION","DEPRECATED","COORD_OP_METHOD_CODE","DX","DY","DZ","RX","RY","RZ","DS","PREFERRED"
1959+
1960+
struct
1961+
{
1962+
const char *src;
1963+
const char *dst;
1964+
int idx;
1965+
} map[] =
1966+
{
1967+
// { "SEQ_KEY", "", -1 },
1968+
{ "SOURCE_CRS_CODE", "source_crs_code", -1 },
1969+
{ "TARGET_CRS_CODE", "target_crs_code", -1 },
1970+
{ "REMARKS", "remarks", -1 },
1971+
{ "COORD_OP_SCOPE", "scope", -1 },
1972+
{ "AREA_OF_USE_CODE", "area_of_use_code", -1 },
1973+
// { "AREA_SOUTH_BOUND_LAT", "", -1 },
1974+
// { "AREA_NORTH_BOUND_LAT", "", -1 },
1975+
// { "AREA_WEST_BOUND_LON", "", -1 },
1976+
// { "AREA_EAST_BOUND_LON", "", -1 },
1977+
// { "SHOW_OPERATION", "", -1 },
1978+
{ "DEPRECATED", "deprecated", -1 },
1979+
{ "COORD_OP_METHOD_CODE", "coord_op_method_code", -1 },
1980+
{ "DX", "p1", -1 },
1981+
{ "DY", "p2", -1 },
1982+
{ "DZ", "p3", -1 },
1983+
{ "RX", "p4", -1 },
1984+
{ "RY", "p5", -1 },
1985+
{ "RZ", "p6", -1 },
1986+
{ "DS", "p7", -1 },
1987+
{ "PREFERRED", "preferred", -1 },
1988+
{ "COORD_OP_CODE", "coord_op_code", -1 },
1989+
};
1990+
1991+
QString update = "UPDATE tbl_datum_transform SET ";
1992+
QString insert, values;
1993+
1994+
int n = CSLCount( fieldnames );
1995+
1996+
int idxid, idxrx, idxry, idxrz;
1997+
for ( unsigned int i = 0; i < sizeof( map ) / sizeof( *map ); i++ )
1998+
{
1999+
bool last = i == sizeof( map ) / sizeof( *map ) - 1;
2000+
2001+
map[i].idx = CSLFindString( fieldnames, map[i].src );
2002+
if ( map[i].idx < 0 )
2003+
{
2004+
qWarning( "field %s not found", map[i].src );
2005+
CSLDestroy( fieldnames );
2006+
fclose( fp );
2007+
return false;
2008+
}
2009+
2010+
if ( strcmp( map[i].src, "COORD_OP_CODE" ) == 0 )
2011+
idxid = i;
2012+
if ( strcmp( map[i].src, "RX" ) == 0 )
2013+
idxrx = i;
2014+
if ( strcmp( map[i].src, "RY" ) == 0 )
2015+
idxry = i;
2016+
if ( strcmp( map[i].src, "RZ" ) == 0 )
2017+
idxrz = i;
2018+
2019+
if ( i > 0 )
2020+
{
2021+
insert += ",";
2022+
values += ",";
2023+
2024+
if ( last )
2025+
{
2026+
update += " WHERE ";
2027+
}
2028+
else
2029+
{
2030+
update += ",";
2031+
}
2032+
}
2033+
2034+
update += QString( "%1=%%2" ).arg( map[i].dst ).arg( i + 1 );
2035+
2036+
insert += map[i].dst;
2037+
values += QString( "%%1" ).arg( i + 1 );
2038+
2039+
qWarning( "%d: src=%s dst=%s idx=%d", i, map[i].src, map[i].dst, map[i].idx );
2040+
}
2041+
2042+
insert = "INSERT INTO tbl_datum_transform(" + insert + ") VALUES (" + values + ")";
2043+
2044+
QgsDebugMsg( QString( "insert:%1" ).arg( insert ) );
2045+
QgsDebugMsg( QString( "update:%1" ).arg( update ) );
2046+
2047+
CSLDestroy( fieldnames );
2048+
2049+
sqlite3 *db;
19572050
int openResult = sqlite3_open( dbPath.toUtf8().constData(), &db );
19582051
if ( openResult != SQLITE_OK )
19592052
{
2053+
fclose( fp );
19602054
return false;
19612055
}
19622056

19632057
if ( sqlite3_exec( db, "BEGIN TRANSACTION", 0, 0, 0 ) != SQLITE_OK )
19642058
{
19652059
qCritical( "Could not begin transaction: %s [%s]\n", QgsApplication::srsDbFilePath().toLocal8Bit().constData(), sqlite3_errmsg( db ) );
2060+
sqlite3_close( db );
2061+
fclose( fp );
19662062
return false;
19672063
}
19682064

2065+
QStringList v;
2066+
v.reserve( sizeof( map ) / sizeof( *map ) );
19692067

1970-
QTextStream textStream( &f );
1971-
textStream.readLine();
2068+
while ( !feof( fp ) )
2069+
{
2070+
char **values = CSVReadParseLine( fp );
19722071

1973-
QString line, coord_op, source_crs, target_crs, coord_op_method,
1974-
p1, p2, p3, p4, p5, p6, p7;
2072+
v.clear();
19752073

1976-
while ( !textStream.atEnd() )
1977-
{
1978-
line = textStream.readLine();
1979-
QStringList csList = line.split( "," );
1980-
int csSize = csList.size();
1981-
if ( csSize < 22 )
2074+
if ( CSLCount( values ) < n )
19822075
{
2076+
qWarning( "Only %d columns", CSLCount( values ) );
19832077
continue;
19842078
}
19852079

1986-
coord_op = csList[1];
1987-
source_crs = csList[2];
1988-
target_crs = csList[3];
1989-
coord_op_method = csList[csSize - 9];
1990-
p1 = csList[csSize - 8];
1991-
p1 = p1.isEmpty() ? "NULL" : p1;
1992-
p2 = csList[csSize - 7];
1993-
p2 = p2.isEmpty() ? "NULL" : p2;
1994-
p3 = csList[csSize - 6];
1995-
p3 = p3.isEmpty() ? "NULL" : p3;
1996-
p4 = csList[csSize - 5];
1997-
p4 = p4.isEmpty() ? "NULL" : p4;
1998-
p5 = csList[csSize - 4];
1999-
p5 = p5.isEmpty() ? "NULL" : p5;
2000-
p6 = csList[csSize - 3];
2001-
p6 = p6.isEmpty() ? "NULL" : p6;
2002-
p7 = csList[csSize - 2];
2003-
p7 = p7.isEmpty() ? "NULL" : p7;
2080+
for ( unsigned int i = 0; i < sizeof( map ) / sizeof( *map ); i++ )
2081+
{
2082+
int idx = map[i].idx;
2083+
Q_ASSERT( idx != -1 );
2084+
Q_ASSERT( idx < n );
2085+
v.insert( i, *values[ idx ] ? quotedValue( values[idx] ) : "NULL" );
2086+
}
20042087

20052088
//switch sign of rotation parameters. See http://trac.osgeo.org/proj/wiki/GenParms#towgs84-DatumtransformationtoWGS84
2006-
if ( coord_op_method == "9607" )
2089+
if ( v[ idxid ] == "9607" )
20072090
{
2008-
p4 = qgsDoubleToString( -( p4.toDouble() ) );
2009-
p5 = qgsDoubleToString( -( p5.toDouble() ) );
2010-
p6 = qgsDoubleToString( -( p6.toDouble() ) );
2011-
coord_op_method = "9606";
2091+
v[ idxid ] = "9606";
2092+
v[ idxrx ] = qgsDoubleToString( -v[ idxrx ].toDouble() );
2093+
v[ idxry ] = qgsDoubleToString( -v[ idxry ].toDouble() );
2094+
v[ idxrz ] = qgsDoubleToString( -v[ idxrz ].toDouble() );
20122095
}
20132096

20142097
//entry already in db?
2015-
sqlite3_stmt* stmt;
2098+
sqlite3_stmt *stmt;
20162099
QString cOpCode;
2017-
QString sql = QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( coord_op );
2100+
QString sql = QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( v[ idxid ] );
20182101
int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
20192102
if ( prepareRes != SQLITE_OK )
2020-
{
20212103
continue;
2022-
}
20232104

20242105
if ( sqlite3_step( stmt ) == SQLITE_ROW )
20252106
{
20262107
cOpCode = ( const char * ) sqlite3_column_text( stmt, 0 );
20272108
}
20282109
sqlite3_finalize( stmt );
20292110

2030-
if ( !cOpCode.isEmpty() )
2111+
sql = cOpCode.isEmpty() ? insert : update;
2112+
for ( int i = 0; i < v.size(); i++ )
20312113
{
2032-
//already in database, do update
2033-
QgsDebugMsgLevel( "Trying datum transform update", 4 );
2034-
sql = QString( "UPDATE tbl_datum_transform SET source_crs_code = %2, target_crs_code = %3, coord_op_method_code = %4, p1 = %5, p2 = %6, p3 = %7, p4 = %8, p5 = %9, p6 = %10, p7 = %11 WHERE coord_op_code = %1" )
2035-
.arg( coord_op ).arg( source_crs ).arg( target_crs ).arg( coord_op_method ).arg( p1 ).arg( p2 ).arg( p3 ).arg( p4 ).arg( p5 ).arg( p6 ).arg( p7 );
2036-
}
2037-
else
2038-
{
2039-
//not yet in database, do insert
2040-
QgsDebugMsgLevel( "Trying datum transform insert", 4 );
2041-
sql = QString( "INSERT INTO tbl_datum_transform ( epsg_nr, coord_op_code, source_crs_code, target_crs_code, coord_op_method_code, p1, p2, p3, p4, p5, p6, p7 ) VALUES ( %1, %1, %2, %3, %4, %5, %6, %7, %8, %9, %10, %11 )" )
2042-
.arg( coord_op ).arg( source_crs ).arg( target_crs ).arg( coord_op_method ).arg( p1 ).arg( p2 ).arg( p3 ).arg( p4 ).arg( p5 ).arg( p6 ).arg( p7 );
2043-
2114+
sql = sql.arg( v[i] );
20442115
}
20452116

20462117
if ( sqlite3_exec( db, sql.toUtf8(), 0, 0, 0 ) != SQLITE_OK )
20472118
{
2048-
QgsDebugMsg( QString( "Error [%1]" ).arg( sqlite3_errmsg( db ) ) );
2119+
qCritical( "SQL: %s", sql.toUtf8().constData() );
2120+
qCritical( "Error: %s", sqlite3_errmsg( db ) );
20492121
}
20502122
}
20512123

src/core/qgscoordinatetransform.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -792,16 +792,16 @@ QList< QList< int > > QgsCoordinateTransform::datumTransformations( const QgsCoo
792792
}
793793

794794
QList<int> directTransforms;
795-
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code = %2" ).arg( srcAuthCode ).arg( destAuthCode ),
795+
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code=%1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( destAuthCode ),
796796
directTransforms );
797797
QList<int> reverseDirectTransforms;
798-
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code = %2" ).arg( destAuthCode ).arg( srcAuthCode ),
798+
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( srcAuthCode ),
799799
reverseDirectTransforms );
800800
QList<int> srcToWgs84;
801-
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE ( source_crs_code = %1 AND target_crs_code = %2 ) OR ( source_crs_code = %2 AND target_crs_code = %1 )" ).arg( srcAuthCode ).arg( 4326 ),
801+
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( 4326 ),
802802
srcToWgs84 );
803803
QList<int> destToWgs84;
804-
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE ( source_crs_code = %1 AND target_crs_code = %2 ) OR ( source_crs_code = %2 AND target_crs_code = %1 )" ).arg( destAuthCode ).arg( 4326 ),
804+
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( 4326 ),
805805
destToWgs84 );
806806

807807
//add direct datum transformations
@@ -891,7 +891,7 @@ QString QgsCoordinateTransform::datumTransformString( int datumTransform )
891891
}
892892

893893
sqlite3_stmt* stmt;
894-
QString sql = QString( "SELECT coord_op_method_code, p1, p2, p3, p4, p5, p6, p7 FROM tbl_datum_transform WHERE coord_op_code = %1" ).arg( datumTransform );
894+
QString sql = QString( "SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7 FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
895895
int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
896896
if ( prepareRes != SQLITE_OK )
897897
{
@@ -932,7 +932,7 @@ QString QgsCoordinateTransform::datumTransformString( int datumTransform )
932932
return transformString;
933933
}
934934

935-
bool QgsCoordinateTransform::datumTransformCrsInfo( int datumTransform, int& epsgNr, QString& srcProjection, QString& dstProjection )
935+
bool QgsCoordinateTransform::datumTransformCrsInfo( int datumTransform, int& epsgNr, QString& srcProjection, QString& dstProjection, QString &remarks, QString &scope, bool &preferred, bool &deprecated )
936936
{
937937
sqlite3* db;
938938
int openResult = sqlite3_open( QgsApplication::srsDbFilePath().toUtf8().constData(), &db );
@@ -943,7 +943,7 @@ bool QgsCoordinateTransform::datumTransformCrsInfo( int datumTransform, int& eps
943943
}
944944

945945
sqlite3_stmt* stmt;
946-
QString sql = QString( "SELECT epsg_nr, source_crs_code, target_crs_code FROM tbl_datum_transform WHERE coord_op_code = %1" ).arg( datumTransform );
946+
QString sql = QString( "SELECT epsg_nr,source_crs_code,target_crs_code,remarks,scope,preferred,deprecated FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
947947
int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
948948
if ( prepareRes != SQLITE_OK )
949949
{
@@ -962,6 +962,10 @@ bool QgsCoordinateTransform::datumTransformCrsInfo( int datumTransform, int& eps
962962
epsgNr = sqlite3_column_int( stmt, 0 );
963963
srcCrsId = sqlite3_column_int( stmt, 1 );
964964
destCrsId = sqlite3_column_int( stmt, 2 );
965+
remarks = QString::fromUtf8(( const char * ) sqlite3_column_text( stmt, 3 ) );
966+
scope = QString::fromUtf8(( const char * ) sqlite3_column_text( stmt, 4 ) );
967+
preferred = sqlite3_column_int( stmt, 5 ) != 0;
968+
deprecated = sqlite3_column_int( stmt, 6 ) != 0;
965969

966970
QgsCoordinateReferenceSystem srcCrs;
967971
srcCrs.createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( srcCrsId ) );

src/core/qgscoordinatetransform.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ class CORE_EXPORT QgsCoordinateTransform : public QObject
216216
static QString datumTransformString( int datumTransform );
217217
/**Gets name of source and dest geographical CRS (to show in a tooltip)
218218
@return epsgNr epsg code of the transformation (or 0 if not in epsg db)*/
219-
static bool datumTransformCrsInfo( int datumTransform, int& epsgNr, QString& srcProjection, QString& dstProjection );
219+
static bool datumTransformCrsInfo( int datumTransform, int& epsgNr, QString& srcProjection, QString& dstProjection, QString &remarks, QString &scope, bool &preferred, bool &deprecated );
220220

221221
int sourceDatumTransform() const { return mSourceDatumTransform; }
222222
void setSourceDatumTransform( int dt ) { mSourceDatumTransform = dt; }

0 commit comments

Comments
 (0)