void CreateSingleWayInteraction::paintEvent(QPaintEvent* anEvent, QPainter& thePainter) { if (theRoad && (!theRoad->layer() || theRoad->isDeleted())) { // The road was begon and then undoed. Restarting.... HaveFirst = false; theRoad = NULL; Creating = false; view()->setInteracting(false); } if (HaveFirst) { QPointF PreviousPoint; if (theRoad && theRoad->size() && !Prepend) PreviousPoint = COORD_TO_XY(CAST_NODE(theRoad->get(theRoad->size()-1))->position()); else PreviousPoint = COORD_TO_XY(FirstPoint); QBrush SomeBrush(QColor(0xff,0x77,0x11,128)); QPen TP(SomeBrush,qBound(3, int(view()->pixelPerM()*4+2), 10)); ::draw(thePainter,TP,Feature::UnknownDirection, PreviousPoint,LastCursor ,4 ,view()->projection()); Coord NewPoint = XY_TO_COORD(LastCursor); const qreal distance = FirstPoint.distanceFrom(NewPoint); QString distanceTag; if (distance < 1.0) distanceTag = QString("%1 m").arg(int(distance * 1000)); else distanceTag = QString("%1 km").arg(distance, 0, 'f', 3); thePainter.drawText(LastCursor + QPointF(10,-10), distanceTag); } FeatureSnapInteraction::paintEvent(anEvent,thePainter); }
void ScaleInteraction::snapMousePressEvent(QMouseEvent * anEvent, Feature* aLast) { QList<Feature*> sel; if (view()->isSelectionLocked()) { if (theMain->properties()->selection(0)) sel.append(theMain->properties()->selection(0)); else sel.append(aLast); } else { sel = theMain->properties()->selection(); if (!sel.size() && aLast) sel.append(aLast); } Radius = 1.0; clearNoSnap(); Scaling.clear(); OriginalPosition.clear(); if (!sel.size()) return; view()->setInteracting(true); StartDragPosition = XY_TO_COORD(anEvent->pos()); OriginNode = NULL; NodeOrigin = false; CoordBox selBB = sel[0]->boundingBox(); for (int j=0; j<sel.size(); j++) { selBB.merge(sel[j]->boundingBox()); if (CHECK_WAY(sel[j])) { Way* R = STATIC_CAST_WAY(sel[j]); for (int i=0; i<R->size(); ++i) if (std::find(Scaling.begin(),Scaling.end(),R->get(i)) == Scaling.end()) Scaling.push_back(R->getNode(i)); addToNoSnap(R); } else if (CHECK_NODE(sel[j])) { if (!OriginNode && !NodeOrigin) { OriginNode = STATIC_CAST_NODE(sel[j]); NodeOrigin = true; } else { NodeOrigin = false; } } } if (Scaling.size() > 1) { if (NodeOrigin) { ScaleCenter = COORD_TO_XY(OriginNode->position()); } else { ScaleCenter = COORD_TO_XY(selBB.center()); } for (int i=0; i<Scaling.size(); ++i) { OriginalPosition.push_back(Scaling[i]->position()); addToNoSnap(Scaling[i]); } } else Scaling.clear(); }
void EditInteraction::paintEvent(QPaintEvent* anEvent, QPainter& thePainter) { if (Dragging) { thePainter.setPen(QPen(QColor(255,0,0),1,Qt::DotLine)); thePainter.drawRect(QRectF(COORD_TO_XY(StartDrag),COORD_TO_XY(EndDrag))); } FeatureSnapInteraction::paintEvent(anEvent, thePainter); }
void CreateDoubleWayInteraction::paintEvent(QPaintEvent* /* anEvent */, QPainter& thePainter) { if (R1 && (!R1->layer() || R1->isDeleted())) { // The roads were begon and then undoed. Restarting.... HaveFirst = false; view()->setInteracting(false); R1 = R2 = NULL; } qreal rB = view()->pixelPerM()*DockData.RoadDistance->text().toDouble()/2; if (!HaveFirst) { thePainter.setPen(QColor(0,0,0)); thePainter.drawEllipse(int(LastCursor.x()-rB),int(LastCursor.y()-rB),int(rB*2),int(rB*2)); } else { Coord PreviousPoint; if (R1 && R1->size()) PreviousPoint = PreviousPoints[R1->size()-1]; else PreviousPoint = FirstPoint; if (distance(COORD_TO_XY(PreviousPoint), LastCursor) > 1) { qreal rA = FirstDistance * view()->pixelPerM()/2; LineF FA1(COORD_TO_XY(PreviousPoint),LastCursor); LineF FA2(FA1); LineF FB1(FA1); LineF FB2(FA1); FA1.slide(-rA); FA2.slide(rA); FB1.slide(-rB); FB2.slide(rB); QPointF A1(FA1.project(COORD_TO_XY(PreviousPoint))); QPointF A2(FA2.project(COORD_TO_XY(PreviousPoint))); QPointF B1(FB1.project(LastCursor)); QPointF B2(FB2.project(LastCursor)); QBrush SomeBrush(QColor(0xff,0x77,0x11,128)); QPen TP(SomeBrush,view()->pixelPerM()*4); if (DockData.DriveRight->isChecked()) { ::draw(thePainter,TP,Feature::OneWay, B1,A1,rB/4,view()->projection()); ::draw(thePainter,TP,Feature::OneWay, A2,B2,rB/4,view()->projection()); } else { ::draw(thePainter,TP,Feature::OneWay, A1,B1,rB/4,view()->projection()); ::draw(thePainter,TP,Feature::OneWay, B2,A2,rB/4,view()->projection()); } } } }
qreal RotateInteraction::calculateNewAngle(QMouseEvent *event) { QPointF p1 = COORD_TO_XY(StartDragPosition); QLineF v1(RotationCenter, p1); QLineF v2(RotationCenter, event->pos()); return v1.angleTo(v2); }
Coord RotateInteraction::rotatePosition(Coord position, qreal angle) { QPointF p = COORD_TO_XY(position); QLineF v(RotationCenter, p); v.setAngle(v.angle() + angle); return XY_TO_COORD(v.p2().toPoint()); }
Coord ScaleInteraction::scalePosition(Coord position, qreal radius) { QPointF p = COORD_TO_XY(position); QLineF v(ScaleCenter, p); v.setLength(v.length() * radius); return XY_TO_COORD(v.p2().toPoint()); }
void RotateInteraction::paintEvent(QPaintEvent* anEvent, QPainter& thePainter) { if (!RotationCenter.isNull()) { thePainter.setPen(QPen(QColor(255,0,0),1)); thePainter.drawEllipse(COORD_TO_XY(RotationCenter), 5, 5); } FeatureSnapInteraction::paintEvent(anEvent, thePainter); }
void ScaleInteraction::snapMouseMoveEvent(QMouseEvent* anEvent, Feature* /*Closer*/) { if (Scaling.size() && !panning()) { Radius = distance(ScaleCenter,anEvent->pos()) / distance(ScaleCenter, COORD_TO_XY(StartDragPosition)); for (int i=0; i<Scaling.size(); ++i) { if (NodeOrigin && Scaling[i] == OriginNode) continue; Scaling[i]->setPosition(scalePosition(OriginalPosition[i], Radius)); } view()->invalidate(true, true, false); } }
CreateSingleWayInteraction::CreateSingleWayInteraction(MainWindow* aMain, Node *firstNode, bool aCurved) : FeatureSnapInteraction(aMain), theRoad(0), FirstPoint(0,0), FirstNode(firstNode), HaveFirst(false), Prepend(false), IsCurved(aCurved), Creating(false) , SnapAngle(0) , ParallelMode(false) { if (firstNode) { FirstPoint = firstNode->position(); LastCursor = COORD_TO_XY(FirstPoint); HaveFirst = true; view()->setInteracting(true); if ((theRoad = Way::GetSingleParentRoad(firstNode))) { if (theRoad->isExtrimity(firstNode)) { Prepend = (theRoad->get(0) == firstNode) ? true : false; } else theRoad = NULL; } } }
void CreateRoundaboutInteraction::calculatePoints() { Points.clear(); if (HaveCenter) { QPointF CenterF(COORD_TO_XY(Center)); qreal Radius = distance(CenterF,LastCursor)/view()->pixelPerM(); qreal Precision = DockData.precision->value(); //2.49; /* Let the precision be the approximate number of meters per arc */ qreal Circumference = 2*M_PI*Radius; qreal Steps = Circumference/Precision; if (Steps < 3) Steps = 3; qreal Angle = 2*M_PI/Steps; /* Normalize the radius for drawing */ Radius *= view()->pixelPerM(); qreal Modifier = DockData.drivingSide->currentIndex() == 1 ? -1:1; for (qreal a = 0; a<2*M_PI; a+=Angle) { QPointF point(CenterF.x()+cos(Modifier*a)*Radius,CenterF.y()+sin(Modifier*a)*Radius); Points.append(point); } } }
void CreateDoubleWayInteraction::mousePressEvent(QMouseEvent* anEvent) { if (anEvent->buttons() & Qt::LeftButton) { if (!HaveFirst) { HaveFirst = true; view()->setInteracting(true); FirstPoint = XY_TO_COORD(anEvent->pos()); FirstDistance = DockData.RoadDistance->text().toDouble(); } else if (R1) { int i1 = R1->size()-1; int i2 = 1; LineF P1( COORD_TO_XY(R1->getNode(i1-1)), COORD_TO_XY(R1->getNode(i1))); LineF P2( COORD_TO_XY(R2->getNode(i2-1)), COORD_TO_XY(R2->getNode(i2))); Coord PreviousPoint = PreviousPoints[R1->size()-1]; if (distance(COORD_TO_XY(PreviousPoint), LastCursor) > 1) { qreal rB = view()->pixelPerM()*DockData.RoadDistance->text().toDouble()/2; qreal rA = FirstDistance * view()->pixelPerM()/2; LineF FA1(COORD_TO_XY(PreviousPoint),LastCursor); LineF FA2(FA1); LineF FB1(FA1); LineF FB2(FA1); qreal Modifier = DockData.DriveRight->isChecked()?1:-1; FA1.slide(rA*Modifier); FA2.slide(-rA*Modifier); FB1.slide(rB*Modifier); FB2.slide(-rB*Modifier); LineF N1(FA1.project(COORD_TO_XY(PreviousPoint)), FB1.project(LastCursor)); LineF N2(FA2.project(COORD_TO_XY(PreviousPoint)), FB2.project(LastCursor)); Node* A1; Node* A2; CommandList* L = new CommandList(MainWindow::tr("Add nodes to double-way Road %1").arg(R1->id().numId), R1); A1 = R1->getNode(i1); A2 = R2->getNode(i2-1); L->add(new MoveNodeCommand(A1,XY_TO_COORD( P1.intersectionWith(N1).toPoint()))); L->add(new MoveNodeCommand(A2,XY_TO_COORD( P2.intersectionWith(N2).toPoint()))); Node* B1 = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD( FB1.project(LastCursor).toPoint())); Node* B2 = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD( FB2.project(LastCursor).toPoint())); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),B1,true)); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),B2,true)); L->add(new WayAddNodeCommand(R1,B1)); L->add(new WayAddNodeCommand(R2,B2,(int)0)); document()->addHistory(L); view()->invalidate(true, true, false); //FirstPoint = view()->projection().inverse(anEvent->pos()); PreviousPoints[R1->size()-1] = XY_TO_COORD(anEvent->pos()); FirstDistance = DockData.RoadDistance->text().toDouble(); } } else { Coord PreviousPoint = FirstPoint; if (distance(COORD_TO_XY(PreviousPoint), LastCursor) > 1) { qreal rB = view()->pixelPerM()*DockData.RoadDistance->text().toDouble()/2; qreal rA = FirstDistance * view()->pixelPerM()/2; LineF FA1(COORD_TO_XY(PreviousPoint),LastCursor); LineF FA2(FA1); LineF FB1(FA1); LineF FB2(FA1); qreal Modifier = DockData.DriveRight->isChecked()?1:-1; FA1.slide(rA*Modifier); FA2.slide(-rA*Modifier); FB1.slide(rB*Modifier); FB2.slide(-rB*Modifier); Node* A1 = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD( FA1.project(COORD_TO_XY(PreviousPoint)).toPoint())); Node* A2 = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD( FA2.project(COORD_TO_XY(PreviousPoint)).toPoint())); Node* B1 = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD( FB1.project(LastCursor).toPoint())); Node* B2 = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD( FB2.project(LastCursor).toPoint())); R1 = g_backend.allocWay(theMain->document()->getDirtyOrOriginLayer()); R2 = g_backend.allocWay(theMain->document()->getDirtyOrOriginLayer()); CommandList* L = new CommandList(MainWindow::tr("Create double-way Road %1").arg(R1->id().numId), R1); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),A1,true)); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),A2,true)); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),B1,true)); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),B2,true)); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),R1,true)); L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),R2,true)); if (M_PREFS->getAutoSourceTag()) { QStringList sl = theMain->document()->getCurrentSourceTags(); if (sl.size()) { R1->setTag("source", sl.join(";")); R2->setTag("source", sl.join(";")); } } R1->setTag("oneway","yes"); R2->setTag("oneway","yes"); L->add(new WayAddNodeCommand(R1,A1)); L->add(new WayAddNodeCommand(R1,B1)); L->add(new WayAddNodeCommand(R2,B2)); L->add(new WayAddNodeCommand(R2,A2)); document()->addHistory(L); view()->invalidate(true, true, false); //FirstPoint = view()->projection().inverse(anEvent->pos()); PreviousPoints[R1->size()-1] = XY_TO_COORD(anEvent->pos()); FirstDistance = DockData.RoadDistance->text().toDouble(); } } } else Interaction::mousePressEvent(anEvent); }
void CreateSingleWayInteraction::snapMouseMoveEvent(QMouseEvent* ev, Feature* lastSnap) { if (Node* Pt = dynamic_cast<Node*>(lastSnap)) LastCursor = COORD_TO_XY(Pt); else if (Way* R = dynamic_cast<Way*>(lastSnap)) { Coord P(XY_TO_COORD(ev->pos())); findSnapPointIndex(R, P); LastCursor = COORD_TO_XY(P); } else if (theRoad && theRoad->size() > 1 && SnapAngle) { QLineF l1(COORD_TO_XY(theRoad->getNode(theRoad->size()-1)), COORD_TO_XY(theRoad->getNode(theRoad->size()-2))); QLineF l2(COORD_TO_XY(theRoad->getNode(theRoad->size()-1)), ev->pos()); qreal a = l1.angleTo(l2); a = qRound(a/SnapAngle) * SnapAngle; l2.setAngle(l1.angle() + a); LastCursor = l2.p2().toPoint(); } else if (HaveFirst && ParallelMode) { #define CLEAR_DISTANCE 200 QPointF PreviousPoint; if (theRoad && theRoad->size() && !Prepend) PreviousPoint = COORD_TO_XY(CAST_NODE(theRoad->get(theRoad->size()-1))->position()); else PreviousPoint = COORD_TO_XY(FirstPoint); CoordBox HotZone(XY_TO_COORD(ev->pos()-QPoint(CLEAR_DISTANCE, CLEAR_DISTANCE)),XY_TO_COORD(ev->pos()+QPoint(CLEAR_DISTANCE, CLEAR_DISTANCE))); qreal BestDistanceNW = 9999, AngleNW = 0; qreal BestDistanceNE = 9999, AngleNE = 0; qreal* BestDistance = &BestDistanceNW; qreal* BestAngle = &BestDistanceNE; qreal curAngle = 666; Way* R; for (int j=0; j<document()->layerSize(); ++j) { QList < Feature* > ret = g_backend.indexFind(document()->getLayer(j), HotZone); foreach(Feature* F, ret) { if (!(R = CAST_WAY(F))) continue; if (R->isHidden()) continue; if (R->notEverythingDownloaded()) continue; for (int i=0; i<R->size()-1; ++i) { LineF F(COORD_TO_XY(R->getNode(i)),COORD_TO_XY(R->getNode(i+1))); qreal D = F.capDistance(ev->pos()); if (D < CLEAR_DISTANCE) { QLineF l(COORD_TO_XY(R->getNode(i)), COORD_TO_XY(R->getNode(i+1))); qreal a = l.angle(); if ((a >= 0 && a < 90) || (a < -270 && a >= -360)) { BestDistance = &BestDistanceNE; BestAngle = &AngleNE; curAngle = a; } else if ((a >= 90 && a < 180) || (a < -180 && a >= -270)) { BestDistance = &BestDistanceNW; BestAngle = &AngleNW; curAngle = a; } else if ((a >= 180 && a < 270) || (a < -90 && a >= -180)) { BestDistance = &BestDistanceNE; BestAngle = &AngleNE; curAngle = a - 180; } else if ((a >= 270 && a < 360) || (a < 0 && a >= -90)) { BestDistance = &BestDistanceNW; BestAngle = &AngleNW; curAngle = a - 180; } if (D < *BestDistance) { *BestDistance = D; *BestAngle = curAngle; } } } qDebug() << BestDistanceNE << BestDistanceNW << AngleNE << AngleNW; } } /* Check if for some reason not a single angle was found. */ Q_ASSERT(curAngle >= -360 && curAngle <= 360); QLineF l(PreviousPoint, ev->pos()); qreal a = l.angle(); if ((a >= 0 && a < 90) || (a < -270 && a >= -360)) { if (BestDistanceNE < 9999) a = AngleNE; } else if ((a >= 90 && a < 180) || (a < -180 && a >= -270)) { if (BestDistanceNW < 9999) a = AngleNW; } else if ((a >= 180 && a < 270) || (a < -90 && a >= -180)) { if (BestDistanceNE < 9999) a = AngleNE - 180; } else if ((a >= 270 && a < 360) || (a < 0 && a >= -90)) { if (BestDistanceNW < 9999) a = AngleNW - 180; } l.setAngle(a); LastCursor = l.p2().toPoint(); } else