Skip to content

Commit

Permalink
[FEATURE] Allow setting project CRS to "no projection"
Browse files Browse the repository at this point in the history
This replaces the older "OTF off" setting. If a project has
no projection set, then the following things happen:

- no reprojection is done while rendering - features are just
drawn using their raw coordinates
- ellipsoid, distance and area units, and coordinate display
are locked out.
- all measurements are done in unknown map units, and no conversion
is possible.

As well as addressing the use cases in which users disabled
OTF reprojection, this setting may also be useful for users
who use QGIS to create "non-earth" maps, such as RPG or fantasy
maps, or for microscopic analysis, or some other local reference
system not related to earth based projections.
  • Loading branch information
nyalldawson committed Mar 1, 2017
1 parent 3c7c65e commit 899888d
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 98 deletions.
17 changes: 13 additions & 4 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10268,11 +10268,20 @@ void QgisApp::removeWebToolBarIcon( QAction *qAction )

void QgisApp::updateCrsStatusBar()
{
mOnTheFlyProjectionStatusButton->setText( mMapCanvas->mapSettings().destinationCrs().authid() );
if ( QgsProject::instance()->crs().isValid() )
{
mOnTheFlyProjectionStatusButton->setText( QgsProject::instance()->crs().authid() );

mOnTheFlyProjectionStatusButton->setToolTip(
tr( "Current CRS: %1" ).arg( mMapCanvas->mapSettings().destinationCrs().description() ) );
mOnTheFlyProjectionStatusButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mIconProjectionEnabled.svg" ) ) );
mOnTheFlyProjectionStatusButton->setToolTip(
tr( "Current CRS: %1" ).arg( mMapCanvas->mapSettings().destinationCrs().description() ) );
mOnTheFlyProjectionStatusButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mIconProjectionEnabled.svg" ) ) );
}
else
{
mOnTheFlyProjectionStatusButton->setText( QString() );
mOnTheFlyProjectionStatusButton->setToolTip( tr( "No projection" ) );
mOnTheFlyProjectionStatusButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mIconProjectionDisabled.svg" ) ) );
}
}

void QgisApp::destinationCrsChanged()
Expand Down
65 changes: 58 additions & 7 deletions src/app/qgsmeasuredialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,20 @@ QgsMeasureDialog::QgsMeasureDialog( QgsMeasureTool* tool, Qt::WindowFlags f )
else
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QgsProject::instance()->distanceUnits() ) );

if ( !mTool->canvas()->mapSettings().destinationCrs().isValid() )
{
mUnitsCombo->setEnabled( false );
if ( mMeasureArea )
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QgsUnitTypes::DistanceUnknownUnit ) );
else
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QgsUnitTypes::AreaUnknownUnit ) );
}

updateSettings();

connect( mUnitsCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( unitsChanged( int ) ) );
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
connect( mTool->canvas(), &QgsMapCanvas::destinationCrsChanged, this, &QgsMeasureDialog::crsChanged );

groupBox->setCollapsed( true );
}
Expand All @@ -68,6 +78,23 @@ void QgsMeasureDialog::openConfigTab()
QgisApp::instance()->showOptionsDialog( this, QStringLiteral( "mOptionsPageMapTools" ) );
}

void QgsMeasureDialog::crsChanged()
{
if ( !mTool->canvas()->mapSettings().destinationCrs().isValid() )
{
mUnitsCombo->setEnabled( false );
if ( mMeasureArea )
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QgsUnitTypes::DistanceUnknownUnit ) );
else
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( QgsUnitTypes::AreaUnknownUnit ) );
}
else
{
mUnitsCombo->setEnabled( true );
}
updateUi();
}

