Skip to content

Commit

Permalink
[FEATURE] allow user specific PROJ.4 search paths and update srs.db t…
Browse files Browse the repository at this point in the history
…o include grid reference (fixes #3099)

git-svn-id: http://svn.osgeo.org/qgis/trunk@14399 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Oct 18, 2010
1 parent 9b287ce commit 6308416
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 78 deletions.
Binary file modified resources/srs.db
Binary file not shown.
43 changes: 43 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -85,6 +85,15 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
}
}

//local directories to search when looking for an PROJ.4 file with a given basename
foreach( QString path, settings.value( "projSearchPaths" ).toStringList() )
{
QListWidgetItem* newItem = new QListWidgetItem( mListProjPaths );
newItem->setText( path );
newItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable );
mListProjPaths->addItem( newItem );
}

//Network timeout
mNetworkTimeoutSpinBox->setValue( settings.value( "/qgis/networkAndProxy/networkTimeout", "60000" ).toInt() );

Expand Down Expand Up @@ -464,6 +473,13 @@ void QgsOptions::saveOptions()
}
settings.setValue( "svg/searchPathsForSVG", myPaths );

QStringList paths;
for ( int i = 0; i < mListProjPaths->count(); ++i )
{
paths << mListProjPaths->item( i )->text();
}
settings.setValue( "projSearchPaths", paths );

//Network timeout
settings.setValue( "/qgis/networkAndProxy/networkTimeout", mNetworkTimeoutSpinBox->value() );

Expand Down Expand Up @@ -872,6 +888,33 @@ void QgsOptions::on_mBtnRemoveSVGPath_clicked()
delete itemToRemove;
}

void QgsOptions::on_mBtnAddProjPath_clicked()
{
QString myDir = QFileDialog::getExistingDirectory(
this,
tr( "Choose a directory" ),
QDir::toNativeSeparators( QDir::homePath() ),
QFileDialog::ShowDirsOnly
);

if ( ! myDir.isEmpty() )
{
QListWidgetItem* newItem = new QListWidgetItem( mListProjPaths );
newItem->setText( myDir );
newItem->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable );
mListProjPaths->addItem( newItem );
mListProjPaths->setCurrentItem( newItem );
}
}

void QgsOptions::on_mBtnRemoveProjPath_clicked()
{
int currentRow = mListProjPaths->currentRow();
QListWidgetItem* itemToRemove = mListProjPaths->takeItem( currentRow );
delete itemToRemove;
}


void QgsOptions::on_mAddUrlPushButton_clicked()
{
QListWidgetItem* newItem = new QListWidgetItem( mExcludeUrlListWidget );
Expand Down
6 changes: 6 additions & 0 deletions src/app/qgsoptions.h
Expand Up @@ -101,6 +101,12 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
*/
void on_mBtnRemoveSVGPath_clicked();

/* Let the user add a path to the list of search paths used for finding PROJ.4 files. */
void on_mBtnAddProjPath_clicked();

/* Let the user remove a path to the list of search paths for finding PROJ.4 files. */
void on_mBtnRemoveProjPath_clicked();

void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }

void on_mBrowseCacheDirectory_clicked();
Expand Down
7 changes: 4 additions & 3 deletions src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -1161,9 +1161,10 @@ int QgsCoordinateReferenceSystem::openDb( QString path, sqlite3 **db )
// ... unfortunately it happens on Windows
QgsMessageOutput* output = QgsMessageOutput::createMessageOutput();
output->setTitle( "Error" );
output->setMessage( "Could not open CRS database " + path +
"<br>Error(" + QString::number( myResult ) + "): " +
QString( sqlite3_errmsg( *db ) ), QgsMessageOutput::MessageText );
output->setMessage( QObject::tr( "Could not open CRS database %1<br>Error(%2): %3" )
.arg( path )
.arg( myResult )
.arg( sqlite3_errmsg( *db ) ), QgsMessageOutput::MessageText );
output->showMessage();
}
return myResult;
Expand Down
76 changes: 49 additions & 27 deletions src/core/qgscoordinatetransform.cpp
Expand Up @@ -15,15 +15,18 @@
* *
***************************************************************************/
/* $Id$ */
#include <cassert>
#include "qgscoordinatetransform.h"
#include "qgsmessageoutput.h"
#include "qgslogger.h"

//qt includes
#include <QDomNode>
#include <QDomElement>
#include <QApplication>
#include "qgslogger.h"
#include <QSettings>
#include <QStringList>
#include <QFileInfo>
#include <QSet>

