Move bounds retrieval to QgsCoordinateReferenceSystem

Allows reuse in scripts/plugins/etc
This commit is contained in:
Nyall Dawson 2017-10-16 11:36:57 +10:00
parent 0002168c0d
commit f579f1a449
5 changed files with 120 additions and 49 deletions

View File

@ -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

View File

@ -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 -----------------------------------

View File

@ -31,6 +31,7 @@
//qgis includes
#include "qgis.h"
#include "qgsunittypes.h"
#include "qgsrectangle.h"
class QDomNode;
class QDomDocument;
@ -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 -----------------------------------
/**

View File

@ -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;

View File

@ -75,6 +75,7 @@ class TestQgsCoordinateReferenceSystem: public QObject
void createFromProj4Invalid();
void validSrsIds();
void asVariant();
void bounds();
private:
void debugPrint( QgsCoordinateReferenceSystem &crs );
@ -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"