Skip to content

Commit 6ff744a

Browse files
committedDec 15, 2017
Use proj strings to serialize datum transforms IDs
Since datum transforms IDs are local only, and can even change when underlying library versions are updated, we can't use them to safely store and retrieve datum transforms. Instead we use the proj strings and recover the local session transform ID from that.
1 parent 3187352 commit 6ff744a

File tree

2 files changed

+80
-44
lines changed

2 files changed

+80
-44
lines changed
 

‎src/core/qgscoordinatetransformcontext.cpp

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,18 @@ void QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q
188188
const QDomElement transformElem = srcDestNodes.at( i ).toElement();
189189
QString key1 = transformElem.attribute( QStringLiteral( "source" ) );
190190
QString key2 = transformElem.attribute( QStringLiteral( "dest" ) );
191-
bool ok = false;
192-
int value1 = transformElem.attribute( QStringLiteral( "sourceTransform" ) ).toInt( &ok );
193-
bool ok2 = false;
194-
int value2 = transformElem.attribute( QStringLiteral( "destTransform" ) ).toInt( &ok2 );
195-
if ( ok && ok2 )
196-
{
197-
d->mSourceDestDatumTransforms.insert( qMakePair( key1, key2 ), QgsCoordinateTransform::TransformPair( value1, value2 ) );
198-
}
191+
192+
QString value1 = transformElem.attribute( QStringLiteral( "sourceTransform" ) );
193+
QString value2 = transformElem.attribute( QStringLiteral( "destTransform" ) );
194+
195+
int datumId1 = -1;
196+
int datumId2 = -1;
197+
if ( !value1.isEmpty() )
198+
datumId1 = QgsCoordinateTransform::projStringToDatumTransformId( value1 );
199+
if ( !value2.isEmpty() )
200+
datumId2 = QgsCoordinateTransform::projStringToDatumTransformId( value2 );
201+
//TODO - throw warning if value1 or value2 is non-empty, yet no matching transform was found
202+
d->mSourceDestDatumTransforms.insert( qMakePair( key1, key2 ), QgsCoordinateTransform::TransformPair( datumId1, datumId2 ) );
199203
}
200204

201205
#if 0
@@ -205,12 +209,13 @@ void QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q
205209
{
206210
const QDomElement transformElem = srcNodes.at( i ).toElement();
207211
QString key = transformElem.attribute( QStringLiteral( "crs" ) );
208-
bool ok = false;
209-
int value = transformElem.attribute( QStringLiteral( "transform" ) ).toInt( &ok );
210-
if ( ok )
211-
{
212-
d->mSourceDatumTransforms.insert( key, value );
213-
}
212+
QString value = transformElem.attribute( QStringLiteral( "transform" ) );
213+
if ( value.isEmpty() )
214+
continue;
215+
216+
int datumId = QgsCoordinateTransform::projStringToDatumTransformId( value );
217+
//TODO - throw warning if datumId is -1
218+
d->mSourceDatumTransforms.insert( key, datumId );
214219
}
215220

216221
// dest transforms
@@ -219,12 +224,13 @@ void QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q
219224
{
220225
const QDomElement transformElem = destNodes.at( i ).toElement();
221226
QString key = transformElem.attribute( QStringLiteral( "crs" ) );
222-
bool ok = false;
223-
int value = transformElem.attribute( QStringLiteral( "transform" ) ).toInt( &ok );
224-
if ( ok )
225-
{
226-
d->mDestDatumTransforms.insert( key, value );
227-
}
227+
QString value = transformElem.attribute( QStringLiteral( "transform" ) );
228+
if ( value.isEmpty() )
229+
continue;
230+
231+
int datumId = QgsCoordinateTransform::projStringToDatumTransformId( value );
232+
//TODO - throw warning if datumId is -1
233+
d->mDestDatumTransforms.insert( key, datumId );
228234
}
229235
#endif
230236

@@ -243,8 +249,8 @@ void QgsCoordinateTransformContext::writeXml( QDomElement &element, const QgsRea
243249
QDomElement transformElem = element.ownerDocument().createElement( QStringLiteral( "srcDest" ) );
244250
transformElem.setAttribute( QStringLiteral( "source" ), it.key().first );
245251
transformElem.setAttribute( QStringLiteral( "dest" ), it.key().second );
246-
transformElem.setAttribute( QStringLiteral( "sourceTransform" ), it.value().sourceTransformId );
247-
transformElem.setAttribute( QStringLiteral( "destTransform" ), it.value().destinationTransformId );
252+
transformElem.setAttribute( QStringLiteral( "sourceTransform" ), it.value().sourceTransformId < 0 ? QString() : QgsCoordinateTransform::datumTransformToProj( it.value().sourceTransformId ) );
253+
transformElem.setAttribute( QStringLiteral( "destTransform" ), it.value().destinationTransformId < 0 ? QString() : QgsCoordinateTransform::datumTransformToProj( it.value().destinationTransformId ) );
248254
contextElem.appendChild( transformElem );
249255
}
250256

@@ -254,7 +260,7 @@ void QgsCoordinateTransformContext::writeXml( QDomElement &element, const QgsRea
254260
{
255261
QDomElement transformElem = element.ownerDocument().createElement( QStringLiteral( "source" ) );
256262
transformElem.setAttribute( QStringLiteral( "crs" ), it.key() );
257-
transformElem.setAttribute( QStringLiteral( "transform" ), it.value() );
263+
transformElem.setAttribute( QStringLiteral( "transform" ), it.value() < 0 ? QString() : it.value() );
258264
contextElem.appendChild( transformElem );
259265
}
260266

@@ -263,7 +269,7 @@ void QgsCoordinateTransformContext::writeXml( QDomElement &element, const QgsRea
263269
{
264270
QDomElement transformElem = element.ownerDocument().createElement( QStringLiteral( "dest" ) );
265271
transformElem.setAttribute( QStringLiteral( "crs" ), it.key() );
266-
transformElem.setAttribute( QStringLiteral( "transform" ), it.value() );
272+
transformElem.setAttribute( QStringLiteral( "transform" ), it.value() < 0 ? QString() : it.value() );
267273
contextElem.appendChild( transformElem );
268274
}
269275
#endif
@@ -305,13 +311,15 @@ void QgsCoordinateTransformContext::readSettings()
305311
destAuthId = split.at( 1 ).split( '_' ).at( 0 );
306312
}
307313

314+
QString proj = settings.value( *pkeyIt ).toString();
315+
int datumId = QgsCoordinateTransform::projStringToDatumTransformId( proj );
308316
if ( pkeyIt->contains( QLatin1String( "srcTransform" ) ) )
309317
{
310-
transforms[ qMakePair( srcAuthId, destAuthId )].first = settings.value( *pkeyIt ).toInt();
318+
transforms[ qMakePair( srcAuthId, destAuthId )].first = datumId;
311319
}
312320
else if ( pkeyIt->contains( QLatin1String( "destTransform" ) ) )
313321
{
314-
transforms[ qMakePair( srcAuthId, destAuthId )].second = settings.value( *pkeyIt ).toInt();
322+
transforms[ qMakePair( srcAuthId, destAuthId )].second = datumId;
315323
}
316324
}
317325
}
@@ -346,10 +354,16 @@ void QgsCoordinateTransformContext::writeSettings()
346354
QString srcAuthId = transformIt.key().first;
347355
QString destAuthId = transformIt.key().second;
348356
int sourceDatumTransform = transformIt.value().sourceTransformId;
357+
QString sourceDatumProj;
358+
if ( sourceDatumTransform >= 0 )
359+
sourceDatumProj = QgsCoordinateTransform::datumTransformToProj( sourceDatumTransform );
349360
int destinationDatumTransform = transformIt.value().destinationTransformId;
361+
QString destinationDatumProj;
362+
if ( destinationDatumTransform >= 0 )
363+
destinationDatumProj = QgsCoordinateTransform::datumTransformToProj( destinationDatumTransform );
350364

