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"
7
#include "Maps/TrackPoint.h"
8
#include "Utils/LineF.h"
9
#include "PropertiesDock.h"
10
#include "Preferences/MerkaartorPreferences.h"
12
#include <QtGui/QDockWidget>
13
#include <QtGui/QPainter>
17
CreateRoundaboutInteraction::CreateRoundaboutInteraction(MainWindow* aMain, MapView* aView)
18
: Interaction(aView), Main(aMain), Center(0,0), HaveCenter(false)
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);
27
DockData.DriveRight->setChecked(MerkaartorPreferences::instance()->getRightSideDriving());
30
CreateRoundaboutInteraction::~CreateRoundaboutInteraction()
32
MerkaartorPreferences::instance()->setRightSideDriving(DockData.DriveRight->isChecked());
37
QString CreateRoundaboutInteraction::toHtml()
40
//help = (MainWindow::tr("LEFT-CLICK to select; LEFT-DRAG to move"));
43
desc = QString("<big><b>%1</b></big><br/>").arg(MainWindow::tr("Create roundabout Interaction"));
44
desc += QString("<b>%1</b><br/>").arg(help);
48
"<small><i>" + QString(metaObject()->className()) + "</i></small><br/>"
50
S += "</body></html>";
55
void CreateRoundaboutInteraction::testIntersections(CommandList* L, Road* Left, int FromIdx, Road* Right, int RightIndex)
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)
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))
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);
77
void CreateRoundaboutInteraction::mousePressEvent(QMouseEvent * event)
79
if (event->buttons() & Qt::LeftButton)
84
Center = XY_TO_COORD(event->pos());
88
QPointF CenterF(COORD_TO_XY(Center));
89
double Radius = distance(CenterF,LastCursor)/view()->pixelPerM();
90
double Precision = 2.49;
93
double Angle = 2*acos(1-Precision/Radius);
94
double Steps = ceil(2*M_PI/Angle);
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));
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)
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));
120
L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),R,true));
121
for (FeatureIterator it(document()); !it.isEnd(); ++it)
123
Road* W1 = dynamic_cast<Road*>(it.get());
125
for (int i=1; i<W1->size(); ++i)
127
int Before = W1->size();
128
testIntersections(L,R,1,W1,i);
129
int After = W1->size();
133
Main->properties()->setSelection(R);
134
document()->addHistory(L);
135
view()->invalidate(true, false);
140
Interaction::mousePressEvent(event);
143
void CreateRoundaboutInteraction::mouseMoveEvent(QMouseEvent* event)
145
LastCursor = event->pos();
148
Interaction::mouseMoveEvent(event);
151
void CreateRoundaboutInteraction::paintEvent(QPaintEvent* , QPainter& thePainter)
155
QPointF CenterF(COORD_TO_XY(Center));
156
double Radius = distance(CenterF,LastCursor)/view()->pixelPerM();
157
double Precision = 1.99;
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)
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());
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());
180
QCursor CreateRoundaboutInteraction::cursor() const
182
return QCursor(Qt::CrossCursor);