~ubuntu-branches/ubuntu/saucy/merkaartor/saucy

« back to all changes in this revision

Viewing changes to src/Interaction/CreateRoundaboutInteraction.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bernd Zeimetz
  • Date: 2009-09-13 00:52:12 UTC
  • mto: (1.2.7 upstream) (0.1.3 upstream) (3.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20090913005212-pjecal8zxm07x0fj
ImportĀ upstreamĀ versionĀ 0.14+svnfixes~20090912

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Interaction/CreateRoundaboutInteraction.h"
 
2
#include "Command/DocumentCommands.h"
 
3
#include "Command/RoadCommands.h"
 
4
#include "Command/TrackPointCommands.h"
 
5
#include "Maps/Painting.h"
 
6
#include "Maps/Road.h"
 
7
#include "Maps/TrackPoint.h"
 
8
#include "Utils/LineF.h"
 
9
#include "PropertiesDock.h"
 
10
#include "Preferences/MerkaartorPreferences.h"
 
11
 
 
12
#include <QtGui/QDockWidget>
 
13
#include <QtGui/QPainter>
 
14
 
 
15
#include <math.h>
 
16
 
 
17
CreateRoundaboutInteraction::CreateRoundaboutInteraction(MainWindow* aMain, MapView* aView)
 
18
        : Interaction(aView), Main(aMain), Center(0,0), HaveCenter(false)
 
19
{
 
20
        theDock = new QDockWidget(Main);
 
21
        QWidget* DockContent = new QWidget(theDock);
 
22
        DockData.setupUi(DockContent);
 
23
        theDock->setWidget(DockContent);
 
24
        theDock->setAllowedAreas(Qt::LeftDockWidgetArea);
 
25
        Main->addDockWidget(Qt::LeftDockWidgetArea, theDock);
 
26
        theDock->show();
 
27
        DockData.DriveRight->setChecked(MerkaartorPreferences::instance()->getRightSideDriving());
 
28
}
 
29
 
 
30
CreateRoundaboutInteraction::~CreateRoundaboutInteraction()
 
31
{
 
32
        MerkaartorPreferences::instance()->setRightSideDriving(DockData.DriveRight->isChecked());
 
33
        delete theDock;
 
34
        view()->update();
 
35
}
 
36
 
 
37
QString CreateRoundaboutInteraction::toHtml()
 
38
{
 
39
        QString help;
 
40
        //help = (MainWindow::tr("LEFT-CLICK to select; LEFT-DRAG to move"));
 
41
 
 
42
        QString desc;
 
43
        desc = QString("<big><b>%1</b></big><br/>").arg(MainWindow::tr("Create roundabout Interaction"));
 
44
        desc += QString("<b>%1</b><br/>").arg(help);
 
45
 
 
46
        QString S =
 
47
        "<html><head/><body>"
 
48
        "<small><i>" + QString(metaObject()->className()) + "</i></small><br/>"
 
49
        + desc;
 
50
        S += "</body></html>";
 
51
 
 
52
        return S;
 
53
}
 
54
 
 
55
void CreateRoundaboutInteraction::testIntersections(CommandList* L, Road* Left, int FromIdx, Road* Right, int RightIndex)
 
56
{
 
57
        LineF L1(COORD_TO_XY(Right->getNode(RightIndex-1)),
 
58
                COORD_TO_XY(Right->getNode(RightIndex)));
 
59
        for (int i=FromIdx; i<Left->size(); ++i)
 
60
        {
 
61
                LineF L2(COORD_TO_XY(Left->getNode(i-1)),
 
62
                        COORD_TO_XY(Left->getNode(i)));
 
63
                QPointF Intersection(L1.intersectionWith(L2));
 
64
                if (L1.segmentContains(Intersection) && L2.segmentContains(Intersection))
 
65
                {
 
66
                        TrackPoint* Pt = new TrackPoint(XY_TO_COORD(Intersection));
 
67
                        L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),Pt,true));
 
68
                        L->add(new RoadAddTrackPointCommand(Left,Pt,i));
 
69
                        L->add(new RoadAddTrackPointCommand(Right,Pt,RightIndex));
 
70
                        testIntersections(L,Left,i+2,Right,RightIndex);
 
71
                        testIntersections(L,Left,i+2,Right,RightIndex+1);
 
72
                        return;
 
73
                }
 
74
        }
 
75
}
 
76
 
 
77
void CreateRoundaboutInteraction::mousePressEvent(QMouseEvent * event)
 