extern "C"
{
Expand All @@ -33,10 +36,7 @@ extern "C"
// if defined shows all information about transform to stdout
// #define COORDINATE_TRANSFORM_VERBOSE



QgsCoordinateTransform::QgsCoordinateTransform( ) : QObject(), mSourceCRS(), mDestCRS()

{
setFinder();
}
Expand All @@ -45,6 +45,7 @@ QgsCoordinateTransform::QgsCoordinateTransform( const QgsCoordinateReferenceSyst
const QgsCoordinateReferenceSystem& dest )
{
setFinder();

mSourceCRS = source;
mDestCRS = dest;
initialise();
Expand Down Expand Up @@ -315,7 +316,7 @@ void QgsCoordinateTransform::transformInPlace( std::vector<double>& x,
if ( mShortCircuit || !mInitialisedFlag )
return;

assert( x.size() == y.size() );
Q_ASSERT( x.size() == y.size() );

// Apparently, if one has a std::vector, it is valid to use the
// address of the first element in the vector as a pointer to an
Expand Down Expand Up @@ -457,8 +458,8 @@ void QgsCoordinateTransform::transformCoords( const int& numPoints, double *x, d
}
else
{
assert( mSourceProjection != 0 );
assert( mDestinationProjection != 0 );
Q_ASSERT( mSourceProjection != 0 );
Q_ASSERT( mDestinationProjection != 0 );
projResult = pj_transform( mSourceProjection, mDestinationProjection, numPoints, 0, x, y, z );
dir = tr( "forward transform" );
}
Expand Down Expand Up @@ -531,7 +532,6 @@ bool QgsCoordinateTransform::readXML( QDomNode & theNode )

bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc )
{

QDomElement myNodeElement = theNode.toElement();
QDomElement myTransformElement = theDoc.createElement( "coordinatetransform" );

Expand All @@ -548,29 +548,51 @@ bool QgsCoordinateTransform::writeXML( QDomNode & theNode, QDomDocument & theDoc
return true;
}

const char *finder( const char *name )
void QgsCoordinateTransform::setFinder()
{
QString proj;
#ifdef WIN32
proj = QApplication::applicationDirPath()
+ "/share/proj/" + QString( name );
#endif
return proj.toUtf8();
pj_set_finder( finder );
}

void QgsCoordinateTransform::setFinder()
const char *QgsCoordinateTransform::finder( const char *name )
{
#ifdef WIN32
// Attention! It should be possible to set PROJ_LIB
// but it can happen that it was previously set by installer
// (version 0.7) and the old installation was deleted
QSettings settings;
QStringList paths = settings.value( "projSearchPaths" ).toStringList();

// Another problem: PROJ checks if pj_finder was set before
// PROJ_LIB environment variable. pj_finder is probably set in
// GRASS gproj library when plugin is loaded, consequently
// PROJ_LIB is ignored
if ( getenv( "PROJ_LIB" ) )
{
paths << getenv( "PROJ_LIB" );
}

pj_set_finder( finder );
#ifdef WIN32
paths << QApplication::applicationDirPath() + "/share/proj";
#endif
}

foreach( QString path, paths )
{
QFileInfo fi( QString( "%1/%2" ).arg( path ).arg( name ) );
if ( fi.exists() )
return fi.canonicalFilePath().toUtf8();
}

if ( QString( name ).endsWith( ".gsb", Qt::CaseInsensitive ) )
{
static QSet<QString> missing;

if ( !missing.contains( name ) )
{
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( "Grid transformation missing" );
output->setMessage( tr( "PROJ.4 file %1 not found in any of these directories:\n\n"
"%2\n\n"
"Note: This message won't reappear for this file in this session." )
.arg( name )
.arg( paths.join( "\n" ) ),
QgsMessageOutput::MessageText );
output->showMessage();
}

missing << name;
}

return name;
}
83 changes: 45 additions & 38 deletions src/core/qgscoordinatetransform.h
Expand Up @@ -256,9 +256,14 @@ class CORE_EXPORT QgsCoordinateTransform: public QObject
projPJ mDestinationProjection;

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

/*!
* Finder for PROJ grid files.
*/
static const char *finder( const char *name );
};

//! Output stream operator
Expand All @@ -271,45 +276,47 @@ inline std::ostream& operator << ( std::ostream& os, const QgsCoordinateTransfor
{
//do nothing this is a dummy
}
/*
if (r.isInitialised())
{
mySummary += "Yes";
}
else
{
mySummary += "No" ;
}
mySummary += "\n\tShort Circuit? : " ;
if (r.isShortCircuited())
{
mySummary += "Yes";
}
else
{
mySummary += "No" ;
}

mySummary += "\n\tSource Spatial Ref Sys : ";
if (r.sourceCrs())
{
mySummary << r.sourceCrs();
}
else
{
mySummary += "Undefined" ;
}
#if 0
if ( r.isInitialised() )
{
mySummary += "Yes";
}
else
{
mySummary += "No" ;
}
mySummary += "\n\tShort Circuit? : " ;
if ( r.isShortCircuited() )
{
mySummary += "Yes";
}
else
{
mySummary += "No" ;
}

mySummary += "\n\tSource Spatial Ref Sys : ";
if ( r.sourceCrs() )
{
mySummary << r.sourceCrs();
}
else
{
mySummary += "Undefined" ;
}

mySummary += "\n\tDest Spatial Ref Sys : " ;
if ( r.destCRS() )
{
mySummary << r.destCRS();
}
else
{
mySummary += "Undefined" ;
}
#endif

mySummary += "\n\tDest Spatial Ref Sys : " ;
if (r.destCRS())
{
mySummary << r.destCRS();
}
else
{
mySummary += "Undefined" ;
}
*/
mySummary += ( "\nCoordinate Transform def ends \n%%%%%%%%%%%%%%%%%%%%%%%%\n" );
return os << mySummary.toLocal8Bit().data() << std::endl;
}
Expand Down

0 comments on commit 6308416

Please sign in to comment.