mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-04 00:04:03 -04:00
[Feature] Add ScaleBar and MessageLog components to QgsQuick library.
This commit is contained in:
parent
8d5e5c944d
commit
0cd9e19abc
@ -13,6 +13,15 @@ QGIS Quick consists of a Qt plugin that provides the QML components and of a sha
|
||||
|
||||
\subsection qgsquick_overview_widgets QML Classes
|
||||
\subsubsection qgsquick_overview_widgets_mapcanvas MapCanvas
|
||||
Similarly to QgsMapCanvas, this component can be used for displaying GIS data on a canvas. See also QgsQuickMapCanvasMap.
|
||||
\subsubsection qgsquick_overview_widgets_scalebar ScaleBar
|
||||
A QML component that shows the scale ratio between its length and distance on the MapCanvas. There are predefined rounded values
|
||||
for several zooming levels with 'm' or 'km' postfixes. After any zoom in/out event on canvas recalculates its properties and updates
|
||||
text. See also QgsQuickScaleBarKit.
|
||||
|
||||
\subsubsection qgsquick_overview_widgets_messagelog MessageLog
|
||||
A simple panel which can be used for publishing logs messages to a user such as basic information about the application or its status.
|
||||
See also QgsQuickMessageLogModel.
|
||||
|
||||
\section qgsquick_styling Styling
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
SET(QGIS_QUICK_GUI_MOC_HDRS
|
||||
qgsquickmapcanvasmap.h
|
||||
qgsquickmapsettings.h
|
||||
qgsquickmessagelogmodel.h
|
||||
qgsquickscalebarkit.h
|
||||
qgsquickutils.h
|
||||
)
|
||||
|
||||
@ -12,6 +14,8 @@ SET(QGIS_QUICK_GUI_HDRS
|
||||
SET(QGIS_QUICK_GUI_SRC
|
||||
qgsquickmapcanvasmap.cpp
|
||||
qgsquickmapsettings.cpp
|
||||
qgsquickmessagelogmodel.cpp
|
||||
qgsquickscalebarkit.cpp
|
||||
qgsquickutils.cpp
|
||||
)
|
||||
|
||||
|
@ -11,6 +11,8 @@ SET(QGIS_QUICK_PLUGIN_SRC
|
||||
|
||||
SET(QGIS_QUICK_PLUGIN_RESOURCES
|
||||
qgsquickmapcanvas.qml
|
||||
qgsquickmessagelog.qml
|
||||
qgsquickscalebar.qml
|
||||
qmldir
|
||||
)
|
||||
|
||||
@ -37,7 +39,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/quickgui
|
||||
|
||||
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/quickgui
|
||||
)
|
||||
@ -99,13 +101,14 @@ IF(QMLPLUGINDUMP_FOUND)
|
||||
# Qt Creator understand also the C++ classes registered in the plugin and thus available in QML code
|
||||
# If the qmlplugindumpcommand fails, add -v argument to see detailed output for debugging
|
||||
SET(QGIS_QUICK_PLUGIN_TYPEINFO ${QGIS_QUICK_PLUGIN_RUNTIME_DIR}/qgsquick.qmltypes)
|
||||
SET(QGIS_QUICK_VERSION 0.1)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET qgis_quick_plugin
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${QGIS_QUICK_TYPEINFO_GENERATE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${QGIS_QUICK_TYPEINFO_GENERATE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:qgis_quick_plugin> ${QGIS_QUICK_TYPEINFO_GENERATE_DIR}
|
||||
COMMAND ${QMLPLUGINDUMP_EXECUTABLE}
|
||||
ARGS QgsQuick 0.1 . --output ${QGIS_QUICK_PLUGIN_TYPEINFO}
|
||||
ARGS QgsQuick ${QGIS_QUICK_VERSION} . --output ${QGIS_QUICK_PLUGIN_TYPEINFO}
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
POST_BUILD
|
||||
)
|
||||
|
98
src/quickgui/plugin/qgsquickmessagelog.qml
Normal file
98
src/quickgui/plugin/qgsquickmessagelog.qml
Normal file
@ -0,0 +1,98 @@
|
||||
/***************************************************************************
|
||||
qgsquickmessagelog.qml
|
||||
--------------------------------------
|
||||
Date : January 2018
|
||||
Copyright : (C) 2018 by Peter Petrik
|
||||
Email : zilolv 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
import QtQuick.Controls 2.0
|
||||
import QtQuick 2.5
|
||||
import QgsQuick 0.1 as QgsQuick
|
||||
|
||||
|
||||
/**
|
||||
* \brief A component that shows all log messages. The component shows
|
||||
* the items from QgsQuickMessageLogModel.
|
||||
*/
|
||||
Item {
|
||||
/**
|
||||
* Input for messages. Must be connected before usage from QgsQuick.MessageLog.
|
||||
*
|
||||
* See also QgsQuickMessageLogModel
|
||||
*/
|
||||
property alias model: table.model
|
||||
/**
|
||||
* Background color
|
||||
*/
|
||||
property color bgColor: "white"
|
||||
/**
|
||||
* Separator color
|
||||
*/
|
||||
property color separatorColor: "gray"
|
||||
|
||||
/**
|
||||
* Separator width
|
||||
*/
|
||||
property int separatorSize: 1 * QgsQuick.Utils.dp
|
||||
/**
|
||||
* True if there are unread messages in the list. All messages
|
||||
* are marked read when the widget receives visibility.
|
||||
*/
|
||||
property bool unreadMessages: false
|
||||
|
||||
id: item
|
||||
|
||||
/**
|
||||
* List containing message logs
|
||||
*/
|
||||
ListView {
|
||||
id: table
|
||||
anchors.fill: parent
|
||||
|
||||
delegate: Column {
|
||||
Text {
|
||||
text: MessageTag
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: Message
|
||||
width: table.width
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
/**
|
||||
* Message separator.
|
||||
*/
|
||||
Rectangle {
|
||||
color: item.separatorColor
|
||||
height: item.separatorSize
|
||||
width: table.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles adding new messages to the list.
|
||||
*/
|
||||
Connections {
|
||||
target: model
|
||||
|
||||
onRowsInserted: {
|
||||
if (!visible)
|
||||
unreadMessages = true
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible)
|
||||
unreadMessages = false
|
||||
}
|
||||
}
|
@ -31,7 +31,9 @@
|
||||
|
||||
#include "qgsquickmapcanvasmap.h"
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgsquickmessagelogmodel.h"
|
||||
#include "qgsquickplugin.h"
|
||||
#include "qgsquickscalebarkit.h"
|
||||
#include "qgsquickutils.h"
|
||||
|
||||
static QObject *_utilsProvider( QQmlEngine *engine, QJSEngine *scriptEngine )
|
||||
@ -55,11 +57,10 @@ void QgsQuickPlugin::registerTypes( const char *uri )
|
||||
qmlRegisterType< QgsProject >( uri, 0, 1, "Project" );
|
||||
qmlRegisterType< QgsQuickMapCanvasMap >( uri, 0, 1, "MapCanvasMap" );
|
||||
qmlRegisterType< QgsQuickMapSettings >( uri, 0, 1, "MapSettings" );
|
||||
qmlRegisterType< QgsQuickMessageLogModel >( uri, 0, 1, "MessageLogModel" );
|
||||
qmlRegisterType< QgsQuickScaleBarKit >( uri, 0, 1, "ScaleBarKit" );
|
||||
qmlRegisterType< QgsVectorLayer >( uri, 0, 1, "VectorLayer" );
|
||||
|
||||
qmlRegisterSingletonType< QgsQuickUtils >( uri, 0, 1, "Utils", _utilsProvider );
|
||||
|
||||
qmlRegisterUncreatableType< QgsRelationManager >( uri, 0, 1, "RelationManager", "The relation manager is available from the Project. Try `qgisProject.relationManager`" );
|
||||
qmlRegisterUncreatableType< QgsMessageLog >( uri, 0, 1, "QgsMessageLog", "Expose MessageLevel" );
|
||||
}
|
||||
|
||||
|
141
src/quickgui/plugin/qgsquickscalebar.qml
Normal file
141
src/quickgui/plugin/qgsquickscalebar.qml
Normal file
@ -0,0 +1,141 @@
|
||||
/***************************************************************************
|
||||
qgsquickscalebar.qml
|
||||
--------------------------------------
|
||||
Date : Nov 2017
|
||||
Copyright : (C) 2017 by Peter Petrik
|
||||
Email : zilolv 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import QgsQuick 0.1 as QgsQuick
|
||||
|
||||
Item {
|
||||
id: scaleBar
|
||||
|
||||
/**
|
||||
* The mapSettings property contains configuration for rendering of the map.
|
||||
*
|
||||
* Must be connected before usage from QgsQuick.MapCanvas::mapSettings
|
||||
*/
|
||||
property alias mapSettings: scaleBarKit.mapSettings
|
||||
/**
|
||||
* Preferred width of scalebar in pixels on the screen. Defaults set to 300.
|
||||
*
|
||||
* barWidth is calculated to be close to preferred width, but has "nice" textual
|
||||
* representation
|
||||
*/
|
||||
property alias preferredWidth: scaleBarKit.preferredWidth
|
||||
/**
|
||||
* Kit for all calculation of width and text of the scalebar
|
||||
*
|
||||
* See also QgsQuickMapCanvasMap::mapSettings
|
||||
*/
|
||||
property QgsQuick.ScaleBarKit scaleBarKit: QgsQuick.ScaleBarKit {
|
||||
id: scaleBarKit
|
||||
}
|
||||
/**
|
||||
* Reserved text width.
|
||||
*/
|
||||
property int textWidth: fontMetrics.averageCharacterWidth * 8
|
||||
/**
|
||||
* Text color
|
||||
*/
|
||||
property color barColor: "white"
|
||||
/**
|
||||
* Background color
|
||||
*/
|
||||
property color barBackgroundColor: "grey"
|
||||
/**
|
||||
* Opacity
|
||||
*/
|
||||
property double barOpacity: 0.8
|
||||
/**
|
||||
* Textual representation of the bar length (e.g 800 m)
|
||||
*/
|
||||
property string barText: scaleBarKit.distance + " " + scaleBarKit.units
|
||||
/**
|
||||
* Calculated width of bar in pixels
|
||||
*/
|
||||
property int barWidth: scaleBarKit.width
|
||||
/**
|
||||
* Size of scalebar line (height of bar)
|
||||
*/
|
||||
property int lineWidth: 5 * QgsQuick.Utils.dp
|
||||
|
||||
width: textWidth + barWidth
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: background
|
||||
onClicked: {
|
||||
animation.restart()
|
||||
}
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: animation
|
||||
target: scaleBar
|
||||
property: "barWidth"
|
||||
to: 200
|
||||
duration: 1000
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
color: scaleBar.barBackgroundColor
|
||||
opacity: scaleBar.barOpacity
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
}
|
||||
|
||||
FontMetrics {
|
||||
id: fontMetrics
|
||||
font: text.font
|
||||
}
|
||||
|
||||
Row {
|
||||
opacity: 1
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
id: text
|
||||
width: textWidth
|
||||
height: scaleBar.height
|
||||
text: barText
|
||||
color: barColor
|
||||
font.pixelSize: scaleBar.height - 2 * scaleBar.lineWidth
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: leftBar
|
||||
width: scaleBar.lineWidth
|
||||
height: scaleBar.height - 20 * QgsQuick.Utils.dp
|
||||
y: (scaleBar.height - leftBar.height) / 2
|
||||
color: barColor
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: scaleBar.width - text.width - 15 * QgsQuick.Utils.dp
|
||||
height: scaleBar.lineWidth
|
||||
y: (scaleBar.height - scaleBar.lineWidth) / 2
|
||||
color: barColor
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rightBar
|
||||
width: scaleBar.lineWidth
|
||||
height: scaleBar.height - 20 * QgsQuick.Utils.dp
|
||||
y: (scaleBar.height - leftBar.height) / 2
|
||||
color: barColor
|
||||
}
|
||||
}
|
||||
}
|
@ -14,5 +14,7 @@ module QgsQuick
|
||||
plugin qgis_quick_plugin
|
||||
|
||||
MapCanvas 0.1 qgsquickmapcanvas.qml
|
||||
ScaleBar 0.1 qgsquickscalebar.qml
|
||||
MessageLog 0.1 qgsquickmessagelog.qml
|
||||
|
||||
typeinfo qgsquick.qmltypes
|
||||
|
76
src/quickgui/qgsquickmessagelogmodel.cpp
Normal file
76
src/quickgui/qgsquickmessagelogmodel.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
qgsquickmessagelogmodel.cpp
|
||||
--------------------------------------
|
||||
date : 13.7.2016
|
||||
copyright : (C) 2016 by Matthias Kuhn
|
||||
email : matthias (at) opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgis.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsapplication.h"
|
||||
|
||||
#include "qgsquickmessagelogmodel.h"
|
||||
|
||||
QgsQuickMessageLogModel::QgsQuickMessageLogModel( QObject *parent )
|
||||
: QAbstractListModel( parent )
|
||||
{
|
||||
connect( QgsApplication::messageLog(), static_cast<void ( QgsMessageLog::* )( const QString &message, const QString &tag, Qgis::MessageLevel level )>( &QgsMessageLog::messageReceived ), this, &QgsQuickMessageLogModel::onMessageReceived );
|
||||
}
|
||||
|
||||
QgsQuickMessageLogModel::LogMessage QgsQuickMessageLogModel::logMessage( const QString &tag, const QString &message, Qgis::MessageLevel level )
|
||||
{
|
||||
LogMessage msg;
|
||||
msg.tag = tag;
|
||||
msg.message = message;
|
||||
msg.level = level;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> QgsQuickMessageLogModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
|
||||
roles[MessageRole] = QByteArrayLiteral( "Message" );
|
||||
roles[MessageTagRole] = QByteArrayLiteral( "MessageTag" );
|
||||
roles[MessageLevelRole] = QByteArrayLiteral( "MessageLevel" );
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
int QgsQuickMessageLogModel::rowCount( const QModelIndex &parent ) const
|
||||
{
|
||||
Q_UNUSED( parent )
|
||||
return mMessages.size();
|
||||
}
|
||||
|
||||
QVariant QgsQuickMessageLogModel::data( const QModelIndex &index, int role ) const
|
||||
{
|
||||
if ( index.row() >= mMessages.size() )
|
||||
return QVariant();
|
||||
|
||||
if ( role == MessageRole )
|
||||
return mMessages.at( index.row() ).message;
|
||||
else if ( role == MessageTagRole )
|
||||
return mMessages.at( index.row() ).tag;
|
||||
else if ( role == MessageLevelRole )
|
||||
return mMessages.at( index.row() ).level;
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void QgsQuickMessageLogModel::onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level )
|
||||
{
|
||||
beginInsertRows( QModelIndex(), 0, 0 );
|
||||
mMessages.prepend( logMessage( tag, message, level ) );
|
||||
QgsDebugMsg( QStringLiteral( "Next message %1 : %2" ).arg( tag, message ) );
|
||||
endInsertRows();
|
||||
}
|
80
src/quickgui/qgsquickmessagelogmodel.h
Normal file
80
src/quickgui/qgsquickmessagelogmodel.h
Normal file
@ -0,0 +1,80 @@
|
||||
/***************************************************************************
|
||||
qgsquickmessagelogmodel.h
|
||||
--------------------------------------
|
||||
date : 13.7.2016
|
||||
copyright : (C) 2016 by Matthias Kuhn
|
||||
email : matthias (at) opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSQUICKMESSAGELOGMODEL_H
|
||||
#define QGSQUICKMESSAGELOGMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgsmessagelog.h"
|
||||
|
||||
#include "qgis_quick.h"
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
*
|
||||
* This model will connect to the QgsMessageLog singleton and store any
|
||||
* messages received. Can be used as a model for QListView,
|
||||
* for example QgsQuick.MessageLog (QML only)
|
||||
*
|
||||
* \note QML Type: MessageLogModel
|
||||
*
|
||||
* \sa QgsMessageLog
|
||||
*
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
class QUICK_EXPORT QgsQuickMessageLogModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
struct LogMessage
|
||||
{
|
||||
LogMessage() = default;
|
||||
|
||||
QString tag;
|
||||
QString message;
|
||||
Qgis::MessageLevel level;
|
||||
};
|
||||
|
||||
enum Roles
|
||||
{
|
||||
MessageRole = Qt::UserRole,
|
||||
MessageTagRole,
|
||||
MessageLevelRole
|
||||
};
|
||||
|
||||
public:
|
||||
//! Create new message log model
|
||||
QgsQuickMessageLogModel( QObject *parent = nullptr );
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
int rowCount( const QModelIndex &parent ) const override;
|
||||
QVariant data( const QModelIndex &index, int role ) const override;
|
||||
|
||||
private slots:
|
||||
void onMessageReceived( const QString &message, const QString &tag, Qgis::MessageLevel level );
|
||||
|
||||
private:
|
||||
//! LogMessage factory
|
||||
LogMessage logMessage( const QString &tag, const QString &message, Qgis::MessageLevel level );
|
||||
|
||||
//! Storage of all messages.
|
||||
QVector<LogMessage> mMessages;
|
||||
};
|
||||
|
||||
#endif // QGSQUICKMESSAGELOGMODEL_H
|
114
src/quickgui/qgsquickscalebarkit.cpp
Normal file
114
src/quickgui/qgsquickscalebarkit.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/***************************************************************************
|
||||
qgsquickscalebarkit.cpp
|
||||
--------------------------------------
|
||||
Date : Nov 2017
|
||||
Copyright : (C) 2017 by Peter Petrik
|
||||
Email : zilolv 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 <QSize>
|
||||
#include <QPoint>
|
||||
|
||||
#include "qgsdistancearea.h"
|
||||
#include "qgspointxy.h"
|
||||
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgsquickscalebarkit.h"
|
||||
#include "qgsquickutils.h"
|
||||
#include "qgsunittypes.h"
|
||||
|
||||
QgsQuickScaleBarKit::QgsQuickScaleBarKit( QObject *parent )
|
||||
: QObject( parent )
|
||||
, mPreferredWidth( 300 )
|
||||
, mWidth( mPreferredWidth )
|
||||
, mDistance( 0 )
|
||||
, mUnits( "" )
|
||||
{
|
||||
connect( this, &QgsQuickScaleBarKit::mapSettingsChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
connect( this, &QgsQuickScaleBarKit::preferredWidthChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
}
|
||||
|
||||
void QgsQuickScaleBarKit::setMapSettings( QgsQuickMapSettings *mapSettings )
|
||||
{
|
||||
if ( mMapSettings == mapSettings )
|
||||
return;
|
||||
|
||||
// If we have already something connected, disconnect it!
|
||||
if ( mMapSettings )
|
||||
{
|
||||
disconnect( mMapSettings, nullptr, this, nullptr );
|
||||
}
|
||||
|
||||
mMapSettings = mapSettings;
|
||||
|
||||
// Connect all signals to change scale bar when needed!
|
||||
if ( mMapSettings )
|
||||
{
|
||||
connect( mMapSettings, &QgsQuickMapSettings::extentChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
connect( mMapSettings, &QgsQuickMapSettings::destinationCrsChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
connect( mMapSettings, &QgsQuickMapSettings::mapUnitsPerPixelChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
connect( mMapSettings, &QgsQuickMapSettings::visibleExtentChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
connect( mMapSettings, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
connect( mMapSettings, &QgsQuickMapSettings::outputDpiChanged, this, &QgsQuickScaleBarKit::updateScaleBar );
|
||||
}
|
||||
|
||||
emit mapSettingsChanged();
|
||||
}
|
||||
|
||||
int QgsQuickScaleBarKit::width() const
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
QString QgsQuickScaleBarKit::units() const
|
||||
{
|
||||
return mUnits;
|
||||
}
|
||||
|
||||
int QgsQuickScaleBarKit::distance() const
|
||||
{
|
||||
return mDistance;
|
||||
}
|
||||
|
||||
void QgsQuickScaleBarKit::updateScaleBar()
|
||||
{
|
||||
if ( !mMapSettings )
|
||||
return;
|
||||
|
||||
double dist = QgsQuickUtils().screenUnitsToMeters( mMapSettings, mPreferredWidth ); // meters
|
||||
if ( dist > 1000.0 )
|
||||
{
|
||||
dist = dist / 1000.0; // meters to kilometers
|
||||
mUnits = QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceKilometers );
|
||||
}
|
||||
else
|
||||
{
|
||||
mUnits = QgsUnitTypes::toAbbreviatedString( QgsUnitTypes::DistanceMeters );
|
||||
}
|
||||
|
||||
// we want to show nice round distances e.g. 200 km instead of e.g. 273 km
|
||||
// so we determine which "nice" number to use and also update the scale bar
|
||||
// length accordingly. First digit will be 1, 2 or 5, the rest will be zeroes.
|
||||
int digits = int( floor( log10( ( dist ) ) ) ); // number of digits after first one
|
||||
double base = pow( 10, digits ); // e.g. for 1234 this will be 1000
|
||||
double first_digit = dist / base; // get the first digit
|
||||
int round_digit;
|
||||
if ( first_digit < 2 )
|
||||
round_digit = 1;
|
||||
else if ( first_digit < 5 )
|
||||
round_digit = 2;
|
||||
else
|
||||
round_digit = 5;
|
||||
|
||||
mDistance = int( round_digit * base );
|
||||
mWidth = int( mPreferredWidth * mDistance / dist );
|
||||
|
||||
emit scaleBarChanged();
|
||||
}
|
123
src/quickgui/qgsquickscalebarkit.h
Normal file
123
src/quickgui/qgsquickscalebarkit.h
Normal file
@ -0,0 +1,123 @@
|
||||
/***************************************************************************
|
||||
qgsquickscalebarkit.h
|
||||
--------------------------------------
|
||||
Date : Nov 2017
|
||||
Copyright : (C) 2017 by Peter Petrik
|
||||
Email : zilolv 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSQUICKSCALEBARKIT_H
|
||||
#define QGSQUICKSCALEBARKIT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include "qgis_quick.h"
|
||||
#include "qgsquickutils.h"
|
||||
|
||||
class QgsQuickMapSettings;
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
*
|
||||
* The class QgsQuickScaleBarKit encapsulates the utilies to calculate
|
||||
* scale bar properties
|
||||
*
|
||||
* It requires connection to mapSettings of the active canvas to automatically
|
||||
* update text and width
|
||||
*
|
||||
* From preferred width in pixel, it calculates the width (pixel) of scalebar
|
||||
* distance in meters or kilometers (int) rounded to "nice" number (e.g. 72.4 to 100)
|
||||
* and units text (e.g. km)
|
||||
*
|
||||
* \note QML Type: ScaleBarKit
|
||||
*
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
class QUICK_EXPORT QgsQuickScaleBarKit : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* Associated map settings. Should be initialized before the first use from mapcanvas map settings.
|
||||
*/
|
||||
Q_PROPERTY( QgsQuickMapSettings *mapSettings MEMBER mMapSettings WRITE setMapSettings NOTIFY mapSettingsChanged )
|
||||
|
||||
/**
|
||||
* Preferred width of scalebar in pixels. Default set to 300.
|
||||
*/
|
||||
Q_PROPERTY( int preferredWidth MEMBER mPreferredWidth NOTIFY preferredWidthChanged )
|
||||
|
||||
/**
|
||||
* Units of distance (e.g. km or m) Read-only (result).
|
||||
*/
|
||||
Q_PROPERTY( QString units READ units NOTIFY scaleBarChanged )
|
||||
|
||||
/**
|
||||
* Distance rounded to "nice" number (e.g. 100, 20) corresponding to width. To be used with units property for labels. Read-only (result).
|
||||
*/
|
||||
Q_PROPERTY( int distance READ distance NOTIFY scaleBarChanged )
|
||||
|
||||
/**
|
||||
* Calculated width of scalebar in pixels representing distance + units. Differs minimum possible from preferredWidth to
|
||||
* get "nice" distance number.
|
||||
*/
|
||||
Q_PROPERTY( int width READ width NOTIFY scaleBarChanged )
|
||||
|
||||
public:
|
||||
//! create new scale bar kit
|
||||
explicit QgsQuickScaleBarKit( QObject *parent = nullptr );
|
||||
~QgsQuickScaleBarKit() = default;
|
||||
|
||||
//! \copydoc QgsQuickScaleBarKit::mapSettings
|
||||
void setMapSettings( QgsQuickMapSettings *mapSettings );
|
||||
|
||||
//! \copydoc QgsQuickScaleBarKit::width
|
||||
int width() const;
|
||||
|
||||
/**
|
||||
* \copydoc QgsQuickScaleBarKit::units
|
||||
* \see QgsQuickScaleBarKit::units()
|
||||
*/
|
||||
int distance() const;
|
||||
|
||||
/**
|
||||
* \copydoc QgsQuickScaleBarKit::units
|
||||
* \see QgsQuickScaleBarKit::distance()
|
||||
*/
|
||||
QString units() const;
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* width, distance and/or units changed
|
||||
*/
|
||||
void scaleBarChanged();
|
||||
|
||||
//! \copydoc QgsQuickScaleBarKit::mapSettings
|
||||
void mapSettingsChanged();
|
||||
|
||||
//! \copydoc QgsQuickScaleBarKit::preferredWidth
|
||||
void preferredWidthChanged();
|
||||
|
||||
public slots:
|
||||
//! recalculate width, distance and units.
|
||||
void updateScaleBar();
|
||||
|
||||
private:
|
||||
QgsQuickMapSettings *mMapSettings = nullptr; // not owned
|
||||
int mPreferredWidth; // pixels
|
||||
int mWidth; // pixels
|
||||
int mDistance; // in meters or kilometers, rounded
|
||||
QString mUnits; // km or m
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSQUICKSCALEBARKIT_H
|
@ -16,11 +16,8 @@
|
||||
#include <QString>
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgscoordinatetransform.h"
|
||||
#include "qgsdistancearea.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgsquickutils.h"
|
||||
@ -33,6 +30,28 @@ QgsQuickUtils::QgsQuickUtils( QObject *parent )
|
||||
{
|
||||
}
|
||||
|
||||
double QgsQuickUtils::screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels ) const
|
||||
{
|
||||
if ( mapSettings == nullptr ) return 0.0;
|
||||
|
||||
QgsDistanceArea mDistanceArea;
|
||||
mDistanceArea.setEllipsoid( QStringLiteral( "WGS84" ) );
|
||||
mDistanceArea.setSourceCrs( mapSettings->destinationCrs(), mapSettings->transformContext() );
|
||||
|
||||
// calculate the geographic distance from the central point of extent
|
||||
// to the specified number of points on the right side
|
||||
QSize s = mapSettings->outputSize();
|
||||
QPoint pointCenter( s.width() / 2, s.height() / 2 );
|
||||
QgsPointXY p1 = mapSettings->screenToCoordinate( pointCenter );
|
||||
QgsPointXY p2 = mapSettings->screenToCoordinate( pointCenter + QPoint( baseLengthPixels, 0 ) );
|
||||
return mDistanceArea.measureLine( p1, p2 );
|
||||
}
|
||||
|
||||
void QgsQuickUtils::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
|
||||
{
|
||||
QgsMessageLog::logMessage( message, tag, level );
|
||||
}
|
||||
|
||||
QString QgsQuickUtils::dumpScreenInfo() const
|
||||
{
|
||||
QRect rec = QApplication::desktop()->screenGeometry();
|
||||
|
@ -21,8 +21,13 @@
|
||||
#include <QString>
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgsmessagelog.h"
|
||||
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgis_quick.h"
|
||||
|
||||
class QgsCoordinateReferenceSystem;
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
*
|
||||
@ -58,6 +63,16 @@ class QUICK_EXPORT QgsQuickUtils: public QObject
|
||||
//! \copydoc QgsQuickUtils::dp
|
||||
qreal screenDensity() const;
|
||||
|
||||
/**
|
||||
* Calculate the distance in meter representing baseLengthPixels pixels on the screen based on the current map settings.
|
||||
*/
|
||||
Q_INVOKABLE double screenUnitsToMeters( QgsQuickMapSettings *mapSettings, int baseLengthPixels ) const;
|
||||
|
||||
//! Log message in QgsMessageLog
|
||||
Q_INVOKABLE void logMessage( const QString &message,
|
||||
const QString &tag = QString( "QgsQuick" ),
|
||||
Qgis::MessageLevel level = Qgis::Warning );
|
||||
|
||||
/**
|
||||
* Returns a string with information about screen size and resolution
|
||||
*
|
||||
|
@ -79,6 +79,7 @@ ENDMACRO (ADD_QGIS_TEST)
|
||||
# Tests:
|
||||
|
||||
ADD_QGIS_TEST(qgsquickutils testqgsquickutils.cpp)
|
||||
ADD_QGIS_TEST(qgsquickscalebarkit testqgsquickscalebarkit.cpp)
|
||||
|
||||
|
||||
#############################################################
|
||||
|
@ -37,4 +37,36 @@ ApplicationWindow {
|
||||
console.log("clicked:" + screenPoint)
|
||||
}
|
||||
}
|
||||
|
||||
Drawer {
|
||||
id: logPanel
|
||||
visible: true
|
||||
modal: true
|
||||
interactive: true
|
||||
height: window.height
|
||||
width: QgsQuick.Utils.dp * 700
|
||||
edge: Qt.RightEdge
|
||||
z: 2 // make sure items from here are on top of the Z-order
|
||||
|
||||
background: Rectangle {
|
||||
color: "white"
|
||||
}
|
||||
|
||||
QgsQuick.MessageLog {
|
||||
id: messageLog
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
model: QgsQuick.MessageLogModel {}
|
||||
visible: true
|
||||
}
|
||||
}
|
||||
|
||||
QgsQuick.ScaleBar {
|
||||
id: scaleBar
|
||||
y: window.height - height
|
||||
height: 50
|
||||
mapSettings: mapCanvas.mapSettings
|
||||
preferredWidth: 115 * QgsQuick.Utils.dp
|
||||
z: 1
|
||||
}
|
||||
}
|
||||
|
63
tests/src/quickgui/testqgsquickscalebarkit.cpp
Normal file
63
tests/src/quickgui/testqgsquickscalebarkit.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
testqgsquickscalebarkit.cpp.cpp
|
||||
--------------------------------------
|
||||
Date : May 2018
|
||||
Copyright : (C) 2018 by Viktor Sklencar
|
||||
Email : vsklencar 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 <QObject>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgstest.h"
|
||||
#include "qgis.h"
|
||||
|
||||
#include "qgsquickutils.h"
|
||||
#include "qgsquickmapcanvasmap.h"
|
||||
#include "qgsquickscalebarkit.h"
|
||||
|
||||
|
||||
class TestQgsQuickScaleBarKit: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void init() {} // will be called before each testfunction is executed.
|
||||
void cleanup() {} // will be called after every testfunction.
|
||||
|
||||
void updateScaleBar(); // test text of scalebar after update.
|
||||
};
|
||||
|
||||
void TestQgsQuickScaleBarKit::updateScaleBar()
|
||||
{
|
||||
QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 );
|
||||
QVERIFY( crsGPS.authid() == "EPSG:4326" );
|
||||
|
||||
QgsRectangle extent = QgsRectangle( 49, 16, 50, 17 );
|
||||
QgsQuickMapCanvasMap canvas;
|
||||
|
||||
QgsQuickMapSettings *ms = canvas.mapSettings();
|
||||
ms->setDestinationCrs( crsGPS );
|
||||
ms->setExtent( extent );
|
||||
ms->setOutputSize( QSize( 1000, 500 ) );
|
||||
|
||||
QgsQuickScaleBarKit kit;
|
||||
kit.setMapSettings( ms );
|
||||
QVERIFY( kit.units() == QString( "km" ) );
|
||||
QVERIFY( kit.distance() == 50 );
|
||||
|
||||
qreal scale = 0.005;
|
||||
canvas.zoom( extent.center().toQPointF(), scale );
|
||||
QVERIFY( kit.units() == QString( "m" ) );
|
||||
QVERIFY( kit.distance() == 200 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsQuickScaleBarKit )
|
||||
#include "testqgsquickscalebarkit.moc"
|
@ -30,8 +30,8 @@ class TestQgsQuickUtils: public QObject
|
||||
void cleanup() {} // will be called after every testfunction.
|
||||
|
||||
void screen_density();
|
||||
|
||||
void dump_screen_info();
|
||||
void screenUnitsToMeters();
|
||||
|
||||
private:
|
||||
QgsQuickUtils utils;
|
||||
@ -49,5 +49,18 @@ void TestQgsQuickUtils::dump_screen_info()
|
||||
QVERIFY( utils.dumpScreenInfo().contains( QStringLiteral( "%1" ).arg( dp ) ) );
|
||||
}
|
||||
|
||||
void TestQgsQuickUtils::screenUnitsToMeters()
|
||||
{
|
||||
QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 );
|
||||
QVERIFY( crsGPS.authid() == "EPSG:4326" );
|
||||
|
||||
QgsQuickMapSettings ms;
|
||||
ms.setDestinationCrs( crsGPS );
|
||||
ms.setExtent( QgsRectangle( 49, 16, 50, 17 ) );
|
||||
ms.setOutputSize( QSize( 1000, 500 ) );
|
||||
double sutm = utils.screenUnitsToMeters( &ms, 1 );
|
||||
QVERIFY( fabs( sutm - 213 ) < 1.0 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsQuickUtils )
|
||||
#include "testqgsquickutils.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user