31using namespace Qt::StringLiterals;
37 mEllipsoidDefinition.acronym =
"PARAMETER:6378000:6357000"_L1;
73 if ( !mEllipsoidDefinition.parameters.valid )
75 mEllipsoidDefinition.acronym =
"PARAMETER:6378000:6357000"_L1;
85 QgsDebugError( u
"Can't calculate scale from the input values"_s );
89 double conversionFactor = 0;
91 calculateMetrics( mapExtent, delta, conversionFactor );
93 const double scale = ( delta * conversionFactor ) / (
static_cast< double >( canvasWidth ) / mDpi );
94 QgsDebugMsgLevel( u
"scale = %1 conversionFactor = %2"_s.arg( scale ).arg( conversionFactor ), 4 );
102 QgsDebugError( u
"Can't calculate image size from the input values"_s );
105 double conversionFactor = 0;
108 calculateMetrics( mapExtent, delta, conversionFactor );
109 const double imageWidth = ( delta * conversionFactor ) / (
static_cast< double >( scale ) ) * mDpi;
111 const double imageHeight = ( deltaHeight * conversionFactor ) / (
static_cast< double >( scale ) ) * mDpi;
113 QgsDebugMsgLevel( u
"imageWidth = %1 imageHeight = %2 conversionFactor = %3"_s.arg( imageWidth ).arg( imageHeight ).arg( conversionFactor ), 4 );
115 return QSizeF( imageWidth, imageHeight );
118void QgsScaleCalculator::calculateMetrics(
const QgsRectangle &mapExtent,
double &delta,
double &conversionFactor )
const
125 conversionFactor = 1;
185 conversionFactor = 39.3700787;
209 return ( dTop + dMiddle + dBottom ) / 3.0;
242 const double semiMajor = mEllipsoidDefinition.parameters.semiMajor;
243 const double semiMinor = mEllipsoidDefinition.parameters.semiMinor;
246 static const double RADS = ( 4.0 * std::atan( 1.0 ) ) / 180.0;
247 const double a = std::pow( std::cos( lat * RADS ), 2 );
248 const double c = 2.0 * std::atan2( std::sqrt( a ), std::sqrt( 1.0 - a ) );
250 const double E = std::sqrt( ( semiMajor * semiMajor - semiMinor * semiMinor ) / ( semiMajor * semiMajor ) );
251 const double radius = semiMajor * ( 1.0 - E * E ) / std::pow( 1.0 - E * E * std::sin( lat * RADS ) * std::sin( lat * RADS ), 1.5 );
252 const double meters = ( longitude2 - longitude1 ) / 180.0 * radius *
c;
254 QgsDebugMsgLevel(
"Distance across map extent (m): " + QString::number( meters ), 4 );
DistanceUnit
Units of distance.
@ YardsBritishSears1922Truncated
British yards (Sears 1922 truncated).
@ MilesUSSurvey
US Survey miles.
@ LinksBritishSears1922
British links (Sears 1922).
@ YardsBritishBenoit1895A
British yards (Benoit 1895 A).
@ LinksBritishBenoit1895A
British links (Benoit 1895 A).
@ Centimeters
Centimeters.
@ YardsIndian1975
Indian yards (1975).
@ FeetUSSurvey
US Survey feet.
@ Millimeters
Millimeters.
@ FeetBritishSears1922
British feet (Sears 1922).
@ YardsClarkes
Clarke's yards.
@ YardsIndian
Indian yards.
@ FeetBritishBenoit1895B
British feet (Benoit 1895 B).
@ Miles
Terrestrial miles.
@ LinksUSSurvey
US Survey links.
@ ChainsUSSurvey
US Survey chains.
@ FeetClarkes
Clarke's feet.
@ Unknown
Unknown distance unit.
@ FeetBritish1936
British feet (1936).
@ FeetIndian1962
Indian feet (1962).
@ YardsBritishSears1922
British yards (Sears 1922).
@ FeetIndian1937
Indian feet (1937).
@ YardsIndian1937
Indian yards (1937).
@ Degrees
Degrees, for planar geographic CRS distance measurements.
@ ChainsBritishBenoit1895B
British chains (Benoit 1895 B).
@ LinksBritishSears1922Truncated
British links (Sears 1922 truncated).
@ ChainsBritishBenoit1895A
British chains (Benoit 1895 A).
@ YardsBritishBenoit1895B
British yards (Benoit 1895 B).
@ FeetBritish1865
British feet (1865).
@ YardsIndian1962
Indian yards (1962).
@ FeetBritishSears1922Truncated
British feet (Sears 1922 truncated).
@ MetersGermanLegal
German legal meter.
@ LinksBritishBenoit1895B
British links (Benoit 1895 B).
@ ChainsInternational
International chains.
@ LinksInternational
International links.
@ ChainsBritishSears1922Truncated
British chains (Sears 1922 truncated).
@ FeetIndian
Indian (geodetic) feet.
@ NauticalMiles
Nautical miles.
@ ChainsClarkes
Clarke's chains.
@ LinksClarkes
Clarke's links.
@ ChainsBritishSears1922
British chains (Sears 1922).
@ FeetIndian1975
Indian feet (1975).
@ FeetGoldCoast
Gold Coast feet.
@ FeetBritishBenoit1895A
British feet (Benoit 1895 A).
ScaleCalculationMethod
Scale calculation logic.
@ HorizontalTop
Calculate horizontally, across top of map.
@ HorizontalMiddle
Calculate horizontally, across midle of map.
@ AtEquator
Always calculate the scale at the equator, regardless of the actual visible map extent....
@ HorizontalAverage
Calculate horizontally, using the average of the top, middle and bottom scales.
@ HorizontalBottom
Calculate horizontally, across bottom of map.
static EllipsoidParameters ellipsoidParameters(const QString &ellipsoid)
Returns the parameters for the specified ellipsoid.
A rectangle specified with double values.
double calculate(const QgsRectangle &mapExtent, double canvasWidth) const
Calculate the scale denominator.
void setDpi(double dpi)
Sets the dpi (dots per inch) for the output resolution, to be used in scale calculations.
QString ellipsoid() const
Returns ellipsoid's acronym.
void setMapUnits(Qgis::DistanceUnit mapUnits)
Set the map units.
double calculateGeographicDistance(const QgsRectangle &mapExtent) const
Calculate the distance in meters, horizontally across the specified map extent (in geographic coordin...
void setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
QSizeF calculateImageSize(const QgsRectangle &mapExtent, double scale) const
Calculate the image size in pixel (physical) units.
Qgis::ScaleCalculationMethod method() const
Returns the method to use for map scale calculations.
double dpi() const
Returns the DPI (dots per inch) used in scale calculations.
Qgis::DistanceUnit mapUnits() const
Returns current map units.
void setMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for map scale calculations.
QgsScaleCalculator(double dpi=0, Qgis::DistanceUnit mapUnits=Qgis::DistanceUnit::Meters)
Constructor.
double calculateGeographicDistanceAtLatitude(double latitude, double longitude1, double longitude2) const
Calculate the distance in meters, horizontally between two longitudes at a specified latitude.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)