Mapnik Viewer - initial import

This commit is contained in:
Artem Pavlenko 2007-08-07 15:09:41 +00:00
parent 80566ea1ba
commit 8887b9eb99
40 changed files with 2172 additions and 0 deletions

View file

@ -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);
}

View file

@ -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 <QDialog>
class about_dialog : public QDialog
{
Q_OBJECT
public:
about_dialog(QWidget * parent = 0);
private:
Ui::Dialog ui;
};
#endif //ABOUT_DIALOG_HPP

107
demo/viewer/forms/about.ui Normal file
View file

@ -0,0 +1,107 @@
<ui version="4.0" >
<author></author>
<comment></comment>
<exportmacro></exportmacro>
<class>Dialog</class>
<widget class="QDialog" name="Dialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>484</width>
<height>558</height>
</rect>
</property>
<property name="minimumSize" >
<size>
<width>484</width>
<height>558</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>484</width>
<height>585</height>
</size>
</property>
<property name="windowTitle" >
<string>About</string>
</property>
<widget class="QLabel" name="label" >
<property name="geometry" >
<rect>
<x>10</x>
<y>20</y>
<width>461</width>
<height>351</height>
</rect>
</property>
<property name="text" >
<string/>
</property>
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
<property name="pixmap" >
<pixmap resource="../mapviewer.qrc" >:/images/canada_map.png</pixmap>
</property>
</widget>
<widget class="QPushButton" name="okButton" >
<property name="geometry" >
<rect>
<x>190</x>
<y>500</y>
<width>87</width>
<height>32</height>
</rect>
</property>
<property name="text" >
<string>OK</string>
</property>
</widget>
<widget class="QLabel" name="label_2" >
<property name="geometry" >
<rect>
<x>20</x>
<y>380</y>
<width>441</width>
<height>128</height>
</rect>
</property>
<property name="text" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;/head>&lt;body style=" white-space: pre-wrap; font-family:Bitstream Vera Sans; font-size:11pt; font-weight:400; font-style:normal; text-decoration:none;">&lt;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&lt;/p>&lt;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;">&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-style:italic;">Copyright © 2006 Artem Pavlenko&lt;/span>&lt;/p>&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> &lt;/p>&lt;/body>&lt;/html></string>
</property>
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
<property name="alignment" >
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</widget>
<pixmapfunction></pixmapfunction>
<resources>
<include location="../mapviewer.qrc" />
</resources>
<connections>
<connection>
<sender>okButton</sender>
<signal>clicked()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>278</x>
<y>253</y>
</hint>
<hint type="destinationlabel" >
<x>96</x>
<y>254</y>
</hint>
</hints>
</connection>
</connections>
</ui>

83
demo/viewer/forms/info.ui Normal file
View file

@ -0,0 +1,83 @@
<ui version="4.0" >
<class>InfoDialog</class>
<widget class="QDialog" name="InfoDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>277</width>
<height>249</height>
</rect>
</property>
<property name="windowTitle" >
<string>Feature Info</string>
</property>
<widget class="QWidget" name="layoutWidget" >
<property name="geometry" >
<rect>
<x>10</x>
<y>10</y>
<width>258</width>
<height>226</height>
</rect>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" colspan="3" >
<widget class="QTableWidget" name="tableWidget" />
</item>
<item row="1" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>61</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" >
<widget class="QPushButton" name="pushButton" >
<property name="text" >
<string>OK</string>
</property>
</widget>
</item>
<item row="1" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>71</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>InfoDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel" >
<x>216</x>
<y>408</y>
</hint>
<hint type="destinationlabel" >
<x>195</x>
<y>220</y>
</hint>
</hints>
</connection>
</connections>
</ui>

BIN
demo/viewer/images/about.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
demo/viewer/images/down.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 B

BIN
demo/viewer/images/help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
demo/viewer/images/home.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
demo/viewer/images/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
demo/viewer/images/left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
demo/viewer/images/pan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
demo/viewer/images/right.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

BIN
demo/viewer/images/up.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -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<QPair<QString,QString> > 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;i<info.size();++i)
{
QTableWidgetItem *keyItem = new QTableWidgetItem(info[i].first);
QTableWidgetItem *valueItem = new QTableWidgetItem(info[i].second);
ui.tableWidget->setItem(i,0,keyItem);
ui.tableWidget->setItem(i,1,valueItem);
}
}

View file

@ -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 <QDialog>
class info_dialog : public QDialog
{
Q_OBJECT
public:
info_dialog(QVector<QPair<QString,QString> > const& info,QWidget * parent = 0);
private:
Ui::InfoDialog ui;
};
#endif //INFO_DIALOG_HPP

View file

@ -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 <QtGui>
#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);
}

View file

@ -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 <QAbstractItemDelegate>
#include <QFontMetrics>
#include <QModelIndex>
#include <QSize>
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

View file

@ -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 <QIcon>
#include <iostream>
#include <mapnik/layer.hpp>
using mapnik::Map;
LayerListModel::LayerListModel(boost::shared_ptr<Map> 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<mapnik::Layer> & layers = const_cast<std::vector<mapnik::Layer>& >(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;
}

View file

@ -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 <QAbstractListModel>
#include <QModelIndex>
#include <QVariant>
#include <mapnik/map.hpp>
//using namespace mapnik;
class LayerListModel : public QAbstractListModel
{
Q_OBJECT
public:
LayerListModel(boost::shared_ptr<mapnik::Map> 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<mapnik::Map> map_;
};
#endif //LAYER_LIST_MODEL_HPP

View file

@ -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 <qabstractitemdelegate.h>
#include <qapplication.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qvector.h>
#include <qstyle.h>
#include <qevent.h>
#include <qscrollbar.h>
#include <qrubberband.h>
#include <qdebug.h>
#include <iostream>
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");
}

View file

@ -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 <QTabWidget>
#include <QListView>
#include <QTreeView>
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

69
demo/viewer/main.cpp Normal file
View file

@ -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 <QApplication>
#include <QStringList>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
#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();
}

