diff --git a/.github/workflows/docs-test.yml b/.github/workflows/docs-test.yml index 51834e5..3223a3f 100644 --- a/.github/workflows/docs-test.yml +++ b/.github/workflows/docs-test.yml @@ -33,6 +33,9 @@ jobs: with: version: "1.10.0" + - name: Install doxyqml + run: pip install doxyqml + - name: Generate documentation working-directory: docs run: doxygen diff --git a/.github/workflows/gh-pages-docs.yml b/.github/workflows/gh-pages-docs.yml index e9949ef..2c51985 100644 --- a/.github/workflows/gh-pages-docs.yml +++ b/.github/workflows/gh-pages-docs.yml @@ -18,6 +18,9 @@ jobs: with: version: "1.10.0" + - name: Install doxyqml + run: pip install doxyqml + - name: Generate documentation working-directory: docs run: doxygen diff --git a/.gitignore b/.gitignore index 768b223..b8f1dbe 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.user compile_commands.json docs/output +.venv diff --git a/docs/Doxyfile b/docs/Doxyfile index 9c8d109..07842b5 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -348,7 +348,7 @@ OPTIMIZE_OUTPUT_SLICE = NO # # Note see also the list of default file extension mappings. -EXTENSION_MAPPING = +EXTENSION_MAPPING = qml=C++ # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable @@ -783,7 +783,7 @@ MAX_INITIALIZER_LINES = 30 # list will mention the files that were used to generate the documentation. # The default value is: YES. -SHOW_USED_FILES = YES +SHOW_USED_FILES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View @@ -951,6 +951,8 @@ WARN_LOGFILE = INPUT = \ ../src/core \ + ../src/widgets \ + location \ Documentation.md \ Building.md \ Usage.md @@ -1043,7 +1045,8 @@ FILE_PATTERNS = *.c \ *.vhdl \ *.ucf \ *.qsf \ - *.ice + *.ice \ + *.qml # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. @@ -1074,7 +1077,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = *_p.hpp +EXCLUDE_PATTERNS = *_p.hpp example_* snippets_* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -1088,7 +1091,7 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -1147,7 +1150,7 @@ INPUT_FILTER = # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. -FILTER_PATTERNS = +FILTER_PATTERNS = *.qml=doxyqml # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for diff --git a/docs/README.md b/docs/README.md index eb20f7b..f581426 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,12 +7,15 @@ of MapLibre Native Qt Bindings using [Doxygen](https://www.doxygen.nl). is used as a theme and is included as a submodule. To update, simply check out a new version of the submodule. -The `[Documentation.md](./Documentation.md)` file contains the contents of +The [`Documentation.md`](./Documentation.md) file contains the contents of the first page you see when you open the documentation website, -while `[config/header.html](./config/header.html)` and -`[config/footer.html](./config/footer.html)`contain the contents of +while [`config/header.html`](./config/header.html) and +[`config/footer.html`](./config/footer.html) contain the contents of the header and the footer, respectively. +Standalone documentation is available at [`location`](./location/) with +examples provided in the [`examples`](./examples/) directory. + To generate the documentation, run ```shell diff --git a/docs/examples/example_Style.qml b/docs/examples/example_Style.qml new file mode 100644 index 0000000..625b1a4 --- /dev/null +++ b/docs/examples/example_Style.qml @@ -0,0 +1,57 @@ +import QtQuick 2.15 +import QtLocation 6.5 +import QtPositioning 6.5 + +import MapLibre 3.0 + +Item { + width: 512 + height: 512 + + Plugin { + id: mapPlugin + name: "maplibre" + + PluginParameter { + name: "maplibre.map.styles" + value: "https://demotiles.maplibre.org/style.json" + } + } + + MapView { + id: mapView + anchors.fill: parent + map.plugin: mapPlugin + + map.zoomLevel: 5 + map.center: QtPositioning.coordinate(41.874, -75.789) + + MapLibre.style: Style { + id: style + + SourceParameter { + id: radarSourceParam + styleId: "radar" + type: "image" + property string url: "https://maplibre.org/maplibre-gl-js/docs/assets/radar1.gif" + property var coordinates: [ + [-80.425, 46.437], + [-71.516, 46.437], + [-71.516, 37.936], + [-80.425, 37.936] + ] + } + + LayerParameter { + id: radarLayerParam + styleId: "radar-layer" + type: "raster" + property string source: "radar" + + paint: { + "raster-opacity": 0.9 + } + } + } + } +} diff --git a/docs/examples/snippets_Map.qml b/docs/examples/snippets_Map.qml new file mode 100644 index 0000000..f2a4e22 --- /dev/null +++ b/docs/examples/snippets_Map.qml @@ -0,0 +1,26 @@ +//! [Map plugin] +Plugin { + id: mapPlugin + name: "maplibre" + + PluginParameter { + name: "maplibre.map.styles" + value: "https://demotiles.maplibre.org/style.json" + } +} +//! [Map plugin] + +//! [Style attachment] +MapView { + id: mapView + anchors.fill: parent + map.plugin: mapPlugin + + map.zoomLevel: 5 + map.center: QtPositioning.coordinate(41.874, -75.789) + + MapLibre.style: Style { + id: style + } +} +//! [Style attachment] diff --git a/docs/examples/snippets_Style.qml b/docs/examples/snippets_Style.qml new file mode 100644 index 0000000..74538c2 --- /dev/null +++ b/docs/examples/snippets_Style.qml @@ -0,0 +1,72 @@ +//! [Attaching a Style] +MapLibre.style: Style { + id: style + + SourceParameter { + id: radarSourceParam + styleId: "radar" + type: "image" + property string url: "https://maplibre.org/maplibre-gl-js/docs/assets/radar1.gif" + property var coordinates: [ + [-80.425, 46.437], + [-71.516, 46.437], + [-71.516, 37.936], + [-80.425, 37.936] + ] + } + + LayerParameter { + id: radarLayerParam + styleId: "radar-layer" + type: "raster" + property string source: "radar" + + paint: { + "raster-opacity": 0.9 + } + } +} +//! [Attaching a Style] + +//! [Adding a parameter to a style] +let layerParam = Qt.createQmlObject(` + import MapLibre 3.0 + + LayerParameter { + styleId: "tileLayer" + type: "raster" + property string source: "tileSource" + } + `, + style, + "layerParamSnippet") +style.addParameter(layerParam) +//! [Adding a parameter to a style] + +//! [Source parameter] +SourceParameter { + id: radarSourceParam + styleId: "radar" + type: "image" + property string url: "https://maplibre.org/maplibre-gl-js/docs/assets/radar1.gif" + property var coordinates: [ + [-80.425, 46.437], + [-71.516, 46.437], + [-71.516, 37.936], + [-80.425, 37.936] + ] +} +//! [Source parameter] + +//! [Layer parameter] +LayerParameter { + id: radarLayerParam + styleId: "radar-layer" + type: "raster" + property string source: "radar" + + paint: { + "raster-opacity": 0.9 + } +} +//! [Layer parameter] diff --git a/docs/location/LayerParameter.qml b/docs/location/LayerParameter.qml new file mode 100644 index 0000000..2ba629c --- /dev/null +++ b/docs/location/LayerParameter.qml @@ -0,0 +1,20 @@ +// Copyright (C) 2024 MapLibre contributors + +// SPDX-License-Identifier: BSD-2-Clause + +/*! + \class LayerParameter + \brief A QML type for setting parameters of a layer. Generated from \ref QMapLibre::LayerParameter and should be nested in a \ref Style. + \ingroup QMapLibreLocation + + Additional layer-specific properties can be set directly as QML properties + to the instance of the LayerParameter. + + \snippet{trimleft} snippets_Style.qml Layer parameter +*/ + +SourceParameter { + property string type //!< layer type + property object layout //!< layout properties as a dictionary + property object paint //!< paint properties as a dictionary +} diff --git a/docs/location/QMapLibreLocation.dox b/docs/location/QMapLibreLocation.dox new file mode 100644 index 0000000..a1a0ac6 --- /dev/null +++ b/docs/location/QMapLibreLocation.dox @@ -0,0 +1,14 @@ +/*! + \defgroup QMapLibreLocation QMapLibre Location + \brief Qt Location plugin for MapLibre with the ID \c maplibre. + + The Qt Location QML plugin can be set with the \c Plugin instance. + + \snippet{trimleft} snippets_Map.qml Map plugin + + Additional style properties can be attached to the map. + For that import MapLibre 3.0 is needed. + See \ref Style for more details. + + \snippet{trimleft} snippets_Map.qml Style attachment +*/ diff --git a/docs/location/SourceParameter.qml b/docs/location/SourceParameter.qml new file mode 100644 index 0000000..d5e5160 --- /dev/null +++ b/docs/location/SourceParameter.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2024 MapLibre contributors + +// SPDX-License-Identifier: BSD-2-Clause + +/*! + \class SourceParameter + \brief A QML type for setting parameters of a source. Generated from \ref QMapLibre::SourceParameter and should be nested in a \ref Style. + \ingroup QMapLibreLocation + + Additional source-specific properties can be set directly as QML properties + to the instance of the SourceParameter. + + \snippet{trimleft} snippets_Style.qml Source parameter +*/ + +Item { + property string m_type //!< source type +} diff --git a/docs/location/Style.qml b/docs/location/Style.qml new file mode 100644 index 0000000..3e9136b --- /dev/null +++ b/docs/location/Style.qml @@ -0,0 +1,41 @@ +// Copyright (C) 2024 MapLibre contributors + +// SPDX-License-Identifier: BSD-2-Clause + +/*! + \class Style + \brief A QML helper item to be attached to a \c MapView using \c MapLibre.style property. + \ingroup QMapLibreLocation + + This item does not have any properties and expect to have \ref StyleParameter + implementations as children. See also \ref SourceParameter and \ref LayerParameter. + + \snippet{trimleft} snippets_Style.qml Attaching a Style + + Parameters can also be manipulated programatically using \ref addParameter, + \ref removeParameter and \ref clearParameters functions. + + \snippet{trimleft} snippets_Style.qml Adding a parameter to a style + + \example example_Style.qml + This is an example of how to use the Style item. +*/ + +Item { + /*! + \brief Add a parameter programatically + \param type:StyleParameter parameter The parameter to be added + */ + function addParameter(parameter) {} + + /*! + \brief Remove a parameter programatically + \param type:StyleParameter parameter The parameter to be removed + */ + function removeParameter(parameter) {} + + /*! + \brief Clear all parameters programatically + */ + function clearParameters() {} +} diff --git a/docs/location/StyleParameter.qml b/docs/location/StyleParameter.qml new file mode 100644 index 0000000..b0a408b --- /dev/null +++ b/docs/location/StyleParameter.qml @@ -0,0 +1,15 @@ +// Copyright (C) 2024 MapLibre contributors + +// SPDX-License-Identifier: BSD-2-Clause + +/*! + \class StyleParameter + \brief A base QML type for style parameters and is not intended to be used directly. + \ingroup QMapLibreLocation + + See also \ref SourceParameter and \ref LayerParameter. +*/ + +Item { + property string styleId //!< style id to be references inside MapLibre +} diff --git a/src/core/map.cpp b/src/core/map.cpp index 4235bdb..e768e1b 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -253,6 +253,8 @@ namespace QMapLibre { \brief The Map class is a Qt wrapper for the MapLibre Native engine. \ingroup QMapLibre + \headerfile map.hpp + Map is a Qt friendly version the MapLibre Native engine using Qt types and deep integration with Qt event loop. Map relies as much as possible on Qt, trying to minimize the external dependencies. For instance it will diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 13027b9..194e796 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -64,6 +64,8 @@ namespace QMapLibre { \brief The Settings class stores the initial configuration for Map. \ingroup QMapLibre + \headerfile settings.hpp + Settings is used to configure Map at the moment of its creation. Once created, the Settings of a Map can no longer be changed. diff --git a/src/core/style/layer_parameter.cpp b/src/core/style/layer_parameter.cpp index b30ccf7..ece6358 100644 --- a/src/core/style/layer_parameter.cpp +++ b/src/core/style/layer_parameter.cpp @@ -12,6 +12,8 @@ namespace QMapLibre { \brief A helper utility to create and configure map layers in the Map \ingroup QMapLibre + \headerfile layer_parameter.hpp + Needs to have a \ref type set to one of the supported types. Other properties are set dynamically, depending on the type. */ diff --git a/src/core/style/source_parameter.cpp b/src/core/style/source_parameter.cpp index 69cf913..5e84773 100644 --- a/src/core/style/source_parameter.cpp +++ b/src/core/style/source_parameter.cpp @@ -11,6 +11,8 @@ namespace QMapLibre { \brief A helper utility to create an additional map data source in the Map \ingroup QMapLibre + \headerfile source_parameter.hpp + Needs to have a \ref type set to one of the supported types. Other properties are set dynamically, depending on the type. */ diff --git a/src/core/types.cpp b/src/core/types.cpp index 6035277..f170900 100644 --- a/src/core/types.cpp +++ b/src/core/types.cpp @@ -79,6 +79,8 @@ namespace QMapLibre { \brief %Map style helper type. \ingroup QMapLibre + \headerfile types.hpp + Represents map styles via its \a url, \a name, \a description (optional), \a night (optional) and \a type (optional). @@ -119,6 +121,8 @@ namespace QMapLibre { \brief %Map feature helper type. \ingroup QMapLibre + \headerfile types.hpp + Represents map features via its \a type (PointType, LineStringType or PolygonType), \a geometry, \a properties map and \a id (optional). @@ -154,6 +158,8 @@ namespace QMapLibre { \brief %Map feature property helper type. \ingroup QMapLibre + \headerfile types.hpp + Represents map Feature properties via its \a type (\ref LayoutProperty or \ref PaintProperty), \a name and \a value. @@ -205,6 +211,8 @@ namespace QMapLibre { \brief Shape annotation geometry helper type. \ingroup QMapLibre + \headerfile types.hpp + Represents a shape annotation geometry via its \a type and \a geometry. \enum ShapeAnnotationGeometry::Type @@ -236,6 +244,8 @@ namespace QMapLibre { \brief Symbol annotation helper type. \ingroup QMapLibre + \headerfile types.hpp + A symbol annotation comprises of its \a geometry and an \a icon identifier. \var SymbolAnnotation::geometry @@ -250,6 +260,8 @@ namespace QMapLibre { \brief Line annotation helper type. \ingroup QMapLibre + \headerfile types.hpp + Represents a line annotation object, along with its properties. A line annotation comprises of its \a geometry and line properties @@ -273,6 +285,8 @@ namespace QMapLibre { \brief Fill annotation helper type. \ingroup QMapLibre + \headerfile types.hpp + Represents a fill annotation object, along with its properties. A fill annotation comprises of its \a geometry and fill properties @@ -296,6 +310,8 @@ namespace QMapLibre { \brief Camera options helper type. \ingroup QMapLibre + \headerfile types.hpp + CameraOptions provides camera options to the renderer. \var CameraOptions::center @@ -318,6 +334,8 @@ namespace QMapLibre { \struct CustomLayerRenderParameters \ingroup QMapLibre + \headerfile types.hpp + CustomLayerRenderParameters provides the data passed on each render pass for a custom layer. @@ -350,6 +368,8 @@ namespace QMapLibre { \class CustomLayerHostInterface \ingroup QMapLibre + \headerfile types.hpp + Represents a host interface to be implemented for rendering custom layers. \warning This is used for delegating the rendering of a layer to the user of diff --git a/src/widgets/gl_widget.cpp b/src/widgets/gl_widget.cpp index 652b4d9..7ee488a 100644 --- a/src/widgets/gl_widget.cpp +++ b/src/widgets/gl_widget.cpp @@ -10,6 +10,35 @@ namespace QMapLibre { +/*! + \defgroup QMapLibreWidgets QMapLibre Widgets + \brief Qt Widgets for MapLibre. +*/ + +/*! + \class GLWidget + \brief A simple OpenGL widget that displays a \ref QMapLibre::Map. + \ingroup QMapLibreWidgets + + \headerfile gl_widget.hpp + + The widget is intended as a standalone map viewer in a Qt Widgets application. + It owns its own instance of \ref QMapLibre::Map that is rendered to the widget. + + \fn GLWidget::onMouseDoubleClickEvent + \brief Emitted when the user double-clicks the mouse. + + \fn GLWidget::onMouseMoveEvent + \brief Emitted when the user moves the mouse. + + \fn GLWidget::onMousePressEvent + \brief Emitted when the user presses the mouse. + + \fn GLWidget::onMouseReleaseEvent + \brief Emitted when the user releases the mouse. +*/ + +/*! Default constructor */ GLWidget::GLWidget(const Settings &settings) : d_ptr(std::make_unique(this, settings)) {} @@ -20,10 +49,16 @@ GLWidget::~GLWidget() { d_ptr.reset(); } +/*! + \brief Get the QMapLibre::Map instance. +*/ Map *GLWidget::map() { return d_ptr->m_map.get(); } +/*! + \brief Mouse press event handler. +*/ void GLWidget::mousePressEvent(QMouseEvent *event) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) const QPointF &position = event->position(); @@ -38,6 +73,9 @@ void GLWidget::mousePressEvent(QMouseEvent *event) { d_ptr->handleMousePressEvent(event); } +/*! + \brief Mouse release event handler. +*/ void GLWidget::mouseReleaseEvent(QMouseEvent *event) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) const QPointF &position = event->position(); @@ -47,6 +85,9 @@ void GLWidget::mouseReleaseEvent(QMouseEvent *event) { emit onMouseReleaseEvent(d_ptr->m_map->coordinateForPixel(position)); } +/*! + \brief Mouse move event handler. +*/ void GLWidget::mouseMoveEvent(QMouseEvent *event) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) const QPointF &position = event->position(); @@ -58,10 +99,18 @@ void GLWidget::mouseMoveEvent(QMouseEvent *event) { d_ptr->handleMouseMoveEvent(event); } +/*! + \brief Mouse wheel event handler. +*/ void GLWidget::wheelEvent(QWheelEvent *event) { d_ptr->handleWheelEvent(event); } +/*! + \brief Initializes the map and sets up default settings. + + This function is called internally by Qt when the widget is initialized. +*/ void GLWidget::initializeGL() { d_ptr->m_map = std::make_unique(nullptr, d_ptr->m_settings, size(), devicePixelRatioF()); connect(d_ptr->m_map.get(), SIGNAL(needsRendering()), this, SLOT(update())); @@ -77,14 +126,20 @@ void GLWidget::initializeGL() { } } +/*! + \brief Renders the map. + + This function is called internally by Qt when the widget needs to be redrawn. +*/ void GLWidget::paintGL() { d_ptr->m_map->resize(size()); d_ptr->m_map->setFramebufferObject(defaultFramebufferObject(), size() * devicePixelRatioF()); d_ptr->m_map->render(); } -// GLWidgetPrivate +/*! \cond PRIVATE */ +// GLWidgetPrivate GLWidgetPrivate::GLWidgetPrivate(QObject *parent, Settings settings) : QObject(parent), m_settings(std::move(settings)) {} @@ -154,4 +209,6 @@ void GLWidgetPrivate::handleWheelEvent(QWheelEvent *event) const { event->accept(); } +/*! \endcond */ + } // namespace QMapLibre