New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QgisQuick 1.0 (QML QGIS Components Plugin) #109

Open
PeterPetrik opened this Issue Nov 3, 2017 · 10 comments

Comments

Projects
None yet
5 participants
@PeterPetrik
Copy link

PeterPetrik commented Nov 3, 2017

QGIS Enhancement: QgisQuick 1.0

Date 2017/11/03

Author Peter Petrik (@PeterPetrik)

Contact peter dot petrik at lutraconsulting dot co dot uk

maintainer @PeterPetrik

Version QGIS 3.2

Summary

This QEP proposes the implementation of Qt Quick-based GUI components for QGIS widgets.

There is a need for GIS on mobile devices for surveys, data gathering and other out-of-office tasks. The current GUI (based on QtWidgets) can hardly be used on mobile devices, especially considering the styling of widgets and lack of speed. Also, the QtWidget-based GUI does not resemble the look and feel of native mobile applications. To overcome these issues we propose the development of new GUI widgets based on Qt Quick. The main purpose of this enhancement is to create a new GUI library based on Qt Quick and a small application that demonstrates the creation of a mobile-friendly port of QGIS.

Technology Overview

There are some existing applications targeting Android devices, most notable is the QField project. qgis-quick-component is a sandbox of QGIS widgets built with Qt Quick. These projects serve as proof of concepts and guidelines for development of Qt Quick components for QGIS.

Qt Quick provides tools to create a rich application with a fluid and dynamic user interface. Qt Quick Controls 2 provides highly optimized controls for embedded/mobile devices with limited resources. In order to achieve the best performance on mobile devices, Qt Quick Controls 1 will not be used.

Map rendering is done through QgsMapRendererJob with the styles set-up in the QGIS (desktop) project. Hence the resulting map has the same look and feel as in QGIS desktop. For the first version, layer styling will not be supported. Users can perform this in QGIS Desktop.

Differences between QField and QgisQuick

QField already provides most of the features needed for on-site work. In addition, there are also python plugins for synchronization and preparation of the project for mobile. However, the project is structured as a single application with dependency on QGIS libraries. It is not straight-forward to take a selection of components from QField and create a custom mobile application suitable for a slightly different purpose (for example to build a "viewer" application with only scale bar, with no layer tree and with different logos and color scheme).

On the other hand QgisQuick will come as a QML (gui) component library, where the final application can be composed quickly from the components. Also, the components will be decoupled from each other and could be easily replaced or customized (by set of QML properties) in a final application.

Other benefits for integration with QGIS are:

  • QgisQuick components are properly tested with CI
  • QgisQuick components are up-to-date with recent API changes
  • QgisQuick components are decoupled from each other
  • QgisQuick components have proper documentation
  • Better contribution to the development of the components

During implementation, we will use code/principles from QField wherever possible. This will ensure that QField can smoothly switch to using QgisQuick components in the future.

Source Code Changes

A new GUI library "QgisQuick" (src/quickgui) and application "qgisquick" (tests/src/quickapp) will be created. All new files will have a qgsquick prefix. All new classes will have a QgsQuick prefix, e.g. qgsquickproject.h

class QgsQuickProject : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QString fileName READ projectFile WRITE setProjectFile NOTIFY projectFileChanged)
  ...

In a QML context, all classes will be used within the namespace QgsQuick, e.g.

import QtQuick 2.4
import QgisQuick 1.0 as QgsQuick

QgsQuick.Project {
  id: project
  fileName: qgisProject
}

QML Plugin (library) QgisQuick

The QML plugin (shared library and QML files) will be based on Qt Quick and Qt Quick Components 2 and will consist of base widgets/components. These components (e.g. MapCanvas, ScaleBar) could be used to cherry-pick and create any custom QGIS-based mobile-friendly application. The QgisQuick library would mimic classes in core, gui and app applicable to mobile context. The aim is to develop components required for the majority of mobile GIS applications for ease and re-usability.

For a start, these components should be implemented (ported from QField where possible):

  • MapCanvas (Visual)
  • MapSettings (for rendering)
  • Digitizing Tools (Add/Edit/Delete features/attributes)
  • Identify Feature
  • Feature Form

Position markers:

  • Coordinate Locator (Visual): Show coordinate on the map (for digitizing)
  • GPS Marker: Show GPS coordinates (from GPS receiver)
  • Identify Highlight: Show features near clicked location
  • Digitizing Rubberband: Add/Delete/Edit features rubberband

Map decorators:

  • Scale Bar
  • Measure Tool
  • Digitizing Tool

Mobile components

  • Photo from camera

The API of the library will match QGIS the desktop API wherever possible. This would benefit GUI developers by allowing them to quickly create a mobile version. For example, to have rendering settings available in QML, we would have the class:

class QgsQuickMapSettings : public QObject
{
    Q_OBJECT

