QGIS/src/core/qgscoordinateutils.cpp
Nyall Dawson 86d9492372 Remove context-unaware QgsCoordinateTransform constructors from Python bindings
This forces Python code and plugins to become datum transform
aware, and given that upgrading python code is easy (just
add QgsProject.instance() as a new argument to the constructor)
it's relatively painless to force this on PyQGIS users.

Also fix upgrade the easy QgsCoordinateTransform c++ constructors
where the project is available, or where using QgsProject::instance()
is safe to do.

For others, just avoid the deprecated warnings until we can
get access to the correct project instance where the transform
is being constructed.
2017-12-15 14:13:22 +10:00

104 lines
4.4 KiB
C++

/***************************************************************************
qgscoordinateutils.cpp
----------------------
begin : February 2016
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 "qgscoordinateutils.h"
#include "qgscoordinatereferencesystem.h"
#include "qgscoordinatetransform.h"
#include "qgsproject.h"
#include "qgis.h"
#include "qgsexception.h"
#include "qgscoordinateformatter.h"
///@cond NOT_STABLE_API
int QgsCoordinateUtils::calculateCoordinatePrecision( double mapUnitsPerPixel, const QgsCoordinateReferenceSystem &mapCrs )
{
// Get the display precision from the project settings
bool automatic = QgsProject::instance()->readBoolEntry( QStringLiteral( "PositionPrecision" ), QStringLiteral( "/Automatic" ) );
int dp = 0;
if ( automatic )
{
QString format = QgsProject::instance()->readEntry( QStringLiteral( "PositionPrecision" ), QStringLiteral( "/DegreeFormat" ), QStringLiteral( "MU" ) );
bool formatGeographic = ( format == QLatin1String( "DM" ) || format == QLatin1String( "DMS" ) || format == QLatin1String( "D" ) );
// we can only calculate an automatic precision if one of these is true:
// - both map CRS and format are geographic
// - both map CRS and format are not geographic
// - map CRS is geographic but format is not geographic (i.e. map units)
if ( mapCrs.isGeographic() || !formatGeographic )
{
// Work out a suitable number of decimal places for the coordinates with the aim of always
// having enough decimal places to show the difference in position between adjacent pixels.
// Also avoid taking the log of 0.
if ( !qgsDoubleNear( mapUnitsPerPixel, 0.0 ) )
dp = static_cast<int>( std::ceil( -1.0 * std::log10( mapUnitsPerPixel ) ) );
}
else
{
dp = format == QLatin1String( "D" ) ? 4 : 2; //guess sensible fallback
}
}
else
dp = QgsProject::instance()->readNumEntry( QStringLiteral( "PositionPrecision" ), QStringLiteral( "/DecimalPlaces" ) );
// Keep dp sensible
if ( dp < 0 )
dp = 0;
return dp;
}
QString QgsCoordinateUtils::formatCoordinateForProject( const QgsPointXY &point, const QgsCoordinateReferenceSystem &destCrs, int precision )
{
QString format = QgsProject::instance()->readEntry( QStringLiteral( "PositionPrecision" ), QStringLiteral( "/DegreeFormat" ), QStringLiteral( "MU" ) );
QgsPointXY geo = point;
if ( format == QLatin1String( "DM" ) || format == QLatin1String( "DMS" ) || format == QLatin1String( "D" ) )
{
// degrees
if ( destCrs.isValid() && !destCrs.isGeographic() )
{
// need to transform to geographic coordinates
Q_NOWARN_DEPRECATED_PUSH
QgsCoordinateTransform ct( destCrs, QgsCoordinateReferenceSystem( GEOSRID ) );
Q_NOWARN_DEPRECATED_POP
try
{
geo = ct.transform( point );
}
catch ( QgsCsException & )
{
return QString();
}
}
if ( format == QLatin1String( "DM" ) )
return QgsCoordinateFormatter::format( geo, QgsCoordinateFormatter::FormatDegreesMinutes, precision, QgsCoordinateFormatter::FlagDegreesPadMinutesSeconds | QgsCoordinateFormatter::FlagDegreesUseStringSuffix );
else if ( format == QLatin1String( "DMS" ) )
return QgsCoordinateFormatter::format( geo, QgsCoordinateFormatter::FormatDegreesMinutesSeconds, precision, QgsCoordinateFormatter::FlagDegreesPadMinutesSeconds | QgsCoordinateFormatter::FlagDegreesUseStringSuffix );
else
return QgsCoordinateFormatter::asPair( geo.x(), geo.y(), precision );
}
else
{
// coordinates in map units
return QgsCoordinateFormatter::asPair( point.x(), point.y(), precision );
}
}
///@endcond