78
{
 
79
        if (event->buttons() & Qt::LeftButton)
 
80
        {
 
81
                if (!HaveCenter)
 
82
                {
 
83
                        HaveCenter = true;
 
84
                        Center = XY_TO_COORD(event->pos());
 
85
                }
 
86
                else
 
87
                {
 
88
                        QPointF CenterF(COORD_TO_XY(Center));
 
89
                        double Radius = distance(CenterF,LastCursor)/view()->pixelPerM();
 
90
                        double Precision = 2.49;
 
91
                        if (Radius<2.5)
 
92
                                Radius = 2.5;
 
93
                        double Angle = 2*acos(1-Precision/Radius);
 
94
                        double Steps = ceil(2*M_PI/Angle);
 
95
                        Angle = 2*M_PI/Steps;
 
96
                        Radius *= view()->pixelPerM();
 
97
                        double Modifier = DockData.DriveRight->isChecked()?-1:1;
 
98
                        QBrush SomeBrush(QColor(0xff,0x77,0x11,128));
 
99
                        QPen TP(SomeBrush,view()->pixelPerM()*4);
 
100
                        QPointF Prev(CenterF.x()+cos(Modifier*Angle/2)*Radius,CenterF.y()+sin(Modifier*Angle/2)*Radius);
 
101
                        TrackPoint* First = new TrackPoint(XY_TO_COORD(Prev));
 
102
                        Road* R = new Road;
 
103
                        R->add(First);
 
104
                        R->setTag("oneway","yes");
 
105
                        R->setTag("junction","roundabout");
 
106
                        if (M_PREFS->apiVersionNum() < 0.6)
 
107
                                R->setTag("created_by", QString("Merkaartor v%1%2").arg(STRINGIFY(VERSION)).arg(STRINGIFY(REVISION)));
 
108
                        CommandList* L  = new CommandList(MainWindow::tr("Create Roundabout %1").arg(R->id()), R);
 
109
                        L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),First,true));
 
110
                        for (double a = Angle*3/2; a<2*M_PI; a+=Angle)
 
111
                        {
 
112
                                QPointF Next(CenterF.x()+cos(Modifier*a)*Radius,CenterF.y()+sin(Modifier*a)*Radius);
 
113
                                TrackPoint* New = new TrackPoint(XY_TO_COORD(Next));
 
114
                                if (M_PREFS->apiVersionNum() < 0.6)
 
115
                                        New->setTag("created_by", QString("Merkaartor v%1%2").arg(STRINGIFY(VERSION)).arg(STRINGIFY(REVISION)));
 
116
                                L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),New,true));
 
117
                                R->add(New);
 
118
                        }
 
119
                        R->add(First);
 
120
                        L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),R,true));
 
121
                        for (FeatureIterator it(document()); !it.isEnd(); ++it)
 
122
                        {
 
123
                                Road* W1 = dynamic_cast<Road*>(it.get());
 
124
                                if (W1 && (W1 != R))
 
125
                                        for (int i=1; i<W1->size(); ++i)
 
126
                                        {
 
127
                                                int Before = W1->size();
 
128
                                                testIntersections(L,R,1,W1,i);
 
129
                                                int After = W1->size();
 
130
                                                i += (After-Before);
 
131
                                        }
 
132
                        }
 
133
                        Main->properties()->setSelection(R);
 
134
                        document()->addHistory(L);
 
135
                        view()->invalidate(true, false);
 
136
                        view()->launch(0);
 
137
                }
 
138
        }
 
139
        else
 
140
                Interaction::mousePressEvent(event);
 
141
}
 
142
 
 
143
void CreateRoundaboutInteraction::mouseMoveEvent(QMouseEvent* event)
 
144
{
 
145
        LastCursor = event->pos();
 
146
        if (HaveCenter)
 
147
                view()->update();
 
148
        Interaction::mouseMoveEvent(event);
 
149
}
 
150
 
 
151
void CreateRoundaboutInteraction::paintEvent(QPaintEvent* , QPainter& thePainter)
 
152
{
 
153
        if (HaveCenter)
 
154
        {
 
155
                QPointF CenterF(COORD_TO_XY(Center));
 
156
                double Radius = distance(CenterF,LastCursor)/view()->pixelPerM();
 
157
                double Precision = 1.99;
 
158
                if (Radius<2)
 
159
                        Radius = 2;
 
160
                double Angle = 2*acos(1-Precision/Radius);
 
161
                double Steps = ceil(2*M_PI/Angle);
 
162
                Angle = 2*M_PI/Steps;
 
163
                Radius *= view()->pixelPerM();
 
164
                double Modifier = DockData.DriveRight->isChecked()?-1:1;
 
165
                QBrush SomeBrush(QColor(0xff,0x77,0x11,128));
 
166
                QPen TP(SomeBrush,view()->pixelPerM()*4);
 
167
                QPointF Prev(CenterF.x()+cos(Modifier*Angle/2)*Radius,CenterF.y()+sin(Modifier*Angle/2)*Radius);
 
168
                for (double a = Angle*3/2; a<2*M_PI; a+=Angle)
 
169
                {
 
170
                        QPointF Next(CenterF.x()+cos(Modifier*a)*Radius,CenterF.y()+sin(Modifier*a)*Radius);
 
171
                        ::draw(thePainter,TP,MapFeature::OneWay, Prev,Next,4,view()->projection());
 
172
                        Prev = Next;
 
173
                }
 
174
                QPointF Next(CenterF.x()+cos(Modifier*Angle/2)*Radius,CenterF.y()+sin(Modifier*Angle/2)*Radius);
 
175
                ::draw(thePainter,TP,MapFeature::OneWay, Prev,Next,4,view()->projection());
 
176
        }
 
177
}
 
178
 
 
179
#ifndef Q_OS_SYMBIAN
 
180
QCursor CreateRoundaboutInteraction::cursor() const
 
181
{
 
182
        return QCursor(Qt::CrossCursor);
 
183
}
 
184
#endif