Root/poilayer.cpp

1/*
2 * Copyright 2010-2011 Niels Kummerfeldt <niels.kummerfeldt@tu-harburg.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) 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., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
18 */
19
20#include "poilayer.h"
21
22#include "mapwidget.h"
23#include "projection.h"
24
25#include <QtCore/QDebug>
26#include <QtCore/QDir>
27#include <QtCore/QFile>
28#include <QtCore/QSettings>
29#include <QtXml/QXmlStreamReader>
30
31QHash<QString, QPixmap*> PoiLayer::m_iconCache = QHash<QString, QPixmap*>();
32
33PoiLayer::PoiLayer(MapWidget *map) :
34    AbstractLayer(map),
35    m_level(0),
36    m_points(),
37    m_pointsOnScreen(),
38    m_icons(),
39    m_names(),
40    m_pointsOffset(0, 0),
41    m_iconPath()
42{
43    QSettings set(QDir::homePath()+"/Maps/nanomap.conf", QSettings::NativeFormat);
44
45    set.beginGroup("poi");
46    m_iconPath = set.value("iconpath", "/usr/share/NanoMap/icons").toString();
47    set.endGroup();
48}
49
50void PoiLayer::load(const QString &filename)
51{
52    QFile file(filename);
53    if (file.open(QIODevice::ReadOnly)) {
54        QXmlStreamReader xml(&file);
55
56        QStringList categories;
57        categories << "highway";
58        categories << "traffic_calming";
59        categories << "barrier";
60        categories << "waterway";
61        categories << "railway";
62        categories << "aeroway";
63        categories << "aerialway";
64        categories << "power";
65        categories << "man_made";
66        categories << "leisure";
67        categories << "amenity";
68        categories << "office";
69        categories << "shop";
70        categories << "craft";
71        categories << "emergency";
72        categories << "tourism";
73        categories << "historic";
74        categories << "landuse";
75        categories << "military";
76        categories << "natural";
77        categories << "geological";
78        categories << "sport";
79
80        QHash<QString, QString> tags;
81        QPointF pos;
82        while (!xml.atEnd()) {
83            xml.readNext();
84            if (xml.isStartElement()) {
85                if (xml.name() == "node") {
86                    float lat = xml.attributes().value("lat").toString().toFloat();
87                    float lon = xml.attributes().value("lon").toString().toFloat();
88
89                    pos = QPointF(Projection::lon2rawx(lon), Projection::lat2rawy(lat));
90                } else if (xml.name() == "tag") {
91                    tags.insert(xml.attributes().value("k").toString(),
92                                xml.attributes().value("v").toString());
93                }
94            } else if (xml.isEndElement()) {
95                if (xml.name() == "node") {
96                    foreach (const QString &c, categories) {
97                        QString t = tags.value(c, "");
98                        if (!t.isEmpty()) {
99                            QString icon = m_iconPath+"/"+c+"-"+t+".png";
100                            if (QFile::exists(icon)) {
101                                if (!m_iconCache.contains(t)) {
102                                    m_iconCache.insert(t, new QPixmap(icon));
103                                }
104                                m_points << pos;
105                                m_icons << t;
106                                m_names << tags.value("name", "");
107                                break;
108                            }
109                        }
110                    }
111                    tags.clear();
112                }
113            }
114        }
115        zoom(0);
116    }
117}
118
119void PoiLayer::zoom(int level)
120{
121    m_level = level;
122    if (m_points.isEmpty()) {
123        return;
124    }
125
126    int scale = 1 << level;
127    m_pointsOnScreen.clear();
128    m_pointsOffset = map()->raw2screen(m_points.first().x(), m_points.first().y(), scale);
129    m_pointsOnScreen << QPoint(0, 0);
130    if (m_points.count() > 1) {
131        for (int i = 1; i < m_points.count(); ++i) {
132            QPointF p = m_points.at(i);
133            m_pointsOnScreen << map()->raw2screen(p.x(), p.y(), scale) - m_pointsOffset;
134        }
135    }
136}
137
138void PoiLayer::pan(const QPoint &move)
139{
140    m_pointsOffset += move;
141}
142
143void PoiLayer::paint(QPainter *painter)
144{
145    QFont font = painter->font();
146    font.setPointSize(8);
147    painter->setFont(font);
148
149    QFontMetrics fm(font);
150    int dy = -fm.ascent()-10;
151
152    painter->setBrush(QColor(200, 200, 255, 190));
153    QPoint p;
154    for (int i = 0; i < m_pointsOnScreen.count(); ++i) {
155        p = m_pointsOnScreen.at(i) + m_pointsOffset;
156        painter->drawPixmap(p - QPoint(8, 8), *m_iconCache.value(m_icons.at(i)));
157
158        QPoint delta = p - QPoint(160, 120);
159        if (m_level > 12 && delta.manhattanLength() < 25) {
160            int dx = fm.width(m_names.at(i));
161            painter->setPen(QColor(200, 200, 255, 190));
162            painter->drawRect(QRect(p - QPoint(dx/2, -10), QSize(dx, fm.height())));
163            painter->setPen(Qt::black);
164            painter->drawText(p - QPoint(dx/2, dy), m_names.at(i));
165        }
166    }
167}
168
169

Archive Download this file

Branches:
master



interactive