QGIS API Documentation  3.6.0-Noosa (5873452)
qgsquickutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsquickutils.cpp
3  --------------------------------------
4  Date : Nov 2017
5  Copyright : (C) 2017 by Peter Petrik
6  Email : zilolv at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include <QApplication>
17 #include <QDesktopWidget>
18 #include <QString>
19 
20 #include "qgis.h"
22 #include "qgscoordinatetransform.h"
23 #include "qgsdistancearea.h"
24 #include "qgslogger.h"
25 #include "qgsvectorlayer.h"
26 #include "qgsfeature.h"
27 #include "qgsapplication.h"
28 
30 #include "qgsquickmapsettings.h"
31 #include "qgsquickutils.h"
32 #include "qgsunittypes.h"
33 
34 
35 QgsQuickUtils::QgsQuickUtils( QObject *parent )
36  : QObject( parent )
37  , mScreenDensity( calculateScreenDensity() )
38 {
39 }
40 
45 {
47 }
48 
49 QgsPointXY QgsQuickUtils::pointXY( double x, double y )
50 {
51  return QgsPointXY( x, y );
52 }
53 
54 QgsPoint QgsQuickUtils::point( double x, double y, double z, double m )
55 {
56  return QgsPoint( x, y, z, m );
57 }
58 
59 QgsPoint QgsQuickUtils::coordinateToPoint( const QGeoCoordinate &coor )
60 {
61  return QgsPoint( coor.longitude(), coor.latitude(), coor.altitude() );
62 }
63 
65  const QgsCoordinateReferenceSystem &destCrs,
66  const QgsCoordinateTransformContext &context,
67  const QgsPointXY &srcPoint )
68 {
69  QgsCoordinateTransform mTransform( srcCrs, destCrs, context );
70  QgsPointXY pt = mTransform.transform( srcPoint );
71  return pt;
72 }
73 
74 double QgsQuickUtils::screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels )
75 {
76  if ( mapSettings == nullptr ) return 0.0;
77 
78  QgsDistanceArea mDistanceArea;
79  mDistanceArea.setEllipsoid( QStringLiteral( "WGS84" ) );
80  mDistanceArea.setSourceCrs( mapSettings->destinationCrs(), mapSettings->transformContext() );
81 
82  // calculate the geographic distance from the central point of extent
83  // to the specified number of points on the right side
84  QSize s = mapSettings->outputSize();
85  QPoint pointCenter( s.width() / 2, s.height() / 2 );
86  QgsPointXY p1 = mapSettings->screenToCoordinate( pointCenter );
87  QgsPointXY p2 = mapSettings->screenToCoordinate( pointCenter + QPoint( baseLengthPixels, 0 ) );
88  return mDistanceArea.measureLine( p1, p2 );
89 }
90 
91 bool QgsQuickUtils::fileExists( const QString &path )
92 {
93  QFileInfo check_file( path );
94  // check if file exists and if yes: Is it really a file and no directory?
95  return ( check_file.exists() && check_file.isFile() );
96 }
97 
98 QString QgsQuickUtils::getFileName( const QString &path )
99 {
100  QFileInfo fileInfo( path );
101  QString filename( fileInfo.fileName() );
102  return filename;
103 }
104 
105 void QgsQuickUtils::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
106 {
107  QgsMessageLog::logMessage( message, tag, level );
108 }
109 
111 {
112  return QgsQuickFeatureLayerPair( feature, layer );
113 }
114 
115 const QUrl QgsQuickUtils::getThemeIcon( const QString &name )
116 {
117  QString path = QStringLiteral( "qrc:/%1.svg" ).arg( name );
118  QgsDebugMsg( QStringLiteral( "Using icon %1 from %2" ).arg( name, path ) );
119  return QUrl( path );
120 }
121 
122 const QUrl QgsQuickUtils::getEditorComponentSource( const QString &widgetName )
123 {
124  QString path( "qgsquick%1.qml" );
125  QStringList supportedWidgets = { QStringLiteral( "textedit" ),
126  QStringLiteral( "valuemap" ),
127  QStringLiteral( "checkbox" ),
128  QStringLiteral( "externalresource" ),
129  QStringLiteral( "datetime" )
130  };
131  if ( supportedWidgets.contains( widgetName ) )
132  {
133  return QUrl( path.arg( widgetName ) );
134  }
135  else
136  {
137  return QUrl( path.arg( QStringLiteral( "textedit" ) ) );
138  }
139 }
140 
142  const QgsPoint &point,
144  int decimals,
145  QgsCoordinateFormatter::FormatFlags flags )
146 {
147  return QgsCoordinateFormatter::format( point, format, decimals, flags );
148 }
149 
150 QString QgsQuickUtils::formatDistance( double distance,
152  int decimals,
154 {
155  double destDistance;
156  QgsUnitTypes::DistanceUnit destUnits;
157 
158  humanReadableDistance( distance, units, destSystem, destDistance, destUnits );
159 
160  return QStringLiteral( "%1 %2" )
161  .arg( QString::number( destDistance, 'f', decimals ) )
162  .arg( QgsUnitTypes::toAbbreviatedString( destUnits ) );
163 }
164 
165 
168  double &destDistance, QgsUnitTypes::DistanceUnit &destUnits )
169 {
170  if ( ( destSystem == QgsUnitTypes::MetricSystem ) || ( destSystem == QgsUnitTypes::UnknownSystem ) )
171  {
172  return formatToMetricDistance( srcDistance, srcUnits, destDistance, destUnits );
173  }
174  else if ( destSystem == QgsUnitTypes::ImperialSystem )
175  {
176  return formatToImperialDistance( srcDistance, srcUnits, destDistance, destUnits );
177  }
178  else if ( destSystem == QgsUnitTypes::USCSSystem )
179  {
180  return formatToUSCSDistance( srcDistance, srcUnits, destDistance, destUnits );
181  }
182  else
183  {
184  Q_ASSERT( false ); //should never happen
185  }
186 }
187 
188 void QgsQuickUtils::formatToMetricDistance( double srcDistance,
190  double &destDistance,
191  QgsUnitTypes::DistanceUnit &destUnits )
192 {
193  double dist = srcDistance * QgsUnitTypes::fromUnitToUnitFactor( srcUnits, QgsUnitTypes::DistanceMillimeters );
194  if ( dist < 0 )
195  {
196  destDistance = 0;
198  return;
199  }
200 
202  if ( dist > mmToKm )
203  {
204  destDistance = dist / mmToKm;
206  return;
207  }
208 
210  if ( dist > mmToM )
211  {
212  destDistance = dist / mmToM;
213  destUnits = QgsUnitTypes::DistanceMeters;
214  return;
215  }
216 
218  if ( dist > mmToCm )
219  {
220  destDistance = dist / mmToCm;
222  return;
223  }
224 
225  destDistance = dist;
227 }
228 
229 void QgsQuickUtils::formatToImperialDistance( double srcDistance,
231  double &destDistance,
232  QgsUnitTypes::DistanceUnit &destUnits )
233 {
234  double dist = srcDistance * QgsUnitTypes::fromUnitToUnitFactor( srcUnits, QgsUnitTypes::DistanceFeet );
235  if ( dist < 0 )
236  {
237  destDistance = 0;
238  destUnits = QgsUnitTypes::DistanceFeet;
239  return;
240  }
241 
243  if ( dist > feetToMile )
244  {
245  destDistance = dist / feetToMile;
246  destUnits = QgsUnitTypes::DistanceMiles;
247  return;
248  }
249 
251  if ( dist > feetToYard )
252  {
253  destDistance = dist / feetToYard;
254  destUnits = QgsUnitTypes::DistanceYards;
255  return;
256  }
257 
258  destDistance = dist;
259  destUnits = QgsUnitTypes::DistanceFeet;
260  return;
261 }
262 
263 void QgsQuickUtils::formatToUSCSDistance( double srcDistance,
265  double &destDistance,
266  QgsUnitTypes::DistanceUnit &destUnits )
267 {
268  double dist = srcDistance * QgsUnitTypes::fromUnitToUnitFactor( srcUnits, QgsUnitTypes::DistanceFeet );
269  if ( dist < 0 )
270  {
271  destDistance = 0;
272  destUnits = QgsUnitTypes::DistanceFeet;
273  return;
274  }
275 
277  if ( dist > feetToMile )
278  {
279  destDistance = dist / feetToMile;
281  return;
282  }
283 
285  if ( dist > feetToYard )
286  {
287  destDistance = dist / feetToYard;
288  destUnits = QgsUnitTypes::DistanceYards;
289  return;
290  }
291 
292  destDistance = dist;
293  destUnits = QgsUnitTypes::DistanceFeet;
294  return;
295 }
296 
298 {
299  QRect rec = QApplication::desktop()->screenGeometry();
300  int dpiX = QApplication::desktop()->physicalDpiX();
301  int dpiY = QApplication::desktop()->physicalDpiY();
302  int height = rec.height();
303  int width = rec.width();
304  double sizeX = static_cast<double>( width ) / dpiX * 25.4;
305  double sizeY = static_cast<double>( height ) / dpiY * 25.4;
306 
307  QString msg;
308  msg += tr( "screen resolution: %1x%2 px\n" ).arg( width ).arg( height );
309  msg += tr( "screen DPI: %1x%2\n" ).arg( dpiX ).arg( dpiY );
310  msg += tr( "screen size: %1x%2 mm\n" ).arg( QString::number( sizeX, 'f', 0 ), QString::number( sizeY, 'f', 0 ) );
311  msg += tr( "screen density: %1" ).arg( mScreenDensity );
312  return msg;
313 }
314 
316 {
317  return mScreenDensity;
318 }
319 
320 qreal QgsQuickUtils::calculateScreenDensity()
321 {
322  // calculate screen density for calculation of real pixel sizes from density-independent pixels
323  int dpiX = QApplication::desktop()->physicalDpiX();
324  int dpiY = QApplication::desktop()->physicalDpiY();
325  int dpi = dpiX < dpiY ? dpiX : dpiY; // In case of asymmetrical DPI. Improbable
326  return dpi / 160.; // 160 DPI is baseline for density-independent pixels in Android
327 }
static Q_INVOKABLE const QUrl getEditorComponentSource(const QString &widgetName)
Returns url to field editor component for a feature form.
static Q_INVOKABLE QgsPoint coordinateToPoint(const QGeoCoordinate &coor)
Converts QGeoCoordinate to QgsPoint.
SystemOfMeasurement
Systems of unit measurement.
Definition: qgsunittypes.h:44
static Q_INVOKABLE QgsCoordinateReferenceSystem coordinateReferenceSystemFromEpsgId(long epsg)
Creates crs from epsg code in QML.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
A class to represent a 2D point.
Definition: qgspointxy.h:43
static Q_INVOKABLE QgsPoint point(double x, double y, double z=std::numeric_limits< double >::quiet_NaN(), double m=std::numeric_limits< double >::quiet_NaN())
Creates QgsPoint in QML.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition: qgis.h:66
The QgsQuickMapSettings class encapsulates QgsMapSettings class to offer settings of configuration of...
static Q_INVOKABLE double screenUnitsToMeters(QgsQuickMapSettings *mapSettings, int baseLengthPixels)
Calculates the distance in meter representing baseLengthPixels pixels on the screen based on the curr...
Format
Available formats for displaying coordinates.
British Imperial.
Definition: qgsunittypes.h:48
qreal screenDensity() const
"dp" is useful for building building components that work well with different screen densities...
static Q_INVOKABLE QgsPointXY transformPoint(const QgsCoordinateReferenceSystem &srcCrs, const QgsCoordinateReferenceSystem &destCrs, const QgsCoordinateTransformContext &context, const QgsPointXY &srcPoint)
Transforms point between different crs from QML.
static Q_INVOKABLE QgsCoordinateReferenceSystem fromEpsgId(long epsg)
Creates a CRS from a given EPSG ID.
Q_INVOKABLE QgsPoint screenToCoordinate(const QPointF &point) const
Convert a screen coordinate to a map coordinate.
static Q_INVOKABLE QString toAbbreviatedString(QgsUnitTypes::DistanceUnit unit)
Returns a translated abbreviation representing a distance unit.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Unknown system of measurement.
Definition: qgsunittypes.h:46
static void humanReadableDistance(double srcDistance, QgsUnitTypes::DistanceUnit srcUnits, QgsUnitTypes::SystemOfMeasurement destSystem, double &destDistance, QgsUnitTypes::DistanceUnit &destUnits)
Converts distance to human readable distance in destination system of measurement.
static Q_INVOKABLE QString getFileName(const QString &path)
Extracts filename from path.
International System of Units (SI)
Definition: qgsunittypes.h:47
Contains information about the context in which a coordinate transform is executed.
static Q_INVOKABLE const QUrl getThemeIcon(const QString &name)
Returns QUrl to image from library&#39;s /images folder.
QgsQuickUtils(QObject *parent=nullptr)
Create new utilities.
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
United States customary system.
Definition: qgsunittypes.h:49
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:54
QgsCoordinateReferenceSystem destinationCrs
CRS of destination coordinate reference system.
QSize outputSize
The size of the resulting map image.
A general purpose distance and area calculator, capable of performing ellipsoid based calculations...
This class represents a coordinate reference system (CRS).
Class for doing transforms between two map coordinate systems.
QString dumpScreenInfo() const
Returns a string with information about screen size and resolution - useful for debugging.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
static Q_INVOKABLE QString formatDistance(double distance, QgsUnitTypes::DistanceUnit units, int decimals, QgsUnitTypes::SystemOfMeasurement destSystem=QgsUnitTypes::MetricSystem)
Converts distance to human readable distance.
static Q_INVOKABLE QgsQuickFeatureLayerPair featureFactory(const QgsFeature &feature, QgsVectorLayer *layer=nullptr)
QgsQuickFeatureLayerPair factory for tuple of QgsFeature and QgsVectorLayer used in QgsQUick library...
Pair of QgsFeature and QgsVectorLayer.
static Q_INVOKABLE QgsPointXY pointXY(double x, double y)
Creates QgsPointXY in QML.
Terrestrial miles.
Definition: qgsunittypes.h:61
static Q_INVOKABLE QString formatPoint(const QgsPoint &point, QgsCoordinateFormatter::Format format=QgsCoordinateFormatter::FormatPair, int decimals=3, QgsCoordinateFormatter::FormatFlags flags=QgsCoordinateFormatter::FlagDegreesUseStringSuffix)
Formats a point according to the specified parameters.
static Q_INVOKABLE double fromUnitToUnitFactor(QgsUnitTypes::DistanceUnit fromUnit, QgsUnitTypes::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
static Q_INVOKABLE bool fileExists(const QString &path)
Returns whether file on path exists.
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
static Q_INVOKABLE void logMessage(const QString &message, const QString &tag=QString("QgsQuick"), Qgis::MessageLevel level=Qgis::Warning)
Log message in QgsMessageLog.
static QString format(const QgsPointXY &point, Format format, int precision=12, FormatFlags flags=FlagDegreesUseStringSuffix)
Formats a point according to the specified parameters.