364
demo/viewer/mainwindow.cpp Normal file
View file

@ -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 <iostream>
// qt
#include <QtGui>
#include <QSplitter>
#include <QTreeView>
#include <QListView>
#include <QTabWidget>
#include <QList>
#include <QItemDelegate>
#include <QSlider>
// mapnik
#include <mapnik/load_map.hpp>
#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<int> 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<double> 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<mapnik::Map> 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<QAction *>(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);
}

115
demo/viewer/mainwindow.hpp Normal file
View file

@ -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 <QMainWindow>
#include <QPrinter>
#include <QList>
#include <QActionGroup>
#include <QStatusBar>
#include <QAbstractItemModel>
#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<double>(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<QAction *> 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<double> default_extent_;
};
#endif //MAINWINDOW_HPP

View file

@ -0,0 +1,20 @@
<RCC>
<qresource prefix="/" >
<file>images/about.png</file>
<file>images/canada_map.png</file>
<file>images/down.png</file>
<file>images/globe.png</file>
<file>images/globe_bw.png</file>
<file>images/help.png</file>
<file>images/home.png</file>
<file>images/info.png</file>
<file>images/left.png</file>
<file>images/pan.png</file>
<file>images/print.png</file>
<file>images/right.png</file>
<file>images/up.png</file>
<file>images/zoombox.png</file>
<file>images/style.png</file>
<file>images/filter.png</file>
</qresource>
</RCC>

452
demo/viewer/mapwidget.cpp Normal file
View file

@ -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 <QtGui>
#include <boost/bind.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/ctrans.hpp>
#include <mapnik/memory_datasource.hpp>
#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<QPair<QString,QString> > 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<mapnik::memory_datasource> 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<std::string,mapnik::value> const& props = feat->props();
std::map<std::string,mapnik::value>::const_iterator itr=props.begin();
for (; itr!=props.end();++itr)
{
if (itr->second.to_string().length() > 0)
{
info.push_back(QPair<QString,QString>(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<double> box = t.backward(Envelope<double>(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:"<<e->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<double> 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<double> ext = map_->getCurrentExtent();
double width = static_cast<double>(map_->getWidth());
double height= static_cast<double>(map_->getHeight());
mapnik::coord2d pt = ext.center();
double res = scale_denom * 0.00028;
mapnik::Envelope<double> 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<Image32> 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<Map> MapWidget::getMap()
{
return map_;
}
void MapWidget::setMap(boost::shared_ptr<Map> map)
{
map_ = map;
}

91
demo/viewer/mapwidget.hpp Normal file
View file

@ -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 <QWidget>
#include <QImage>
#include <QPixmap>
#include <QPen>
#include <iostream>
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <mapnik/map.hpp>
class MapWidget : public QWidget
{
Q_OBJECT
public:
enum eTool
{
ZoomToBox = 1,
Pan,
Info,
};
private:
boost::shared_ptr<mapnik::Map> map_;
int selected_;
QPixmap pix_;
mapnik::Envelope<double> 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<mapnik::Map> getMap();
inline QPixmap const& pixmap() const { return pix_;}
void setMap(boost::shared_ptr<mapnik::Map> map);
void defaultView();
void zoomToBox(mapnik::Envelope<double> 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

View file

@ -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 <boost/scoped_ptr.hpp>
#include <boost/utility.hpp>
#include <QList>
#include <QIcon>
class node : private boost::noncopyable
{
struct node_base
{
virtual QString name() const=0;
virtual QIcon icon() const=0;
virtual ~node_base() {}
};
template <typename T>
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 <typename T>
node ( T const& obj, node * parent=0)
: impl_(new wrap<T>(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<node*>(this));
else
return 0;
}
~node()
{
qDeleteAll(children_);
}
private:
boost::scoped_ptr<node_base> impl_;
QList<node*> 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<mapnik::Map> map)
: map_(map) {}
~map_node() {}
QString name() const
{
return QString("Map");
}
QIcon icon() const
{
return QIcon(":/images/map.png");
}
private:
boost::shared_ptr<mapnik::Map> map_;
};
StyleModel::StyleModel(boost::shared_ptr<mapnik::Map> map, QObject * parent)
: QAbstractItemModel(parent),
root_(new node(map_node(map)))
{
typedef std::map<std::string,mapnik::feature_type_style> 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<node*>(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<node*>(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<node*>(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<node*>(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();
}

View file

@ -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 <QAbstractItemModel>
#include <mapnik/map.hpp>
#include <boost/scoped_ptr.hpp>
class node;
class StyleModel : public QAbstractItemModel
{
Q_OBJECT
public:
StyleModel(boost::shared_ptr<mapnik::Map> 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<mapnik::Map> map_;
boost::scoped_ptr<node> root_;
};
#endif // STYLE_MODEL_HPP

42
demo/viewer/viewer.pro Normal file
View file

@ -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