206 changes: 203 additions & 3 deletions src/core/qgscoordinatetransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/
#include "qgscoordinatetransform.h"
#include "qgsapplication.h"
#include "qgscrscache.h"
#include "qgsmessagelog.h"
#include "qgslogger.h"
Expand All @@ -24,12 +25,14 @@
#include <QDomElement>
#include <QApplication>
#include <QPolygonF>
#include <QStringList>
#include <QVector>

extern "C"
{
#include <proj_api.h>
}
#include <sqlite3.h>

// if defined shows all information about transform to stdout
// #define COORDINATE_TRANSFORM_VERBOSE
Expand All @@ -39,6 +42,8 @@ QgsCoordinateTransform::QgsCoordinateTransform()
, mInitialisedFlag( false )
, mSourceProjection( 0 )
, mDestinationProjection( 0 )
, mSourceDatumTransform( -1 )
, mDestinationDatumTransform( -1 )
{
setFinder();
}
Expand All @@ -48,6 +53,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSyst
, mInitialisedFlag( false )
, mSourceProjection( 0 )
, mDestinationProjection( 0 )
, mSourceDatumTransform( -1 )
, mDestinationDatumTransform( -1 )
{
setFinder();
mSourceCRS = source;
Expand All @@ -62,6 +69,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrsId, long theDes
, mDestCRS( theDestSrsId, QgsCoordinateReferenceSystem::InternalCrsId )
, mSourceProjection( 0 )
, mDestinationProjection( 0 )
, mSourceDatumTransform( -1 )
, mDestinationDatumTransform( -1 )
{
initialise();
}
Expand All @@ -71,6 +80,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( QString theSourceCRS, QString th
, mInitialisedFlag( false )
, mSourceProjection( 0 )
, mDestinationProjection( 0 )
, mSourceDatumTransform( -1 )
, mDestinationDatumTransform( -1 )
{
setFinder();
mSourceCRS.createFromWkt( theSourceCRS );
Expand All @@ -89,6 +100,8 @@ QgsCoordinateTransform::QgsCoordinateTransform( long theSourceSrid,
, mInitialisedFlag( false )
, mSourceProjection( 0 )
, mDestinationProjection( 0 )
, mSourceDatumTransform( -1 )
, mDestinationDatumTransform( -1 )
{
setFinder();

Expand Down Expand Up @@ -154,11 +167,37 @@ void QgsCoordinateTransform::initialise()
mDestCRS = QgsCRSCache::instance()->crsByAuthId( mSourceCRS.authid() );
}

bool useDefaultDatumTransform = ( mSourceDatumTransform == - 1 && mDestinationDatumTransform == -1 );

// init the projections (destination and source)
pj_free( mDestinationProjection );
mDestinationProjection = pj_init_plus( mDestCRS.toProj4().toUtf8() );

pj_free( mSourceProjection );
mSourceProjection = pj_init_plus( mSourceCRS.toProj4().toUtf8() );
QString sourceProjString = mSourceCRS.toProj4();
if ( !useDefaultDatumTransform )
{
sourceProjString = stripDatumTransform( sourceProjString );
}
if ( mSourceDatumTransform != -1 )
{
sourceProjString += ( " " + datumTransformString( mSourceDatumTransform ) );
}
mSourceProjection = pj_init_plus( sourceProjString.toUtf8() );

pj_free( mDestinationProjection );
QString destProjString = mDestCRS.toProj4();
if ( !useDefaultDatumTransform )
{
destProjString = stripDatumTransform( destProjString );
}
if ( mDestinationDatumTransform != -1 )
{
destProjString += ( " " + datumTransformString( mDestinationDatumTransform ) );
}
else if ( sourceProjString.contains( "+nadgrids" ) ) //add null grid if source transformation is ntv2
{
destProjString += " +nadgrids=@null";
}
mDestinationProjection = pj_init_plus( destProjString.toUtf8() );

#ifdef COORDINATE_TRANSFORM_VERBOSE
QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() );
Expand Down Expand Up @@ -666,6 +705,9 @@ bool QgsCoordinateTransform::readXML( QDomNode & theNode )
QDomNode myDestNode = theNode.namedItem( "destinationsrs" );
mDestCRS.readXML( myDestNode );

mSourceDatumTransform = theNode.toElement().attribute( "sourceDatumTransform", "-1" ).toInt();
mDestinationDatumTransform = theNode.toElement().attribute( "destinationDatumTransform", "-1" ).toInt();

initialise();

return true;
Expand All @@ -675,6 +717,8 @@ bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc
{
QDomElement myNodeElement = theNode.toElement();
QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );
myTransformElement.setAttribute( "sourceDatumTransform", QString::number( mSourceDatumTransform ) );
myTransformElement.setAttribute( "destinationDatumTransform", QString::number( mDestinationDatumTransform ) );

QDomElement mySourceElement = theDoc.createElement( "sourcesrs" );
mSourceCRS.writeXML( mySourceElement, theDoc );
Expand Down Expand Up @@ -716,3 +760,159 @@ void QgsCoordinateTransform::setFinder()
pj_set_finder( finder );
#endif
}

QList< QList< int > > QgsCoordinateTransform::datumTransformations( const QgsCoordinateReferenceSystem& srcCRS, const QgsCoordinateReferenceSystem& destCRS )
{
QList< QList< int > > transformations;

QString srcGeoId = srcCRS.geographicCRSAuthId();
QString destGeoId = destCRS.geographicCRSAuthId();

if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
{
return transformations;
}

QStringList srcSplit = srcGeoId.split( ":" );
QStringList destSplit = destGeoId.split( ":" );

if ( srcSplit.size() < 2 || destSplit.size() < 2 )
{
return transformations;
}

int srcAuthCode = srcSplit.at( 1 ).toInt();
int destAuthCode = destSplit.at( 1 ).toInt();

if ( srcAuthCode == destAuthCode )
{
return transformations; //crs have the same datum
}

QList<int> directTransforms;
searchDatumTransform( QString( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code = %2" ).arg( srcAuthCode ).arg( destAuthCode ),
directTransforms );
QList<int> srcToWgs84;
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 ),
srcToWgs84 );
QList<int> destToWgs84;
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 ),
destToWgs84 );

//add direct datum transformations
QList<int>::const_iterator directIt = directTransforms.constBegin();
for ( ; directIt != directTransforms.constEnd(); ++directIt )
{
transformations.push_back( QList<int>() << *directIt << -1 );
}