    Q_PROPERTY( QgsRectangle extent READ extent WRITE setExtent NOTIFY extentChanged )
    Q_PROPERTY( QSize outputSize READ outputSize WRITE setOutputSize NOTIFY outputSizeChanged )
    Q_PROPERTY( double outputDpi READ outputDpi WRITE setOutputDpi NOTIFY outputDpiChanged )
    Q_PROPERTY( QgsCoordinateReferenceSystem destinationCrs READ destinationCrs WRITE setDestinationCrs NOTIFY destinationCrsChanged )
    Q_PROPERTY( QList<QgsMapLayer*> layers READ layers WRITE setLayers NOTIFY layersChanged )
    ...

that internally encapsulates QgsMapSettings, but can be used in a QML context via QgisQuick plugin

QgsGeometry to QSGGeometry

For highlight/selection of features, we need to convert QgsGeometry to QSGGeometry (Qt Quick geometry). For points and linestring it is trivial. But since QSGGeometry is based on triangles, one needs to convert polygons to triangles. QField uses the triangulation library tessellate, but it would be more convenient to use the recently added library for the 3D project poly2tri (src/3d/poly2tri).

Application qgisquick

A small demo application will be created from QgisQuick components to demonstrate their usage and show how an application could be crafted from components. This application could be also used and customized directly for projects that do not need any special features.

For production applications, one would be able to copy-paste the test application and modify
.qml file to add all components needed for the particular application.

We will also implement some custom components to demonstrate how to put together a real-life (production) application.
Likely candidate components include:

  • Project Menu
  • Layers Menu
  • Message Log

Data synchronization

Data synchronization will not be handled for now. One can prepare a project suitable for offline editing or use plugins like QFieldSync. Project files will be transfered to a device by plain file copy.

The demo application will contain a sample project with a couple of layers, so one can test the application on an Android device out of the box without needing to prepare a custom project or copy it to the device.

Build system and Dependencies

Desktop

Qt Quick support will need to be explicitly enabled during CMake configuration using WITH_QTQUICK=TRUE. The Qt Quick GUI will not be dependent on the QtWidget GUI, so one can build QGIS with the CMake flag WITH_GUI=FALSE

There will be new dependencies for Qt Quick (quick) and Qt Quick Controls 2 (quickcontrols2) libraries. The Qt Quick Controls 2 library is available in Qt since 5.7.

Android

For Android devices, cross compilation is required. This requires compiling all dependencies (e.g. gdal) with the Android NDK compiler. Initially, OSGeo4A will be used to compile shared libraries.
OSGeo4A uses the python-for-android project, but the old toolchain with distribute.sh. The old system uses plain bash script recipes for the compilation of libraries. We may consider in the future a rewrite of the recipes to work with the new python-for-android release, which uses recipes written in Python.

However for the applications based on QgisQuick, a QMake-based build system will be recommended. This is due to the fact that creation of an APK with CMake is not straight-forward and hard to maintain at present. With QMake, QtCreator automatically detects all the build dependencies for the APK. The main application consists of only a few files, so the duplication of build scripts for it
(CMake for Desktop, but QMake for Android) will not be a huge issue.

So the workflow for compilation of your custom application for mobile would be:

