Skip to content

Commit

Permalink
Fix style filters setting
Browse files Browse the repository at this point in the history
  • Loading branch information
ntadej committed Aug 30, 2024
1 parent 8edbd05 commit 353aa63
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(MLNQtCore_Headers
utils.hpp

style/style_parameter.hpp
style/filter_parameter.hpp
style/layer_parameter.hpp
style/source_parameter.hpp
)
Expand Down Expand Up @@ -66,6 +67,7 @@ target_sources(
utils.cpp

style/style_parameter.cpp
style/filter_parameter.cpp
style/layer_parameter.cpp
style/source_parameter.cpp

Expand Down
3 changes: 3 additions & 0 deletions src/core/conversion_p.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class ConversionTraits<QVariant> {

static bool isArray(const QVariant &value) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
if (value.metaType() == QMetaType(QMetaType::QString)) {
return false;
}
return QMetaType::canConvert(value.metaType(), QMetaType(QMetaType::QVariantList));
#else
return value.canConvert(QVariant::List);
Expand Down
5 changes: 5 additions & 0 deletions src/core/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,11 @@ void Map::setFilter(const QString &layerId, const QVariant &filter) {
return;
}

if (filter.isNull() || filter.toList().isEmpty()) {
layer->setFilter(mbgl::style::Filter());
return;
}

mbgl::style::conversion::Error error;
std::optional<mbgl::style::Filter> converted = mbgl::style::conversion::convert<mbgl::style::Filter>(filter, error);
if (!converted) {
Expand Down
61 changes: 61 additions & 0 deletions src/core/style/filter_parameter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (C) 2023 MapLibre contributors

// SPDX-License-Identifier: BSD-2-Clause

#include "filter_parameter.hpp"

#include "style_parameter.hpp"

namespace QMapLibre {

/*!
\class FilterParameter
\brief A helper utility to manage filter parameters for a layer.
\ingroup QMapLibre
\headerfile filter_parameter.hpp <QMapLibre/FilterParameter>
*/

/*!
\brief Default constructor
*/
FilterParameter::FilterParameter(QObject *parent)
: StyleParameter(parent) {}

FilterParameter::~FilterParameter() = default;

/*!
\fn void FilterParameter::expressionUpdated()
\brief Signal emitted when the filter expression is updated.
*/

/*!
\brief Filter expression.
\return \c QVariantList.
*/
QVariantList FilterParameter::expression() const {
return m_expression;
}

/*!
\brief Set the filter expression.
\param expression Filter expression as \c QVariantList.
\ref expressionUpdated() signal is emitted when the expression is updated.
*/
void FilterParameter::setExpression(const QVariantList &expression) {
if (m_expression == expression) {
return;
}

m_expression = expression;

Q_EMIT expressionUpdated();
}

/*!
\var FilterParameter::m_expression
\brief Filter expression
*/

} // namespace QMapLibre
38 changes: 38 additions & 0 deletions src/core/style/filter_parameter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2023 MapLibre contributors

// SPDX-License-Identifier: BSD-2-Clause

#ifndef QMAPLIBRE_FILTER_PARAMETER_H
#define QMAPLIBRE_FILTER_PARAMETER_H

#include "style_parameter.hpp"

#include <QMapLibre/Export>

#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QVariantList>

namespace QMapLibre {

class Q_MAPLIBRE_CORE_EXPORT FilterParameter : public StyleParameter {
Q_OBJECT
public:
explicit FilterParameter(QObject *parent = nullptr);
~FilterParameter() override;

[[nodiscard]] QVariantList expression() const;
void setExpression(const QVariantList &expression);

Q_SIGNALS:
void expressionUpdated();

protected:
QVariantList m_expression;

Q_DISABLE_COPY(FilterParameter)
};

} // namespace QMapLibre

#endif // QMAPLIBRE_FILTER_PARAMETER_H
7 changes: 6 additions & 1 deletion src/core/style/layer_style_change.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// SPDX-License-Identifier: BSD-2-Clause

#include "filter_parameter.hpp"
#include "layer_parameter.hpp"
#include "layer_style_change_p.hpp"
#include "style_change_utils_p.hpp"
Expand Down Expand Up @@ -144,10 +145,14 @@ void StyleSetPaintProperties::apply(Map *map) {
}

// StyleSetFilter
StyleSetFilter::StyleSetFilter(QString layerId, QVariant expression)
StyleSetFilter::StyleSetFilter(QString layerId, QVariantList expression)
: m_layerId(std::move(layerId)),
m_expression(std::move(expression)) {}

StyleSetFilter::StyleSetFilter(const FilterParameter *parameter)
: m_layerId(parameter->styleId()),
m_expression(parameter->expression()) {}

void StyleSetFilter::apply(Map *map) {
if (map == nullptr) {
return;
Expand Down
6 changes: 4 additions & 2 deletions src/core/style/layer_style_change_p.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include "export_core.hpp"
#include "filter_parameter.hpp"
#include "layer_parameter.hpp"
#include "style_change_p.hpp"
#include "types.hpp"
Expand Down Expand Up @@ -72,13 +73,14 @@ class Q_MAPLIBRE_CORE_EXPORT StyleSetPaintProperties : public StyleChange {

class Q_MAPLIBRE_CORE_EXPORT StyleSetFilter : public StyleChange {
public:
explicit StyleSetFilter(QString layerId, QVariant expression);
explicit StyleSetFilter(QString layerId, QVariantList expression);
explicit StyleSetFilter(const FilterParameter *parameter);

void apply(Map *map) override;

private:
QString m_layerId;
QVariant m_expression;
QVariantList m_expression;
};

} // namespace QMapLibre
12 changes: 12 additions & 0 deletions src/core/style/style_change.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ std::vector<std::unique_ptr<StyleChange>> StyleChange::addParameter(const StyleP
return changes;
}

const auto *filterParameter = qobject_cast<const FilterParameter *>(parameter);
if (filterParameter != nullptr) {
changes.emplace_back(std::make_unique<StyleSetFilter>(filterParameter));
return changes;
}

return changes;
}

Expand All @@ -67,6 +73,12 @@ std::vector<std::unique_ptr<StyleChange>> StyleChange::removeParameter(const Sty
return changes;
}

const auto *filterParameter = qobject_cast<const FilterParameter *>(parameter);
if (filterParameter != nullptr) {
changes.emplace_back(std::make_unique<StyleSetFilter>(filterParameter->styleId(), QVariantList()));
return changes;
}

return changes;
}

Expand Down
1 change: 1 addition & 0 deletions src/location/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ set(Plugin_Sources
qml_types.hpp
declarative_style.cpp declarative_style.hpp
declarative_style_parameter.hpp
declarative_filter_parameter.cpp declarative_filter_parameter.hpp
declarative_layer_parameter.cpp declarative_layer_parameter.hpp
declarative_source_parameter.cpp declarative_source_parameter.hpp

Expand Down
12 changes: 12 additions & 0 deletions src/location/plugins/declarative_filter_parameter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (C) 2023 MapLibre contributors

// SPDX-License-Identifier: BSD-2-Clause

#include "declarative_filter_parameter.hpp"

namespace QMapLibre {

DeclarativeFilterParameter::DeclarativeFilterParameter(QObject *parent)
: FilterParameter(parent) {}

} // namespace QMapLibre
36 changes: 36 additions & 0 deletions src/location/plugins/declarative_filter_parameter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2023 MapLibre contributors

// SPDX-License-Identifier: BSD-2-Clause

#pragma once

#include "declarative_style_parameter.hpp"

#include <QMapLibre/FilterParameter>

#include <QtQml/QQmlEngine>
#include <QtQml/QQmlParserStatus>

namespace QMapLibre {

class DeclarativeFilterParameter : public FilterParameter, public QQmlParserStatus {
Q_OBJECT
QML_NAMED_ELEMENT(FilterParameter)
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QML_ADDED_IN_VERSION(3, 0)
#endif
Q_INTERFACES(QQmlParserStatus)
// from base class
Q_PROPERTY(QString styleId READ styleId WRITE setStyleId)
Q_PROPERTY(QVariantList expression READ expression WRITE setExpression NOTIFY expressionUpdated)
// this type must not declare any additional properties
public:
explicit DeclarativeFilterParameter(QObject *parent = nullptr);
~DeclarativeFilterParameter() override = default;

private:
// QQmlParserStatus implementation
MLN_DECLARATIVE_PARSER(DeclarativeFilterParameter)
};

} // namespace QMapLibre
27 changes: 22 additions & 5 deletions test/qml/qt6/tst_style_parameters.qml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ Item {
"raster-opacity": 0.9
}
}

FilterParameter {
id: filterParam
styleId: "countries-fill"
expression: ["==", "ADM0_A3", "NLD"]
}
}
}

Expand All @@ -72,7 +78,18 @@ Item {
compare(radarSourceParam.url, "https://maplibre.org/maplibre-gl-js/docs/assets/radar1.gif")
}

function test_style_1_image_change() {
function test_style_1_filter_change() {
filterParam.expression = ["==", "ADM0_A3", "USA"]
compare(filterParam.expression, ["==", "ADM0_A3", "USA"])
wait(500)
}

function test_style_2_filter_remove() {
style.removeParameter(filterParam)
wait(500)
}

function test_style_3_image_change() {
radarSourceParam.url = "https://maplibre.org/maplibre-gl-js/docs/assets/radar2.gif"
compare(radarSourceParam.url, "https://maplibre.org/maplibre-gl-js/docs/assets/radar2.gif")
wait(250)
Expand All @@ -97,7 +114,7 @@ Item {
wait(250)
}

function test_style_2_paint_change() {
function test_style_4_paint_change() {
radarLayerParam.paint = {"raster-opacity": 0.8}
wait(250)
radarLayerParam.paint = {"raster-opacity": 0.6}
Expand All @@ -110,7 +127,7 @@ Item {
wait(500)
}

function test_style_3_paint_set() {
function test_style_5_paint_set() {
radarLayerParam.setPaintProperty("raster-opacity", 0.8)
wait(250)
radarLayerParam.setPaintProperty("raster-opacity", 0.6)
Expand All @@ -123,13 +140,13 @@ Item {
wait(500)
}

function test_style_4_remove_image() {
function test_style_6_remove_image() {
style.removeParameter(radarLayerParam)
style.removeParameter(radarSourceParam)
wait(500)
}

function test_style_5_tiles() {
function test_style_7_tiles() {
let url = "https://s2maps-tiles.eu/wms?service=wms&bbox={bbox-epsg-3857}&format=image/png&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:900913&width=256&height=256&layers=s2cloudless-2021_3857"

let sourceParam = Qt.createQmlObject(`
Expand Down

0 comments on commit 353aa63

Please sign in to comment.