QList<int>::const_iterator srcWgsIt = srcToWgs84.constBegin();
for ( ; srcWgsIt != srcToWgs84.constEnd(); ++srcWgsIt )
{
QList<int>::const_iterator dstWgsIt = destToWgs84.constBegin();
for ( ; dstWgsIt != destToWgs84.constEnd(); ++dstWgsIt )
{
transformations.push_back( QList<int>() << *srcWgsIt << *dstWgsIt );
}
}

return transformations;
}

QString QgsCoordinateTransform::stripDatumTransform( const QString& proj4 )
{
QStringList parameterSplit = proj4.split( "+", QString::SkipEmptyParts );
QString currentParameter;
QString newProjString;

for ( int i = 0; i < parameterSplit.size(); ++i )
{
currentParameter = parameterSplit.at( i );
if ( !currentParameter.startsWith( "towgs84", Qt::CaseInsensitive )
&& !currentParameter.startsWith( "nadgrids", Qt::CaseInsensitive ) )
{
newProjString.append( "+" );
newProjString.append( currentParameter );
newProjString.append( " " );
}
}
return newProjString;
}

void QgsCoordinateTransform::searchDatumTransform( const QString& sql, QList< int >& transforms )
{
sqlite3* db;
int openResult = sqlite3_open( QgsApplication::srsDbFilePath().toUtf8().constData(), &db );
if ( openResult != SQLITE_OK )
{
return;
}

sqlite3_stmt* stmt;
int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
if ( prepareRes != SQLITE_OK )
{
return;
}

QString cOpCode;
while ( sqlite3_step( stmt ) == SQLITE_ROW )
{
cOpCode = ( const char * ) sqlite3_column_text( stmt, 0 );
transforms.push_back( cOpCode.toInt() );
}
sqlite3_finalize( stmt );
sqlite3_close( db );
}

QString QgsCoordinateTransform::datumTransformString( int datumTransform )
{
QString transformString;

sqlite3* db;
int openResult = sqlite3_open( QgsApplication::srsDbFilePath().toUtf8().constData(), &db );
if ( openResult != SQLITE_OK )
{
return transformString;
}

sqlite3_stmt* stmt;
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 );
int prepareRes = sqlite3_prepare( db, sql.toAscii(), sql.size(), &stmt, NULL );
if ( prepareRes != SQLITE_OK )
{
return transformString;
}

if ( sqlite3_step( stmt ) == SQLITE_ROW )
{
//coord_op_methode_code
int methodCode = sqlite3_column_int( stmt, 0 );
if ( methodCode == 9615 ) //ntv2
{
transformString = "+nadgrids=" + QString(( const char * )sqlite3_column_text( stmt, 1 ) );
}
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
{
transformString += "+towgs84=";
double p1 = sqlite3_column_double( stmt, 1 );
double p2 = sqlite3_column_double( stmt, 2 );
double p3 = sqlite3_column_double( stmt, 3 );
double p4 = sqlite3_column_double( stmt, 4 );
double p5 = sqlite3_column_double( stmt, 5 );
double p6 = sqlite3_column_double( stmt, 6 );
double p7 = sqlite3_column_double( stmt, 7 );
if ( methodCode == 9603 ) //3 parameter transformation
{
transformString += QString( "%1,%2,%3" ).arg( p1 ).arg( p2 ).arg( p3 );
}
else //7 parameter transformation
{
transformString += QString( "%1,%2,%3,%4,%5,%6,%7" ).arg( p1 ).arg( p2 ).arg( p3 ).arg( p4 ).arg( p5 ).arg( p6 ).arg( p7 );
}
}
}

return transformString;
}
16 changes: 16 additions & 0 deletions src/core/qgscoordinatetransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,15 @@ class CORE_EXPORT QgsCoordinateTransform : public QObject
* @param theCRSID - A long representing the srsid of the srs to be used */
void setDestCRSID( long theCRSID );

/**Returns list of datum transformations for the given src and dest CRS*/
static QList< QList< int > > datumTransformations( const QgsCoordinateReferenceSystem& srcCRS, const QgsCoordinateReferenceSystem& destCRS );
static QString datumTransformString( int datumTransform );

int sourceDatumTransform() const { return mSourceDatumTransform; }
void setSourceDatumTransform( int dt ) { mSourceDatumTransform = dt; }
int destinationDatumTransform() const { return mDestinationDatumTransform; }
void setDestinationDatumTransform( int dt ) { mDestinationDatumTransform = dt; }

public slots:
//!initialise is used to actually create the Transformer instance
void initialise();
Expand Down Expand Up @@ -265,10 +274,17 @@ class CORE_EXPORT QgsCoordinateTransform : public QObject
*/
projPJ mDestinationProjection;

int mSourceDatumTransform;
int mDestinationDatumTransform;

/*!
* Finder for PROJ grid files.
*/
void setFinder();

/**Removes +nadgrids and +towgs84 from proj4 string*/
static QString stripDatumTransform( const QString& proj4 );
static void searchDatumTransform( const QString& sql, QList< int >& transforms );
};

//! Output stream operator
Expand Down
33 changes: 20 additions & 13 deletions src/core/qgscrscache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,29 @@ QgsCoordinateTransformCache::~QgsCoordinateTransformCache()
}
}

const QgsCoordinateTransform* QgsCoordinateTransformCache::transform( const QString& srcAuthId, const QString& destAuthId )
const QgsCoordinateTransform* QgsCoordinateTransformCache::transform( const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform, int destDatumTransform )
{
QHash< QPair< QString, QString >, QgsCoordinateTransform* >::const_iterator ctIt =
mTransforms.find( qMakePair( srcAuthId, destAuthId ) );
if ( ctIt == mTransforms.constEnd() )
{
const QgsCoordinateReferenceSystem& srcCrs = QgsCRSCache::instance()->crsByAuthId( srcAuthId );
const QgsCoordinateReferenceSystem& destCrs = QgsCRSCache::instance()->crsByAuthId( destAuthId );
QgsCoordinateTransform* ct = new QgsCoordinateTransform( srcCrs, destCrs );
mTransforms.insert( qMakePair( srcAuthId, destAuthId ), ct );
return ct;
}
else
QList< QgsCoordinateTransform* > values =
mTransforms.values( qMakePair( srcAuthId, destAuthId ) );

QList< QgsCoordinateTransform* >::const_iterator valIt = values.constBegin();
for ( ; valIt != values.constEnd(); ++valIt )
{
return ctIt.value();
if ( *valIt && ( *valIt )->sourceDatumTransform() == srcDatumTransform && ( *valIt )->destinationDatumTransform() == destDatumTransform )
{
return *valIt;
}
}

//not found, insert new value
const QgsCoordinateReferenceSystem& srcCrs = QgsCRSCache::instance()->crsByAuthId( srcAuthId );
const QgsCoordinateReferenceSystem& destCrs = QgsCRSCache::instance()->crsByAuthId( destAuthId );
QgsCoordinateTransform* ct = new QgsCoordinateTransform( srcCrs, destCrs );
ct->setSourceDatumTransform( srcDatumTransform );
ct->setDestinationDatumTransform( destDatumTransform );
ct->initialise();
mTransforms.insertMulti( qMakePair( srcAuthId, destAuthId ), ct );
return ct;
}