  • build qgis_core, QgisQuick and their dependencies by OSGeo4A
  • copy tests/src/quickapp to your custom location myapp
  • modify myapp/*.qml files to specify which compoenents to use, modify myapp/*.cpp files for custom behaviour
  • open myapp/app.pro in QtCreator. Select Kit for Android device. Build APK
  • Deploy APK to your device (e.g. by Google Play or via Google Drive or shared location)
  • Run app on your mobile device!

Implementation

Implementation work started on these branches:

Backwards Compatibility

N/A, new library and application.

Votes

(required)

@giohappy

This comment has been minimized.

Copy link

giohappy commented Nov 3, 2017

That sounds great! I hoped to see this since QField came out. I will follow the implementation and I can help with feedbacks on building and deployment (through Windows)

@m-kuhn

This comment has been minimized.

Copy link
Member

m-kuhn commented Nov 3, 2017

Love it. I have been looking for time to do this myself for too long, great someone else takes the initiative!

@m-kuhn

This comment has been minimized.

Copy link
Member

m-kuhn commented Nov 3, 2017

I really like the approach of splitting "often used generic components" from the business logic itself.

Some comments

There will be new dependencies for Qt Quick (quick) and Qt Quick Controls 2 (quickcontrols2) libraries. The Qt Quick Controls 2 library is available in Qt since 5.7.

qtqml as well I guess?

QField uses the triangulation library tessellate, but it would be more convenient to use the recently added library for the 3D project poly2tri (src/3d/poly2tri).

I reviewed some options and IIRC because of robustness issues if using poly2tri without extra deps like clipper decided against it. If that's not an issue, no opinion.

import QgisQuick 1.0 as QgsQuick

I guess import QgsQuick 1.0 (or 3.2?) should be enough?

For the class prefix, I wonder if QgsQuick for everything is not too long? But can't come up with a better proposal right now.

@PeterPetrik

This comment has been minimized.

Copy link

PeterPetrik commented Nov 6, 2017

@m-kuhn Thank you.

qtqml as well I guess?

Yes

I reviewed some options and IIRC because of robustness issues if using poly2tri without extra deps like clipper decided against it. If that's not an issue, no opinion.

I thought it would be better to use the same interface with 3D and use something already in the codebase. But definitely worth of check or using something different in case it does not work.

I guess import QgsQuick 1.0 (or 3.2?) should be enough?

Yes. On the other hand, I usually prefer to use namespaces to see where is an object defined.

@m-kuhn

This comment has been minimized.

Copy link
Member

m-kuhn commented Nov 6, 2017

Yes. On the other hand, I usually prefer to use namespaces to see where is an object defined.

That's fine, the main thing was if QgisQuick vs QgsQuick should be used consistently, I can find both in different places in the proposal here.

@PeterPetrik

This comment has been minimized.

Copy link

PeterPetrik commented Nov 6, 2017

I use QgisQuick for the library name and QgsQuick for all namespaces/prefixes/other stuff in the code.

PeterPetrik added a commit to PeterPetrik/QGIS that referenced this issue Feb 28, 2018

[FEATURE] Introduction of QGIS Quick library
This adds a new library for creation of applications based on Qt Quick
framework.
It contains reusable QML / Qt Quick components based on QGIS core
library.
The initial work introduces MapCanvas, FeatureForm, ScaleBar and various
other components.

To enable compilation of the library, use WITH_QUICK=TRUE

Further documentation of the library is located in doc/qgsquick.dox

For background information see the associated QEP:
qgis/QGIS-Enhancement-Proposals#109

The initial implementation is largely based on the work of Matthias Kuhn
and Marco Bernasocchi on QField probject - kudos to them for the great
job!

PeterPetrik added a commit to PeterPetrik/QGIS that referenced this issue Apr 23, 2018

[FEATURE] Introduction of QGIS Quick library
This adds a new library for creation of applications based on Qt Quick
framework. It contains reusable QML / Qt Quick components based on QGIS core
library. The initial work introduces all infrastrucure and MapCanvas and
MapSettings components.

To enable compilation of the library, use WITH_QUICK=TRUE

Further documentation of the library is located in doc/qgsquick.dox

For background information see the associated QEP:
qgis/QGIS-Enhancement-Proposals#109

The initial implementation is largely based on the work of Matthias Kuhn
and Marco Bernasocchi on QField probjectjob!

PeterPetrik added a commit to PeterPetrik/QGIS that referenced this issue Apr 23, 2018

[FEATURE] Introduction of QGIS Quick library
This adds a new library for creation of applications based on Qt Quick
framework. It contains reusable QML / Qt Quick components based on QGIS core
library. The initial work introduces all infrastrucure and MapCanvas and
MapSettings components.

To enable compilation of the library, use WITH_QUICK=TRUE

Further documentation of the library is located in doc/qgsquick.dox

For background information see the associated QEP:
qgis/QGIS-Enhancement-Proposals#109

The initial implementation is largely based on the work of Matthias Kuhn
and Marco Bernasocchi on QField probjectjob!

PeterPetrik added a commit to PeterPetrik/QGIS that referenced this issue Apr 26, 2018

[FEATURE] Introduction of QGIS Quick library
This pull request is a subset of qgis#6490

This adds a new library for creation of applications based on Qt Quick
framework.
It contains reusable QML / Qt Quick components based on QGIS core
library.
The initial work introduces MapCanvas

To enable compilation of the library, use WITH_QUICK=TRUE

Further documentation of the library is located in doc/qgsquick.dox

For background information see the associated QEP:
qgis/QGIS-Enhancement-Proposals#109

The initial implementation is largely based on the work of Matthias Kuhn
and Marco Bernasocchi on QField probject - kudos to them for the great
job!

sklencar pushed a commit to PeterPetrik/QGIS that referenced this issue May 21, 2018

PeterPetrik added a commit to PeterPetrik/QGIS that referenced this issue Jun 25, 2018

@filipdns

This comment has been minimized.

Copy link

filipdns commented Sep 30, 2018

Hello, I'm looking for open shapefiles from qgis in my qml application, I suppose I can use QgisQuick 1.0 but I can not found it anywhere, could you help me?

@PeterPetrik

This comment has been minimized.

Copy link

PeterPetrik commented Oct 1, 2018

@filipdns Hi, you can check the documentation
https://qgis.org/api/qgsquick.html . To create an application with the qgsquick library, you need to build it and link to your QT Quick application. Best to look in https://github.com/opengisch/QField and https://github.com/lutraconsulting/input applications. It is not trivial at all to set up an environment for Android development, but you should be able to follow OSGeo4A instructions on github.

@filipdns

This comment has been minimized.

Copy link

filipdns commented Oct 1, 2018

@PeterPetrik

This comment has been minimized.

Copy link

PeterPetrik commented Oct 1, 2018

@filipdns It would be better if you write to qgis-developer@lists.osgeo.org about installation/usability questions or directly to me peter.petrik@lutraconsulting.co.uk . This is primary for description of the framework. Fingers crossed for compilation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment