QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgscoordinateutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscoordinateutils.cpp
3  ----------------------
4  begin : February 2016
5  copyright : (C) 2016 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgscoordinateutils.h"
19 #include "qgsproject.h"
20 #include "qgis.h"
21 
23 
24 int QgsCoordinateUtils::calculateCoordinatePrecision( double mapUnitsPerPixel, const QgsCoordinateReferenceSystem& mapCrs )
25 {
26  // Get the display precision from the project settings
27  bool automatic = QgsProject::instance()->readBoolEntry( "PositionPrecision", "/Automatic" );
28  int dp = 0;
29 
30  if ( automatic )
31  {
32  QString format = QgsProject::instance()->readEntry( "PositionPrecision", "/DegreeFormat", "MU" );
33  bool formatGeographic = ( format == "DM" || format == "DMS" || format == "D" );
34 
35  // we can only calculate an automatic precision if one of these is true:
36  // - both map CRS and format are geographic
37  // - both map CRS and format are not geographic
38  // - map CRS is geographic but format is not geographic (i.e. map units)
39  if ( mapCrs.geographicFlag() || !formatGeographic )
40  {
41  // Work out a suitable number of decimal places for the coordinates with the aim of always
42  // having enough decimal places to show the difference in position between adjacent pixels.
43  // Also avoid taking the log of 0.
44  if ( !qgsDoubleNear( mapUnitsPerPixel, 0.0 ) )
45  dp = static_cast<int>( ceil( -1.0 * log10( mapUnitsPerPixel ) ) );
46  }
47  else
48  {
49  dp = format == "D" ? 4 : 2; //guess sensible fallback
50  }
51  }
52  else
53  dp = QgsProject::instance()->readNumEntry( "PositionPrecision", "/DecimalPlaces" );
54 
55  // Keep dp sensible
56  if ( dp < 0 )
57  dp = 0;
58 
59  return dp;
60 }
61 
62 QString QgsCoordinateUtils::formatCoordinateForProject( const QgsPoint& point, const QgsCoordinateReferenceSystem& destCrs, int precision )
63 {
64  QString format = QgsProject::instance()->readEntry( "PositionPrecision", "/DegreeFormat", "MU" );
65 
66  QgsPoint geo = point;
67  if ( format == "DM" || format == "DMS" || format == "D" )
68  {
69  // degrees
70  if ( destCrs.isValid() && !destCrs.geographicFlag() )
71  {
72  // need to transform to geographic coordinates
74  try
75  {
76  geo = ct.transform( point );
77  }
78  catch ( QgsCsException& )
79  {
80  return QString();
81  }
82  }
83 
84  if ( format == "DM" )
85  return geo.toDegreesMinutes( precision, true, true );
86  else if ( format == "DMS" )
87  return geo.toDegreesMinutesSeconds( precision, true, true );
88  else
89  return geo.toString( precision );
90  }
91  else
92  {
93  // coordinates in map units
94  return point.toString( precision );
95  }
96 }
97 
QString readEntry(const QString &scope, const QString &key, const QString &def=QString::null, bool *ok=nullptr) const
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
QString toDegreesMinutes(int thePrecision, const bool useSuffix=true, const bool padded=false) const
Return a string representation as degrees minutes.
Definition: qgspoint.cpp:264
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:353
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
QString toDegreesMinutesSeconds(int thePrecision, const bool useSuffix=true, const bool padded=false) const
Return a string representation as degrees minutes seconds.
Definition: qgspoint.cpp:150
A class to represent a point.
Definition: qgspoint.h:117
QString toString() const
String representation of the point (x,y)
Definition: qgspoint.cpp:134
const long GEOSRID
Magic number for a geographic coord sys in POSTGIS SRID.
Definition: qgis.h:459
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:382
Class for storing a coordinate reference system (CRS)
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
bool geographicFlag() const
Returns whether the CRS is a geographic CRS.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.