351-
settings.setValue( srcAuthId + "//" + destAuthId + "_srcTransform", sourceDatumTransform );
352-
settings.setValue( srcAuthId + "//" + destAuthId + "_destTransform", destinationDatumTransform );
365+
settings.setValue( srcAuthId + "//" + destAuthId + "_srcTransform", sourceDatumProj );
366+
settings.setValue( srcAuthId + "//" + destAuthId + "_destTransform", destinationDatumProj );
353367
}
354368

355369
settings.endGroup();

‎tests/src/python/test_qgscoordinatetransformcontext.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,24 @@ def testWriteReadXmlSingleVariant(self):
300300
def testWriteReadXml(self):
301301
# setup a context
302302
context = QgsCoordinateTransformContext()
303-
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'),
304-
QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2))
305-
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'),
306-
QgsCoordinateReferenceSystem(4283), 3, 4))
307303

308-
self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(1, 2),
309-
('EPSG:28356', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(3, 4)})
304+
source_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
305+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
306+
dest_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
307+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
308+
309+
source_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
310+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
311+
dest_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
312+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
313+
314+
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4204),
315+
QgsCoordinateReferenceSystem(4326), source_id_1, dest_id_1))
316+
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4205),
317+
QgsCoordinateReferenceSystem(4326), source_id_2, dest_id_2))
318+
319+
self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:4204', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_1, dest_id_1),
320+
('EPSG:4205', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_2, dest_id_2)})
310321

311322
# save to xml
312323
doc = QDomDocument("testdoc")
@@ -318,8 +329,8 @@ def testWriteReadXml(self):
318329
context2.readXml(elem, QgsReadWriteContext())
319330

320331
# check result
321-
self.assertEqual(context2.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(1, 2),
322-
('EPSG:28356', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(3, 4)})
332+
self.assertEqual(context2.sourceDestinationDatumTransforms(), {('EPSG:4204', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_1, dest_id_1),
333+
('EPSG:4205', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_2, dest_id_2)})
323334

324335
def testProject(self):
325336
"""
@@ -337,17 +348,28 @@ def testProject(self):
337348
def testReadWriteSettings(self):
338349
context = QgsCoordinateTransformContext()
339350
context.readSettings()
351+
352+
source_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
353+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
354+
dest_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
355+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
356+
357+
source_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
358+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
359+
dest_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
360+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
361+
340362
# should be empty
341363
self.assertEqual(context.sourceDestinationDatumTransforms(), {})
342364

343-
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'),
344-
QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2))
345-
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'),
346-
QgsCoordinateReferenceSystem(4283), 3, 4))
365+
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4204'),
366+
QgsCoordinateReferenceSystem('EPSG:4326'), source_id_1, dest_id_1))
367+
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4205'),
368+
QgsCoordinateReferenceSystem(4326), source_id_2, dest_id_2))
347369

348370
self.assertEqual(context.sourceDestinationDatumTransforms(),
349-
{('EPSG:3111', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(1, 2),
350-
('EPSG:28356', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(3, 4)})
371+
{('EPSG:4204', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_1, dest_id_1),
372+
('EPSG:4205', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_2, dest_id_2)})
351373

352374
# save to settings
353375
context.writeSettings()
@@ -359,8 +381,8 @@ def testReadWriteSettings(self):
359381

360382
# check result
361383
self.assertEqual(context2.sourceDestinationDatumTransforms(),
362-
{('EPSG:3111', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(1, 2),
363-
('EPSG:28356', 'EPSG:4283'): QgsCoordinateTransform.TransformPair(3, 4)})
384+
{('EPSG:4204', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_1, dest_id_1),
385+
('EPSG:4205', 'EPSG:4326'): QgsCoordinateTransform.TransformPair(source_id_2, dest_id_2)})
364386

365387

366388
if __name__ == '__main__':

0 commit comments

Comments
 (0)
Please sign in to comment.