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);
}
Exemplo n.º 2
0
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();
}
Exemplo n.º 3
0
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());
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 9
0
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