source: subversion/applications/editors/merkaartor/PaintStyle/EditPaintStyle.cpp @ 13989

Last change on this file since 13989 was 13597, checked in by Chris Browet, 11 years ago

ADD : Outline coastlines

File size: 9.0 KB
Line 
1#include "PaintStyle/EditPaintStyle.h"
2#include "Map/Painting.h"
3#include "Map/Projection.h"
4#include "Map/TrackPoint.h"
5#include "Map/Relation.h"
6#include "Map/Road.h"
7#include "Map/MapLayer.h"
8#include "PaintStyle/TagSelector.h"
9#include "Utils/LineF.h"
10
11#include <QtCore/QFile>
12#include <QtCore/QTextStream>
13#include <QtGui/QPainter>
14#include <QtGui/QPainterPath>
15#include <QtXml/QDomDocument>
16#include <QtXml/QDomNode>
17
18
19#include <math.h>
20#include <utility>
21
22#define LOCALZOOM               0.05
23#define REGIONALZOOM    0.01
24#define GLOBALZOOM              0.002
25
26EditPaintStyle* EditPaintStyle::m_EPSInstance = 0;
27
28//static bool localZoom(const Projection& theProjection)
29//{
30//      return theProjection.pixelPerM() < LOCALZOOM;
31//}
32
33static bool regionalZoom(const Projection& theProjection)
34{
35        return theProjection.pixelPerM() < REGIONALZOOM;
36}
37
38static bool globalZoom(const Projection& theProjection)
39{
40        return theProjection.pixelPerM() < GLOBALZOOM;
41}
42
43class EditPaintStylePrivate
44{
45        public:
46                EditPaintStylePrivate(QPainter& P, const Projection& aProj)
47                        : thePainter(P), theProjection(aProj)
48                {
49                        First.setP(this);
50                        Second.setP(this);
51                        Third.setP(this);
52                        Fourth.setP(this);
53                }
54
55                QPainter& thePainter;
56                const Projection& theProjection;
57                EPBackgroundLayer First;
58                EPForegroundLayer Second;
59                EPTouchupLayer Third;
60                EPLabelLayer Fourth;
61                bool isTrackPointVisible;
62                bool isTrackSegmentVisible;
63};
64
65#define ALWAYS 10e6
66
67/* Zoom boundaries : expressed in Pixel per Meter
68
69   eg 0.01->ALWAYS means show a feature from a zoom level of 0.01 Pixel Per M,
70   or 100 Meter per Pixel. For a screen of 1000px wide this is when viewing
71   100km or less across.
72
73   eg 0.2->ALWAYS means show a feature from a zoom level 0.2 Px/M or 5M/Px which
74   is viewing 5km or less across a screen of 1000Px. */
75
76void EPBackgroundLayer::setP(EditPaintStylePrivate* ap)
77{
78        p = ap;
79}
80
81
82void EPBackgroundLayer::draw(Road* R)
83{
84        const FeaturePainter* paintsel = R->getEditPainter(p->theProjection.pixelPerM());
85        if (paintsel)
86                paintsel->drawBackground(R,p->thePainter,p->theProjection);
87        else if (/*!globalZoom(p->theProjection) && */!R->hasEditPainter()) //FIXME Untagged roads level of zoom?
88        {
89                QPen thePen(QColor(0,0,0),1);
90
91                p->thePainter.setBrush(Qt::NoBrush);
92                if (dynamic_cast<ImageMapLayer*>(R->layer()) && M_PREFS->getUseShapefileForBackground()) {
93                        thePen = QPen(QColor(0xc0,0xc0,0xc0),1);
94                        if (!R->isCoastline()) {
95                                if (M_PREFS->getBackgroundOverwriteStyle() || !M_STYLE->getGlobalPainter().getDrawBackground())
96                                        p->thePainter.setBrush(M_PREFS->getBgColor());
97                                else
98                                        p->thePainter.setBrush(QBrush(M_STYLE->getGlobalPainter().getBackgroundColor()));
99                        }
100                } else {
101                        if (regionalZoom(p->theProjection))
102                                thePen = QPen(QColor(0x77,0x77,0x77),1);
103                }
104
105                p->thePainter.setPen(thePen);
106                p->thePainter.drawPath(R->getPath());
107        }
108}
109
110void EPBackgroundLayer::draw(Relation* R)
111{
112        const FeaturePainter* paintsel = R->getEditPainter(p->theProjection.pixelPerM());
113        if (paintsel)
114                paintsel->drawBackground(R,p->thePainter,p->theProjection);
115}
116
117
118void EPBackgroundLayer::draw(TrackPoint*)
119{
120}
121
122void EPForegroundLayer::setP(EditPaintStylePrivate* ap)
123{
124        p = ap;
125}
126
127void EPForegroundLayer::draw(Road* R)
128{
129        const FeaturePainter* paintsel = R->getEditPainter(p->theProjection.pixelPerM());
130        if (paintsel)
131                paintsel->drawForeground(R,p->thePainter,p->theProjection);
132}
133
134void EPForegroundLayer::draw(Relation* R)
135{
136        const FeaturePainter* paintsel = R->getEditPainter(p->theProjection.pixelPerM());
137        if (paintsel)
138                paintsel->drawForeground(R,p->thePainter,p->theProjection);
139}
140
141void EPForegroundLayer::draw(TrackPoint*)
142{
143}
144
145void EPTouchupLayer::setP(EditPaintStylePrivate* ap)
146{
147        p = ap;
148}
149
150void EPTouchupLayer::draw(Road* R)
151{
152        const FeaturePainter* paintsel = R->getEditPainter(p->theProjection.pixelPerM());
153        if (paintsel)
154                paintsel->drawTouchup(R,p->thePainter,p->theProjection);
155        else {
156                if ( M_PREFS->getDirectionalArrowsVisible() != DirectionalArrows_Never )
157                {
158                        MapFeature::TrafficDirectionType TT = trafficDirection(R);
159                        if ( (TT != MapFeature::UnknownDirection) || (M_PREFS->getDirectionalArrowsVisible() == DirectionalArrows_Always) ) 
160                        {
161                                double theWidth = p->theProjection.pixelPerM()*R->widthOf()-4;
162                                if (theWidth > 8)
163                                        theWidth = 8;
164                                double DistFromCenter = 2*(theWidth+4);
165                                if (theWidth > 0)
166                                {
167                                        for (unsigned int i=1; i<R->size(); ++i)
168                                        {
169                                                QPointF FromF(p->theProjection.project(R->getNode(i-1)));
170                                                QPointF ToF(p->theProjection.project(R->getNode(i)));
171                                                if (distance(FromF,ToF) > (DistFromCenter*2+4))
172                                                {
173                                                        QPointF H(FromF+ToF);
174                                                        H *= 0.5;
175                                                        double A = angle(FromF-ToF);
176                                                        QPointF T(DistFromCenter*cos(A),DistFromCenter*sin(A));
177                                                        QPointF V1(theWidth*cos(A+M_PI/6),theWidth*sin(A+M_PI/6));
178                                                        QPointF V2(theWidth*cos(A-M_PI/6),theWidth*sin(A-M_PI/6));
179                                                        if ( M_PREFS->getDirectionalArrowsVisible() == DirectionalArrows_Oneway )
180                                                        {
181                                                                if ( (TT == MapFeature::OtherWay) || (TT == MapFeature::BothWays) )
182                                                                {
183                                                                        p->thePainter.setPen(QColor(0,0,0));
184                                                                        p->thePainter.drawLine(H+T,H+T-V1);
185                                                                        p->thePainter.drawLine(H+T,H+T-V2);
186                                                                }
187                                                                if ( (TT == MapFeature::OneWay) || (TT == MapFeature::BothWays) )
188                                                                {
189                                                                        p->thePainter.setPen(QColor(0,0,0));
190                                                                        p->thePainter.drawLine(H-T,H-T+V1);
191                                                                        p->thePainter.drawLine(H-T,H-T+V2);
192                                                                }
193                                                        } 
194                                                        else
195                                                        {
196                                                                p->thePainter.setPen(QColor(255,0,0));
197                                                                p->thePainter.drawLine(H-T,H-T+V1);
198                                                                p->thePainter.drawLine(H-T,H-T+V2);
199                                                        }
200                                                }
201                                        }
202                                }
203                        }
204                }
205        }
206}
207
208void EPTouchupLayer::draw(Relation* /* R */)
209{
210}
211
212void EPTouchupLayer::draw(TrackPoint* Pt)
213{
214        const FeaturePainter* paintsel = Pt->getEditPainter(p->theProjection.pixelPerM());
215        if (paintsel)
216                paintsel->drawTouchup(Pt,p->thePainter,p->theProjection);
217        else if (!Pt->hasEditPainter()) {
218                if (p->isTrackPointVisible || (Pt->lastUpdated() == MapFeature::Log && !p->isTrackSegmentVisible)) {
219                        bool Draw = p->theProjection.pixelPerM() > 1;
220                        if (!Draw && !Pt->sizeParents() && (p->theProjection.pixelPerM() > LOCALZOOM) )
221                                Draw = true;
222                        if (Pt->lastUpdated() == MapFeature::Log && !p->isTrackSegmentVisible)
223                                Draw = true;
224                        if (Draw)
225                        {
226                                QPointF P(p->theProjection.project(Pt));
227
228                                if (Pt->findKey("_waypoint_") != Pt->tagSize()) {
229                                        QRectF R(P-QPointF(4,4),QSize(8,8)); 
230                                        p->thePainter.fillRect(R,QColor(255,0,0,128)); 
231                                }
232                               
233                                QRectF R(P-QPointF(2,2),QSize(4,4));
234                                p->thePainter.fillRect(R,QColor(0,0,0,128));
235                        }
236                }
237        }
238}
239
240void EPLabelLayer::setP(EditPaintStylePrivate* ap)
241{
242        p = ap;
243}
244
245void EPLabelLayer::draw(Road* R)
246{
247        const FeaturePainter* paintsel = R->getEditPainter(p->theProjection.pixelPerM());
248        if (paintsel)
249                paintsel->drawLabel(R,p->thePainter,p->theProjection);
250}
251
252void EPLabelLayer::draw(Relation* /* R */)
253{
254}
255
256void EPLabelLayer::draw(TrackPoint* Pt)
257{
258        const FeaturePainter* paintsel = Pt->getEditPainter(p->theProjection.pixelPerM());
259        if (paintsel)
260                paintsel->drawLabel(Pt,p->thePainter,p->theProjection);
261}
262
263/* EDITPAINTSTYLE */
264
265EditPaintStyle::EditPaintStyle()
266        : p(0)
267{
268}
269
270EditPaintStyle::~EditPaintStyle(void)
271{
272        delete p;
273}
274
275void EditPaintStyle::initialize(QPainter& P, const Projection& theProjection)
276{
277        if (p) {
278                Layers.clear();
279                delete p;
280        }
281
282        p = new EditPaintStylePrivate(P,theProjection);
283        add(&p->First);
284        add(&p->Second);
285        add(&p->Third);
286        add(&p->Fourth);
287
288        p->isTrackPointVisible = M_PREFS->getTrackPointsVisible();
289        p->isTrackSegmentVisible = M_PREFS->getTrackSegmentsVisible();
290}
291
292void EditPaintStyle::savePainters(const QString& filename)
293{
294        QFile data(filename);
295        if (data.open(QFile::WriteOnly | QFile::Truncate))
296        {
297                QTextStream out(&data);
298                out << "<mapStyle>\n";
299                out << globalPainter.toXML();
300                for (int i=0; i<Painters.size(); ++i)
301                {
302                        QString s = Painters[i].toXML(filename);
303                        out << s;
304                }
305                out << "</mapStyle>\n";
306        }
307}
308
309void EditPaintStyle::loadPainters(const QString& filename)
310{
311        QDomDocument doc;
312        QFile file(filename);
313        if (!file.open(QIODevice::ReadOnly))
314                return;
315        if (!doc.setContent(&file))
316        {
317                file.close();
318                return;
319        }
320        file.close();
321        GlobalPainter gp;
322        globalPainter = gp;
323        Painters.clear();
324        QDomElement docElem = doc.documentElement();
325        QDomNode n = docElem.firstChild();
326        while(!n.isNull())
327        {
328                QDomElement e = n.toElement(); // try to convert the node to an element.
329                if(!e.isNull() && e.tagName() == "global")
330                {
331                        globalPainter = GlobalPainter::fromXML(e);
332                } else
333                if(!e.isNull() && e.tagName() == "painter")
334                {
335                        FeaturePainter FP = FeaturePainter::fromXML(e, filename);
336                        Painters.push_back(FP);
337                }
338                n = n.nextSibling();
339        }
340}
341
342int EditPaintStyle::painterSize()
343{
344        return Painters.size();
345}
346
347const GlobalPainter& EditPaintStyle::getGlobalPainter() const
348{
349        return globalPainter;
350}
351
352void EditPaintStyle::setGlobalPainter(GlobalPainter aGlobalPainter)
353{
354        globalPainter = aGlobalPainter;
355}
356
357const FeaturePainter* EditPaintStyle::getPainter(int i) const
358{
359        return &(Painters[i]);
360}
361
362QVector<FeaturePainter> EditPaintStyle::getPainters() const
363{
364        return Painters;
365}
366
367void EditPaintStyle::setPainters(QVector<FeaturePainter> aPainters)
368{
369        Painters = aPainters;
370}
371
372
Note: See TracBrowser for help on using the repository browser.