예제 #1
0
void ZoomInteraction::mouseReleaseEvent(QMouseEvent * event)
{
    if (!HaveFirstPoint)
    {
        P1 = P2 = event->pos();
        HaveFirstPoint = true;
    }
    else
    {
        P2 = event->pos();
        view()->setViewport(CoordBox(XY_TO_COORD(P1),XY_TO_COORD(P2)),view()->rect());
        view()->invalidate(true, true);
        view()->launch(0);
    }
}
예제 #2
0
void EditInteraction::snapMousePressEvent(QMouseEvent * ev, Feature* aLast)
{
    Qt::KeyboardModifiers modifiers = ev->modifiers();
    if (!view()->isSelectionLocked()) {
        if (modifiers) {
            if (modifiersForToggle(modifiers) && aLast)
                PROPERTIES(toggleSelection(aLast));

            if (modifiersForAdd(modifiers) && aLast)
                PROPERTIES(addSelection(aLast));

            if (g_Merk_Segment_Mode && aLast) {
                PROPERTIES(setSelection(aLast));
            }
        } else {
            StackSnap = SnapList;
//				if (aLast)
//					PROPERTIES(setSelection(aLast));
        }
        if (!aLast && modifiersForDrag(modifiers))
        {
            EndDrag = StartDrag = XY_TO_COORD(ev->pos());
            Dragging = true;
        }
        PROPERTIES(checkMenuStatus());
        view()->update();
    }
}
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);
}
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());
}
예제 #5
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());
}
예제 #6
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();
}
void CreateRoundaboutInteraction::mousePressEvent(QMouseEvent * event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        if (!HaveCenter)
        {
            HaveCenter = true;
            view()->setInteracting(true);
            Center = XY_TO_COORD(event->pos());
        }
        else
        {
            calculatePoints();
            if (Points.size() == 0) return;

            QPointF Prev = Points[0];
            Node* First = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD(Prev.toPoint()));
            Way* R = g_backend.allocWay(theMain->document()->getDirtyOrOriginLayer());
            CommandList* L  = new CommandList(MainWindow::tr("Create Roundabout %1").arg(R->id().numId), R);
            L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),R,true));
            R->add(First);
            L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),First,true));
            if (M_PREFS->getAutoSourceTag()) {
                QStringList sl = theMain->document()->getCurrentSourceTags();
                if (sl.size())
                    R->setTag("source", sl.join(";"));
            }
            // "oneway" is implied on roundabouts
            //R->setTag("oneway","yes");
            if (DockData.type->currentIndex() == 0)
                R->setTag("junction","roundabout");
            for (int i = 1; i < Points.size(); i++ ) {
                QPointF Next = Points[i];
                Node* New = g_backend.allocNode(theMain->document()->getDirtyOrOriginLayer(), XY_TO_COORD(Next.toPoint()));
                L->add(new AddFeatureCommand(theMain->document()->getDirtyOrOriginLayer(),New,true));
                R->add(New);
            }
            R->add(First);
            for (FeatureIterator it(document()); !it.isEnd(); ++it) {
                Way* W1 = CAST_WAY(it.get());
                if (W1 && (W1 != R))
                    Way::createJunction(theMain->document(), L, R, W1, true);
            }
            theMain->properties()->setSelection(R);
            document()->addHistory(L);
            view()->setInteracting(false);
            view()->invalidate(true, true, false);
            theMain->launchInteraction(0);
        }
    }
    else
        Interaction::mousePressEvent(event);
}
예제 #8
0
void MoveNodeInteraction::snapMousePressEvent(QMouseEvent * event, Feature* aLast)
{
    QList<Feature*> sel;
    if (view()->isSelectionLocked()) {
        if (theMain->properties()->selection(0))
            sel.append(theMain->properties()->selection(0));
        else
            sel.append(aLast);
    } else {
        if (aLast) {
            if (theMain->properties()->selection().size() && !M_PREFS->getSeparateMoveMode())
                sel = theMain->properties()->selection();
            else
                sel.append(aLast);
        }
    }
    HasMoved = false;
    clearNoSnap();
    Moving.clear();
    OriginalPosition.clear();
    StartDragPosition = XY_TO_COORD(event->pos());
    if (sel.size() == 1) {
        if (Node* Pt = CAST_NODE(sel[0])) {
            StartDragPosition = Pt->position();
            Moving.push_back(Pt);
        } else
            recurseAddNodes(sel[0]);
    } else {
        for (int i=0; i<sel.size(); i++) {
            recurseAddNodes(sel[i]);
        }
    }

    for (int i=0; i<Moving.size(); ++i)
    {
        OriginalPosition.push_back(Moving[i]->position());
        addToNoSnap(Moving[i]);
    }
    Virtual = false;
    theList = new CommandList;
}
예제 #9
0
void EditInteraction::snapMouseReleaseEvent(QMouseEvent * ev , Feature* aLast)
{
    Qt::KeyboardModifiers modifiers = ev->modifiers();
    if (ev->button() != Qt::LeftButton)
        return;

    if (Dragging)
    {
        QList<Feature*> List;
        EndDrag = XY_TO_COORD(ev->pos());
        CoordBox DragBox(StartDrag, EndDrag);
        for (VisibleFeatureIterator it(document()); !it.isEnd(); ++it) {
            if (it.get()->isReadonly())
                continue;

            if (modifiersForGreedyAdd(modifiers))
            {
                if (!DragBox.intersects(it.get()->boundingBox()))
                    continue;
                if (DragBox.contains(it.get()->boundingBox()))
                    List.push_back(it.get());
                else {
                    Coord A, B;
                    if (Way* R = dynamic_cast<Way*>(it.get())) {
                        for (int j=1; j<R->size(); ++j) {
                            A = R->getNode(j-1)->position();
                            B = R->getNode(j)->position();
                            if (CoordBox::visibleLine(DragBox, A, B)) {
                                List.push_back(R);
                                break;
                            }
                        }
                    } else if (Relation* r = dynamic_cast<Relation*>(it.get())) {
                        for (int k=0; k<r->size(); ++k) {
                            if (Way* R = dynamic_cast<Way*>(r->get(k))) {
                                for (int j=1; j<R->size(); ++j) {
                                    A = R->getNode(j-1)->position();
                                    B = R->getNode(j)->position();
                                    if (CoordBox::visibleLine(DragBox, A, B)) {
                                        List.push_back(r);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                if (DragBox.contains(it.get()->boundingBox()))
                    List.push_back(it.get());
            }
        }
        if (!List.isEmpty() || (!modifiersForAdd(modifiers) && !modifiersForToggle(modifiers)))
            PROPERTIES(setSelection(List));
        PROPERTIES(checkMenuStatus());
        Dragging = false;
        view()->update();
    } else {
        if (!panning() && !modifiers) {
            PROPERTIES(setSelection(aLast));
            PROPERTIES(checkMenuStatus());
            view()->update();
        }
    }
}
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