void QgsCoordinateTransformCache::invalidateCrs( const QString& crsAuthId )
Expand Down
5 changes: 3 additions & 2 deletions src/core/qgscrscache.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ class CORE_EXPORT QgsCoordinateTransformCache
/**Returns coordinate transformation. Cache keeps ownership
@param srcAuthId auth id string of source crs
@param destAuthId auth id string of dest crs*/
const QgsCoordinateTransform* transform( const QString& srcAuthId, const QString& destAuthId );
const QgsCoordinateTransform* transform( const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform = -1, int destDatumTransform = -1 );
/**Removes transformations where a changed crs is involved from the cache*/
void invalidateCrs( const QString& crsAuthId );

private:
QHash< QPair< QString, QString >, QgsCoordinateTransform* > mTransforms;
static QgsCoordinateTransformCache* mInstance;
QMultiHash< QPair< QString, QString >, QgsCoordinateTransform* > mTransforms; //same auth_id pairs might have different datum transformations
};

class CORE_EXPORT QgsCRSCache
Expand Down
166 changes: 142 additions & 24 deletions src/core/qgsmaprenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )

mDrawing = true;

const QgsCoordinateTransform* ct;
const QgsCoordinateTransform *ct;

#ifdef QGISDEBUG
QgsDebugMsg( "Starting to render layer stack." );
Expand Down Expand Up @@ -412,7 +412,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
{
r1 = mExtent;
split = splitLayersExtent( ml, r1, r2 );
ct = QgsCoordinateTransformCache::instance()->transform( ml->crs().authid(), mDestCRS->authid() );
ct = transformation( ml );
mRenderContext.setExtent( r1 );
QgsDebugMsg( " extent 1: " + r1.toString() );
QgsDebugMsg( " extent 2: " + r2.toString() );
Expand Down Expand Up @@ -655,7 +655,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
{
QgsRectangle r1 = mExtent;
split = splitLayersExtent( ml, r1, r2 );
ct = new QgsCoordinateTransform( ml->crs(), *mDestCRS );
ct = transformation( ml );
mRenderContext.setExtent( r1 );
}
else
Expand Down Expand Up @@ -736,12 +736,16 @@ bool QgsMapRenderer::hasCrsTransformEnabled() const
return mProjectionsEnabled;
}

