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); } }
Node * Node::fromXML(Document* d, Layer* L, QXmlStreamReader& stream) { qreal Lat = stream.attributes().value("lat").toString().toDouble(); qreal Lon = stream.attributes().value("lon").toString().toDouble(); QString sid = (stream.attributes().hasAttribute("id") ? stream.attributes().value("id").toString() : stream.attributes().value("xml:id").toString()); IFeature::FId id(IFeature::Point, sid.toLongLong()); Node* Pt = CAST_NODE(d->getFeature(id)); if (!Pt) { Pt = g_backend.allocNode(L, Coord(Lon,Lat)); Pt->setId(id); L->add(Pt); Feature::fromXML(stream, Pt); } else { Feature::fromXML(stream, Pt); if (Pt->layer() != L) { Pt->layer()->remove(Pt); L->add(Pt); } Pt->setPosition(Coord(Lon, Lat)); } stream.readNext(); while(!stream.atEnd() && !stream.isEndElement()) { if (stream.name() == "tag") { Pt->setTag(stream.attributes().value("k").toString(), stream.attributes().value("v").toString()); stream.readNext(); } stream.readNext(); } return Pt; }
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 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; }
bool TrackLayer::toXML(QXmlStreamWriter& stream, bool asTemplate, QProgressDialog * progress) { bool OK = true; if (asTemplate) return OK; stream.writeStartElement(metaObject()->className()); Layer::toXML(stream, asTemplate, progress); stream.writeStartElement("gpx"); stream.writeAttribute("version", "1.1"); stream.writeAttribute("creator", "Merkaartor"); stream.writeAttribute("xmlns", "http://www.topografix.com/GPX/1/1"); QList<Node*> waypoints; QList<TrackSegment*> segments; QList<MapFeaturePtr>::iterator it; for(it = p->Features.begin(); it != p->Features.end(); it++) { if (TrackSegment* S = CAST_SEGMENT(*it)) segments.push_back(S); if (Node* P = CAST_NODE(*it)) if (!P->tagValue("_waypoint_","").isEmpty()) waypoints.push_back(P); } for (int i=0; i < waypoints.size(); ++i) { waypoints[i]->toGPX(stream, progress, "wpt"); } stream.writeStartElement("trk"); for (int i=0; i < segments.size(); ++i) segments[i]->toXML(stream, progress); stream.writeEndElement(); stream.writeEndElement(); //gpx stream.writeEndElement(); return OK; }
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 } }
bool DirtyListVisit::add(Feature* F) { if (DeletePass) return false; if (F->isDeleted()) return false; // TODO Needed to add children of updated imported features. Sure there is no advert cases? //if (!F->isDirty()) return false; // Allow "Force Upload" of OSM objects //if (F->hasOSMId()) return false; if (Future.willBeErased(F)) return EraseFromHistory; for (int i=0; i<AlreadyAdded.size(); ++i) if (AlreadyAdded[i] == F) return EraseResponse[i]; bool x; if (Node* Pt = CAST_NODE(F)) { if (Pt->isInteresting()) { if (F->hasOSMId()) x = updatePoint(Pt); else x = addPoint(Pt); AlreadyAdded.push_back(F); EraseResponse.push_back(x); return x; } else return EraseFromHistory; } else if (Way* R = dynamic_cast<Way*>(F)) { for (int i=0; i<R->size(); ++i) if (!R->getNode(i)->isVirtual()) if (!(R->get(i)->hasOSMId()) && notYetAdded(R->get(i))) add(R->get(i)); if (F->hasOSMId()) x = updateRoad(R); else x = addRoad(R); AlreadyAdded.push_back(F); EraseResponse.push_back(x); return x; } else if (Relation* Rel = dynamic_cast<Relation*>(F)) { for (int i=0; i<Rel->size(); ++i) if (!(Rel->get(i)->hasOSMId()) && notYetAdded(Rel->get(i))) add(Rel->get(i)); if (F->hasOSMId()) x = updateRelation(Rel); else x = addRelation(Rel); AlreadyAdded.push_back(F); EraseResponse.push_back(x); return x; } return EraseFromHistory; }
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