Exemplo n.º 1
0
void MoveNodeInteraction::recurseAddNodes(Feature* F)
{
    if (Node* Pt = CAST_NODE(F))
    {
        Moving.push_back(Pt);
    }
    else if (Way* R = CAST_WAY(F)) {
        if (!g_Merk_Segment_Mode) {
            for (int j=0; j<R->size(); ++j)
                if (std::find(Moving.begin(),Moving.end(),R->get(j)) == Moving.end()) {
                    Moving.push_back(R->getNode(j));
                }
        } else {
            for (int j=R->bestSegment(); j<=R->bestSegment()+1; ++j)
                if (std::find(Moving.begin(),Moving.end(),R->get(j)) == Moving.end()) {
                    Moving.push_back(R->getNode(j));
                }
        }
        addToNoSnap(R);
    }
    else if (Relation* L = CAST_RELATION(F)) {
        for (int j=0; j<L->size(); ++j)
            recurseAddNodes(L->get(j));
        addToNoSnap(L);
    }
}
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);
}
Exemplo n.º 3
0
void MoveNodeInteraction::snapMouseReleaseEvent(QMouseEvent * event, Feature* Closer)
{
    if (event->button() != Qt::LeftButton)
        return;

    if (Moving.size() && !panning() && HasMoved)
    {
        Coord Diff(calculateNewPosition(event,Closer, theList)-StartDragPosition);
        if (Moving.size() > 1) {
            theList->setDescription(MainWindow::tr("Move Nodes"));
            theList->setFeature(Moving[0]);
        } else {
            if (!Virtual) {
                theList->setDescription(MainWindow::tr("Move Node %1").arg(Moving[0]->id().numId));
                theList->setFeature(Moving[0]);
            }
        }
        QSet<Way*> WaysToUpdate;
        for (int i=0; i<Moving.size(); ++i)
        {
            Moving[i]->setPosition(OriginalPosition[i]);
            if (Moving[i]->layer()->isTrack())
                theList->add(new MoveNodeCommand(Moving[i],OriginalPosition[i]+Diff, Moving[i]->layer()));
            else
                theList->add(new MoveNodeCommand(Moving[i],OriginalPosition[i]+Diff, document()->getDirtyOrOriginLayer(Moving[i]->layer())));
            for (int j=0; j<Moving[i]->sizeParents(); ++j) {
                if (Way* aRoad = CAST_WAY(Moving[i]->getParent(j)))
                    WaysToUpdate << aRoad;
                else {
                    Feature* f = CAST_FEATURE(Moving[i]->getParent(j));
                    if (f)
                        g_backend.sync(f);
                }
            }
        }
        foreach (Way* w, WaysToUpdate) {
            g_backend.sync(w);
        }
Exemplo n.º 4
0
void PropertiesDock::switchUi()
{
    if (CurrentTagView)
        M_PREFS->setTagListFirstColumnWidth(qMax(CurrentTagView->columnWidth(0), 20));

    if (FullSelection.size() == 0)
        switchToNoUi();
    else if (FullSelection.size() == 1)
    {
        if (FullSelection[0]->isVirtual())
            switchToNoUi();
        else if (CAST_NODE(FullSelection[0]))
            switchToNodeUi();
        else if (CAST_WAY(FullSelection[0]))
            switchToWayUi();
        else if (CAST_RELATION(FullSelection[0]))
            switchToRelationUi();
        else
            switchToNoUi();
    }
    else
        switchToMultiUi();
    resetValues();
}
Exemplo n.º 5
0
void PropertiesDock::checkMenuStatus()
{
    bool IsPoint = false;
    bool IsRoad = false;
    bool IsRelation = false;
    bool IsParentRoad = false;
    bool IsParentRoadInner = false;
    bool IsParentRelation = false;
    bool IsParentArea = false;
    bool IsOpenStreetBug = false;
    int NumRoads = 0;
    int NumCommitableFeature = 0;
    int NumPoints = 0;
    int NumRelation = 0;
    int NumRelationChild = 0;
    int NumAreas = 0;
    int NumParents = 0;
    int NumChildren = 0;
    int NumIncomplete = 0;
    if (Selection.size() == 1)
    {
        IsPoint = CAST_NODE(Selection[0]) != 0;
        IsRoad = CAST_WAY(Selection[0]) != 0;
        IsRelation = CAST_RELATION(Selection[0]) != 0;
        IsParentRoad = IsPoint && isChildOfSingleRoad(Selection[0]);
        IsParentRoadInner = IsPoint && isChildOfSingleRoadInner(Selection[0]);
        IsParentRelation = isChildOfSingleRelation(Selection[0]);
        IsParentArea = isChildOfArea(Selection[0]);
        IsOpenStreetBug = isChildOfArea(Selection[0]);
        IsOpenStreetBug = IsPoint && (Selection[0]->id().type & IFeature::Special);
    }
    for (int i=0; i<Selection.size(); ++i)
    {
        if (Selection[i]->sizeParents())
            ++NumParents;
        if (Selection[i]->size())
            ++NumChildren;
        if (Selection[i]->notEverythingDownloaded())
            ++NumIncomplete;

        if (CAST_NODE(Selection[i]))
            ++NumPoints;
        if (Way* R = dynamic_cast<Way*>(Selection[i]))
        {
            if (R->area() > 0.0)
            {
                ++NumAreas;
            }
            else
            {
                ++NumRoads;
            }
        }
        if (CAST_RELATION(Selection[i]))
            ++NumRelation;
        if (isChildOfRelation(Selection[i]))
            ++NumRelationChild;

        if (!Selection[i]->isUploadable() && !Selection[i]->isSpecial())
            ++NumCommitableFeature;
    }
#ifndef _MOBILE
    Main->ui->createRelationAction->setEnabled(Selection.size());
    Main->ui->editRemoveAction->setEnabled(Selection.size());
    Main->ui->editMoveAction->setEnabled(true);
    Main->ui->editReverseAction->setEnabled(IsRoad || NumAreas + NumRoads > 0);
    Main->ui->roadAddStreetNumbersAction->setEnabled(NumRoads >= 1);
    Main->ui->roadJoinAction->setEnabled(NumRoads >= 1 && canJoinRoads(this));
    Main->ui->roadCreateJunctionAction->setEnabled(NumRoads > 1 && canCreateJunction(this));
    Main->ui->roadSplitAction->setEnabled((IsParentRoadInner && !IsParentArea) || (NumRoads && NumPoints) || (NumAreas && NumPoints > 1));
    Main->ui->roadBreakAction->setEnabled(IsParentRoadInner || ((NumRoads == 1 || NumAreas == 1) && NumPoints) || (NumRoads > 1 && canBreakRoads(this)));
    Main->ui->roadSimplifyAction->setEnabled(IsRoad || NumRoads > 0 || NumAreas > 0);
    Main->ui->roadSubdivideAction->setEnabled((NumRoads + NumAreas) == 1 && (!NumPoints || NumPoints == 2) && canSubdivideRoad(this));
    Main->ui->roadAxisAlignAction->setEnabled((NumRoads + NumAreas) > 0 || (NumRelation > 0 && canAxisAlignRoads(this)));
    Main->ui->areaJoinAction->setEnabled(NumAreas > 1);
    Main->ui->areaSplitAction->setEnabled(NumAreas == 1 && NumPoints == 2 && canSplitArea(this));
    Main->ui->areaTerraceAction->setEnabled(NumAreas == 1 && NumRoads == 0 && canTerraceArea(this));
    Main->ui->featureSelectChildrenAction->setEnabled(NumChildren);
    Main->ui->featureSelectParentsAction->setEnabled(NumParents);
    Main->ui->featureDownloadMissingChildrenAction->setEnabled(NumIncomplete);
    Main->ui->featureDeleteAction->setEnabled((IsPoint || IsRoad || IsRelation) && !Selection[0]->isDirty());
    Main->ui->featureCommitAction->setEnabled(NumCommitableFeature);
    Main->ui->nodeMergeAction->setEnabled(NumPoints > 1);
    Main->ui->nodeAlignAction->setEnabled(NumPoints > 2);
    Main->ui->nodeSpreadAction->setEnabled(NumPoints > 2);
    Main->ui->nodeDetachAction->setEnabled(NumPoints && canDetachNodes(this));
    Main->ui->relationAddMemberAction->setEnabled(NumRelation && Selection.size() > 1);
    Main->ui->relationRemoveMemberAction->setEnabled((NumRelation && Selection.size() > 1 && NumRelationChild) || IsParentRelation);
    Main->ui->relationAddToMultipolygonAction->setEnabled((NumAreas > 1) || (NumAreas >0 && NumRelation == 1));

    Main->ui->editCopyAction->setEnabled(Selection.size());
    Main->clipboardChanged();
#endif
}
Exemplo n.º 6
0
// export
bool ExportGPX::export_(const QList<Feature *>& featList)
{
    QList<Node*>	waypoints;
    QList<TrackSegment*>	segments;
    QList<Layer*>	tracks;
    QList<Way*>	routes;

    if(! IImportExport::export_(featList) ) return false;

    bool OK = true;

    QXmlStreamWriter stream(Device);
    stream.setAutoFormatting(true);
    stream.setAutoFormattingIndent(2);
    stream.writeStartDocument();

    QProgressDialog progress(QApplication::tr("Exporting GPX..."), QApplication::tr("Cancel"), 0, 0);
    progress.setWindowModality(Qt::WindowModal);
    progress.setMaximum(progress.maximum() + featList.count());

    stream.writeStartElement("gpx");
    stream.writeAttribute("version", "1.1");
    stream.writeAttribute("creator", QString("%1 v%2%3").arg(STRINGIFY(PRODUCT)).arg(STRINGIFY(VERSION)).arg(STRINGIFY(REVISION)));
    stream.writeAttribute("xmlns", "http://www.topografix.com/GPX/1/1");

    for (int i=0; i<theFeatures.size(); ++i) {
        if (TrackSegment* S = dynamic_cast<TrackSegment*>(theFeatures[i])) {
            segments.push_back(S);
            if (!tracks.contains(S->layer()))
                tracks.push_back(S->layer());
        } else
        if (Node* P = CAST_NODE(theFeatures[i])) {
            if (!P->tagValue("_waypoint_","").isEmpty())
                waypoints.push_back(P);
            if (!P->tagValue("name","").isEmpty() && !P->sizeParents())
                waypoints.push_back(P);
        } else
        if (Way* R = CAST_WAY(theFeatures[i])) {
            if (R->size())
                routes.push_back(R);
        }
    }

    for (int i=0; i < waypoints.size(); ++i) {
        waypoints[i]->toGPX(stream, &progress, "wpt", true);
    }

    for (int i=0; i < routes.size(); ++i) {
        routes[i]->toGPX(stream, &progress, true);
    }

    for (int i=0; i<tracks.size(); ++i) {
        stream.writeStartElement("trk");
        stream.writeTextElement("name", tracks[i]->name());

        for (int j=0; j < segments.size(); ++j)
            if (tracks[i]->exists(segments[j]))
                segments[j]->toGPX(stream, &progress, true);
        stream.writeEndElement();
    }
    stream.writeEndElement();
    stream.writeEndDocument();

    progress.setValue(progress.maximum());
    if (progress.wasCanceled())
        return false;

    return OK;
}
Exemplo n.º 7
0
void MapRenderer::render(
        QPainter* P,
        QMap<RenderPriority, QSet <Feature*> > theFeatures,
        const RendererOptions& options,
        MapView* aView
)
{
    #ifndef NDEBUG
        QTime Start(QTime::currentTime());
    #endif

    theView = aView;
    theOptions = options;

    QMap<RenderPriority, QSet<Feature*> >::const_iterator itm;
    QSet<Feature*>::const_iterator it;

    bool bgLayerVisible = TEST_RFLAGS(RendererOptions::BackgroundVisible);
    bool fgLayerVisible = TEST_RFLAGS(RendererOptions::ForegroundVisible);
    bool tchpLayerVisible = TEST_RFLAGS(RendererOptions::TouchupVisible);
    bool lblLayerVisible = TEST_RFLAGS(RendererOptions::NamesVisible);

    Way * R = NULL;
    Node * Pt = NULL;
    Relation * RR = NULL;

    QPixmap pix(theView->size());
    thePainter = new QPainter();

    itm = theFeatures.constBegin();
    while (itm != theFeatures.constEnd())
    {
        pix.fill(Qt::transparent);
        thePainter->begin(&pix);
        if (M_PREFS->getUseAntiAlias())
            thePainter->setRenderHint(QPainter::Antialiasing);
        int curLayer = (itm.key()).layer();
        while (itm != theFeatures.constEnd() && (itm.key()).layer() == curLayer)
        {
            for (it = itm.value().constBegin(); it != itm.value().constEnd(); ++it)
            {
                qreal alpha = (*it)->getAlpha();
                thePainter->setOpacity(alpha);

                R = NULL;
                Pt = NULL;
                RR = NULL;

                if (!(R = CAST_WAY(*it)))
                    if (!(Pt = CAST_NODE(*it)))
                        RR = CAST_RELATION(*it);

                if (R) {
                    // If there is painter at the relation level, don't paint at the way level
                    bool draw = true;
                    for (int i=0; i<R->sizeParents(); ++i) {
                        if (!R->getParent(i)->isDeleted() && R->getParent(i)->hasPainter(PixelPerM))
                            draw = false;
                    }
                    if (!draw)
                        continue;
                }

                if (!Pt) {
                    if (bgLayerVisible)
                    {
                        thePainter->save();
                        if (R && R->area() == 0)
                            thePainter->setCompositionMode(QPainter::CompositionMode_DestinationOver);

                        if (R)
                            bglayer.draw(R);
                        else if (Pt)
                            bglayer.draw(Pt);
                        else if (RR)
                            bglayer.draw(RR);

                        thePainter->restore();
                    }
                    if (fgLayerVisible)
                    {
                        thePainter->save();

                        if (R)
                            fglayer.draw(R);
                        else if (Pt)
                            fglayer.draw(Pt);
                        else if (RR)
                            fglayer.draw(RR);

                        thePainter->restore();
                    }
                }
                if (tchpLayerVisible)
                {
                    thePainter->save();

                    if (R)
                        tchuplayer.draw(R);
                    else if (Pt)
                        tchuplayer.draw(Pt);
                    else if (RR)
                        tchuplayer.draw(RR);

                    thePainter->restore();
                }
                if (lblLayerVisible) {
                    thePainter->save();

                    if (R)
                        lbllayer.draw(R);
                    else if (Pt)
                        lbllayer.draw(Pt);
                    else if (RR)
                        lbllayer.draw(RR);

                    thePainter->restore();
                }

                (*it)->draw(*thePainter, aView);
            }
            ++itm;
        }
        thePainter->end();
        P->drawPixmap(0, 0, pix);
#ifndef NDEBUG
    QTime Stop(QTime::currentTime());
    qDebug() << Start.msecsTo(Stop) << "ms";
#endif
    }
}
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