Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move bounds retrieval to QgsCoordinateReferenceSystem
Allows reuse in scripts/plugins/etc
  • Loading branch information
nyalldawson committed Oct 16, 2017
1 parent 0002168 commit f579f1a
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 49 deletions.
11 changes: 11 additions & 0 deletions python/core/qgscoordinatereferencesystem.sip
Expand Up @@ -601,6 +601,17 @@ Returns whether this CRS is correctly initialized and usable
:rtype: QgsUnitTypes.DistanceUnit
%End

QgsRectangle bounds() const;
%Docstring
Returns the approximate bounds for the region the CRS is usable within.

The returned bounds represent the latitude and longitude extent for the
projection in the WGS 84 CRS.

.. versionadded:: 3.0
:rtype: QgsRectangle
%End


void setValidationHint( const QString &html );
%Docstring
Expand Down
43 changes: 43 additions & 0 deletions src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -1061,6 +1061,49 @@ QgsUnitTypes::DistanceUnit QgsCoordinateReferenceSystem::mapUnits() const
return d->mMapUnits;
}

QgsRectangle QgsCoordinateReferenceSystem::bounds() const
{
if ( !d->mIsValid )
return QgsRectangle();

//check the db is available
QString databaseFileName = QgsApplication::srsDatabaseFilePath();

sqlite3 *database = nullptr;
const char *tail = nullptr;
sqlite3_stmt *stmt = nullptr;

int result = openDatabase( databaseFileName, &database );
if ( result != SQLITE_OK )
{
return QgsRectangle();
}

QString sql = QStringLiteral( "select west_bound_lon, north_bound_lat, east_bound_lon, south_bound_lat from tbl_srs "
"where srs_id=%1" )
.arg( d->mSrsId );
result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );

QgsRectangle rect;
if ( result == SQLITE_OK )
{
if ( sqlite3_step( stmt ) == SQLITE_ROW )
{
double west = sqlite3_column_double( stmt, 0 );
double north = sqlite3_column_double( stmt, 1 );
double east = sqlite3_column_double( stmt, 2 );
double south = sqlite3_column_double( stmt, 3 );
rect = QgsRectangle( west, north, east, south );
}
}

// close the sqlite3 statement
sqlite3_finalize( stmt );
sqlite3_close( database );

return rect;
}


// Mutators -----------------------------------

Expand Down
11 changes: 11 additions & 0 deletions src/core/qgscoordinatereferencesystem.h
Expand Up @@ -31,6 +31,7 @@
//qgis includes
#include "qgis.h"
#include "qgsunittypes.h"
#include "qgsrectangle.h"

class QDomNode;
class QDomDocument;
Expand Down Expand Up @@ -580,6 +581,16 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
*/
QgsUnitTypes::DistanceUnit mapUnits() const;

/**
* Returns the approximate bounds for the region the CRS is usable within.
*
* The returned bounds represent the latitude and longitude extent for the
* projection in the WGS 84 CRS.
*
* \since QGIS 3.0
*/
QgsRectangle bounds() const;

// Mutators -----------------------------------

