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); }
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); }
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(); }
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 }
// 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; }
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