root/trunk/demo/viewer/mainwindow.cpp

Revision 2028, 12.3 kB (checked in by dane, 2 weeks ago)

viewer: zoom to full extent of map when loading from xml

Line 
1/* This file is part of Mapnik (c++ mapping toolkit)
2 * Copyright (C) 2006 Artem Pavlenko
3 *
4 * Mapnik is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18
19//$Id$
20
21// stl
22#include <iostream>
23
24// qt
25#include <QtGui>
26#include <QSplitter>
27#include <QTreeView>
28#include <QListView>
29#include <QTabWidget>
30#include <QList>
31#include <QItemDelegate>
32#include <QSlider>
33
34// mapnik
35#include <mapnik/config_error.hpp>
36#include <mapnik/load_map.hpp>
37#include <mapnik/save_map.hpp>
38
39// qt
40#include "mainwindow.hpp"
41#include "layerlistmodel.hpp"
42#include "styles_model.hpp"
43#include "layerwidget.hpp"
44#include "layerdelegate.hpp"
45#include "about_dialog.hpp"
46
47MainWindow::MainWindow()
48    : filename_(),
49      default_extent_(-20037508.3428,-20037508.3428,20037508.3428,20037508.3428)
50{       
51    mapWidget_ = new MapWidget(this);
52    QSplitter *splitter = new QSplitter(this); 
53    QTabWidget *tabWidget=new QTabWidget;
54    layerTab_ = new LayerTab;
55    layerTab_->setFocusPolicy(Qt::NoFocus);
56    layerTab_->setIconSize(QSize(16,16));
57     
58    //LayerDelegate *delegate = new LayerDelegate(this);   
59    //layerTab_->setItemDelegate(delegate);
60    //layerTab_->setItemDelegate(new QItemDelegate(this));
61    //layerTab_->setViewMode(QListView::IconMode);
62   
63    layerTab_->setFlow(QListView::TopToBottom);
64    tabWidget->addTab(layerTab_,tr("Layers"));
65
66    // Styles tab
67    styleTab_ = new StyleTab;
68    tabWidget->addTab(styleTab_,tr("Styles"));   
69    splitter->addWidget(tabWidget);
70    splitter->addWidget(mapWidget_);
71    QList<int> list;
72    list.push_back(200);
73    list.push_back(600);
74    splitter->setSizes(list);
75   
76    mapWidget_->setFocusPolicy(Qt::StrongFocus);
77    mapWidget_->setFocus();
78   
79    //setCentralWidget(mapWidget_);
80    setCentralWidget(splitter);
81    createActions();
82    createMenus();
83    createToolBars();
84    createContextMenu();
85   
86    setWindowTitle(tr("Mapnik Viewer"));
87    status=new QStatusBar(this);
88    status->showMessage(tr(""));
89    setStatusBar(status);
90    resize(800,600);
91
92    //connect mapview to layerlist
93    connect(mapWidget_, SIGNAL(mapViewChanged()),layerTab_, SLOT(update()));
94    // slider
95    connect(slider_,SIGNAL(valueChanged(int)),mapWidget_,SLOT(zoomToLevel(int)));
96    //
97    connect(layerTab_,SIGNAL(update_mapwidget()),mapWidget_,SLOT(updateMap()));
98    connect(layerTab_,SIGNAL(layerSelected(int)), 
99            mapWidget_,SLOT(layerSelected(int)));
100}
101
102
103MainWindow::~MainWindow()
104{
105    delete mapWidget_;
106}
107
108void MainWindow::closeEvent(QCloseEvent* event)
109{
110    event->accept();
111}
112
113void MainWindow::createContextMenu()
114{
115    layerTab_->setContextMenuPolicy(Qt::ActionsContextMenu);
116    layerTab_->addAction(openAct);
117    layerTab_->addAction(layerInfo);
118}
119
120void MainWindow::open(QString const& path)
121{
122    if (path.isNull())
123    {
124        filename_ = QFileDialog::getOpenFileName(this,tr("Open Mapnik file"),
125                                                 currentPath,"*.xml");
126    }
127    else
128    {
129        filename_ = path;
130    }
131   
132    if (!filename_.isEmpty())
133    {
134       
135        load_map_file(filename_);
136        setWindowTitle(tr("%1 - Mapnik Viewer").arg(filename_));
137    }
138   
139}
140
141void MainWindow::reload()
142{
143    if (!filename_.isEmpty())
144    {
145       
146        mapnik::box2d<double> bbox = mapWidget_->getMap()->get_current_extent();
147        load_map_file(filename_);
148        mapWidget_->zoomToBox(bbox);
149        setWindowTitle(tr("%1 - *Reloaded*").arg(filename_));
150    }
151}
152
153void MainWindow::save()
154{
155    QString initialPath = QDir::currentPath() + "/untitled.xml";
156    QString filename = QFileDialog::getSaveFileName(this, tr("Save"),
157                                                    initialPath,
158                                                    tr("%1 Files (*.xml)")
159                                                    .arg(QString("Mapnik definition")));
160    if (!filename.isEmpty()) 
161    {
162        std::cout<<"saving "<< filename.toStdString() << std::endl;
163        mapnik::save_map(*mapWidget_->getMap(),filename.toStdString());
164    }
165}
166
167void MainWindow::load_map_file(QString const& filename)
168{
169    std::cout<<"loading "<< filename.toStdString() << std::endl;   
170    unsigned width = mapWidget_->width();
171    unsigned height = mapWidget_->height();
172    boost::shared_ptr<mapnik::Map> map(new mapnik::Map(width,height)); 
173    mapWidget_->setMap(map);
174    try 
175    { 
176        mapnik::load_map(*map,filename.toStdString());
177    }
178    catch (mapnik::config_error & ex) 
179    {
180        std::cout << ex.what() << "\n";
181    }
182    catch (...)
183    {
184        std::cerr << "Exception caught in load_map\n";
185    }
186    layerTab_->setModel(new LayerListModel(map,this));
187    styleTab_->setModel(new StyleModel(map,this));
188    zoom_all();
189}
190
191void MainWindow::zoom_to_box()
192{
193    mapWidget_->setTool(MapWidget::ZoomToBox);
194}
195
196void MainWindow::pan()
197{
198    mapWidget_->setTool(MapWidget::Pan);   
199}
200
201void MainWindow::info()
202{
203    mapWidget_->setTool(MapWidget::Info);
204}
205
206void MainWindow::pan_left()
207{
208    mapWidget_->panLeft();
209}
210
211void MainWindow::pan_right()
212{
213    mapWidget_->panRight();
214}
215
216void MainWindow::pan_up()
217{
218    mapWidget_->panUp();
219}
220
221void MainWindow::pan_down()
222{
223    mapWidget_->panDown();
224}
225
226void MainWindow::about()
227{
228    about_dialog dlg;
229    dlg.exec();
230}
231
232void MainWindow::export_as()
233{
234    QAction *action = qobject_cast<QAction *>(sender());
235    QByteArray fileFormat = action->data().toByteArray();
236    QString initialPath = QDir::currentPath() + "/map." + fileFormat;
237
238    QString fileName = QFileDialog::getSaveFileName(this, tr("Export As"),
239                                                    initialPath,
240                                                    tr("%1 Files (*.%2);;All Files (*)")
241                                                    .arg(QString(fileFormat.toUpper()))
242                                                    .arg(QString(fileFormat)));
243    if (!fileName.isEmpty()) 
244    {
245        QPixmap const& pix = mapWidget_->pixmap();
246        pix.save(fileName);
247    }
248}
249
250void MainWindow::print()
251{   
252   
253    //Q_ASSERT(mapWidget_->pixmap());
254    //QPrintDialog dialog(&printer, this);
255    //if (dialog.exec()) {
256    //   QPainter painter(&printer);
257    //   QRect rect = painter.viewport();
258    //   QSize size = mapWidget_->pixmap()->size();
259    //   size.scale(rect.size(), Qt::KeepAspectRatio);
260    //   painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
261    //   painter.setWindow(mapWidget_->pixmap()->rect());
262    //   painter.drawPixmap(0, 0, *mapWidget_->pixmap());
263    //}
264}
265
266void MainWindow::createActions()
267{ 
268    //exportAct = new QAction(tr("&Export as ..."),this);
269    //exportAct->setShortcut(tr("Ctrl+E"));
270    //connect(exportAct, SIGNAL(triggered()), this, SLOT(export_as()));
271    zoomAllAct = new QAction(QIcon(":/images/home.png"),tr("Zoom All"),this);
272    connect(zoomAllAct, SIGNAL(triggered()), this, SLOT(zoom_all()));
273   
274    zoomBoxAct = new QAction(QIcon(":/images/zoombox.png"),tr("Zoom To Box"),this);
275    zoomBoxAct->setCheckable(true);
276    connect(zoomBoxAct, SIGNAL(triggered()), this, SLOT(zoom_to_box()));
277   
278    panAct = new QAction(QIcon(":/images/pan.png"),tr("Pan"),this);
279    panAct->setCheckable(true);
280    connect(panAct, SIGNAL(triggered()), this, SLOT(pan()));
281   
282    infoAct = new QAction(QIcon(":/images/info.png"),tr("Info"),this);
283    infoAct->setCheckable(true);
284    connect(infoAct, SIGNAL(triggered()), this, SLOT(info()));
285   
286    toolsGroup=new QActionGroup(this);
287    toolsGroup->addAction(zoomBoxAct);
288    toolsGroup->addAction(panAct);
289    toolsGroup->addAction(infoAct);
290    zoomBoxAct->setChecked(true);
291       
292    openAct=new QAction(tr("Open Map definition"),this);
293    connect(openAct,SIGNAL(triggered()),this,SLOT(open()));
294    saveAct=new QAction(tr("Save Map definition"),this);
295    connect(saveAct,SIGNAL(triggered()),this,SLOT(save()));
296
297    panLeftAct = new QAction(QIcon(":/images/left.png"),tr("&Pan Left"),this);
298    connect(panLeftAct, SIGNAL(triggered()), this, SLOT(pan_left()));
299    panRightAct = new QAction(QIcon(":/images/right.png"),tr("&Pan Right"),this);
300    connect(panRightAct, SIGNAL(triggered()), this, SLOT(pan_right()));
301    panUpAct = new QAction(QIcon(":/images/up.png"),tr("&Pan Up"),this);
302    connect(panUpAct, SIGNAL(triggered()), this, SLOT(pan_up()));
303    panDownAct = new QAction(QIcon(":/images/down.png"),tr("&Pan Down"),this);
304    connect(panDownAct, SIGNAL(triggered()), this, SLOT(pan_down()));
305   
306    reloadAct = new QAction(QIcon(":/images/reload.png"),tr("Reload"),this);
307    connect(reloadAct, SIGNAL(triggered()), this, SLOT(reload()));
308   
309    layerInfo = new QAction(QIcon(":/images/info.png"),tr("&Layer info"),layerTab_);
310    connect(layerInfo, SIGNAL(triggered()), layerTab_,SLOT(layerInfo()));
311    connect(layerTab_, SIGNAL(doubleClicked(QModelIndex const&)), layerTab_,SLOT(layerInfo2(QModelIndex const&)));
312    foreach (QByteArray format, QImageWriter::supportedImageFormats()) 
313    {
314        QString text = tr("%1...").arg(QString(format).toUpper());
315     
316        QAction *action = new QAction(text, this);
317        action->setData(format);
318        connect(action, SIGNAL(triggered()), this, SLOT(export_as()));
319        exportAsActs.append(action);
320    }
321   
322    printAct = new QAction(QIcon(":/images/print.png"),tr("&Print ..."),this);
323    printAct->setShortcut(tr("Ctrl+E"));
324    connect(printAct, SIGNAL(triggered()), this, SLOT(print()));
325   
326    exitAct = new QAction(tr("E&xit"), this);
327    exitAct->setShortcut(tr("Ctrl+Q"));
328    connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
329
330    aboutAct = new QAction(QIcon(":/images/about.png"),tr("&About"), this);
331    connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
332}
333
334void MainWindow::createMenus()
335{
336    exportMenu = new QMenu(tr("&Export As"), this);
337    foreach (QAction *action, exportAsActs)
338        exportMenu->addAction(action); 
339       
340    fileMenu = new QMenu(tr("&File"),this);
341    fileMenu->addAction(openAct);
342    fileMenu->addAction(saveAct);
343    fileMenu->addMenu(exportMenu);
344    fileMenu->addAction(printAct);
345    fileMenu->addSeparator();
346    fileMenu->addAction(exitAct);
347    menuBar()->addMenu(fileMenu);
348   
349    helpMenu = new QMenu(tr("&Help"), this);
350    helpMenu->addAction(aboutAct);
351    menuBar()->addMenu(helpMenu);
352}
353
354void MainWindow::createToolBars()
355{
356    fileToolBar = addToolBar(tr("Actions"));
357    fileToolBar->addAction(zoomAllAct);
358    fileToolBar->addAction(zoomBoxAct);
359    fileToolBar->addAction(panAct);
360    fileToolBar->addAction(panLeftAct);
361    fileToolBar->addAction(panRightAct);
362    fileToolBar->addAction(panUpAct);
363    fileToolBar->addAction(panDownAct);
364    fileToolBar->addAction(infoAct);
365    fileToolBar->addAction(reloadAct);
366    fileToolBar->addAction(printAct);
367    slider_ = new QSlider(Qt::Horizontal,fileToolBar);
368    slider_->setRange(1,18);
369    slider_->setTickPosition(QSlider::TicksBelow);
370    slider_->setTickInterval(1);
371    slider_->setTracking(false);
372    fileToolBar->addWidget(slider_);
373    fileToolBar->addAction(aboutAct);
374}
375
376
377
378void MainWindow::set_default_extent(double x0,double y0, double x1, double y1)
379{
380    try 
381    {
382        boost::shared_ptr<mapnik::Map> map_ptr = mapWidget_->getMap();
383        if (map_ptr) 
384        {
385            mapnik::projection prj(map_ptr->srs());
386            prj.forward(x0,y0);
387            prj.forward(x1,y1);
388            default_extent_=mapnik::box2d<double>(x0,y0,x1,y1);
389            mapWidget_->zoomToBox(default_extent_);
390            std::cout << "SET DEFAULT EXT\n";
391        }
392    }
393    catch (...) {}
394}
395
396void MainWindow::set_scaling_factor(double scaling_factor)
397{
398    mapWidget_->set_scaling_factor(scaling_factor);
399}
400
401void MainWindow::zoom_all()
402{
403    boost::shared_ptr<mapnik::Map> map_ptr = mapWidget_->getMap();
404    if (map_ptr) 
405    {
406        map_ptr->zoom_all();
407        mapnik::box2d<double> const& ext = map_ptr->get_current_extent();
408        mapWidget_->zoomToBox(ext);
409    }
410}
Note: See TracBrowser for help on using the browser.