/**
Expand Down
69 changes: 20 additions & 49 deletions src/gui/qgsprojectionselectiontreewidget.cpp
Expand Up @@ -1019,65 +1019,36 @@ long QgsProjectionSelectionTreeWidget::getLargestCrsIdMatch( const QString &sql

void QgsProjectionSelectionTreeWidget::updateBoundsPreview()
{
sqlite3 *database = nullptr;
const char *tail = nullptr;
sqlite3_stmt *stmt = nullptr;

QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem();
if ( !lvi || lvi->text( QgisCrsIdColumn ).isEmpty() )
return;

int result = sqlite3_open_v2( mSrsDatabaseFileName.toUtf8().data(), &database, SQLITE_OPEN_READONLY, nullptr );
if ( result )
{
QgsDebugMsg( QString( "Can't open * user * database: %1" ).arg( sqlite3_errmsg( database ) ) );
//no need for assert because user db may not have been created yet
QgsCoordinateReferenceSystem currentCrs = crs();
if ( !currentCrs.isValid() )
return;
}

QString sql = QStringLiteral( "select west_bound_lon, north_bound_lat, east_bound_lon, south_bound_lat from tbl_srs "
"where srs_id=%2" )
.arg( lvi->text( QgisCrsIdColumn ) );
result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &stmt, &tail );

if ( result == SQLITE_OK )
QgsRectangle rect = currentCrs.bounds();
if ( !rect.isEmpty() )
{
if ( sqlite3_step( stmt ) == SQLITE_ROW )
{
double west = sqlite3_column_double( stmt, 0 );
double north = sqlite3_column_double( stmt, 1 );
double east = sqlite3_column_double( stmt, 2 );
double south = sqlite3_column_double( stmt, 3 );
QgsRectangle rect( west, north, east, south );
if ( !rect.isEmpty() )
{
mPreviewBand->setToGeometry( QgsGeometry::fromRect( rect ), nullptr );
mPreviewBand->setColor( QColor( 255, 0, 0, 65 ) );
mAreaCanvas->setExtent( rect );
mPreviewBand->show();
mAreaCanvas->zoomOut();
QString extentString = tr( "Extent: %1" ).arg( rect.toString( 2 ) );
QString proj4String = tr( "Proj4: %1" ).arg( selectedProj4String() );
teProjection->setText( extentString + "\n" + proj4String );
}
else
{
mPreviewBand->hide();
mAreaCanvas->zoomToFullExtent();
QString extentString = tr( "Extent: Extent not known" );
QString proj4String = tr( "Proj4: %1" ).arg( selectedProj4String() );
teProjection->setText( extentString + "\n" + proj4String );
}
}

mPreviewBand->setToGeometry( QgsGeometry::fromRect( rect ), nullptr );
mPreviewBand->setColor( QColor( 255, 0, 0, 65 ) );
mAreaCanvas->setExtent( rect );
mPreviewBand->show();
mAreaCanvas->zoomOut();
QString extentString = tr( "Extent: %1" ).arg( rect.toString( 2 ) );
QString proj4String = tr( "Proj4: %1" ).arg( selectedProj4String() );
teProjection->setText( extentString + "\n" + proj4String );
}
else
{
mPreviewBand->hide();
mAreaCanvas->zoomToFullExtent();
QString extentString = tr( "Extent: Extent not known" );
QString proj4String = tr( "Proj4: %1" ).arg( selectedProj4String() );
teProjection->setText( extentString + "\n" + proj4String );
}

// close the sqlite3 statement
sqlite3_finalize( stmt );
sqlite3_close( database );
}


QStringList QgsProjectionSelectionTreeWidget::authorities()
{
sqlite3 *database = nullptr;
Expand Down
35 changes: 35 additions & 0 deletions tests/src/core/testqgscoordinatereferencesystem.cpp
Expand Up @@ -75,6 +75,7 @@ class TestQgsCoordinateReferenceSystem: public QObject
void createFromProj4Invalid();
void validSrsIds();
void asVariant();
void bounds();

private:
void debugPrint( QgsCoordinateReferenceSystem &crs );
Expand Down Expand Up @@ -764,5 +765,39 @@ void TestQgsCoordinateReferenceSystem::asVariant()
QCOMPARE( fromVar.authid(), original.authid() );
}

void TestQgsCoordinateReferenceSystem::bounds()
{
QgsCoordinateReferenceSystem invalid;
QVERIFY( invalid.bounds().isNull() );

QgsCoordinateReferenceSystem crs3111( "EPSG:3111" );
QgsRectangle bounds = crs3111.bounds();
QGSCOMPARENEAR( bounds.xMinimum(), 140.960000, 0.0001 );
QGSCOMPARENEAR( bounds.xMaximum(), 150.040000, 0.0001 );
QGSCOMPARENEAR( bounds.yMinimum(), -39.200000, 0.0001 );
QGSCOMPARENEAR( bounds.yMaximum(), -33.980000, 0.0001 );

QgsCoordinateReferenceSystem crs28356( "EPSG:28356" );
bounds = crs28356.bounds();
QGSCOMPARENEAR( bounds.xMinimum(), 150.000000, 0.0001 );
QGSCOMPARENEAR( bounds.xMaximum(), 156.000000, 0.0001 );
QGSCOMPARENEAR( bounds.yMinimum(), -58.960000, 0.0001 );
QGSCOMPARENEAR( bounds.yMaximum(), -13.870000, 0.0001 );

QgsCoordinateReferenceSystem crs3857( "EPSG:3857" );
bounds = crs3857.bounds();
QGSCOMPARENEAR( bounds.xMinimum(), -180.000000, 0.0001 );
QGSCOMPARENEAR( bounds.xMaximum(), 180.000000, 0.0001 );
QGSCOMPARENEAR( bounds.yMinimum(), -85.060000, 0.0001 );
QGSCOMPARENEAR( bounds.yMaximum(), 85.060000, 0.0001 );

QgsCoordinateReferenceSystem crs4326( "EPSG:4326" );
bounds = crs4326.bounds();
QGSCOMPARENEAR( bounds.xMinimum(), -180.000000, 0.0001 );
QGSCOMPARENEAR( bounds.xMaximum(), 180.000000, 0.0001 );
QGSCOMPARENEAR( bounds.yMinimum(), -90.00000, 0.0001 );
QGSCOMPARENEAR( bounds.yMaximum(), 90.00000, 0.0001 );
}

QGSTEST_MAIN( TestQgsCoordinateReferenceSystem )
#include "testqgscoordinatereferencesystem.moc"

0 comments on commit f579f1a

Please sign in to comment.