mapnik/demo/viewer/styles_model.cpp

382 lines
10 KiB
C++
Raw Permalink Normal View History

2007-08-07 17:09:41 +02:00
/* This file is part of Mapnik (c++ mapping toolkit)
2011-10-23 16:09:12 +02:00
*
2024-07-22 11:20:47 +02:00
* Copyright (C) 2024 Artem Pavlenko
2007-08-07 17:09:41 +02:00
*
* Mapnik 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 any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
2016-01-26 10:54:42 +01:00
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2007-08-07 17:09:41 +02:00
*/
#include "styles_model.hpp"
#include <mapnik/config.hpp>
#include <mapnik/util/variant.hpp>
2010-03-24 19:01:37 +01:00
#include <mapnik/expression_string.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/feature_type_style.hpp>
2014-10-01 15:07:27 +02:00
#include <mapnik/symbolizer.hpp>
2009-01-14 13:41:37 +01:00
// boost
#include <boost/concept_check.hpp>
2009-01-14 13:41:37 +01:00
// qt
2007-08-07 17:09:41 +02:00
#include <QList>
#include <QIcon>
#include <QPainter>
#include <QPixmap>
2007-08-07 17:09:41 +02:00
2015-01-13 11:45:07 +01:00
class node : private mapnik::util::noncopyable
2007-08-07 17:09:41 +02:00
{
2010-03-24 19:01:37 +01:00
struct node_base
{
2022-01-26 23:34:08 +01:00
virtual QString name() const = 0;
virtual QIcon icon() const = 0;
2011-05-04 17:53:36 +02:00
virtual ~node_base() {}
2010-03-24 19:01:37 +01:00
};
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
template<typename T>
2010-03-24 19:01:37 +01:00
struct wrap : public node_base
{
2022-01-26 23:34:08 +01:00
wrap(T const& obj)
: obj_(obj)
{}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
~wrap() {}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString name() const { return obj_.name(); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QIcon icon() const { return obj_.icon(); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
T obj_;
2010-03-24 19:01:37 +01:00
};
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
public:
template<typename T>
node(T const& obj, node* parent = 0)
: impl_(new wrap<T>(obj))
, parent_(parent)
2010-03-24 19:01:37 +01:00
{}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString name() const { return impl_->name(); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QIcon icon() const { return impl_->icon(); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
unsigned num_children() const { return children_.count(); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
node* child(unsigned row) const { return children_.value(row); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
node* parent() const { return parent_; }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
node* add_child(node* child)
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
children_.push_back(child);
return child;
2010-03-24 19:01:37 +01:00
}
2022-01-26 23:34:08 +01:00
int row() const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
if (parent_)
2007-08-07 17:09:41 +02:00
return parent_->children_.indexOf(const_cast<node*>(this));
2011-05-04 17:53:36 +02:00
else
2007-08-07 17:09:41 +02:00
return 0;
2010-03-24 19:01:37 +01:00
}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
~node() { qDeleteAll(children_); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
private:
const std::unique_ptr<node_base> impl_;
2010-03-24 19:01:37 +01:00
QList<node*> children_;
2022-01-26 23:34:08 +01:00
node* parent_;
2007-08-07 17:09:41 +02:00
};
struct symbolizer_info
{
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::point_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
boost::ignore_unused_variable_warning(sym);
return QString("PointSymbolizer");
2010-03-24 19:01:37 +01:00
}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::line_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
boost::ignore_unused_variable_warning(sym);
return QString("LineSymbolizer");
2010-03-24 19:01:37 +01:00
}
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::line_pattern_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
boost::ignore_unused_variable_warning(sym);
return QString("LinePatternSymbolizer");
2010-03-24 19:01:37 +01:00
}
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::polygon_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
boost::ignore_unused_variable_warning(sym);
return QString("PolygonSymbolizer");
2010-03-24 19:01:37 +01:00
}
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::polygon_pattern_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
boost::ignore_unused_variable_warning(sym);
return QString("PolygonSymbolizer");
2010-03-24 19:01:37 +01:00
}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::text_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
boost::ignore_unused_variable_warning(sym);
return QString("TextSymbolizer");
2010-03-24 19:01:37 +01:00
}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::shield_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
boost::ignore_unused_variable_warning(sym);
return QString("ShieldSymbolizer");
2010-03-24 19:01:37 +01:00
}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::markers_symbolizer const& sym) const
{
boost::ignore_unused_variable_warning(sym);
return QString("MarkersSymbolizer");
}
2022-01-26 23:34:08 +01:00
QString operator()(mapnik::building_symbolizer const& sym) const
{
boost::ignore_unused_variable_warning(sym);
return QString("BuildingSymbolizer");
}
2022-01-26 23:34:08 +01:00
template<typename T>
QString operator()(T const&) const
2010-03-24 19:01:37 +01:00
{
2022-01-26 23:34:08 +01:00
return QString("FIXME");
2010-03-24 19:01:37 +01:00
}
};
struct symbolizer_icon
{
2022-01-26 23:34:08 +01:00
QIcon operator()(mapnik::polygon_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2022-01-26 23:34:08 +01:00
QPixmap pix(16, 16);
2011-05-04 17:53:36 +02:00
QPainter painter(&pix);
mapnik::color const& fill = mapnik::get<mapnik::color>(sym, mapnik::keys::fill);
2022-01-26 23:34:08 +01:00
QBrush brush(QColor(fill.red(), fill.green(), fill.blue(), fill.alpha()));
2011-05-04 17:53:36 +02:00
painter.fillRect(0, 0, 16, 16, brush);
return QIcon(pix);
2010-03-24 19:01:37 +01:00
}
2022-01-26 23:34:08 +01:00
QIcon operator()(mapnik::point_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2011-05-04 17:53:36 +02:00
// FIXME!
/*
std::shared_ptr<mapnik::image_rgba8> symbol = sym.get_image();
2011-05-04 17:53:36 +02:00
if (symbol)
{
2015-05-04 12:49:11 +02:00
QImage image(symbol->bytes(),
2011-05-04 17:53:36 +02:00
symbol->width(),symbol->height(),QImage::Format_ARGB32);
QPixmap pix = QPixmap::fromImage(image.rgbSwapped());
return QIcon(pix);
}
*/
return QIcon();
2010-03-24 19:01:37 +01:00
}
2022-01-26 23:34:08 +01:00
QIcon operator()(mapnik::line_symbolizer const& sym) const
2010-03-24 19:01:37 +01:00
{
2022-01-26 23:34:08 +01:00
QPixmap pix(48, 16);
2011-05-04 17:53:36 +02:00
pix.fill();
QPainter painter(&pix);
2022-01-26 23:34:08 +01:00
// mapnik::stroke const& strk = sym.get_stroke();
mapnik::color const& col = mapnik::get<mapnik::color>(sym, mapnik::keys::stroke);
2022-01-26 23:34:08 +01:00
QPen pen(QColor(col.red(), col.green(), col.blue(), col.alpha()));
pen.setWidth(mapnik::get<double>(sym, mapnik::keys::width));
2011-05-04 17:53:36 +02:00
painter.setPen(pen);
2022-01-26 23:34:08 +01:00
painter.drawLine(0, 7, 47, 7);
// painter.drawLine(7,15,12,0);
// painter.drawLine(12,0,8,15);
2011-05-04 17:53:36 +02:00
return QIcon(pix);
2010-03-24 19:01:37 +01:00
}
2022-01-26 23:34:08 +01:00
template<typename T>
QIcon operator()(T const&) const
2010-03-24 19:01:37 +01:00
{
2022-01-26 23:34:08 +01:00
return QIcon(":/images/filter.png");
2010-03-24 19:01:37 +01:00
}
};
class symbolizer_node
{
2022-01-26 23:34:08 +01:00
public:
symbolizer_node(mapnik::symbolizer const& sym)
: sym_(sym)
{}
~symbolizer_node() {}
2011-10-23 16:09:12 +02:00
QString name() const
2010-03-24 19:01:37 +01:00
{
2022-01-26 23:34:08 +01:00
// return QString("Symbolizer:fixme");
return mapnik::util::apply_visitor(symbolizer_info(), sym_);
2010-03-24 19:01:37 +01:00
}
2011-10-23 16:09:12 +02:00
2010-03-24 19:01:37 +01:00
QIcon icon() const
{
2022-01-26 23:34:08 +01:00
return mapnik::util::apply_visitor(symbolizer_icon(), sym_); // QIcon(":/images/filter.png");
2010-03-24 19:01:37 +01:00
}
mapnik::symbolizer const& sym_;
};
2007-08-07 17:09:41 +02:00
class rule_node
{
2022-01-26 23:34:08 +01:00
public:
rule_node(QString name, mapnik::rule const& r)
: name_(name)
, rule_(r)
{}
2010-03-24 19:01:37 +01:00
~rule_node() {}
QString name() const
{
2011-05-04 17:53:36 +02:00
mapnik::expression_ptr filter = rule_.get_filter();
return QString(mapnik::to_expression_string(*filter).c_str());
2011-10-23 16:09:12 +02:00
}
2022-01-26 23:34:08 +01:00
QIcon icon() const { return QIcon(":/images/filter.png"); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
private:
2010-03-24 19:01:37 +01:00
QString name_;
mapnik::rule const& rule_;
2007-08-07 17:09:41 +02:00
};
class style_node
{
2022-01-26 23:34:08 +01:00
public:
2010-03-24 19:01:37 +01:00
style_node(QString name, mapnik::feature_type_style const& style)
2022-01-26 23:34:08 +01:00
: name_(name)
, style_(style)
{}
2011-10-23 16:09:12 +02:00
2010-03-24 19:01:37 +01:00
~style_node() {}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString name() const { return name_; }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QIcon icon() const { return QIcon(":/images/style.png"); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
private:
2010-03-24 19:01:37 +01:00
QString name_;
mapnik::feature_type_style const& style_;
2007-08-07 17:09:41 +02:00
};
class map_node
{
2022-01-26 23:34:08 +01:00
public:
explicit map_node(std::shared_ptr<mapnik::Map> map)
2022-01-26 23:34:08 +01:00
: map_(map)
{}
2010-03-24 19:01:37 +01:00
~map_node() {}
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QString name() const { return QString("Map"); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
QIcon icon() const { return QIcon(":/images/map.png"); }
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
private:
std::shared_ptr<mapnik::Map> map_;
2007-08-07 17:09:41 +02:00
};
2022-01-26 23:34:08 +01:00
StyleModel::StyleModel(std::shared_ptr<mapnik::Map> map, QObject* parent)
: QAbstractItemModel(parent)
, root_(new node(map_node(map)))
2007-08-07 17:09:41 +02:00
{
2022-01-26 23:34:08 +01:00
using style_type = std::map<std::string, mapnik::feature_type_style>;
style_type const& styles = map->styles();
2010-03-24 19:01:37 +01:00
style_type::const_iterator itr = styles.begin();
style_type::const_iterator end = styles.end();
for (; itr != end; ++itr)
{
2022-01-26 23:34:08 +01:00
node* style_n = root_->add_child(new node(style_node(QString(itr->first.c_str()), itr->second), root_.get()));
2011-05-04 17:53:36 +02:00
mapnik::rules const& rules = itr->second.get_rules();
mapnik::rules::const_iterator itr2 = rules.begin();
2022-01-26 23:34:08 +01:00
for (; itr2 != rules.end(); ++itr2)
2011-05-04 17:53:36 +02:00
{
2022-01-26 23:34:08 +01:00
node* rule_n = style_n->add_child(new node(rule_node(QString("Rule"), *itr2), style_n));
mapnik::rule::symbolizers::const_iterator itr3 = (*itr2).begin();
2022-01-26 23:34:08 +01:00
for (; itr3 != itr2->end(); ++itr3)
2011-05-04 17:53:36 +02:00
{
2022-01-26 23:34:08 +01:00
rule_n->add_child(new node(symbolizer_node(*itr3), rule_n));
2011-05-04 17:53:36 +02:00
}
}
2011-10-23 16:09:12 +02:00
}
2007-08-07 17:09:41 +02:00
}
StyleModel::~StyleModel() {}
2011-10-23 16:09:12 +02:00
// interface
2022-01-26 23:34:08 +01:00
QModelIndex StyleModel::index(int row, int col, QModelIndex const& parent) const
2007-08-07 17:09:41 +02:00
{
2022-01-26 23:34:08 +01:00
// qDebug("index() row=%d col=%d parent::internalId() = %lld", row,col,parent.internalId());
node* parent_node;
2011-10-23 16:09:12 +02:00
2010-03-24 19:01:37 +01:00
if (!parent.isValid())
2011-05-04 17:53:36 +02:00
parent_node = root_.get();
2010-03-24 19:01:37 +01:00
else
2011-05-04 17:53:36 +02:00
parent_node = static_cast<node*>(parent.internalPointer());
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
node* child_node = parent_node->child(row);
2010-03-24 19:01:37 +01:00
if (child_node)
2022-01-26 23:34:08 +01:00
return createIndex(row, col, child_node);
2010-03-24 19:01:37 +01:00
else
2011-05-04 17:53:36 +02:00
return QModelIndex();
2007-08-07 17:09:41 +02:00
}
2022-01-26 23:34:08 +01:00
QModelIndex StyleModel::parent(QModelIndex const& index) const
2007-08-07 17:09:41 +02:00
{
2022-01-26 23:34:08 +01:00
node* child_node = static_cast<node*>(index.internalPointer());
node* parent_node = child_node->parent();
2010-03-24 19:01:37 +01:00
if (parent_node == root_.get())
2011-05-04 17:53:36 +02:00
return QModelIndex();
2011-10-23 16:09:12 +02:00
2022-01-26 23:34:08 +01:00
return createIndex(parent_node->row(), 0, parent_node);
2007-08-07 17:09:41 +02:00
}
int StyleModel::rowCount(QModelIndex const& parent) const
{
2022-01-26 23:34:08 +01:00
// qDebug("rowCount");
node* parent_node;
if (parent.column() > 0)
return 0;
2010-03-24 19:01:37 +01:00
if (!parent.isValid())
2011-05-04 17:53:36 +02:00
parent_node = root_.get();
2010-03-24 19:01:37 +01:00
else
2011-05-04 17:53:36 +02:00
parent_node = static_cast<node*>(parent.internalPointer());
2010-03-24 19:01:37 +01:00
return parent_node->num_children();
2007-08-07 17:09:41 +02:00
}
2022-01-26 23:34:08 +01:00
int StyleModel::columnCount(QModelIndex const&) const
2007-08-07 17:09:41 +02:00
{
2010-03-24 19:01:37 +01:00
return 1;
2007-08-07 17:09:41 +02:00
}
2022-01-26 23:34:08 +01:00
QVariant StyleModel::data(const QModelIndex& index, int role) const
2007-08-07 17:09:41 +02:00
{
2022-01-26 23:34:08 +01:00
// qDebug("data index::internalId() = %lld", index.internalId());
2010-03-24 19:01:37 +01:00
if (!index.isValid())
2011-05-04 17:53:36 +02:00
return QVariant();
2022-01-26 23:34:08 +01:00
node* cur_node = static_cast<node*>(index.internalPointer());
2010-03-24 19:01:37 +01:00
if (cur_node)
{
2011-05-04 17:53:36 +02:00
if (role == Qt::DisplayRole)
{
return QVariant(cur_node->name());
}
2022-01-26 23:34:08 +01:00
else if (role == Qt::DecorationRole)
2011-05-04 17:53:36 +02:00
{
return cur_node->icon();
}
2010-03-24 19:01:37 +01:00
}
return QVariant();
2007-08-07 17:09:41 +02:00
}