void QgsMeasureDialog::updateSettings()
{
QSettings settings;
Expand Down Expand Up @@ -268,8 +295,16 @@ void QgsMeasureDialog::updateUi()

if ( mMeasureArea )
{
if ( mTool->canvas()->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
&& ( mAreaUnits == QgsUnitTypes::AreaSquareDegrees || mAreaUnits == QgsUnitTypes::AreaUnknownUnit ) )
if ( !mTool->canvas()->mapSettings().destinationCrs().isValid() )
{
// no CRS => no units, newb!
toolTip += "<br> * " + tr( "No map projection set, so area is calculated using cartesian calculations." );
toolTip += "<br> * " + tr( "Units are unknown." );
forceCartesian = true;
convertToDisplayUnits = false;
}
else if ( mTool->canvas()->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
&& ( mAreaUnits == QgsUnitTypes::AreaSquareDegrees || mAreaUnits == QgsUnitTypes::AreaUnknownUnit ) )
{
//both source and destination units are degrees
toolTip += "<br> * " + tr( "Both project CRS (%1) and measured area are in degrees, so area is calculated using cartesian calculations in square degrees." ).arg(
Expand All @@ -294,7 +329,7 @@ void QgsMeasureDialog::updateUi()
toolTip += tr( "Area is calculated in %1, based on project CRS (%2)." ).arg( QgsUnitTypes::toString( resultUnit ),
mTool->canvas()->mapSettings().destinationCrs().description() );
}
setWindowTitle( tr( "Measure (OTF on)" ) );
setWindowTitle( tr( "Measure" ) );

if ( QgsUnitTypes::unitType( resultUnit ) == QgsUnitTypes::Geographic &&
QgsUnitTypes::unitType( mAreaUnits ) == QgsUnitTypes::Standard )
Expand Down Expand Up @@ -330,8 +365,16 @@ void QgsMeasureDialog::updateUi()
}
else
{
if ( mTool->canvas()->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
&& mDistanceUnits == QgsUnitTypes::DistanceDegrees )
if ( !mTool->canvas()->mapSettings().destinationCrs().isValid() )
{
// no CRS => no units, newb!
toolTip += "<br> * " + tr( "No map projection set, so distance is calculated using cartesian calculations." );
toolTip += "<br> * " + tr( "Units are unknown." );
forceCartesian = true;
convertToDisplayUnits = false;
}
else if ( mTool->canvas()->mapSettings().destinationCrs().mapUnits() == QgsUnitTypes::DistanceDegrees
&& mDistanceUnits == QgsUnitTypes::DistanceDegrees )
{
//both source and destination units are degrees
toolTip += "<br> * " + tr( "Both project CRS (%1) and measured length are in degrees, so distance is calculated using cartesian calculations in degrees." ).arg(
Expand All @@ -356,7 +399,7 @@ void QgsMeasureDialog::updateUi()
toolTip += tr( "Distance is calculated in %1, based on project CRS (%2)." ).arg( QgsUnitTypes::toString( resultUnit ),
mTool->canvas()->mapSettings().destinationCrs().description() );
}
setWindowTitle( tr( "Measure (OTF on)" ) );
setWindowTitle( tr( "Measure" ) );

if ( QgsUnitTypes::unitType( resultUnit ) == QgsUnitTypes::Geographic &&
QgsUnitTypes::unitType( mDistanceUnits ) == QgsUnitTypes::Standard )
Expand Down Expand Up @@ -402,7 +445,14 @@ void QgsMeasureDialog::updateUi()
else
{
mUnitsCombo->setCurrentIndex( mUnitsCombo->findData( mDistanceUnits ) );
mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QgsUnitTypes::toString( mDistanceUnits ) ) ) );
if ( mDistanceUnits != QgsUnitTypes::DistanceUnknownUnit )
{
mTable->setHeaderLabels( QStringList( tr( "Segments [%1]" ).arg( QgsUnitTypes::toString( mDistanceUnits ) ) ) );
}
else
{
mTable->setHeaderLabels( QStringList( tr( "Segments" ) ) );
}
}

if ( mMeasureArea )
Expand Down Expand Up @@ -481,6 +531,7 @@ void QgsMeasureDialog::repopulateComboBoxUnits( bool isArea )
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceMiles ), QgsUnitTypes::DistanceMiles );
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceDegrees ), QgsUnitTypes::DistanceDegrees );
mUnitsCombo->addItem( QgsUnitTypes::toString( QgsUnitTypes::DistanceNauticalMiles ), QgsUnitTypes::DistanceNauticalMiles );
mUnitsCombo->addItem( tr( "map units" ), QgsUnitTypes::DistanceUnknownUnit );
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/app/qgsmeasuredialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class APP_EXPORT QgsMeasureDialog : public QDialog, private Ui::QgsMeasureBase
//! Open configuration tab
void openConfigTab();

void crsChanged();

private:

//! formats distance to most appropriate units
Expand Down
8 changes: 4 additions & 4 deletions src/app/qgsmeasuretool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ QgsMeasureTool::QgsMeasureTool( QgsMapCanvas* canvas, bool measureArea )
mDialog->setWindowFlags( mDialog->windowFlags() | Qt::Tool );
mDialog->restorePosition();

connect( canvas, SIGNAL( destinationCrsChanged() ),
this, SLOT( updateSettings() ) );
connect( canvas, &QgsMapCanvas::destinationCrsChanged, this, &QgsMeasureTool::updateSettings );
}

QgsMeasureTool::~QgsMeasureTool()
Expand All @@ -81,7 +80,8 @@ void QgsMeasureTool::activate()

// If we suspect that they have data that is projected, yet the
// map CRS is set to a geographic one, warn them.
if ( mCanvas->mapSettings().destinationCrs().isGeographic() &&
if ( mCanvas->mapSettings().destinationCrs().isValid() &&
mCanvas->mapSettings().destinationCrs().isGeographic() &&
( mCanvas->extent().height() > 360 ||
mCanvas->extent().width() > 720 ) )
{
Expand Down Expand Up @@ -129,7 +129,7 @@ void QgsMeasureTool::updateSettings()
mRubberBandPoints->setColor( QColor( myRed, myGreen, myBlue, 150 ) );

// Reproject the points to the new destination CoordinateReferenceSystem
if ( mRubberBand->size() > 0 && mDestinationCrs != mCanvas->mapSettings().destinationCrs() )
if ( mRubberBand->size() > 0 && mDestinationCrs != mCanvas->mapSettings().destinationCrs() && mCanvas->mapSettings().destinationCrs().isValid() )
{
QList<QgsPoint> points = mPoints;
bool lastDone = mDone;
Expand Down
Loading

0 comments on commit 899888d

Please sign in to comment.