void QgsMapRenderer::setDestinationCrs( const QgsCoordinateReferenceSystem& crs )
void QgsMapRenderer::setDestinationCrs( const QgsCoordinateReferenceSystem& crs, bool refreshCoordinateTransformInfo )
{
QgsDebugMsg( "* Setting destCRS : = " + crs.toProj4() );
QgsDebugMsg( "* DestCRS.srsid() = " + QString::number( crs.srsid() ) );
if ( *mDestCRS != crs )
{
if ( refreshCoordinateTransformInfo )
{
mLayerCoordinateTransformInfo.clear();
}
QgsRectangle rect;
if ( !mExtent.isEmpty() )
{
Expand Down Expand Up @@ -790,17 +794,23 @@ bool QgsMapRenderer::splitLayersExtent( QgsMapLayer* layer, QgsRectangle& extent
// extent separately.
static const double splitCoord = 180.0;

const QgsCoordinateTransform *transform = transformation( layer );
if ( layer->crs().geographicFlag() )
{
// Note: ll = lower left point
// and ur = upper right point
QgsPoint ll = tr( layer )->transform( extent.xMinimum(), extent.yMinimum(),
QgsCoordinateTransform::ReverseTransform );

QgsPoint ur = tr( layer )->transform( extent.xMaximum(), extent.yMaximum(),
QgsCoordinateTransform::ReverseTransform );
QgsPoint ll( extent.xMinimum(), extent.yMinimum() );
QgsPoint ur( extent.xMaximum(), extent.yMaximum() );

extent = tr( layer )->transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform );
if ( transform )
{
ll = transform->transform( ll.x(), ll.y(),
QgsCoordinateTransform::ReverseTransform );
ur = transform->transform( ur.x(), ur.y(),
QgsCoordinateTransform::ReverseTransform );
extent = transform->transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform );
}

if ( ll.x() > ur.x() )
{
Expand All @@ -812,7 +822,10 @@ bool QgsMapRenderer::splitLayersExtent( QgsMapLayer* layer, QgsRectangle& extent
}
else // can't cross 180
{
extent = tr( layer )->transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform );
if ( transform )
{
extent = transform->transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform );
}
}
}
catch ( QgsCsException &cse )
Expand All @@ -828,14 +841,18 @@ bool QgsMapRenderer::splitLayersExtent( QgsMapLayer* layer, QgsRectangle& extent

QgsRectangle QgsMapRenderer::layerExtentToOutputExtent( QgsMapLayer* theLayer, QgsRectangle extent )
{
QgsDebugMsg( QString( "sourceCrs = " + tr( theLayer )->sourceCrs().authid() ) );
QgsDebugMsg( QString( "destCRS = " + tr( theLayer )->destCRS().authid() ) );
QgsDebugMsg( QString( "extent = " + extent.toString() ) );
//QgsDebugMsg( QString( "sourceCrs = " + tr( theLayer )->sourceCrs().authid() ) );
//QgsDebugMsg( QString( "destCRS = " + tr( theLayer )->destCRS().authid() ) );
//QgsDebugMsg( QString( "extent = " + extent.toString() ) );
if ( hasCrsTransformEnabled() )
{
try
{
extent = tr( theLayer )->transformBoundingBox( extent );
const QgsCoordinateTransform *transform = transformation( theLayer );
if ( transform )
{
extent = transform->transformBoundingBox( extent );
}
}
catch ( QgsCsException &cse )
{
Expand All @@ -850,14 +867,21 @@ QgsRectangle QgsMapRenderer::layerExtentToOutputExtent( QgsMapLayer* theLayer, Q

QgsRectangle QgsMapRenderer::outputExtentToLayerExtent( QgsMapLayer* theLayer, QgsRectangle extent )
{
QgsDebugMsg( QString( "layer sourceCrs = " + tr( theLayer )->sourceCrs().authid() ) );
QgsDebugMsg( QString( "layer destCRS = " + tr( theLayer )->destCRS().authid() ) );
#if QGISDEBUG
const QgsCoordinateTransform *transform = transformation( theLayer );
QgsDebugMsg( QString( "layer sourceCrs = " + ( transform ? transform->sourceCrs().authid() : "none" ) ) );
QgsDebugMsg( QString( "layer destCRS = " + ( transform ? transform->destCRS().authid() : "none" ) ) );
QgsDebugMsg( QString( "extent = " + extent.toString() ) );
#endif
if ( hasCrsTransformEnabled() )
{
try
{
extent = tr( theLayer )->transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform );
const QgsCoordinateTransform *transform = transformation( theLayer );
if ( transform )
{
extent = transform->transformBoundingBox( extent, QgsCoordinateTransform::ReverseTransform );
}
}
catch ( QgsCsException &cse )
{
Expand All @@ -876,7 +900,11 @@ QgsPoint QgsMapRenderer::layerToMapCoordinates( QgsMapLayer* theLayer, QgsPoint
{
try
{
point = tr( theLayer )->transform( point, QgsCoordinateTransform::ForwardTransform );
const QgsCoordinateTransform *transform = transformation( theLayer );
if ( transform )
{
point = transform->transform( point, QgsCoordinateTransform::ForwardTransform );
}
}
catch ( QgsCsException &cse )
{
Expand All @@ -896,7 +924,11 @@ QgsRectangle QgsMapRenderer::layerToMapCoordinates( QgsMapLayer* theLayer, QgsRe
{
try
{
rect = tr( theLayer )->transform( rect, QgsCoordinateTransform::ForwardTransform );
const QgsCoordinateTransform *transform = transformation( theLayer );
if ( transform )
{
rect = transform->transform( rect, QgsCoordinateTransform::ForwardTransform );
}
}
catch ( QgsCsException &cse )
{
Expand All @@ -916,7 +948,9 @@ QgsPoint QgsMapRenderer::mapToLayerCoordinates( QgsMapLayer* theLayer, QgsPoint
{
try
{
point = tr( theLayer )->transform( point, QgsCoordinateTransform::ReverseTransform );
const QgsCoordinateTransform *transform = transformation( theLayer );
if ( transform )
point = transform->transform( point, QgsCoordinateTransform::ReverseTransform );
}
catch ( QgsCsException &cse )
{
Expand All @@ -936,7 +970,9 @@ QgsRectangle QgsMapRenderer::mapToLayerCoordinates( QgsMapLayer* theLayer, QgsRe
{
try
{
rect = tr( theLayer )->transform( rect, QgsCoordinateTransform::ReverseTransform );
const QgsCoordinateTransform *transform = transformation( theLayer );
if ( transform )
rect = transform->transform( rect, QgsCoordinateTransform::ReverseTransform );
}
catch ( QgsCsException &cse )
{
Expand Down Expand Up @@ -1073,11 +1109,36 @@ bool QgsMapRenderer::readXML( QDomNode & theNode )
element = projNode.toElement();
setProjectionsEnabled( element.text().toInt() );

//load coordinate transform into
mLayerCoordinateTransformInfo.clear();
QDomElement layerCoordTransformInfoElem = theNode.firstChildElement( "layer_coordinate_transform_info" );
if ( !layerCoordTransformInfoElem.isNull() )
{
QDomNodeList layerCoordinateTransformList = layerCoordTransformInfoElem.elementsByTagName( "layer_coordinate_transform" );
QDomElement layerCoordTransformElem;
for ( int i = 0; i < layerCoordinateTransformList.size(); ++i )
{
layerCoordTransformElem = layerCoordinateTransformList.at( i ).toElement();
QString layerId = layerCoordTransformElem.attribute( "layerid" );
if ( layerId.isEmpty() )
{
continue;
}

QgsLayerCoordinateTransform lct;
lct.srcAuthId = layerCoordTransformElem.attribute( "srcAuthId" );
lct.destAuthId = layerCoordTransformElem.attribute( "destAuthId" );
lct.srcDatumTransform = layerCoordTransformElem.attribute( "srcDatumTransform", "-1" ).toInt();
lct.destDatumTransform = layerCoordTransformElem.attribute( "destDatumTransform", "-1" ).toInt();
mLayerCoordinateTransformInfo.insert( layerId, lct );
}
}

// set destination CRS
QgsCoordinateReferenceSystem srs;
QDomNode srsNode = theNode.namedItem( "destinationsrs" );
srs.readXML( srsNode );
setDestinationCrs( srs );
setDestinationCrs( srs, false );

// set extent
QgsRectangle aoi;
Expand Down Expand Up @@ -1105,6 +1166,7 @@ bool QgsMapRenderer::readXML( QDomNode & theNode )
aoi.setYMaximum( ymax );

setExtent( aoi );

return true;
}

Expand Down Expand Up @@ -1177,6 +1239,20 @@ bool QgsMapRenderer::writeXML( QDomNode & theNode, QDomDocument & theDoc )
theNode.appendChild( srsNode );
destinationCrs().writeXML( srsNode, theDoc );

// layer coordinate transform infos
QDomElement layerCoordTransformInfo = theDoc.createElement( "layer_coordinate_transform_info" );
QHash< QString, QgsLayerCoordinateTransform >::const_iterator coordIt = mLayerCoordinateTransformInfo.constBegin();
for ( ; coordIt != mLayerCoordinateTransformInfo.constEnd(); ++coordIt )
{
QDomElement layerCoordTransformElem = theDoc.createElement( "layer_coordinate_transform" );
layerCoordTransformElem.setAttribute( "layerid", coordIt.key() );
layerCoordTransformElem.setAttribute( "srcAuthId", coordIt->srcAuthId );
layerCoordTransformElem.setAttribute( "destAuthId", coordIt->destAuthId );
layerCoordTransformElem.setAttribute( "srcDatumTransform", QString::number( coordIt->srcDatumTransform ) );
layerCoordTransformElem.setAttribute( "destDatumTransform", QString::number( coordIt->destDatumTransform ) );
layerCoordTransformInfo.appendChild( layerCoordTransformElem );
}
theNode.appendChild( layerCoordTransformInfo );
return true;
}

Expand All @@ -1188,13 +1264,40 @@ void QgsMapRenderer::setLabelingEngine( QgsLabelingEngineInterface* iface )
mLabelingEngine = iface;
}

const QgsCoordinateTransform* QgsMapRenderer::tr( QgsMapLayer *layer )
const QgsCoordinateTransform *QgsMapRenderer::transformation( const QgsMapLayer *layer ) const
{
if ( !layer || !mDestCRS )
{
return 0;
}
return QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), mDestCRS->authid() );

if ( layer->crs().authid() == mDestCRS->authid() )
{
return 0;
}

QHash< QString, QgsLayerCoordinateTransform >::const_iterator ctIt = mLayerCoordinateTransformInfo.find( layer->id() );
if ( ctIt != mLayerCoordinateTransformInfo.constEnd()
&& ctIt->srcAuthId == layer->crs().authid()
&& ctIt->destAuthId == mDestCRS->authid() )
{
return QgsCoordinateTransformCache::instance()->transform( ctIt->srcAuthId, ctIt->destAuthId, ctIt->srcDatumTransform, ctIt->destDatumTransform );
}
else
{
emit datumTransformInfoRequested( layer, layer->crs().authid(), mDestCRS->authid() );
}

//still not present? get coordinate transformation with -1/-1 datum transform as default
ctIt = mLayerCoordinateTransformInfo.find( layer->id() );
if ( ctIt == mLayerCoordinateTransformInfo.constEnd()
|| ctIt->srcAuthId == layer->crs().authid()
|| ctIt->destAuthId == mDestCRS->authid()
)
{
return QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), mDestCRS->authid(), -1, -1 );
}
return QgsCoordinateTransformCache::instance()->transform( ctIt->srcAuthId, ctIt->destAuthId, ctIt->srcDatumTransform, ctIt->destDatumTransform );
}

/** Returns a QPainter::CompositionMode corresponding to a QgsMapRenderer::BlendMode
Expand Down Expand Up @@ -1271,4 +1374,19 @@ QgsMapRenderer::BlendMode QgsMapRenderer::getBlendModeEnum( const QPainter::Comp
}
}

void QgsMapRenderer::addLayerCoordinateTransform( const QString& layerId, const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform, int destDatumTransform )
{
QgsLayerCoordinateTransform lt;
lt.srcAuthId = srcAuthId;
lt.destAuthId = destAuthId;
lt.srcDatumTransform = srcDatumTransform;
lt.destDatumTransform = destDatumTransform;
mLayerCoordinateTransformInfo.insert( layerId, lt );
}

void QgsMapRenderer::clearLayerCoordinateTransforms()
{
mLayerCoordinateTransformInfo.clear();
}

bool QgsMapRenderer::mDrawing = false;
22 changes: 18 additions & 4 deletions src/core/qgsmaprenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ class CORE_EXPORT QgsLabelingEngineInterface
virtual QgsLabelingEngineInterface* clone() = 0;
};


struct CORE_EXPORT QgsLayerCoordinateTransform
{
QString srcAuthId;
QString destAuthId;
int srcDatumTransform; //-1 if unknown or not specified
int destDatumTransform;
};

/** \ingroup core
* A non GUI class for rendering a map layer set onto a QPainter.
Expand Down Expand Up @@ -243,7 +249,7 @@ class CORE_EXPORT QgsMapRenderer : public QObject
bool hasCrsTransformEnabled() const;

//! sets destination coordinate reference system
void setDestinationCrs( const QgsCoordinateReferenceSystem& crs );
void setDestinationCrs( const QgsCoordinateReferenceSystem& crs, bool refreshCoordinateTransformInfo = true );

//! returns CRS of destination coordinate reference system
const QgsCoordinateReferenceSystem& destinationCrs() const;
Expand Down Expand Up @@ -289,6 +295,11 @@ class CORE_EXPORT QgsMapRenderer : public QObject
//! Added in 1.9
static QgsMapRenderer::BlendMode getBlendModeEnum( const QPainter::CompositionMode blendMode );

void addLayerCoordinateTransform( const QString& layerId, const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform = -1, int destDatumTransform = -1 );
void clearLayerCoordinateTransforms();

const QgsCoordinateTransform* transformation( const QgsMapLayer *layer ) const;

signals:

void drawingProgress( int current, int total );
Expand All @@ -304,6 +315,9 @@ class CORE_EXPORT QgsMapRenderer : public QObject
//! emitted when layer's draw() returned false
void drawError( QgsMapLayer* );

//! Notifies higher level components to show the datum transform dialog and add a QgsLayerCoordinateTransformInfo for that layer
void datumTransformInfoRequested( const QgsMapLayer* ml, const QString& srcAuthId, const QString& destAuthId ) const;

public slots:

//! called by signal from layer current being drawn
Expand Down Expand Up @@ -376,8 +390,8 @@ class CORE_EXPORT QgsMapRenderer : public QObject
//! Locks rendering loop for concurrent draws
QMutex mRenderMutex;

private:
const QgsCoordinateTransform* tr( QgsMapLayer *layer );
QHash< QString, QgsLayerCoordinateTransform > mLayerCoordinateTransformInfo;

};

#endif
Expand Down
53 changes: 30 additions & 23 deletions src/core/qgsvectorfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,26 +744,50 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
SymbologyExport symbologyExport,
double symbologyScale )
{
QgsDebugMsg( "fileName = " + fileName );
const QgsCoordinateReferenceSystem* outputCRS;
QgsCoordinateTransform* ct = 0;
int shallTransform = false;
if ( destCRS && layer )
{
ct = new QgsCoordinateTransform( layer->crs(), *destCRS );
}

QgsVectorFileWriter::WriterError error = writeAsVectorFormat( layer, fileName, fileEncoding, ct, driverName, onlySelected,
errorMessage, datasourceOptions, layerOptions, skipAttributeCreation, newFilename, symbologyExport, symbologyScale );
delete ct;
return error;
}

QgsVectorFileWriter::WriterError QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
const QString& fileName,
const QString& fileEncoding,
const QgsCoordinateTransform* ct,
const QString& driverName,
bool onlySelected,
QString *errorMessage,
const QStringList &datasourceOptions, // added in 1.6
const QStringList &layerOptions, // added in 1.6
bool skipAttributeCreation, // added in 1.6
QString *newFilename, // added in 1.9
SymbologyExport symbologyExport, //added in 2.0
double symbologyScale // added in 2.0
)
{
if ( !layer )
{
return ErrInvalidLayer;
}

if ( destCRS && destCRS->isValid() )
bool shallTransform = false;
const QgsCoordinateReferenceSystem* outputCRS = 0;
if ( ct )
{
// This means we should transform
outputCRS = destCRS;
outputCRS = &( ct->destCRS() );
shallTransform = true;
}
else
{
// This means we shouldn't transform, use source CRS as output (if defined)
outputCRS = &layer->crs();
outputCRS = &( layer->crs() );
}
QgsVectorFileWriter* writer =
new QgsVectorFileWriter( fileName, fileEncoding, skipAttributeCreation ? QgsFields() : layer->pendingFields(), layer->wkbType(), outputCRS, driverName, datasourceOptions, layerOptions, newFilename, symbologyExport );
Expand Down Expand Up @@ -805,18 +829,6 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,

const QgsFeatureIds& ids = layer->selectedFeaturesIds();

// Create our transform
if ( destCRS )
{
ct = new QgsCoordinateTransform( layer->crs(), *destCRS );
}

// Check for failure
if ( ct == NULL )
{
shallTransform = false;
}

//create symbol table if needed
if ( writer->symbologyExport() != NoSymbology )
{
Expand Down Expand Up @@ -928,11 +940,6 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer* layer,
writer->stopRender( layer );
delete writer;

if ( shallTransform )
{
delete ct;
}

if ( errors > 0 && errorMessage && n > 0 )
{
*errorMessage += QObject::tr( "\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
Expand Down
15 changes: 15 additions & 0 deletions src/core/qgsvectorfilewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,21 @@ class CORE_EXPORT QgsVectorFileWriter
double symbologyScale = 1.0 // added in 2.0
);

static WriterError writeAsVectorFormat( QgsVectorLayer* layer,
const QString& fileName,
const QString& fileEncoding,
const QgsCoordinateTransform* ct,
const QString& driverName = "ESRI Shapefile",
bool onlySelected = false,
QString *errorMessage = 0,
const QStringList &datasourceOptions = QStringList(), // added in 1.6
const QStringList &layerOptions = QStringList(), // added in 1.6
bool skipAttributeCreation = false, // added in 1.6
QString *newFilename = 0, // added in 1.9
SymbologyExport symbologyExport = NoSymbology, //added in 2.0
double symbologyScale = 1.0 // added in 2.0
);

/** create shapefile and initialize it */
QgsVectorFileWriter( const QString& vectorFileName,
const QString& fileEncoding,
Expand Down
1 change: 1 addition & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ qgscredentialdialog.cpp
qgscursors.cpp
qgsdatadefinedbutton.cpp
qgsdetaileditemdata.cpp
qgsdatumtransformdialog.cpp
qgsdetaileditemdelegate.cpp
qgsdetaileditemwidget.cpp
qgsdialog.cpp
Expand Down
60 changes: 60 additions & 0 deletions src/gui/qgsdatumtransformdialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "qgsdatumtransformdialog.h"
#include "qgscoordinatetransform.h"

QgsDatumTransformDialog::QgsDatumTransformDialog( const QString& layerName, const QList< QList< int > >& dt, QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f )
{
setupUi( this );
setWindowTitle( tr( "Select datum transformations for layer" ) + " " + layerName );
QList< QList< int > >::const_iterator it = dt.constBegin();
for ( ; it != dt.constEnd(); ++it )
{
QTreeWidgetItem* item = new QTreeWidgetItem();
for ( int i = 0; i < 2; ++i )
{
if ( i >= it->size() )
{
break;
}

int nr = it->at( i );
item->setData( i, Qt::UserRole, nr );
if ( nr != -1 )
{
item->setText( i, QgsCoordinateTransform::datumTransformString( nr ) );
}
}
mDatumTransformTreeWidget->addTopLevelItem( item );
}
}

QgsDatumTransformDialog::~QgsDatumTransformDialog()
{
}

QgsDatumTransformDialog::QgsDatumTransformDialog(): QDialog()
{
setupUi( this );
}

QList< int > QgsDatumTransformDialog::selectedDatumTransform()
{
QList<int> list;
QTreeWidgetItem * item = mDatumTransformTreeWidget->currentItem();
if ( item )
{
for ( int i = 0; i < 2; ++i )
{
int transformNr = item->data( i, Qt::UserRole ).toInt();
if ( transformNr != -1 )
{
list << transformNr;
}
}
}
return list;
}

bool QgsDatumTransformDialog::rememberSelection() const
{
return mRememberSelectionCheckBox->isChecked();
}
20 changes: 20 additions & 0 deletions src/gui/qgsdatumtransformdialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef QGSDATUMTRANSFORMDIALOG_H
#define QGSDATUMTRANSFORMDIALOG_H

#include "ui_qgsdatumtransformdialogbase.h"

class GUI_EXPORT QgsDatumTransformDialog: public QDialog, private Ui::QgsDatumTransformDialogBase
{
public:
QgsDatumTransformDialog( const QString& layerName, const QList< QList< int > >& dt, QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsDatumTransformDialog();

QList< int > selectedDatumTransform();

bool rememberSelection() const;

private:
QgsDatumTransformDialog();
};

#endif // QGSDATUMTRANSFORMDIALOG_H
7 changes: 5 additions & 2 deletions src/gui/qgshighlight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ void QgsHighlight::init()
{
if ( mMapCanvas->mapRenderer()->hasCrsTransformEnabled() )
{
QgsCoordinateTransform transform( mLayer->crs(), mMapCanvas->mapRenderer()->destinationCrs() );
mGeometry->transform( transform );
const QgsCoordinateTransform* ct = mMapCanvas->mapRenderer()->transformation( mLayer );
if ( ct )
{
mGeometry->transform( *ct );
}
}
updateRect();
update();
Expand Down
62 changes: 62 additions & 0 deletions src/gui/qgsmapcanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ email : sherman at mrcc.com
#include <QPaintEvent>
#include <QPixmap>
#include <QRect>
#include <QSettings>
#include <QTextStream>
#include <QResizeEvent>
#include <QString>
Expand All @@ -38,6 +39,8 @@ email : sherman at mrcc.com

#include "qgis.h"
#include "qgsapplication.h"
#include "qgscrscache.h"
#include "qgsdatumtransformdialog.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmapcanvasmap.h"
Expand Down Expand Up @@ -110,6 +113,8 @@ QgsMapCanvas::QgsMapCanvas( QWidget * parent, const char *name )
setFocusPolicy( Qt::StrongFocus );

mMapRenderer = new QgsMapRenderer;
connect( mMapRenderer, SIGNAL( datumTransformInfoRequested( const QgsMapLayer*, const QString&, const QString& ) ),
this, SLOT( getDatumTransformInfo( const QgsMapLayer*, const QString& , const QString& ) ) );

// create map canvas item which will show the map
mMap = new QgsMapCanvasMap( this );
Expand Down Expand Up @@ -1543,6 +1548,63 @@ void QgsMapCanvas::writeProject( QDomDocument & doc )
mMapRenderer->writeXML( mapcanvasNode, doc );
}

/**Ask user which datum transform to use*/
void QgsMapCanvas::getDatumTransformInfo( const QgsMapLayer* ml, const QString& srcAuthId, const QString& destAuthId )
{
if ( !ml )
{
return;
}

//check if default datum transformation available
QSettings s;
QString settingsString = "/Projections/" + srcAuthId + "//" + destAuthId;
QVariant defaultSrcTransform = s.value( settingsString + "_srcTransform" );
QVariant defaultDestTransform = s.value( settingsString + "_destTransform" );
if ( defaultSrcTransform.isValid() && defaultDestTransform.isValid() )
{
mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
return;
}

const QgsCoordinateReferenceSystem& srcCRS = QgsCRSCache::instance()->crsByAuthId( srcAuthId );
const QgsCoordinateReferenceSystem& destCRS = QgsCRSCache::instance()->crsByAuthId( destAuthId );

//get list of datum transforms
QList< QList< int > > dt = QgsCoordinateTransform::datumTransformations( srcCRS, destCRS );
if ( dt.size() < 2 )
{
return;
}

//if several possibilities: present dialog
QgsDatumTransformDialog d( ml->name(), dt );
if ( mMapRenderer && ( d.exec() == QDialog::Accepted ) )
{
int srcTransform = -1;
int destTransform = -1;
QList<int> t = d.selectedDatumTransform();
if ( t.size() > 0 )
{
srcTransform = t.at( 0 );
}
if ( t.size() > 1 )
{
destTransform = t.at( 1 );
}
mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
if ( d.rememberSelection() )
{
s.setValue( settingsString + "_srcTransform", srcTransform );
s.setValue( settingsString + "_destTransform", destTransform );
}
}
else
{
mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
}
}

void QgsMapCanvas::zoomByFactor( double scaleFactor )
{
if ( mDrawing )
Expand Down
3 changes: 3 additions & 0 deletions src/gui/qgsmapcanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
//! called to write map canvas settings to project
void writeProject( QDomDocument & );

//! ask user about datum transformation
void getDatumTransformInfo( const QgsMapLayer* ml, const QString& srcAuthId, const QString& destAuthId );

private slots:
//! called when current maptool is destroyed
void mapToolDestroyed();
Expand Down
5 changes: 5 additions & 0 deletions src/mapserver/qgsconfigparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,3 +599,8 @@ void QgsConfigParser::serviceCapabilities( QDomElement& parentElement, QDomDocum
}
}
}

QList< QPair< QString, QgsLayerCoordinateTransform > > QgsConfigParser::layerCoordinateTransforms() const
{
return QList< QPair< QString, QgsLayerCoordinateTransform > >();
}
2 changes: 2 additions & 0 deletions src/mapserver/qgsconfigparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ class QgsConfigParser
/**Applies configuration specific label settings*/
virtual void loadLabelSettings( QgsLabelingEngineInterface* lbl ) { Q_UNUSED( lbl ); }

virtual QList< QPair< QString, QgsLayerCoordinateTransform > > layerCoordinateTransforms() const;

protected:
/**Parser to forward not resolved requests (e.g. SLD parser based on user request might have a fallback parser with admin configuration)*/
QgsConfigParser* mFallbackParser;
Expand Down
27 changes: 27 additions & 0 deletions src/mapserver/qgsprojectparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3670,3 +3670,30 @@ void QgsProjectParser::loadLabelSettings( QgsLabelingEngineInterface* lbl )
}
}
}

QList< QPair< QString, QgsLayerCoordinateTransform > > QgsProjectParser::layerCoordinateTransforms() const
{
QList< QPair< QString, QgsLayerCoordinateTransform > > layerTransformList;

QDomElement coordTransformInfoElem = mXMLDoc->documentElement().firstChildElement( "mapcanvas" ).firstChildElement( "layer_coordinate_transform_info" );
if ( coordTransformInfoElem.isNull() )
{
return layerTransformList;
}

QDomNodeList layerTransformNodeList = coordTransformInfoElem.elementsByTagName( "layer_coordinate_transform" );
for ( int i = 0; i < layerTransformNodeList.size(); ++i )
{
QPair< QString, QgsLayerCoordinateTransform > layerEntry;
QDomElement layerTransformElem = layerTransformNodeList.at( i ).toElement();
layerEntry.first = layerTransformElem.attribute( "layerid" );
QgsLayerCoordinateTransform t;
t.srcAuthId = layerTransformElem.attribute( "srcAuthId" );
t.destAuthId = layerTransformElem.attribute( "destAuthId" );
t.srcDatumTransform = layerTransformElem.attribute( "srcDatumTransform", "-1" ).toInt();
t.destDatumTransform = layerTransformElem.attribute( "destDatumTransform", "-1" ).toInt();
layerEntry.second = t;
layerTransformList.push_back( layerEntry );
}
return layerTransformList;
}
2 changes: 2 additions & 0 deletions src/mapserver/qgsprojectparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ class QgsProjectParser: public QgsConfigParser

void loadLabelSettings( QgsLabelingEngineInterface* lbl );

QList< QPair< QString, QgsLayerCoordinateTransform > > layerCoordinateTransforms() const;

private:

//forbidden
Expand Down
13 changes: 13 additions & 0 deletions src/mapserver/qgswmsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ int QgsWMSServer::configureMapRender( const QPaintDevice* paintDevice ) const
return 1; //paint device is needed for height, width, dpi
}

mMapRenderer->clearLayerCoordinateTransforms();
mMapRenderer->setOutputSize( QSize( paintDevice->width(), paintDevice->height() ), paintDevice->logicalDpiX() );

//map extent
Expand Down Expand Up @@ -1259,6 +1260,18 @@ int QgsWMSServer::configureMapRender( const QPaintDevice* paintDevice ) const
mMapRenderer->setDestinationCrs( outputCRS );
mMapRenderer->setProjectionsEnabled( true );
mapUnits = outputCRS.mapUnits();

//read layer coordinate transforms from project file (e.g. ct with special datum shift)
if ( mConfigParser )
{
QList< QPair< QString, QgsLayerCoordinateTransform > > lt = mConfigParser->layerCoordinateTransforms();
QList< QPair< QString, QgsLayerCoordinateTransform > >::const_iterator ltIt = lt.constBegin();
for ( ; ltIt != lt.constEnd(); ++ltIt )
{
QgsLayerCoordinateTransform t = ltIt->second;
mMapRenderer->addLayerCoordinateTransform( ltIt->first, t.srcAuthId, t.destAuthId, t.srcDatumTransform, t.destDatumTransform );
}
}
}
mMapRenderer->setMapUnits( mapUnits );

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/globe/globe_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ void GlobePlugin::run()

// Set a home viewpoint
manip->setHomeViewpoint(
osgEarth::Util::Viewpoint( osg::Vec3d( -90, 0, 0 ), 0.0, -90.0, 4e7 ),
osgEarth::Util::Viewpoint( osg::Vec3d( -90, 0, 0 ), 0.0, -90.0, 2e7 ),
1.0 );

setupControls();
Expand Down
22 changes: 11 additions & 11 deletions src/plugins/plugin_template/plugingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
// pieces of text. One-liners can be added in the .ui file

// Note: Format does not relate to translation.
QString format( "<html><body><h3>%1</h3>%2<h3>%3</h3>%4<p><a href=http://svn.qgis.org/api_doc/html>"
"http://svn.qgis.org/api_doc/html</a><p>"
QString format( "<html><body><h3>%1</h3>%2<h3>%3</h3>%4<p><a href=http://qgis.org/api>"
"http://qgis.org/api</a><p>"
"%5<p>%6<p>%7<p>%8<p><h3>%9</h3>"
"<h4>CMakeLists.txt</h4>%11"
"<h4>[pluginlcasename].h, [pluginlcasename].cpp</h4>%12"
Expand All @@ -37,18 +37,18 @@
"<h4>[pluginlcasename].png</h4>%16"
"<h4>README</h4>%17"
"<h3>%18</h3>%19<ul>%20</ul>%21<p>%22"
"<p><b>The QGIS Team<br>2007</b>"
"<p><b>The QGIS Team</b>"
"</body></html>" );

// Note: Table does not translate
QString table( "<table><tr><td>QGisInterface<td><a href=http://svn.qgis.org/api_doc/html/classQgisInterface.html>"
"http://svn.qgis.org/api_doc/html/classQgisInterface.htm</a>"
"<tr><td>QgsMapCanvas<td><a href=http://svn.qgis.org/api_doc/html/classQgsMapCanvas.html>"
"http://svn.qgis.org/api_doc/html/classQgsMapCanvas.html</a>"
"<tr><td>QgsMapTool<td><a href=http://svn.qgis.org/api_doc/html/classQgsMapTool.html>"
"http://svn.qgis.org/api_doc/html/classQgsMapTool.html</a>"
"<tr><td>QgsPlugin<td><a href=http://svn.qgis.org/api_doc/html/classQgisPlugin.html>"
"http://svn.qgis.org/api_doc/html/classQgisPlugin.html</a></table>" );
QString table( "<table><tr><td>QGisInterface<td><a href=http://qgis.org/api/classQgisInterface.html>"
"http://qgis.org/api/classQgisInterface.html</a>"
"<tr><td>QgsMapCanvas<td><a href=http://qgis.org/api/classQgsMapCanvas.html>"
"http://qgis.org/api/classQgsMapCanvas.html</a>"
"<tr><td>QgsMapTool<td><a href=http://qgis.org/api/classQgsMapTool.html>"
"http://qgis.org/api/classQgsMapTool.html</a>"
"<tr><td>QgsPlugin<td><a href=http://qgis.org/api/classQgisPlugin.html>"
"http://qgis.org/api/classQgisPlugin.html</a></table>" );

// Note: Translatable strings below
QString text = format
Expand Down
2 changes: 1 addition & 1 deletion src/providers/spatialite/qgsspatialitefeatureiterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ QString QgsSpatiaLiteFeatureIterator::whereClauseRect()
}
else
{
if ( P->spatialIndexRTree )
if ( P->spatialIndexRTree && rect.isFinite() )
{
// using the RTree spatial index
QString mbrFilter = QString( "xmin <= %1 AND " ).arg( qgsDoubleToString( rect.xMaximum() ) );
Expand Down
90 changes: 90 additions & 0 deletions src/ui/qgsdatumtransformdialogbase.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsDatumTransformDialogBase</class>
<widget class="QDialog" name="QgsDatumTransformDialogBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>569</width>
<height>237</height>
</rect>
</property>
<property name="windowTitle">
<string>Select datum transformations</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QTreeWidget" name="mDatumTransformTreeWidget">
<column>
<property name="text">
<string>src transform</string>
</property>
</column>
<column>
<property name="text">
<string>dst transform</string>
</property>
</column>
<column>
<property name="text">
<string/>
</property>
</column>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="mRememberSelectionCheckBox">
<property name="text">
<string>Remember selection</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsDatumTransformDialogBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsDatumTransformDialogBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
5 changes: 4 additions & 1 deletion src/ui/qgsfieldspropertiesbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,13 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>186</height>
<height>20</height>
</size>
</property>
</spacer>
Expand Down