mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Fix project unit confusion (pt 2): add project distance unit setting
Adds a new option in project properties to set the units used for distance measurements. This setting defaults to the units set in QGIS options, but can then be overridden for specific projects. The setting is respected for length and perimeter calculations in: - Attribute table field update bar - Field calculator calculations - Identify tool derived length and perimeter values - Default unit shown in measure dialog Also adds unit tests to ensure that length and perimeter calculated by attribute table update bar, field calculator and identify tool are consistent wrt ellipsoidal calculations and distance units. (refs #13209, #12939, #2402, #4857, #4252)
This commit is contained in:
parent
17a29f90d6
commit
ddbdcf8ab1
@ -248,6 +248,11 @@ class QgsProject : QObject
|
||||
/** Convenience function to query topological editing status */
|
||||
bool topologicalEditing() const;
|
||||
|
||||
/** Convenience function to query default distance measurement units for project.
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
QGis::UnitType distanceUnits() const;
|
||||
|
||||
/** Return project's home path
|
||||
@return home path of project (or QString::null if not set) */
|
||||
QString homePath() const;
|
||||
|
@ -107,4 +107,17 @@ class QgsMapToolIdentify : QgsMapTool
|
||||
|
||||
bool identifyRasterLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsRasterLayer *layer, QgsPoint point, const QgsRectangle& viewExtent, double mapUnitsPerPixel );
|
||||
bool identifyVectorLayer( QList<QgsMapToolIdentify::IdentifyResult> *results, QgsVectorLayer *layer, const QgsPoint& point );
|
||||
|
||||
private:
|
||||
|
||||
//! Private helper
|
||||
virtual void convertMeasurement( QgsDistanceArea &calc, double &measure, QGis::UnitType &u, bool isArea );
|
||||
|
||||
/** Transforms the measurements of derived attributes in the desired units*/
|
||||
virtual QGis::UnitType displayUnits();
|
||||
|
||||
/** Desired units for distance display.
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
virtual QGis::UnitType displayDistanceUnits();
|
||||
};
|
||||
|
@ -366,6 +366,7 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, const
|
||||
|
||||
QgsExpression exp( expression );
|
||||
exp.setGeomCalculator( *myDa );
|
||||
exp.setDistanceUnits( QgsProject::instance()->distanceUnits() );
|
||||
bool useGeometry = exp.needsGeometry();
|
||||
|
||||
QgsFeatureRequest request( mMainView->masterModel()->request() );
|
||||
@ -816,6 +817,7 @@ void QgsAttributeTableDialog::setFilterExpression( const QString& filterString )
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
|
||||
filterExpression.setGeomCalculator( myDa );
|
||||
filterExpression.setDistanceUnits( QgsProject::instance()->distanceUnits() );
|
||||
QgsFeatureRequest request( mMainView->masterModel()->request() );
|
||||
request.setSubsetOfAttributes( filterExpression.referencedColumns(), mLayer->fields() );
|
||||
if ( !fetchGeom )
|
||||
|
@ -223,6 +223,8 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib
|
||||
|
||||
QgsRubberBand* mRubberBand;
|
||||
QgsSearchWidgetWrapper* mCurrentSearchWidgetWrapper;
|
||||
|
||||
friend class TestQgsAttributeTable;
|
||||
};
|
||||
|
||||
|
||||
|
@ -164,6 +164,7 @@ void QgsFieldCalculator::accept()
|
||||
QString calcString = builder->expressionText();
|
||||
QgsExpression exp( calcString );
|
||||
exp.setGeomCalculator( myDa );
|
||||
exp.setDistanceUnits( QgsProject::instance()->distanceUnits() );
|
||||
|
||||
QgsExpressionContext expContext;
|
||||
expContext << QgsExpressionContextUtils::globalScope()
|
||||
|
@ -71,6 +71,8 @@ class APP_EXPORT QgsFieldCalculator: public QDialog, private Ui::QgsFieldCalcula
|
||||
|
||||
/** Idx of changed attribute*/
|
||||
int mAttributeId;
|
||||
|
||||
friend class TestQgsFieldCalculator;
|
||||
};
|
||||
|
||||
#endif // QGSFIELDCALCULATOR_H
|
||||
|
@ -193,6 +193,11 @@ QGis::UnitType QgsMapToolIdentifyAction::displayUnits()
|
||||
return ok ? unit : QGis::Meters;
|
||||
}
|
||||
|
||||
QGis::UnitType QgsMapToolIdentifyAction::displayDistanceUnits()
|
||||
{
|
||||
return QgsProject::instance()->distanceUnits();
|
||||
}
|
||||
|
||||
void QgsMapToolIdentifyAction::handleCopyToClipboard( QgsFeatureStore & featureStore )
|
||||
{
|
||||
QgsDebugMsg( QString( "features count = %1" ).arg( featureStore.features().size() ) );
|
||||
|
@ -81,6 +81,7 @@ class APP_EXPORT QgsMapToolIdentifyAction : public QgsMapToolIdentify
|
||||
QgsIdentifyResultsDialog *resultsDialog();
|
||||
|
||||
virtual QGis::UnitType displayUnits() override;
|
||||
virtual QGis::UnitType displayDistanceUnits() override;
|
||||
|
||||
};
|
||||
|
||||
|
@ -54,9 +54,7 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool* tool, Qt::WindowFlags f )
|
||||
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Feet ), QGis::Feet );
|
||||
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::Degrees ), QGis::Degrees );
|
||||
mUnitsCombo->addItem( QgsUnitTypes::toString( QGis::NauticalMiles ), QGis::NauticalMiles );
|
||||
QSettings settings;
|
||||
QString units = settings.value( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::Meters ) ).toString();
|
||||
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QgsUnitTypes::decodeDistanceUnit( units ) ) );
|
||||
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QgsProject::instance()->distanceUnits() ) );
|
||||
|
||||
updateSettings();
|
||||
|
||||
@ -78,7 +76,7 @@ void QgsMeasureDialog::updateSettings()
|
||||
mDecimalPlaces = settings.value( "/qgis/measure/decimalplaces", "3" ).toInt();
|
||||
mCanvasUnits = mTool->canvas()->mapUnits();
|
||||
// Configure QgsDistanceArea
|
||||
mDisplayUnits = static_cast< QGis::UnitType >( mUnitsCombo->itemData( mUnitsCombo->currentIndex() ).toInt() );
|
||||
mDisplayUnits = QgsProject::instance()->distanceUnits();
|
||||
mDa.setSourceCrs( mTool->canvas()->mapSettings().destinationCrs().srsid() );
|
||||
mDa.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) );
|
||||
// Only use ellipsoidal calculation when project wide transformation is enabled.
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "qgslayertreegroup.h"
|
||||
#include "qgslayertreelayer.h"
|
||||
#include "qgslayertreemodel.h"
|
||||
#include "qgsunittypes.h"
|
||||
|
||||
#include "qgsmessagelog.h"
|
||||
|
||||
@ -84,6 +85,12 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
|
||||
mCoordinateDisplayComboBox->addItem( tr( "Degrees, minutes" ), DegreesMinutes );
|
||||
mCoordinateDisplayComboBox->addItem( tr( "Degrees, minutes, seconds" ), DegreesMinutesSeconds );
|
||||
|
||||
mDistanceUnitsCombo->addItem( tr( "Meters" ), QGis::Meters );
|
||||
mDistanceUnitsCombo->addItem( tr( "Feet" ), QGis::Feet );
|
||||
mDistanceUnitsCombo->addItem( tr( "Nautical miles" ), QGis::NauticalMiles );
|
||||
mDistanceUnitsCombo->addItem( tr( "Degrees" ), QGis::Degrees );
|
||||
mDistanceUnitsCombo->addItem( tr( "Map units" ), QGis::UnknownUnit );
|
||||
|
||||
connect( buttonBox->button( QDialogButtonBox::Apply ), SIGNAL( clicked() ), this, SLOT( apply() ) );
|
||||
connect( this, SIGNAL( accepted() ), this, SLOT( apply() ) );
|
||||
connect( projectionSelector, SIGNAL( sridSelected( QString ) ), this, SLOT( srIdUpdated() ) );
|
||||
@ -157,6 +164,8 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
|
||||
else
|
||||
mCoordinateDisplayComboBox->setCurrentIndex( mCoordinateDisplayComboBox->findData( DecimalDegrees ) );
|
||||
|
||||
mDistanceUnitsCombo->setCurrentIndex( mDistanceUnitsCombo->findData( QgsProject::instance()->distanceUnits() ) );
|
||||
|
||||
//get the color selections and set the button color accordingly
|
||||
int myRedInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );
|
||||
int myGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 );
|
||||
@ -779,6 +788,9 @@ void QgsProjectProperties::apply()
|
||||
// Announce that we may have a new display precision setting
|
||||
emit displayPrecisionChanged();
|
||||
|
||||
QGis::UnitType distanceUnits = static_cast< QGis::UnitType >( mDistanceUnitsCombo->itemData( mDistanceUnitsCombo->currentIndex() ).toInt() );
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( distanceUnits ) );
|
||||
|
||||
QgsProject::instance()->writeEntry( "Paths", "/Absolute", cbxAbsolutePath->currentIndex() == 0 );
|
||||
|
||||
if ( mEllipsoidList.at( mEllipsoidIndex ).acronym.startsWith( "PARAMETER" ) )
|
||||
@ -1139,7 +1151,6 @@ void QgsProjectProperties::showProjectionsTab()
|
||||
|
||||
void QgsProjectProperties::on_cbxProjectionEnabled_toggled( bool onFlyEnabled )
|
||||
{
|
||||
QString measureOnFlyState = tr( "Measure tool (CRS transformation: %1)" );
|
||||
if ( !onFlyEnabled )
|
||||
{
|
||||
// reset projection to default
|
||||
@ -1162,8 +1173,6 @@ void QgsProjectProperties::on_cbxProjectionEnabled_toggled( bool onFlyEnabled )
|
||||
|
||||
// unset ellipsoid
|
||||
mEllipsoidIndex = 0;
|
||||
|
||||
btnGrpMeasureEllipsoid->setTitle( measureOnFlyState.arg( tr( "OFF" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1172,8 +1181,6 @@ void QgsProjectProperties::on_cbxProjectionEnabled_toggled( bool onFlyEnabled )
|
||||
mLayerSrsId = projectionSelector->selectedCrsId();
|
||||
}
|
||||
projectionSelector->setSelectedCrsId( mProjectSrsId );
|
||||
|
||||
btnGrpMeasureEllipsoid->setTitle( measureOnFlyState.arg( tr( "ON" ) ) );
|
||||
}
|
||||
|
||||
srIdUpdated();
|
||||
@ -1230,7 +1237,7 @@ void QgsProjectProperties::updateGuiForMapUnits( QGis::UnitType units )
|
||||
else
|
||||
{
|
||||
//make sure map units option is shown in coordinate display combo
|
||||
QString mapUnitString = tr( "Map units (%1)" ).arg( QGis::tr( units ) );
|
||||
QString mapUnitString = tr( "Map units (%1)" ).arg( QgsUnitTypes::toString( units ) );
|
||||
if ( idx < 0 )
|
||||
{
|
||||
mCoordinateDisplayComboBox->insertItem( 0, mapUnitString, MapUnits );
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsvisibilitypresetcollection.h"
|
||||
#include "qgslayerdefinition.h"
|
||||
#include "qgsunittypes.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileInfo>
|
||||
@ -45,6 +46,7 @@
|
||||
#include <QTemporaryFile>
|
||||
#include <QDir>
|
||||
#include <QUrl>
|
||||
#include <QSettings>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <utime.h>
|
||||
@ -452,6 +454,10 @@ void QgsProject::clear()
|
||||
writeEntry( "PositionPrecision", "/DecimalPlaces", 2 );
|
||||
writeEntry( "Paths", "/Absolute", false );
|
||||
|
||||
//copy default distance units to project
|
||||
QSettings s;
|
||||
writeEntry( "Measurement", "/DistanceUnits", s.value( "/qgis/measure/displayunits" ).toString() );
|
||||
|
||||
setDirty( false );
|
||||
}
|
||||
|
||||
@ -2058,6 +2064,19 @@ bool QgsProject::topologicalEditing() const
|
||||
return ( QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ) > 0 );
|
||||
}
|
||||
|
||||
QGis::UnitType QgsProject::distanceUnits() const
|
||||
{
|
||||
QString distanceUnitString = QgsProject::instance()->readEntry( "Measurement", "/DistanceUnits", QString() );
|
||||
if ( !distanceUnitString.isEmpty() )
|
||||
return QgsUnitTypes::decodeDistanceUnit( distanceUnitString );
|
||||
|
||||
//fallback to QGIS default measurement unit
|
||||
QSettings s;
|
||||
bool ok = false;
|
||||
QGis::UnitType type = QgsUnitTypes::decodeDistanceUnit( s.value( "/qgis/measure/displayunits" ).toString(), &ok );
|
||||
return ok ? type : QGis::Meters;
|
||||
}
|
||||
|
||||
void QgsProjectBadLayerDefaultHandler::handleBadLayers( const QList<QDomNode>& /*layers*/, const QDomDocument& /*projectDom*/ )
|
||||
{
|
||||
// just ignore any bad layers
|
||||
|
@ -293,6 +293,11 @@ class CORE_EXPORT QgsProject : public QObject
|
||||
/** Convenience function to query topological editing status */
|
||||
bool topologicalEditing() const;
|
||||
|
||||
/** Convenience function to query default distance measurement units for project.
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
QGis::UnitType distanceUnits() const;
|
||||
|
||||
/** Return project's home path
|
||||
@return home path of project (or QString::null if not set) */
|
||||
QString homePath() const;
|
||||
|
@ -369,9 +369,8 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeatur
|
||||
if ( geometryType == QGis::Line )
|
||||
{
|
||||
double dist = calc.measureLength( feature->constGeometry() );
|
||||
QGis::UnitType myDisplayUnits;
|
||||
convertMeasurement( calc, dist, myDisplayUnits, false );
|
||||
QString str = calc.textUnit( dist, 3, myDisplayUnits, false ); // dist and myDisplayUnits are out params
|
||||
dist = calc.convertLengthMeasurement( dist, displayDistanceUnits() );
|
||||
QString str = formatDistance( dist );
|
||||
derivedAttributes.insert( tr( "Length" ), str );
|
||||
|
||||
const QgsCurveV2* curve = dynamic_cast< const QgsCurveV2* >( feature->constGeometry()->geometry() );
|
||||
@ -399,13 +398,15 @@ QMap< QString, QString > QgsMapToolIdentify::featureDerivedAttributes( QgsFeatur
|
||||
else if ( geometryType == QGis::Polygon )
|
||||
{
|
||||
double area = calc.measureArea( feature->constGeometry() );
|
||||
double perimeter = calc.measurePerimeter( feature->constGeometry() );
|
||||
|
||||
QGis::UnitType myDisplayUnits;
|
||||
convertMeasurement( calc, area, myDisplayUnits, true ); // area and myDisplayUnits are out params
|
||||
QString str = calc.textUnit( area, 3, myDisplayUnits, true );
|
||||
derivedAttributes.insert( tr( "Area" ), str );
|
||||
convertMeasurement( calc, perimeter, myDisplayUnits, false ); // perimeter and myDisplayUnits are out params
|
||||
str = calc.textUnit( perimeter, 3, myDisplayUnits, false );
|
||||
|
||||
double perimeter = calc.measurePerimeter( feature->constGeometry() );
|
||||
perimeter = calc.convertLengthMeasurement( perimeter, displayDistanceUnits() );
|
||||
str = formatDistance( perimeter );
|
||||
derivedAttributes.insert( tr( "Perimeter" ), str );
|
||||
|
||||
str = QLocale::system().toString( feature->constGeometry()->geometry()->nCoordinates() );
|
||||
@ -640,7 +641,7 @@ bool QgsMapToolIdentify::identifyRasterLayer( QList<IdentifyResult> *results, Qg
|
||||
|
||||
void QgsMapToolIdentify::convertMeasurement( QgsDistanceArea &calc, double &measure, QGis::UnitType &u, bool isArea )
|
||||
{
|
||||
// Helper for converting between meters and feet
|
||||
// Helper for converting between units
|
||||
// The parameter &u is out only...
|
||||
|
||||
// Get the canvas units
|
||||
@ -655,6 +656,19 @@ QGis::UnitType QgsMapToolIdentify::displayUnits()
|
||||
return mCanvas->mapUnits();
|
||||
}
|
||||
|
||||
QGis::UnitType QgsMapToolIdentify::displayDistanceUnits()
|
||||
{
|
||||
return mCanvas->mapUnits();
|
||||
}
|
||||
|
||||
QString QgsMapToolIdentify::formatDistance( double distance )
|
||||
{
|
||||
QSettings settings;
|
||||
bool baseUnit = settings.value( "/qgis/measure/keepbaseunit", false ).toBool();
|
||||
|
||||
return QgsDistanceArea::textUnit( distance, 3, displayDistanceUnits(), false, baseUnit );
|
||||
}
|
||||
|
||||
void QgsMapToolIdentify::formatChanged( QgsRasterLayer *layer )
|
||||
{
|
||||
QgsDebugMsg( "Entered" );
|
||||
|
@ -163,6 +163,16 @@ class GUI_EXPORT QgsMapToolIdentify : public QgsMapTool
|
||||
/** Transforms the measurements of derived attributes in the desired units*/
|
||||
virtual QGis::UnitType displayUnits();
|
||||
|
||||
/** Desired units for distance display.
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
virtual QGis::UnitType displayDistanceUnits();
|
||||
|
||||
/** Format a distance into a suitable string for display to the user
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
QString formatDistance( double distance );
|
||||
|
||||
QMap< QString, QString > featureDerivedAttributes( QgsFeature *feature, QgsMapLayer *layer, const QgsPoint& layerPoint = QgsPoint() );
|
||||
|
||||
/** Adds details of the closest vertex to derived attributes
|
||||
|
@ -471,13 +471,13 @@
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBox" name="btnGrpMeasureEllipsoid">
|
||||
<property name="title">
|
||||
<string>Measure tool</string>
|
||||
<string>Measurements</string>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">projgeneral</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayoutMeasureTool">
|
||||
<item row="1" column="0">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="textLabel1_8">
|
||||
<property name="text">
|
||||
<string>Ellipsoid
|
||||
@ -485,29 +485,39 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="1" column="4">
|
||||
<widget class="QLineEdit" name="leSemiMinor"/>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="mDistanceUnitsCombo"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="leSemiMajor"/>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="cmbEllipsoid"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_28">
|
||||
<property name="text">
|
||||
<string>Units for distance measurement</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_41">
|
||||
<property name="text">
|
||||
<string>Semi-major</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="leSemiMajor"/>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QLineEdit" name="leSemiMinor"/>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="label_42">
|
||||
<property name="text">
|
||||
<string>Semi-minor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="cmbEllipsoid"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -2528,6 +2538,7 @@
|
||||
<tabstop>cmbEllipsoid</tabstop>
|
||||
<tabstop>leSemiMajor</tabstop>
|
||||
<tabstop>leSemiMinor</tabstop>
|
||||
<tabstop>mDistanceUnitsCombo</tabstop>
|
||||
<tabstop>mCoordinateDisplayComboBox</tabstop>
|
||||
<tabstop>radAutomatic</tabstop>
|
||||
<tabstop>radManual</tabstop>
|
||||
|
@ -3,17 +3,23 @@
|
||||
# the UI file won't be wrapped!
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||
${CMAKE_SOURCE_DIR}/src/core/symbology-ng
|
||||
${CMAKE_BINARY_DIR}/src/ui
|
||||
${CMAKE_SOURCE_DIR}/src/gui
|
||||
${CMAKE_SOURCE_DIR}/src/python
|
||||
${CMAKE_SOURCE_DIR}/src/app
|
||||
${CMAKE_SOURCE_DIR}/src/app/pluginmanager
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/auth
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/composer
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/geometry
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/raster
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/symbology-ng
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../../../src/ui
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui/editorwidgets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui/editorwidgets/core
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui/attributetable
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui/symbology-ng
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui/raster
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/python
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/app
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/app/pluginmanager
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/ui
|
||||
)
|
||||
INCLUDE_DIRECTORIES(SYSTEM
|
||||
${QT_INCLUDE_DIR}
|
||||
@ -96,3 +102,6 @@ ENDMACRO (ADD_QGIS_TEST)
|
||||
# Tests:
|
||||
|
||||
ADD_QGIS_TEST(qgisappclipboard testqgisappclipboard.cpp)
|
||||
ADD_QGIS_TEST(attributetabletest testqgsattributetable.cpp)
|
||||
ADD_QGIS_TEST(fieldcalculatortest testqgsfieldcalculator.cpp)
|
||||
ADD_QGIS_TEST(maptoolidentifyaction testqgsmaptoolidentifyaction.cpp)
|
||||
|
119
tests/src/app/testqgsattributetable.cpp
Normal file
119
tests/src/app/testqgsattributetable.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/***************************************************************************
|
||||
testqgsattributetable.cpp
|
||||
-------------------------
|
||||
Date : 2016-02-14
|
||||
Copyright : (C) 2016 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include <QtTest/QtTest>
|
||||
#include "qgisapp.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsattributetabledialog.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsunittypes.h"
|
||||
|
||||
/** \ingroup UnitTests
|
||||
* This is a unit test for the attribute table dialog
|
||||
*/
|
||||
class TestQgsAttributeTable : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestQgsAttributeTable();
|
||||
|
||||
private slots:
|
||||
void initTestCase();// will be called before the first testfunction is executed.
|
||||
void cleanupTestCase();// will be called after the last testfunction was executed.
|
||||
void init() {} // will be called before each testfunction is executed.
|
||||
void cleanup() {} // will be called after every testfunction.
|
||||
void testFieldCalculation();
|
||||
|
||||
private:
|
||||
QgisApp * mQgisApp;
|
||||
};
|
||||
|
||||
TestQgsAttributeTable::TestQgsAttributeTable()
|
||||
: mQgisApp( nullptr )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//runs before all tests
|
||||
void TestQgsAttributeTable::initTestCase()
|
||||
{
|
||||
qDebug() << "TestQgisAppClipboard::initTestCase()";
|
||||
// init QGIS's paths - true means that all path will be inited from prefix
|
||||
QgsApplication::init();
|
||||
QgsApplication::initQgis();
|
||||
mQgisApp = new QgisApp();
|
||||
}
|
||||
|
||||
//runs after all tests
|
||||
void TestQgsAttributeTable::cleanupTestCase()
|
||||
{
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
|
||||
void TestQgsAttributeTable::testFieldCalculation()
|
||||
{
|
||||
//test field calculation
|
||||
|
||||
//create a temporary layer
|
||||
QScopedPointer< QgsVectorLayer> tempLayer( new QgsVectorLayer( "LineString?crs=epsg:3111&field=pk:int&field=col1:double", "vl", "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
f1.setAttribute( "pk", 1 );
|
||||
f1.setAttribute( "col1", 0.0 );
|
||||
QgsPolyline line3111;
|
||||
line3111 << QgsPoint( 2484588, 2425722 ) << QgsPoint( 2482767, 2398853 );
|
||||
f1.setGeometry( QgsGeometry::fromPolyline( line3111 ) );
|
||||
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );
|
||||
|
||||
// set project CRS and ellipsoid
|
||||
QgisApp::instance()->mapCanvas()->setCrsTransformEnabled( true );
|
||||
QgsCoordinateReferenceSystem srs( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSID", ( int ) srs.srsid() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCrs", srs.authid() );
|
||||
QgsProject::instance()->writeEntry( "Measure", "/Ellipsoid", QString( "WGS84" ) );
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Meters ) );
|
||||
|
||||
// run length calculation
|
||||
QScopedPointer< QgsAttributeTableDialog > dlg( new QgsAttributeTableDialog( tempLayer.data() ) );
|
||||
tempLayer->startEditing();
|
||||
dlg->runFieldCalculation( tempLayer.data(), "col1", "$length" );
|
||||
tempLayer->commitChanges();
|
||||
// check result
|
||||
QgsFeatureIterator fit = tempLayer->dataProvider()->getFeatures();
|
||||
QgsFeature f;
|
||||
QVERIFY( fit.nextFeature( f ) );
|
||||
double expected = 26932.156;
|
||||
QVERIFY( qgsDoubleNear( f.attribute( "col1" ).toDouble(), expected, 0.001 ) );
|
||||
|
||||
// change project length unit, check calculation respects unit
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Feet ) );
|
||||
QScopedPointer< QgsAttributeTableDialog > dlg2( new QgsAttributeTableDialog( tempLayer.data() ) );
|
||||
tempLayer->startEditing();
|
||||
dlg2->runFieldCalculation( tempLayer.data(), "col1", "$length" );
|
||||
tempLayer->commitChanges();
|
||||
// check result
|
||||
fit = tempLayer->dataProvider()->getFeatures();
|
||||
QVERIFY( fit.nextFeature( f ) );
|
||||
expected = 88360.0918635;
|
||||
QVERIFY( qgsDoubleNear( f.attribute( "col1" ).toDouble(), expected, 0.001 ) );
|
||||
}
|
||||
|
||||
QTEST_MAIN( TestQgsAttributeTable )
|
||||
#include "testqgsattributetable.moc"
|
130
tests/src/app/testqgsfieldcalculator.cpp
Normal file
130
tests/src/app/testqgsfieldcalculator.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
/***************************************************************************
|
||||
testqgsfieldcalculator.cpp
|
||||
--------------------------
|
||||
Date : 2016-02-14
|
||||
Copyright : (C) 2016 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include <QtTest/QtTest>
|
||||
#include "qgisapp.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsfieldcalculator.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsunittypes.h"
|
||||
|
||||
/** \ingroup UnitTests
|
||||
* This is a unit test for the field calculator
|
||||
*/
|
||||
class TestQgsFieldCalculator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestQgsFieldCalculator();
|
||||
|
||||
private slots:
|
||||
void initTestCase();// will be called before the first testfunction is executed.
|
||||
void cleanupTestCase();// will be called after the last testfunction was executed.
|
||||
void init() {} // will be called before each testfunction is executed.
|
||||
void cleanup() {} // will be called after every testfunction.
|
||||
void testLengthCalculations();
|
||||
|
||||
private:
|
||||
QgisApp * mQgisApp;
|
||||
};
|
||||
|
||||
TestQgsFieldCalculator::TestQgsFieldCalculator()
|
||||
: mQgisApp( nullptr )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//runs before all tests
|
||||
void TestQgsFieldCalculator::initTestCase()
|
||||
{
|
||||
qDebug() << "TestQgisAppClipboard::initTestCase()";
|
||||
// init QGIS's paths - true means that all path will be inited from prefix
|
||||
QgsApplication::init();
|
||||
QgsApplication::initQgis();
|
||||
mQgisApp = new QgisApp();
|
||||
}
|
||||
|
||||
//runs after all tests
|
||||
void TestQgsFieldCalculator::cleanupTestCase()
|
||||
{
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
|
||||
void TestQgsFieldCalculator::testLengthCalculations()
|
||||
{
|
||||
//test length calculation respects ellipsoid and project distance units
|
||||
|
||||
//create a temporary layer
|
||||
QScopedPointer< QgsVectorLayer> tempLayer( new QgsVectorLayer( "LineString?crs=epsg:3111&field=pk:int&field=col1:double", "vl", "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
f1.setAttribute( "pk", 1 );
|
||||
f1.setAttribute( "col1", 0.0 );
|
||||
QgsPolyline line3111;
|
||||
line3111 << QgsPoint( 2484588, 2425722 ) << QgsPoint( 2482767, 2398853 );
|
||||
f1.setGeometry( QgsGeometry::fromPolyline( line3111 ) );
|
||||
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );
|
||||
|
||||
// set project CRS and ellipsoid
|
||||
QgisApp::instance()->mapCanvas()->setCrsTransformEnabled( true );
|
||||
QgsCoordinateReferenceSystem srs( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSID", ( int ) srs.srsid() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCrs", srs.authid() );
|
||||
QgsProject::instance()->writeEntry( "Measure", "/Ellipsoid", QString( "WGS84" ) );
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Meters ) );
|
||||
|
||||
// run length calculation
|
||||
tempLayer->startEditing();
|
||||
QScopedPointer< QgsFieldCalculator > calc( new QgsFieldCalculator( tempLayer.data() ) );
|
||||
|
||||
// this next part is fragile, and may need to be modified if the dialog changes:
|
||||
calc->mUpdateExistingGroupBox->setChecked( true );
|
||||
calc->mExistingFieldComboBox->setCurrentIndex( 1 );
|
||||
calc->builder->setExpressionText( "$length" );
|
||||
calc->accept();
|
||||
|
||||
tempLayer->commitChanges();
|
||||
|
||||
// check result
|
||||
QgsFeatureIterator fit = tempLayer->dataProvider()->getFeatures();
|
||||
QgsFeature f;
|
||||
QVERIFY( fit.nextFeature( f ) );
|
||||
double expected = 26932.156;
|
||||
QVERIFY( qgsDoubleNear( f.attribute( "col1" ).toDouble(), expected, 0.001 ) );
|
||||
|
||||
// change project length unit, check calculation respects unit
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Feet ) );
|
||||
tempLayer->startEditing();
|
||||
QScopedPointer< QgsFieldCalculator > calc2( new QgsFieldCalculator( tempLayer.data() ) );
|
||||
calc2->mUpdateExistingGroupBox->setChecked( true );
|
||||
calc2->mExistingFieldComboBox->setCurrentIndex( 1 );
|
||||
calc2->builder->setExpressionText( "$length" );
|
||||
calc2->accept();
|
||||
tempLayer->commitChanges();
|
||||
// check result
|
||||
fit = tempLayer->dataProvider()->getFeatures();
|
||||
QVERIFY( fit.nextFeature( f ) );
|
||||
expected = 88360.0918635;
|
||||
QVERIFY( qgsDoubleNear( f.attribute( "col1" ).toDouble(), expected, 0.001 ) );
|
||||
|
||||
}
|
||||
|
||||
QTEST_MAIN( TestQgsFieldCalculator )
|
||||
#include "testqgsfieldcalculator.moc"
|
188
tests/src/app/testqgsmaptoolidentifyaction.cpp
Normal file
188
tests/src/app/testqgsmaptoolidentifyaction.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/***************************************************************************
|
||||
testqgsmaptoolidentifyaction.cpp
|
||||
--------------------------------
|
||||
Date : 2016-02-14
|
||||
Copyright : (C) 2016 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgsmaptoolidentifyaction.h"
|
||||
|
||||
class TestQgsMapToolIdentifyAction : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestQgsMapToolIdentifyAction()
|
||||
: canvas( 0 )
|
||||
{}
|
||||
|
||||
private slots:
|
||||
void initTestCase(); // will be called before the first testfunction is executed.
|
||||
void cleanupTestCase(); // will be called after the last testfunction was executed.
|
||||
void init(); // will be called before each testfunction is executed.
|
||||
void cleanup(); // will be called after every testfunction.
|
||||
void lengthCalculation(); //test calculation of derived length attributes
|
||||
void perimeterCalculation(); //test calculation of derived perimeter attribute
|
||||
|
||||
private:
|
||||
QgsMapCanvas* canvas;
|
||||
};
|
||||
|
||||
void TestQgsMapToolIdentifyAction::initTestCase()
|
||||
{
|
||||
QgsApplication::init();
|
||||
QgsApplication::initQgis();
|
||||
// Set up the QSettings environment
|
||||
QCoreApplication::setOrganizationName( "QGIS" );
|
||||
QCoreApplication::setOrganizationDomain( "qgis.org" );
|
||||
QCoreApplication::setApplicationName( "QGIS-TEST" );
|
||||
|
||||
QgsApplication::showSettings();
|
||||
}
|
||||
|
||||
void TestQgsMapToolIdentifyAction::cleanupTestCase()
|
||||
{
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
|
||||
void TestQgsMapToolIdentifyAction::init()
|
||||
{
|
||||
canvas = new QgsMapCanvas();
|
||||
}
|
||||
|
||||
void TestQgsMapToolIdentifyAction::cleanup()
|
||||
{
|
||||
delete canvas;
|
||||
}
|
||||
|
||||
void TestQgsMapToolIdentifyAction::lengthCalculation()
|
||||
{
|
||||
QSettings s;
|
||||
s.setValue( "/qgis/measure/keepbaseunit", true );
|
||||
|
||||
//create a temporary layer
|
||||
QScopedPointer< QgsVectorLayer> tempLayer( new QgsVectorLayer( "LineString?crs=epsg:3111&field=pk:int&field=col1:double", "vl", "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
f1.setAttribute( "pk", 1 );
|
||||
f1.setAttribute( "col1", 0.0 );
|
||||
QgsPolyline line3111;
|
||||
line3111 << QgsPoint( 2484588, 2425722 ) << QgsPoint( 2482767, 2398853 );
|
||||
f1.setGeometry( QgsGeometry::fromPolyline( line3111 ) );
|
||||
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );
|
||||
|
||||
// set project CRS and ellipsoid
|
||||
QgsCoordinateReferenceSystem srs( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
|
||||
canvas->setCrsTransformEnabled( true );
|
||||
canvas->setDestinationCrs( srs );
|
||||
canvas->setExtent( f1.geometry()->boundingBox() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSID", ( int ) srs.srsid() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCrs", srs.authid() );
|
||||
QgsProject::instance()->writeEntry( "Measure", "/Ellipsoid", QString( "WGS84" ) );
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Meters ) );
|
||||
|
||||
QgsPoint mapPoint = canvas->getCoordinateTransform()->transform( 2484588, 2425722 );
|
||||
|
||||
QScopedPointer< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );
|
||||
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << tempLayer.data() );
|
||||
QCOMPARE( result.length(), 1 );
|
||||
QString derivedLength = result.at( 0 ).mDerivedAttributes[tr( "Length" )];
|
||||
double length = derivedLength.remove( ',' ).split( ' ' ).at( 0 ).toDouble();
|
||||
QVERIFY( qgsDoubleNear( length, 26932.2, 0.1 ) );
|
||||
|
||||
//check that project units are respected
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Feet ) );
|
||||
result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << tempLayer.data() );
|
||||
QCOMPARE( result.length(), 1 );
|
||||
derivedLength = result.at( 0 ).mDerivedAttributes[tr( "Length" )];
|
||||
length = derivedLength.remove( ',' ).split( ' ' ).at( 0 ).toDouble();
|
||||
QVERIFY( qgsDoubleNear( length, 88360.1, 0.1 ) );
|
||||
|
||||
//test unchecked "keep base units" setting
|
||||
s.setValue( "/qgis/measure/keepbaseunit", false );
|
||||
result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << tempLayer.data() );
|
||||
QCOMPARE( result.length(), 1 );
|
||||
derivedLength = result.at( 0 ).mDerivedAttributes[tr( "Length" )];
|
||||
length = derivedLength.remove( ',' ).split( ' ' ).at( 0 ).toDouble();
|
||||
QVERIFY( qgsDoubleNear( length, 16.735, 0.001 ) );
|
||||
}
|
||||
|
||||
void TestQgsMapToolIdentifyAction::perimeterCalculation()
|
||||
{
|
||||
QSettings s;
|
||||
s.setValue( "/qgis/measure/keepbaseunit", true );
|
||||
|
||||
//create a temporary layer
|
||||
QScopedPointer< QgsVectorLayer> tempLayer( new QgsVectorLayer( "Polygon?crs=epsg:3111&field=pk:int&field=col1:double", "vl", "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
f1.setAttribute( "pk", 1 );
|
||||
f1.setAttribute( "col1", 0.0 );
|
||||
QgsPolyline polygonRing3111;
|
||||
polygonRing3111 << QgsPoint( 2484588, 2425722 ) << QgsPoint( 2482767, 2398853 ) << QgsPoint( 2520109, 2397715 ) << QgsPoint( 2520792, 2425494 ) << QgsPoint( 2484588, 2425722 );
|
||||
QgsPolygon polygon3111;
|
||||
polygon3111 << polygonRing3111;
|
||||
f1.setGeometry( QgsGeometry::fromPolygon( polygon3111 ) );
|
||||
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );
|
||||
|
||||
// set project CRS and ellipsoid
|
||||
QgsCoordinateReferenceSystem srs( 3111, QgsCoordinateReferenceSystem::EpsgCrsId );
|
||||
canvas->setCrsTransformEnabled( true );
|
||||
canvas->setDestinationCrs( srs );
|
||||
canvas->setExtent( f1.geometry()->boundingBox() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCRSID", ( int ) srs.srsid() );
|
||||
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectCrs", srs.authid() );
|
||||
QgsProject::instance()->writeEntry( "Measure", "/Ellipsoid", QString( "WGS84" ) );
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Meters ) );
|
||||
|
||||
QgsPoint mapPoint = canvas->getCoordinateTransform()->transform( 2484588, 2425722 );
|
||||
|
||||
QScopedPointer< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );
|
||||
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << tempLayer.data() );
|
||||
QCOMPARE( result.length(), 1 );
|
||||
QString derivedPerimeter = result.at( 0 ).mDerivedAttributes[tr( "Perimeter" )];
|
||||
double perimeter = derivedPerimeter.remove( ',' ).split( ' ' ).at( 0 ).toDouble();
|
||||
QCOMPARE( perimeter, 128289.074 );
|
||||
|
||||
//check that project units are respected
|
||||
QgsProject::instance()->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::Feet ) );
|
||||
result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << tempLayer.data() );
|
||||
QCOMPARE( result.length(), 1 );
|
||||
derivedPerimeter = result.at( 0 ).mDerivedAttributes[tr( "Perimeter" )];
|
||||
perimeter = derivedPerimeter.remove( ',' ).split( ' ' ).at( 0 ).toDouble();
|
||||
QVERIFY( qgsDoubleNear( perimeter, 420896.0, 0.1 ) );
|
||||
|
||||
//test unchecked "keep base units" setting
|
||||
s.setValue( "/qgis/measure/keepbaseunit", false );
|
||||
result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << tempLayer.data() );
|
||||
QCOMPARE( result.length(), 1 );
|
||||
derivedPerimeter = result.at( 0 ).mDerivedAttributes[tr( "Perimeter" )];
|
||||
perimeter = derivedPerimeter.remove( ',' ).split( ' ' ).at( 0 ).toDouble();
|
||||
QVERIFY( qgsDoubleNear( perimeter, 79.715, 0.001 ) );
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN( TestQgsMapToolIdentifyAction )
|
||||
#include "testqgsmaptoolidentifyaction.moc"
|
||||
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <qgsapplication.h>
|
||||
#include <qgsproject.h>
|
||||
#include "qgsunittypes.h"
|
||||
|
||||
|
||||
class TestQgsProject : public QObject
|
||||
@ -29,6 +30,7 @@ class TestQgsProject : public QObject
|
||||
void cleanup();// will be called after every testfunction.
|
||||
|
||||
void testReadPath();
|
||||
void testProjectUnits();
|
||||
};
|
||||
|
||||
void TestQgsProject::init()
|
||||
@ -43,6 +45,11 @@ void TestQgsProject::cleanup()
|
||||
void TestQgsProject::initTestCase()
|
||||
{
|
||||
// Runs once before any tests are run
|
||||
|
||||
// Set up the QSettings environment
|
||||
QCoreApplication::setOrganizationName( "QGIS" );
|
||||
QCoreApplication::setOrganizationDomain( "qgis.org" );
|
||||
QCoreApplication::setApplicationName( "QGIS-TEST" );
|
||||
}
|
||||
|
||||
|
||||
@ -76,6 +83,28 @@ void TestQgsProject::testReadPath()
|
||||
|
||||
}
|
||||
|
||||
void TestQgsProject::testProjectUnits()
|
||||
{
|
||||
//test setting and retrieving project units
|
||||
|
||||
//first set a default QGIS distance unit
|
||||
QSettings s;
|
||||
s.setValue( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::Feet ) );
|
||||
|
||||
QgsProject* prj = QgsProject::instance();
|
||||
// new project should inherit QGIS default distance unit
|
||||
prj->clear();
|
||||
QCOMPARE( prj->distanceUnits(), QGis::Feet );
|
||||
|
||||
//changing default QGIS unit should not affect existing project
|
||||
s.setValue( "/qgis/measure/displayunits", QgsUnitTypes::encodeUnit( QGis::NauticalMiles ) );
|
||||
QCOMPARE( prj->distanceUnits(), QGis::Feet );
|
||||
|
||||
//test setting new units for project
|
||||
prj->writeEntry( "Measurement", "/DistanceUnits", QgsUnitTypes::encodeUnit( QGis::NauticalMiles ) );
|
||||
QCOMPARE( prj->distanceUnits(), QGis::NauticalMiles );
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN( TestQgsProject )
|
||||
#include "testqgsproject.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user