diff --git a/demo/viewer/about_dialog.cpp b/demo/viewer/about_dialog.cpp new file mode 100644 index 000000000..3594c63e1 --- /dev/null +++ b/demo/viewer/about_dialog.cpp @@ -0,0 +1,28 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#include "about_dialog.hpp" + + +about_dialog::about_dialog(QWidget *parent) + : QDialog(parent) +{ + ui.setupUi(this); +} diff --git a/demo/viewer/about_dialog.hpp b/demo/viewer/about_dialog.hpp new file mode 100644 index 000000000..13d71dda2 --- /dev/null +++ b/demo/viewer/about_dialog.hpp @@ -0,0 +1,38 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + + +#if !defined ABOUT_DIALOG_HPP +#define ABOUT_DIALOG_HPP + +#include "ui_about.h" +#include + +class about_dialog : public QDialog +{ + Q_OBJECT +public: + about_dialog(QWidget * parent = 0); +private: + Ui::Dialog ui; +}; + + +#endif //ABOUT_DIALOG_HPP diff --git a/demo/viewer/forms/about.ui b/demo/viewer/forms/about.ui new file mode 100644 index 000000000..57a2b4e87 --- /dev/null +++ b/demo/viewer/forms/about.ui @@ -0,0 +1,107 @@ + + + + + Dialog + + + + 0 + 0 + 484 + 558 + + + + + 484 + 558 + + + + + 484 + 585 + + + + About + + + + + 10 + 20 + 461 + 351 + + + + + + + Qt::RichText + + + :/images/canada_map.png + + + + + + 190 + 500 + 87 + 32 + + + + OK + + + + + + 20 + 380 + 441 + 128 + + + + <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:Bitstream Vera Sans; font-size:11pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This is a simple viewer for testing new features and fixing bugs. For more information visit http://mapnik.org</p><p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">Copyright © 2006 Artem Pavlenko</span></p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> </p></body></html> + + + Qt::RichText + + + Qt::AlignCenter + + + true + + + + + + + + + + okButton + clicked() + Dialog + accept() + + + 278 + 253 + + + 96 + 254 + + + + + diff --git a/demo/viewer/forms/info.ui b/demo/viewer/forms/info.ui new file mode 100644 index 000000000..a3068b5af --- /dev/null +++ b/demo/viewer/forms/info.ui @@ -0,0 +1,83 @@ + + InfoDialog + + + + 0 + 0 + 277 + 249 + + + + Feature Info + + + + + 10 + 10 + 258 + 226 + + + + + + + + + + Qt::Horizontal + + + + 61 + 20 + + + + + + + + OK + + + + + + + Qt::Horizontal + + + + 71 + 20 + + + + + + + + + + + pushButton + clicked() + InfoDialog + close() + + + 216 + 408 + + + 195 + 220 + + + + + diff --git a/demo/viewer/images/about.png b/demo/viewer/images/about.png new file mode 100755 index 000000000..61c96a2b9 Binary files /dev/null and b/demo/viewer/images/about.png differ diff --git a/demo/viewer/images/canada_map.png b/demo/viewer/images/canada_map.png new file mode 100644 index 000000000..dc87c9d4a Binary files /dev/null and b/demo/viewer/images/canada_map.png differ diff --git a/demo/viewer/images/down.png b/demo/viewer/images/down.png new file mode 100755 index 000000000..119a09910 Binary files /dev/null and b/demo/viewer/images/down.png differ diff --git a/demo/viewer/images/export.png b/demo/viewer/images/export.png new file mode 100644 index 000000000..9e2789965 Binary files /dev/null and b/demo/viewer/images/export.png differ diff --git a/demo/viewer/images/filter.png b/demo/viewer/images/filter.png new file mode 100644 index 000000000..0ad0fcd93 Binary files /dev/null and b/demo/viewer/images/filter.png differ diff --git a/demo/viewer/images/globe.png b/demo/viewer/images/globe.png new file mode 100644 index 000000000..c73182c4d Binary files /dev/null and b/demo/viewer/images/globe.png differ diff --git a/demo/viewer/images/globe_bw.png b/demo/viewer/images/globe_bw.png new file mode 100644 index 000000000..367cbc506 Binary files /dev/null and b/demo/viewer/images/globe_bw.png differ diff --git a/demo/viewer/images/help.png b/demo/viewer/images/help.png new file mode 100644 index 000000000..d56ba2c24 Binary files /dev/null and b/demo/viewer/images/help.png differ diff --git a/demo/viewer/images/home.png b/demo/viewer/images/home.png new file mode 100755 index 000000000..d08e6ab00 Binary files /dev/null and b/demo/viewer/images/home.png differ diff --git a/demo/viewer/images/info.png b/demo/viewer/images/info.png new file mode 100644 index 000000000..d8197d61a Binary files /dev/null and b/demo/viewer/images/info.png differ diff --git a/demo/viewer/images/left.png b/demo/viewer/images/left.png new file mode 100644 index 000000000..e3abdc52e Binary files /dev/null and b/demo/viewer/images/left.png differ diff --git a/demo/viewer/images/mapnik.png b/demo/viewer/images/mapnik.png new file mode 100644 index 000000000..2f96f9f81 Binary files /dev/null and b/demo/viewer/images/mapnik.png differ diff --git a/demo/viewer/images/pan.png b/demo/viewer/images/pan.png new file mode 100644 index 000000000..4b0e37a11 Binary files /dev/null and b/demo/viewer/images/pan.png differ diff --git a/demo/viewer/images/print.png b/demo/viewer/images/print.png new file mode 100644 index 000000000..a510ec655 Binary files /dev/null and b/demo/viewer/images/print.png differ diff --git a/demo/viewer/images/right.png b/demo/viewer/images/right.png new file mode 100755 index 000000000..69d0e5394 Binary files /dev/null and b/demo/viewer/images/right.png differ diff --git a/demo/viewer/images/style.png b/demo/viewer/images/style.png new file mode 100644 index 000000000..ab9c050a5 Binary files /dev/null and b/demo/viewer/images/style.png differ diff --git a/demo/viewer/images/up.png b/demo/viewer/images/up.png new file mode 100755 index 000000000..523198650 Binary files /dev/null and b/demo/viewer/images/up.png differ diff --git a/demo/viewer/images/zoombox.png b/demo/viewer/images/zoombox.png new file mode 100644 index 000000000..cfb5a19d4 Binary files /dev/null and b/demo/viewer/images/zoombox.png differ diff --git a/demo/viewer/images/zoomin.png b/demo/viewer/images/zoomin.png new file mode 100644 index 000000000..3343827e4 Binary files /dev/null and b/demo/viewer/images/zoomin.png differ diff --git a/demo/viewer/info_dialog.cpp b/demo/viewer/info_dialog.cpp new file mode 100644 index 000000000..89652c33e --- /dev/null +++ b/demo/viewer/info_dialog.cpp @@ -0,0 +1,40 @@ + /* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#include "info_dialog.hpp" + + +info_dialog::info_dialog(QVector > const& info, QWidget *parent) + : QDialog(parent) +{ + ui.setupUi(this); + ui.tableWidget->setHorizontalHeaderItem(0,new QTableWidgetItem("Name")); + ui.tableWidget->setHorizontalHeaderItem(1,new QTableWidgetItem("Value")); + + ui.tableWidget->setRowCount(info.size()); + ui.tableWidget->setColumnCount(2); + for (int i=0;isetItem(i,0,keyItem); + ui.tableWidget->setItem(i,1,valueItem); + } +} diff --git a/demo/viewer/info_dialog.hpp b/demo/viewer/info_dialog.hpp new file mode 100644 index 000000000..f9fda8b03 --- /dev/null +++ b/demo/viewer/info_dialog.hpp @@ -0,0 +1,38 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + + +#ifndef INFO_DIALOG_HPP +#define INFO_DIALOG_HPP + +#include "ui_info.h" +#include + +class info_dialog : public QDialog +{ + Q_OBJECT + public: + info_dialog(QVector > const& info,QWidget * parent = 0); + private: + Ui::InfoDialog ui; +}; + + +#endif //INFO_DIALOG_HPP diff --git a/demo/viewer/layerdelegate.cpp b/demo/viewer/layerdelegate.cpp new file mode 100644 index 000000000..b06a129ef --- /dev/null +++ b/demo/viewer/layerdelegate.cpp @@ -0,0 +1,55 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#include +#include "layerdelegate.hpp" + +LayerDelegate::LayerDelegate(QObject *parent) + : QAbstractItemDelegate(parent) +{ +} + +void LayerDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + painter->setRenderHint(QPainter::Antialiasing); + painter->setPen(QPen(QColor(255,0,0),1)); + + if (option.state & QStyle::State_Selected) + painter->setBrush(QBrush(QColor(0, 0, 255, 64))); + else + painter->setBrush(QBrush(QColor(255, 0, 0, 64))); + + + painter->drawRoundRect(option.rect,4,4); + + if (option.state & QStyle::State_Selected) + painter->setBrush(option.palette.highlightedText()); + else + painter->setBrush(QBrush(QColor(255, 120, 0, 127))); + +} + +QSize LayerDelegate::sizeHint(const QStyleOptionViewItem & /* option */, + const QModelIndex & /* index */) const +{ + return QSize(120,24); +} + diff --git a/demo/viewer/layerdelegate.hpp b/demo/viewer/layerdelegate.hpp new file mode 100644 index 000000000..f6ccc391a --- /dev/null +++ b/demo/viewer/layerdelegate.hpp @@ -0,0 +1,44 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ +#ifndef LAYER_DELEGATE_HPP +#define LAYER_DELEGATE_HPP + +#include +#include +#include +#include + +class QAbstractItemModel; +class QObject; +class QPainter; + +class LayerDelegate : public QAbstractItemDelegate +{ + Q_OBJECT + +public: + LayerDelegate(QObject *parent = 0); + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index ) const; +}; + +#endif //LAYER_DELEGATE_HPP diff --git a/demo/viewer/layerlistmodel.cpp b/demo/viewer/layerlistmodel.cpp new file mode 100644 index 000000000..b021652b8 --- /dev/null +++ b/demo/viewer/layerlistmodel.cpp @@ -0,0 +1,113 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + + +#include "layerlistmodel.hpp" +#include + +#include +#include + +using mapnik::Map; + +LayerListModel::LayerListModel(boost::shared_ptr map,QObject *parent) + : QAbstractListModel(parent), + map_(map) {} + +int LayerListModel::rowCount(QModelIndex const&) const +{ + if (map_) return map_->layers().size(); + return 0; +} + +QVariant LayerListModel::data(QModelIndex const& index,int role) const +{ + if (!index.isValid() || !map_) + return QVariant(); + if (index.row() < 0 || index.row() >= map_->layers().size()) + return QVariant(); + if (role == Qt::DisplayRole) + return QString(map_->layers().at(index.row()).name().c_str()); + else if (role == Qt::DecorationRole) + { + double scale = map_->scale(); + if (map_->layers().at(index.row()).isVisible(scale)) + { + return QIcon(":/images/globe.png"); + } + else + { + return QIcon(":/images/globe_bw.png"); + } + } + else if (role == Qt::CheckStateRole) + { + if (map_->layers().at(index.row()).isActive()) + return QVariant(Qt::Checked); + else + return QVariant(Qt::Unchecked); + } + else + { + return QVariant(); + } +} + +QVariant LayerListModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QString("TODO Column %1").arg(section); + else + return QString("TODO Row %1").arg(section); +} + +bool LayerListModel::setData(const QModelIndex &index, + const QVariant &value, int role) +{ + if (!map_) return false; + + if (index.isValid() && role == Qt::CheckStateRole) + { + int status = value.toInt(); + std::vector & layers = const_cast& >(map_->layers()); + layers.at(index.row()).setActive(status); + emit dataChanged(index, index); + return true; + } + return false; +} + +Qt::ItemFlags LayerListModel::flags(QModelIndex const& index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + if (index.isValid()) + flags |= Qt::ItemIsUserCheckable; + return flags; +} + + + + + diff --git a/demo/viewer/layerlistmodel.hpp b/demo/viewer/layerlistmodel.hpp new file mode 100644 index 000000000..8a66f19bc --- /dev/null +++ b/demo/viewer/layerlistmodel.hpp @@ -0,0 +1,49 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + + +#ifndef LAYER_LIST_MODEL_HPP +#define LAYER_LIST_MODEL_HPP + +#include +#include +#include +#include + +//using namespace mapnik; + +class LayerListModel : public QAbstractListModel +{ + Q_OBJECT + public: + LayerListModel(boost::shared_ptr map, QObject * parent = 0); + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + Qt::ItemFlags flags(QModelIndex const& index) const; + + private: + boost::shared_ptr map_; +}; + +#endif //LAYER_LIST_MODEL_HPP diff --git a/demo/viewer/layerwidget.cpp b/demo/viewer/layerwidget.cpp new file mode 100644 index 000000000..7f711d3ec --- /dev/null +++ b/demo/viewer/layerwidget.cpp @@ -0,0 +1,61 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#include "layerwidget.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +LayerTab::LayerTab(QWidget* parent) + : QListView(parent) {} + + +void LayerTab::paintEvent(QPaintEvent *e) +{ + QListView::paintEvent(e); +} + +void LayerTab::dataChanged(const QModelIndex &topLeft, + const QModelIndex &bottomRight) +{ + QListView::dataChanged(topLeft, bottomRight); + qDebug("FIXME : update map view!"); + emit update_mapwidget(); +} + +StyleTab::StyleTab(QWidget*) +{ + +} + +void StyleTab::contextMenuEvent(QContextMenuEvent * event ) +{ + qDebug("test"); +} diff --git a/demo/viewer/layerwidget.hpp b/demo/viewer/layerwidget.hpp new file mode 100644 index 000000000..afe407dac --- /dev/null +++ b/demo/viewer/layerwidget.hpp @@ -0,0 +1,49 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#ifndef LAYERWIDGET_HPP +#define LAYERWIDGET_HPP + +#include +#include +#include + +class LayerTab : public QListView +{ + Q_OBJECT + public: + LayerTab(QWidget* parent=0); + void paintEvent(QPaintEvent *e); + signals: + void update_mapwidget(); + protected slots: + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); +}; + +class StyleTab : public QTreeView +{ + Q_OBJECT +public: + StyleTab(QWidget* parent=0); +protected: + void contextMenuEvent(QContextMenuEvent * event ); +}; + +#endif diff --git a/demo/viewer/main.cpp b/demo/viewer/main.cpp new file mode 100644 index 000000000..e3d4a79e6 --- /dev/null +++ b/demo/viewer/main.cpp @@ -0,0 +1,69 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + + +#include +#include +#include +#include +#include "mainwindow.hpp" + +int main( int argc, char **argv ) +{ + using mapnik::datasource_cache; + using mapnik::freetype_engine; + + datasource_cache::instance()->register_datasources("/usr/local/lib/mapnik/input"); + + freetype_engine::instance()->register_font("/usr/local/lib/mapnik/fonts/DejaVuSans.ttf"); + freetype_engine::instance()->register_font("/usr/local/lib/mapnik/fonts/DejaVuSans-Bold.ttf"); + freetype_engine::instance()->register_font("/usr/local/lib/mapnik/fonts/DejaVuSansMono.ttf"); + + + QApplication app( argc, argv ); + MainWindow window; + window.show(); + if (argc == 3) + { + QStringList list = QString(argv[2]).split(","); + if (list.size()==4) + { + bool ok; + double x0 = list[0].toDouble(&ok); + double y0 = list[1].toDouble(&ok); + double x1 = list[2].toDouble(&ok); + double y1 = list[3].toDouble(&ok); + if (ok) + { + try + { + mapnik::projection prj("+proj=merc +datum=WGS84"); + prj.forward(x0,y0); + prj.forward(x1,y1); + window.set_default_extent(x0,y0,x1,y1); + } + catch (...) {} + } + } + } + + if (argc > 1) window.open(argv[1]); + return app.exec(); +} diff --git a/demo/viewer/mainwindow.cpp b/demo/viewer/mainwindow.cpp new file mode 100644 index 000000000..d43430e80 --- /dev/null +++ b/demo/viewer/mainwindow.cpp @@ -0,0 +1,364 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +// stl +#include + +// qt +#include +#include +#include +#include +#include +#include +#include +#include + +// mapnik +#include + +#include "mainwindow.hpp" +#include "layerlistmodel.hpp" +#include "styles_model.hpp" +#include "layerwidget.hpp" +#include "layerdelegate.hpp" +#include "about_dialog.hpp" + +MainWindow::MainWindow() + : filename_(), + default_extent_(-20037508.3428,-20037508.3428,20037508.3428,20037508.3428) +{ + mapWidget_ = new MapWidget(this); + QSplitter *splitter = new QSplitter(this); + QTabWidget *tabWidget=new QTabWidget; + layerTab_ = new LayerTab; + layerTab_->setFocusPolicy(Qt::NoFocus); + layerTab_->setIconSize(QSize(16,16)); + + //LayerDelegate *delegate = new LayerDelegate(this); + //layerTab_->setItemDelegate(delegate); + //layerTab_->setItemDelegate(new QItemDelegate(this)); + //layerTab_->setViewMode(QListView::IconMode); + + layerTab_->setFlow(QListView::TopToBottom); + tabWidget->addTab(layerTab_,tr("Layers")); + + // Styles tab + styleTab_ = new StyleTab; + tabWidget->addTab(styleTab_,tr("Styles")); + splitter->addWidget(tabWidget); + splitter->addWidget(mapWidget_); + QList list; + list.push_back(200); + list.push_back(600); + splitter->setSizes(list); + + mapWidget_->setFocusPolicy(Qt::StrongFocus); + mapWidget_->setFocus(); + + //setCentralWidget(mapWidget_); + setCentralWidget(splitter); + createActions(); + createMenus(); + createToolBars(); + createContextMenu(); + + setWindowTitle(tr("Mapnik Viewer")); + status=new QStatusBar(this); + status->showMessage(tr("")); + setStatusBar(status); + resize(800,600); + + //connect mapview to layerlist + connect(mapWidget_, SIGNAL(mapViewChanged()),layerTab_, SLOT(update())); + // slider + connect(slider_,SIGNAL(valueChanged(int)),mapWidget_,SLOT(zoomToLevel(int))); + // + connect(layerTab_,SIGNAL(update_mapwidget()),mapWidget_,SLOT(updateMap())); +} + + +MainWindow::~MainWindow() +{ + delete mapWidget_; +} + +void MainWindow::closeEvent(QCloseEvent* event) +{ + event->accept(); +} + +void MainWindow::createContextMenu() +{ + layerTab_->setContextMenuPolicy(Qt::ActionsContextMenu); + layerTab_->addAction(openAct); +} + +void MainWindow::open(QString const& path) +{ + if (path.isNull()) + { + filename_ = QFileDialog::getOpenFileName(this,tr("Open Mapnik file"), + currentPath,"*.xml"); + } + else + { + filename_ = path; + } + + if (!filename_.isEmpty()) + { + load_map_file(filename_); + //zoom_all(); + setWindowTitle(tr("%1 - Mapnik Viewer").arg(filename_)); + } + +} + +void MainWindow::reload() +{ + if (!filename_.isEmpty()) + { + mapnik::Envelope bbox = mapWidget_->getMap()->getCurrentExtent(); + load_map_file(filename_); + mapWidget_->zoomToBox(bbox); + setWindowTitle(tr("%1 - *Reloaded*").arg(filename_)); + } +} + +void MainWindow::save() +{ + QString initialPath = QDir::currentPath() + "/untitled.xml"; + QString filename = QFileDialog::getSaveFileName(this, tr("Save"), + initialPath, + tr("%1 Files (*.xml)") + .arg(QString("Mapnik definition"))); + if (!filename.isEmpty()) + { + std::cout<<"saving "<< filename.toStdString() << std::endl; + } +} + +void MainWindow::load_map_file(QString const& filename) +{ + std::cout<<"loading "<< filename.toStdString() << std::endl; + try + { + unsigned width = mapWidget_->width(); + unsigned height = mapWidget_->height(); + boost::shared_ptr map(new mapnik::Map(width,height)); + mapnik::load_map(*map,filename.toStdString()); + mapWidget_->setMap(map); + mapWidget_->zoomToBox(default_extent_); + layerTab_->setModel(new LayerListModel(map,this)); + styleTab_->setModel(new StyleModel(map,this)); + } + catch (...) + { + std::cout << "Unexpected Exception\n"; + } +} + +void MainWindow::zoom_all() +{ + mapWidget_->defaultView(); +} + +void MainWindow::zoom_to_box() +{ + mapWidget_->setTool(MapWidget::ZoomToBox); +} + +void MainWindow::pan() +{ + mapWidget_->setTool(MapWidget::Pan); +} + +void MainWindow::info() +{ + mapWidget_->setTool(MapWidget::Info); +} + +void MainWindow::pan_left() +{ + mapWidget_->panLeft(); +} + +void MainWindow::pan_right() +{ + mapWidget_->panRight(); +} + +void MainWindow::pan_up() +{ + mapWidget_->panUp(); +} + +void MainWindow::pan_down() +{ + mapWidget_->panDown(); +} + +void MainWindow::about() +{ + about_dialog dlg; + dlg.exec(); +} + +void MainWindow::export_as() +{ + QAction *action = qobject_cast(sender()); + QByteArray fileFormat = action->data().toByteArray(); + QString initialPath = QDir::currentPath() + "/map." + fileFormat; + + QString fileName = QFileDialog::getSaveFileName(this, tr("Export As"), + initialPath, + tr("%1 Files (*.%2);;All Files (*)") + .arg(QString(fileFormat.toUpper())) + .arg(QString(fileFormat))); + if (!fileName.isEmpty()) + { + QPixmap const& pix = mapWidget_->pixmap(); + pix.save(fileName); + } +} + +void MainWindow::print() +{ + + //Q_ASSERT(mapWidget_->pixmap()); + //QPrintDialog dialog(&printer, this); + //if (dialog.exec()) { + // QPainter painter(&printer); + // QRect rect = painter.viewport(); + // QSize size = mapWidget_->pixmap()->size(); + // size.scale(rect.size(), Qt::KeepAspectRatio); + // painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); + // painter.setWindow(mapWidget_->pixmap()->rect()); + // painter.drawPixmap(0, 0, *mapWidget_->pixmap()); + //} +} + +void MainWindow::createActions() +{ + //exportAct = new QAction(tr("&Export as ..."),this); + //exportAct->setShortcut(tr("Ctrl+E")); + //connect(exportAct, SIGNAL(triggered()), this, SLOT(export_as())); + zoomAllAct = new QAction(QIcon(":/images/home.png"),tr("Zoom All"),this); + connect(zoomAllAct, SIGNAL(triggered()), this, SLOT(zoom_all())); + + zoomBoxAct = new QAction(QIcon(":/images/zoombox.png"),tr("Zoom To Box"),this); + zoomBoxAct->setCheckable(true); + connect(zoomBoxAct, SIGNAL(triggered()), this, SLOT(zoom_to_box())); + + panAct = new QAction(QIcon(":/images/pan.png"),tr("Pan"),this); + panAct->setCheckable(true); + connect(panAct, SIGNAL(triggered()), this, SLOT(pan())); + + infoAct = new QAction(QIcon(":/images/info.png"),tr("Info"),this); + infoAct->setCheckable(true); + connect(infoAct, SIGNAL(triggered()), this, SLOT(info())); + + toolsGroup=new QActionGroup(this); + toolsGroup->addAction(zoomBoxAct); + toolsGroup->addAction(panAct); + toolsGroup->addAction(infoAct); + zoomBoxAct->setChecked(true); + + openAct=new QAction(tr("Open Map definition"),this); + connect(openAct,SIGNAL(triggered()),this,SLOT(open())); + saveAct=new QAction(tr("Save Map definition"),this); + connect(saveAct,SIGNAL(triggered()),this,SLOT(save())); + + panLeftAct = new QAction(QIcon(":/images/left.png"),tr("&Pan Left"),this); + connect(panLeftAct, SIGNAL(triggered()), this, SLOT(pan_left())); + panRightAct = new QAction(QIcon(":/images/right.png"),tr("&Pan Right"),this); + connect(panRightAct, SIGNAL(triggered()), this, SLOT(pan_right())); + panUpAct = new QAction(QIcon(":/images/up.png"),tr("&Pan Up"),this); + connect(panUpAct, SIGNAL(triggered()), this, SLOT(pan_up())); + panDownAct = new QAction(QIcon(":/images/down.png"),tr("&Pan Down"),this); + connect(panDownAct, SIGNAL(triggered()), this, SLOT(pan_down())); + + reloadAct = new QAction(QIcon(":/images/reload.png"),tr("Reload"),this); + connect(reloadAct, SIGNAL(triggered()), this, SLOT(reload())); + + foreach (QByteArray format, QImageWriter::supportedImageFormats()) + { + QString text = tr("%1...").arg(QString(format).toUpper()); + + QAction *action = new QAction(text, this); + action->setData(format); + connect(action, SIGNAL(triggered()), this, SLOT(export_as())); + exportAsActs.append(action); + } + + printAct = new QAction(QIcon(":/images/print.png"),tr("&Print ..."),this); + printAct->setShortcut(tr("Ctrl+E")); + connect(printAct, SIGNAL(triggered()), this, SLOT(print())); + + exitAct = new QAction(tr("E&xit"), this); + exitAct->setShortcut(tr("Ctrl+Q")); + connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + + aboutAct = new QAction(QIcon(":/images/about.png"),tr("&About"), this); + connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); +} + +void MainWindow::createMenus() +{ + exportMenu = new QMenu(tr("&Export As"), this); + foreach (QAction *action, exportAsActs) + exportMenu->addAction(action); + + fileMenu = new QMenu(tr("&File"),this); + fileMenu->addAction(openAct); + fileMenu->addAction(saveAct); + fileMenu->addMenu(exportMenu); + fileMenu->addAction(printAct); + fileMenu->addSeparator(); + fileMenu->addAction(exitAct); + menuBar()->addMenu(fileMenu); + + helpMenu = new QMenu(tr("&Help"), this); + helpMenu->addAction(aboutAct); + menuBar()->addMenu(helpMenu); +} + +void MainWindow::createToolBars() +{ + fileToolBar = addToolBar(tr("Actions")); + fileToolBar->addAction(zoomAllAct); + fileToolBar->addAction(zoomBoxAct); + fileToolBar->addAction(panAct); + fileToolBar->addAction(panLeftAct); + fileToolBar->addAction(panRightAct); + fileToolBar->addAction(panUpAct); + fileToolBar->addAction(panDownAct); + fileToolBar->addAction(infoAct); + fileToolBar->addAction(reloadAct); + fileToolBar->addAction(printAct); + slider_ = new QSlider(Qt::Horizontal,fileToolBar); + slider_->setRange(1,18); + slider_->setTickPosition(QSlider::TicksBelow); + slider_->setTickInterval(1); + slider_->setTracking(false); + fileToolBar->addWidget(slider_); + fileToolBar->addAction(aboutAct); +} diff --git a/demo/viewer/mainwindow.hpp b/demo/viewer/mainwindow.hpp new file mode 100644 index 000000000..078f35e4f --- /dev/null +++ b/demo/viewer/mainwindow.hpp @@ -0,0 +1,115 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#ifndef MAINWINDOW_HPP +#define MAINWINDOW_HPP + +#include +#include +#include +#include +#include +#include + +#include "mapwidget.hpp" + +//using namespace mapnik; + +class LayerTab; +class StyleTab; +class QSlider; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + public: + MainWindow(); + virtual ~MainWindow(); + inline void set_default_extent(double x0,double y0,double x1, double y1) + { + default_extent_=mapnik::Envelope(x0,y0,x1,y1); + } + + protected: + void closeEvent(QCloseEvent* event); +public slots: + void zoom_all(); + void zoom_to_box(); + void pan(); + void info(); + void export_as(); + void open(QString const& path = QString()); + void reload(); + void save(); + void print(); + void about(); + void pan_left(); + void pan_right(); + void pan_up(); + void pan_down(); + private: + void createActions(); + void createMenus(); + void createToolBars(); + void createContextMenu(); + void load_map_file(QString const& filename); + + + QString currentPath; + QString filename_; + QAbstractItemModel *model; + LayerTab *layerTab_; + StyleTab * styleTab_; + MapWidget * mapWidget_; + QPrinter printer; + //actions + QList exportAsActs; + QActionGroup *toolsGroup; + + QAction *zoomAllAct; + QAction *zoomBoxAct; + QAction *panAct; + QAction *infoAct; + QAction *openAct; + QAction *saveAct; + QAction *printAct; + QAction *exitAct; + QAction *aboutAct; + QAction *panLeftAct; + QAction *panRightAct; + QAction *panUpAct; + QAction *panDownAct; + QAction *reloadAct; + //toolbars + QToolBar *fileToolBar; + QToolBar *editToolBar; + //menus + QMenu *exportMenu; + QMenu *fileMenu; + QMenu *helpMenu; + //status bar + QStatusBar *status; + QSlider * slider_; + + mapnik::Envelope default_extent_; +}; + + +#endif //MAINWINDOW_HPP diff --git a/demo/viewer/mapnik_viewer.qrc b/demo/viewer/mapnik_viewer.qrc new file mode 100644 index 000000000..1ed968ca7 --- /dev/null +++ b/demo/viewer/mapnik_viewer.qrc @@ -0,0 +1,20 @@ + + + images/about.png + images/canada_map.png + images/down.png + images/globe.png + images/globe_bw.png + images/help.png + images/home.png + images/info.png + images/left.png + images/pan.png + images/print.png + images/right.png + images/up.png + images/zoombox.png + images/style.png + images/filter.png + + diff --git a/demo/viewer/mapwidget.cpp b/demo/viewer/mapwidget.cpp new file mode 100644 index 000000000..73fc1ce6f --- /dev/null +++ b/demo/viewer/mapwidget.cpp @@ -0,0 +1,452 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2006 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#include + +#include + +#include +#include +#include +#include +#include +#include "mapwidget.hpp" +#include "info_dialog.hpp" + +using mapnik::Image32; +using mapnik::Map; +using mapnik::Layer; +using mapnik::Envelope; +using mapnik::coord2d; +using mapnik::feature_ptr; +using mapnik::geometry_ptr; +using mapnik::CoordTransform; +using mapnik::projection; + +double scales [] = {279541132.014, + 139770566.007, + 69885283.0036, + 34942641.5018, + 17471320.7509, + 8735660.37545, + 4367830.18772, + 2183915.09386, + 1091957.54693, + 545978.773466, + 272989.386733, + 136494.693366, + 68247.3466832, + 34123.6733416, + 17061.8366708, + 8530.9183354, + 4265.4591677, + 2132.72958385, + 1066.36479192, + 533.182395962}; + +MapWidget::MapWidget(QWidget *parent) + :QWidget(parent), + map_(), + selected_(1), + extent_(), + cur_tool_(ZoomToBox), + start_x_(0), + start_y_(0), + end_x_(0), + end_y_(0), + drag_(false), + first_(true), + pen_(QColor(0,0,255,96)) +{ + pen_.setWidth(3); + pen_.setCapStyle(Qt::RoundCap); + pen_.setJoinStyle(Qt::RoundJoin); +} + +void MapWidget::setTool(eTool tool) +{ + cur_tool_=tool; +} + +void MapWidget::paintEvent(QPaintEvent*) +{ + QPainter painter(this); + + if (drag_) + { + if (cur_tool_ == ZoomToBox) + { + unsigned width = end_x_-start_x_; + unsigned height = end_y_-start_y_; + painter.drawPixmap(QPoint(0, 0),pix_); + painter.setPen(pen_); + painter.drawRect(start_x_,start_y_,width,height); + } + else if (cur_tool_ == Pan) + { + int dx = end_x_-start_x_; + int dy = end_y_-start_y_; + painter.setBrush(QColor(200,200,255,128)); + painter.drawRect(0,0,width(),height()); + painter.drawPixmap(QPoint(dx,dy),pix_); + } + } + else + { + painter.drawPixmap(QPoint(0, 0),pix_); + } + painter.end(); +} + +void MapWidget::resizeEvent(QResizeEvent * ev) +{ + if (map_) + { + map_->resize(ev->size().width(),ev->size().height()); + updateMap(); + } +} + +void MapWidget::mousePressEvent(QMouseEvent* e) +{ + if (e->button()==Qt::LeftButton) + { + if (cur_tool_ == ZoomToBox || cur_tool_==Pan) + { + start_x_ = e->x(); + start_y_ = e->y(); + drag_=true; + } + else if (cur_tool_==Info) + { + if (map_) + { + QVector > info; + + projection proj(map_->srs()); // map projection + double scale_denom = scale_denominator(*map_,proj.is_geographic()); + + for (unsigned index = 0; index < map_->layerCount();++index) + { + Layer & layer = map_->layers()[index]; + if (!layer.isVisible(scale_denom)) continue; + std::string name = layer.name(); + double x = e->x(); + double y = e->y(); + std::cout << "query at " << x << "," << y << "\n"; + + std::auto_ptr data(new mapnik::memory_datasource); + mapnik::featureset_ptr fs = map_->query_map_point(index,x,y); + + if (fs) + { + feature_ptr feat = fs->next(); + if (feat) + { + std::map const& props = feat->props(); + std::map::const_iterator itr=props.begin(); + for (; itr!=props.end();++itr) + { + if (itr->second.to_string().length() > 0) + { + info.push_back(QPair(QString(itr->first.c_str()), + itr->second.to_string().c_str())); + } + } + + geometry_ptr geom = feat->get_geometry(); + if (geom) + { + (*feat)["mapnik:geometry"] = geom->type(); + data->push(feat); + } + } + } + + if (data->size()) + { + mapnik::Layer annotations("*annotations*"); + annotations.set_srs(map_->layers()[index].srs()); + annotations.add_style("mapnik:selection"); + annotations.set_datasource(mapnik::datasource_ptr(data.release())); + map_->addLayer(annotations); + updateMap(); + info_dialog info_dlg(info,this); + info_dlg.exec(); + break; + } + } + + // remove annotation layer + map_->layers().erase(remove_if(map_->layers().begin(), + map_->layers().end(), + bind(&Layer::name,_1) == "*annotations*") + , map_->layers().end()); + } + } + } + else if (e->button()==Qt::RightButton) + { + //updateMap(); + } +} + +void MapWidget::mouseMoveEvent(QMouseEvent* e) +{ + if (cur_tool_ == ZoomToBox || cur_tool_==Pan) + { + end_x_ = e->x(); + end_y_ = e->y(); + update(); + } +} + +void MapWidget::mouseReleaseEvent(QMouseEvent* e) +{ + if (e->button()==Qt::LeftButton) + { + end_x_ = e->x(); + end_y_ = e->y(); + if (cur_tool_ == ZoomToBox) + { + drag_=false; + if (map_) + { + CoordTransform t(map_->getWidth(),map_->getHeight(),map_->getCurrentExtent()); + Envelope box = t.backward(Envelope(start_x_,start_y_,end_x_,end_y_)); + map_->zoomToBox(box); + updateMap(); + } + } + else if (cur_tool_==Pan) + { + drag_=false; + if (map_) + { + int cx = int(0.5 * map_->getWidth()); + int cy = int(0.5 * map_->getHeight()); + int dx = end_x_ - start_x_; + int dy = end_y_ - start_y_; + map_->pan(cx - dx ,cy - dy); + updateMap(); + } + } + } +} + + +void MapWidget::keyPressEvent(QKeyEvent *e) +{ + std::cout << "key pressed:"<key()<<"\n"; + switch (e->key()) { + case Qt::Key_Minus: + zoomOut(); + break; + case Qt::Key_Plus: + case 61: + zoomIn(); + break; + case 65: + defaultView(); + break; + case Qt::Key_Up: + panUp(); + break; + case Qt::Key_Down: + panDown(); + break; + case Qt::Key_Left: + panLeft(); + break; + case Qt::Key_Right: + panRight(); + break; + case 49: + zoomToLevel(10); + break; + case 50: + zoomToLevel(11); + break; + case 51: + zoomToLevel(12); + break; + case 52: + zoomToLevel(13); + break; + case 53: + zoomToLevel(14); + break; + case 54: + zoomToLevel(15); + break; + case 55: + zoomToLevel(16); + break; + case 56: + zoomToLevel(17); + break; + case 57: + zoomToLevel(18); + break; + } + QWidget::keyPressEvent(e); +} + +void MapWidget::zoomToBox(mapnik::Envelope const& bbox) +{ + if (map_) + { + map_->zoomToBox(bbox); + updateMap(); + } +} + +void MapWidget::defaultView() +{ + if (map_) + { + map_->resize(width(),height()); + map_->zoom_all(); + updateMap(); + } +} + +void MapWidget::zoomIn() +{ + if (map_) + { + map_->zoom(0.5); + updateMap(); + } +} + +void MapWidget::zoomOut() +{ + if (map_) + { + map_->zoom(2.0); + updateMap(); + } +} + +void MapWidget::panUp() +{ + if (map_) + { + double cx = 0.5*map_->getWidth(); + double cy = 0.5*map_->getHeight(); + map_->pan(int(cx),int(cy - cy*0.25)); + updateMap(); + } +} + +void MapWidget::panDown() +{ + if (map_) + { + double cx = 0.5*map_->getWidth(); + double cy = 0.5*map_->getHeight(); + map_->pan(int(cx),int(cy + cy*0.25)); + updateMap(); + } +} + +void MapWidget::panLeft() +{ + if (map_) + { + double cx = 0.5*map_->getWidth(); + double cy = 0.5*map_->getHeight(); + map_->pan(int(cx - cx * 0.25),int(cy)); + updateMap(); + } +} + +void MapWidget::panRight() +{ + if (map_) + { + double cx = 0.5*map_->getWidth(); + double cy = 0.5*map_->getHeight(); + map_->pan(int(cx + cx * 0.25),int(cy)); + updateMap(); + } +} + + +void MapWidget::zoomToLevel(int level) +{ + if ( map_ && level >= 0 && level < 19 ) + { + double scale_denom = scales[level]; + std::cerr << "scale denominator = " << scale_denom << "\n"; + mapnik::Envelope ext = map_->getCurrentExtent(); + double width = static_cast(map_->getWidth()); + double height= static_cast(map_->getHeight()); + mapnik::coord2d pt = ext.center(); + + double res = scale_denom * 0.00028; + + mapnik::Envelope box(pt.x - 0.5 * width * res, + pt.y - 0.5 * height*res, + pt.x + 0.5 * width * res, + pt.y + 0.5 * height*res); + map_->zoomToBox(box); + updateMap(); + } +} + +void MapWidget::export_to_file(unsigned ,unsigned ,std::string const&,std::string const&) +{ + //Image32 image(width,height); + //agg_renderer renderer(map,image); + //renderer.apply(); + //image.saveToFile(filename,type); +} + +void MapWidget::updateMap() +{ + if (map_) + { + unsigned width=map_->getWidth(); + unsigned height=map_->getHeight(); + + Image32 buf(width,height); + mapnik::agg_renderer ren(*map_,buf); + ren.apply(); + + QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32); + pix_=QPixmap::fromImage(image.rgbSwapped()); + update(); + // emit signal to interested widgets + emit mapViewChanged(); + std::cout << map_->getCurrentExtent() << "\n"; + } +} + +boost::shared_ptr MapWidget::getMap() +{ + return map_; +} + +void MapWidget::setMap(boost::shared_ptr map) +{ + map_ = map; +} diff --git a/demo/viewer/mapwidget.hpp b/demo/viewer/mapwidget.hpp new file mode 100644 index 000000000..e30ecdc0a --- /dev/null +++ b/demo/viewer/mapwidget.hpp @@ -0,0 +1,91 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#ifndef MAP_WIDGET_HPP +#define MAP_WIDGET_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class MapWidget : public QWidget +{ + Q_OBJECT + + public: + enum eTool + { + ZoomToBox = 1, + Pan, + Info, + }; + + private: + boost::shared_ptr map_; + int selected_; + QPixmap pix_; + mapnik::Envelope extent_; + eTool cur_tool_; + int start_x_; + int start_y_; + int end_x_; + int end_y_; + bool drag_; + bool first_; + QPen pen_; + public: + MapWidget(QWidget *parent=0); + void setTool(eTool tool); + boost::shared_ptr getMap(); + inline QPixmap const& pixmap() const { return pix_;} + void setMap(boost::shared_ptr map); + void defaultView(); + void zoomToBox(mapnik::Envelope const& box); + void zoomIn(); + void zoomOut(); + void panLeft(); + void panRight(); + void panUp(); + void panDown(); + public slots: + void zoomToLevel(int level); + void updateMap(); + signals: + void mapViewChanged(); + protected: + void paintEvent(QPaintEvent* ev); + void resizeEvent(QResizeEvent* ev); + void mousePressEvent(QMouseEvent* e); + void mouseMoveEvent(QMouseEvent* e); + void mouseReleaseEvent(QMouseEvent* e); + void keyPressEvent(QKeyEvent *e); + void export_to_file(unsigned width, + unsigned height, + std::string const& filename, + std::string const& type); +}; + +#endif // MAP_WIDGET_HPP diff --git a/demo/viewer/styles_model.cpp b/demo/viewer/styles_model.cpp new file mode 100644 index 000000000..d37fa37b8 --- /dev/null +++ b/demo/viewer/styles_model.cpp @@ -0,0 +1,268 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#include "styles_model.hpp" +#include +#include +#include +#include + +class node : private boost::noncopyable +{ + struct node_base + { + virtual QString name() const=0; + virtual QIcon icon() const=0; + virtual ~node_base() {} + }; + + template + struct wrap : public node_base + { + wrap(T const& obj) + : obj_(obj) {} + + ~wrap() {} + + QString name () const + { + return obj_.name(); + } + + QIcon icon() const + { + return obj_.icon(); + } + + T obj_; + }; + + public: + template + node ( T const& obj, node * parent=0) + : impl_(new wrap(obj)), + parent_(parent) + {} + + QString name() const + { + return impl_->name(); + } + + QIcon icon() const + { + return impl_->icon(); + } + + unsigned num_children() const + { + return children_.count(); + } + + node * child(unsigned row) const + { + return children_.value(row); + } + + node * parent() const + { + return parent_; + } + + node * add_child(node * child) + { + children_.push_back(child); + return child; + } + int row () const + { + if (parent_) + return parent_->children_.indexOf(const_cast(this)); + else + return 0; + } + + ~node() + { + qDeleteAll(children_); + } + + private: + boost::scoped_ptr impl_; + QList children_; + node * parent_; +}; + +class rule_node +{ + public: + rule_node(QString name,mapnik::rule_type const & r) + : name_(name), + rule_(r) {} + ~rule_node() {} + QString name() const + { + mapnik::filter_ptr filter = rule_.get_filter(); + + return QString(filter->to_string().c_str()); + } + + QIcon icon() const + { + return QIcon(":/images/filter.png"); + } + + private: + QString name_; + mapnik::rule_type const& rule_; +}; + +class style_node +{ + public: + style_node(QString name, mapnik::feature_type_style const& style) + : name_(name), + style_(style) {} + + ~style_node() {} + + QString name() const + { + return name_; + } + + QIcon icon() const + { + return QIcon(":/images/style.png"); + } + + private: + QString name_; + mapnik::feature_type_style const& style_; +}; + +class map_node +{ + public: + explicit map_node(boost::shared_ptr map) + : map_(map) {} + ~map_node() {} + + QString name() const + { + return QString("Map"); + } + + QIcon icon() const + { + return QIcon(":/images/map.png"); + } + + private: + boost::shared_ptr map_; +}; + +StyleModel::StyleModel(boost::shared_ptr map, QObject * parent) + : QAbstractItemModel(parent), + root_(new node(map_node(map))) +{ + typedef std::map style_type; + style_type const & styles = map->styles(); + style_type::const_iterator itr = styles.begin(); + style_type::const_iterator end = styles.end(); + for (; itr != end; ++itr) + { + node * style = root_->add_child(new node(style_node(QString(itr->first.c_str()),itr->second),root_.get())); + mapnik::rules const& rules = itr->second.get_rules(); + mapnik::rules::const_iterator itr2 = rules.begin(); + for ( ; itr2 != rules.end();++itr2) + { + style->add_child(new node(rule_node(QString("Rule"),*itr2),style)); + } + } +} + +StyleModel::~StyleModel() {} + +// interface +QModelIndex StyleModel::index (int row, int col, QModelIndex const& parent) const +{ + qDebug("index() row=%d col=%d parent::internalId() = %lld", row,col,parent.internalId()); + node * parent_node; + + if (!parent.isValid()) + parent_node = root_.get(); + else + parent_node = static_cast(parent.internalPointer()); + + node * child_node = parent_node->child(row); + if (child_node) + return createIndex(row,col,child_node); + else + return QModelIndex(); +} + +QModelIndex StyleModel::parent (QModelIndex const& index) const +{ + node * child_node = static_cast(index.internalPointer()); + node * parent_node = child_node->parent(); + if (parent_node == root_.get()) + return QModelIndex(); + + return createIndex(parent_node->row(),0,parent_node); +} + +int StyleModel::rowCount(QModelIndex const& parent) const +{ + qDebug("rowCount"); + node * parent_node; + if (parent.column() > 0) return 0; + if (!parent.isValid()) + parent_node = root_.get(); + else + parent_node = static_cast(parent.internalPointer()); + return parent_node->num_children(); +} + +int StyleModel::columnCount( QModelIndex const&) const +{ + return 1; +} + +QVariant StyleModel::data(const QModelIndex & index, int role) const +{ + qDebug("data index::internalId() = %lld", index.internalId()); + if (!index.isValid()) + return QVariant(); + node * cur_node = static_cast(index.internalPointer()); + if (cur_node) + { + if (role == Qt::DisplayRole) + { + + return QVariant(cur_node->name()); + } + else if ( role == Qt::DecorationRole) + { + return cur_node->icon(); + } + } + return QVariant(); +} diff --git a/demo/viewer/styles_model.hpp b/demo/viewer/styles_model.hpp new file mode 100644 index 000000000..621a3fd33 --- /dev/null +++ b/demo/viewer/styles_model.hpp @@ -0,0 +1,46 @@ +/* This file is part of Mapnik (c++ mapping toolkit) + * Copyright (C) 2007 Artem Pavlenko + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +//$Id$ + +#ifndef STYLE_MODEL_HPP +#define STYLE_MODEL_HPP + +#include +#include +#include + +class node; +class StyleModel : public QAbstractItemModel +{ + Q_OBJECT + public: + StyleModel(boost::shared_ptr map, QObject * parent=0); + ~StyleModel(); + // interface + QModelIndex index (int row, int col, QModelIndex const& parent = QModelIndex()) const; + QModelIndex parent (QModelIndex const& child) const; + int rowCount( QModelIndex const& parent = QModelIndex()) const; + int columnCount( QModelIndex const& parent = QModelIndex()) const; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + private: + //boost::shared_ptr map_; + boost::scoped_ptr root_; +}; + +#endif // STYLE_MODEL_HPP diff --git a/demo/viewer/viewer.pro b/demo/viewer/viewer.pro new file mode 100644 index 000000000..170960589 --- /dev/null +++ b/demo/viewer/viewer.pro @@ -0,0 +1,42 @@ +###################################################################### +# Mapnik viewer - Copyright (C) 2007 Artem Pavlenko +###################################################################### +CC = g++ +TEMPLATE = app + +INCLUDEPATH += /usr/local/include +INCLUDEPATH += /opt/boost_1_35/include/boost-1_35 +INCLUDEPATH += /usr/local/include/freetype2 + +INCLUDEPATH += . + + +unix:LIBS = -L/usr/local/lib -lmapnik -lfreetype + +# Input + +CONFIG += qt debug_and_release +FORMS += forms/about.ui forms/info.ui + +HEADERS += mainwindow.hpp \ + mapwidget.hpp \ + layerwidget.hpp \ + layerlistmodel.hpp \ + layerdelegate.hpp \ + styles_model.hpp + +HEADERS += about_dialog.hpp \ + info_dialog.hpp + +SOURCES += main.cpp \ + mainwindow.cpp \ + mapwidget.cpp \ + layerwidget.cpp \ + layerlistmodel.cpp \ + layerdelegate.cpp \ + styles_model.cpp + +SOURCES += about_dialog.cpp \ + info_dialog.cpp + +RESOURCES += mapnik_viewer.qrc