void QgsSelectedFeature::moveSelectedVertexes( QgsVector v ) { int nUpdates = 0; Q_FOREACH ( QgsVertexEntry *entry, mVertexMap ) { if ( entry->isSelected() ) nUpdates++; } if ( nUpdates == 0 ) return; mVlayer->beginEditCommand( QObject::tr( "Moved vertices" ) ); int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ); beginGeometryChange(); QMultiMap<double, QgsSnappingResult> currentResultList; for ( int i = mVertexMap.size() - 1; i > -1 && nUpdates > 0; i-- ) { QgsVertexEntry *entry = mVertexMap.value( i, nullptr ); if ( !entry || !entry->isSelected() ) continue; if ( topologicalEditing ) { // snap from current vertex currentResultList.clear(); mVlayer->snapWithContext( entry->pointV1(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex ); } // only last update should trigger the geometry update // as vertex selection gets lost on the update if ( --nUpdates == 0 ) endGeometryChange(); QgsPointV2 p = entry->point(); p.setX( p.x() + v.x() ); p.setY( p.y() + v.y() ); mVlayer->moveVertex( p, mFeatureId, i ); if ( topologicalEditing ) { QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin(); for ( ; resultIt != currentResultList.end(); ++resultIt ) { // move all other if ( mFeatureId != resultIt.value().snappedAtGeometry ) mVlayer->moveVertex( p, resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr ); } } } if ( nUpdates > 0 ) endGeometryChange(); mVlayer->endEditCommand(); }
QList<HistoryModel::HistoryEntryMatch> HistoryModel::findEntries(const QString &prefix, bool markAsTypedIn) const { QList<HistoryEntryItem*> matchedEntries; QList<HistoryModel::HistoryEntryMatch> allMatches; QList<HistoryModel::HistoryEntryMatch> currentMatches; QMultiMap<QDateTime, HistoryModel::HistoryEntryMatch> matchesMap; QHash<QUrl, QList<HistoryEntryItem*> >::const_iterator urlsIterator; for (urlsIterator = m_urls.constBegin(); urlsIterator != m_urls.constEnd(); ++urlsIterator) { if (urlsIterator.value().isEmpty() || matchedEntries.contains(urlsIterator.value().first())) { continue; } const QString result(Utils::matchUrl(urlsIterator.key(), prefix)); if (!result.isEmpty()) { HistoryEntryMatch match; match.entry = urlsIterator.value().first(); match.match = result; if (markAsTypedIn) { match.isTypedIn = true; } matchesMap.insert(match.entry->data(TimeVisitedRole).toDateTime(), match); matchedEntries.append(match.entry); } } currentMatches = matchesMap.values(); matchesMap.clear(); for (int i = (currentMatches.count() - 1); i >= 0; --i) { allMatches.append(currentMatches.at(i)); } return allMatches; }
void QgsMapToolNodeTool::createTopologyRubberBands( QgsVectorLayer* vlayer, const QList<QgsVertexEntry*> &vertexMap, int vertex ) { QMultiMap<double, QgsSnappingResult> currentResultList; QgsGeometry *geometry = mSelectedFeature->geometry(); // snap from current vertex currentResultList.clear(); vlayer->snapWithContext( vertexMap[vertex]->point(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex ); QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin(); for ( ; resultIt != currentResultList.end(); ++resultIt ) { // move all other if ( mSelectedFeature->featureId() != resultIt.value().snappedAtGeometry ) { if ( mTopologyMovingVertexes.contains( resultIt.value().snappedAtGeometry ) ) { if ( mTopologyMovingVertexes[resultIt.value().snappedAtGeometry]->contains( resultIt.value().snappedVertexNr ) ) { // skip vertex already exists in some rubberband continue; } } QgsRubberBand* trb = new QgsRubberBand( mCanvas, QGis::Line ); mTopologyRubberBand.append( trb ); int rbId = mTopologyRubberBand.size() - 1; trb->setWidth( 1 ); trb->setColor( Qt::red ); int tVertex = resultIt.value().snappedVertexNr; int tVertexBackup = -1, tVertexAfter = -1; int tVertexFirst = tVertex; // vertex number to check for cycling QgsFeature topolFeature; vlayer->getFeatures( QgsFeatureRequest().setFilterFid( resultIt.value().snappedAtGeometry ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( topolFeature ); QgsGeometry* topolGeometry = topolFeature.geometry(); while ( tVertex != -1 ) // looking for first vertex to rubberband { tVertexBackup = tVertex; topolGeometry->adjacentVertices( tVertex, tVertex, tVertexAfter ); if ( tVertex == -1 || tVertex == tVertexFirst ) break; // check if this is not first vertex of the feature or cycling error // if closest vertex is not from selected feature or is not selected end double dist; QgsPoint point = topolGeometry->vertexAt( tVertex ); int at, before, after; geometry->closestVertex( point, at, before, after, dist ); if ( dist > ZERO_TOLERANCE || !vertexMap[at]->isSelected() ) // problem with double precision { break; // found first vertex } } int movingPointIndex = 0; Vertexes* movingPoints = new Vertexes(); Vertexes* addedPoints = new Vertexes(); if ( mTopologyMovingVertexes.contains( resultIt.value().snappedAtGeometry ) ) { addedPoints = mTopologyMovingVertexes[ resultIt.value().snappedAtGeometry ]; } if ( tVertex == -1 ) // adding first point if needed { tVertex = tVertexBackup; } else { trb->addPoint( toMapCoordinates( vlayer, topolGeometry->vertexAt( tVertex ) ) ); if ( tVertex == tVertexFirst ) // cycle first vertex need to be added also { movingPoints->insert( movingPointIndex ); } movingPointIndex = 1; topolGeometry->adjacentVertices( tVertex, tVertexAfter, tVertex ); } while ( tVertex != -1 ) { // if closest vertex is not from selected feature or is not selected end double dist; QgsPoint point = topolGeometry->vertexAt( tVertex ); int at, before, after; geometry->closestVertex( point, at, before, after, dist ); // find first no matching vertex if ( dist > ZERO_TOLERANCE || !vertexMap[at]->isSelected() ) // problem with double precision { trb->addPoint( toMapCoordinates( vlayer, topolGeometry->vertexAt( tVertex ) ) ); break; // found first vertex } else // add moving point to rubberband { if ( addedPoints->contains( tVertex ) ) break; // just preventing to circle trb->addPoint( toMapCoordinates( vlayer, topolGeometry->vertexAt( tVertex ) ) ); movingPoints->insert( movingPointIndex ); movingPointIndex++; addedPoints->insert( tVertex ); } topolGeometry->adjacentVertices( tVertex, tVertexAfter, tVertex ); } mTopologyMovingVertexes.insert( resultIt.value().snappedAtGeometry, addedPoints ); mTopologyRubberBandVertexes.insert( rbId, movingPoints ); } } }
int QgsSnapper::snapMapPoint( const QgsPoint& mapCoordPoint, QList<QgsSnappingResult>& snappingResult, const QList<QgsPoint>& excludePoints ) { snappingResult.clear(); QMultiMap<double, QgsSnappingResult> snappingResultList;//all snapping results QMultiMap<double, QgsSnappingResult> currentResultList; //snapping results of examined layer //start point in (output) map coordinates QgsPoint layerCoordPoint; //start point in layer coordinates QgsSnappingResult newResult; QList<QgsSnapper::SnapLayer>::iterator snapLayerIt; for ( snapLayerIt = mSnapLayers.begin(); snapLayerIt != mSnapLayers.end(); ++snapLayerIt ) { if ( !snapLayerIt->mLayer->hasGeometryType() ) continue; currentResultList.clear(); //transform point from map coordinates to layer coordinates layerCoordPoint = mMapSettings.mapToLayerCoordinates( snapLayerIt->mLayer, mapCoordPoint ); double tolerance = QgsTolerance::toleranceInMapUnits( snapLayerIt->mTolerance, snapLayerIt->mLayer, mMapSettings, snapLayerIt->mUnitType ); if ( snapLayerIt->mLayer->snapWithContext( layerCoordPoint, tolerance, currentResultList, snapLayerIt->mSnapTo ) != 0 ) { //error } //transform each result from layer crs to map crs (including distance) QMultiMap<double, QgsSnappingResult>::iterator currentResultIt; for ( currentResultIt = currentResultList.begin(); currentResultIt != currentResultList.end(); ++currentResultIt ) { //for each snapping result: transform start point, snap point and other points into map coordinates to find out distance //store results in snapping result list newResult = currentResultIt.value(); newResult.snappedVertex = mMapSettings.layerToMapCoordinates( snapLayerIt->mLayer, currentResultIt.value().snappedVertex ); newResult.beforeVertex = mMapSettings.layerToMapCoordinates( snapLayerIt->mLayer, currentResultIt.value().beforeVertex ); newResult.afterVertex = mMapSettings.layerToMapCoordinates( snapLayerIt->mLayer, currentResultIt.value().afterVertex ); snappingResultList.insert( sqrt( newResult.snappedVertex.sqrDist( mapCoordPoint ) ), newResult ); } } //excluded specific points from result cleanResultList( snappingResultList, excludePoints ); //evaluate results according to snap mode QMultiMap<double, QgsSnappingResult>::iterator evalIt = snappingResultList.begin(); if ( evalIt == snappingResultList.end() ) { return 0; } //Gives a priority to vertex snapping over segment snapping QgsSnappingResult returnResult = evalIt.value(); for ( evalIt = snappingResultList.begin(); evalIt != snappingResultList.end(); ++evalIt ) { if ( evalIt.value().snappedVertexNr != -1 ) { returnResult = evalIt.value(); snappingResultList.erase( evalIt ); break; } } //We return the preferred result snappingResult.push_back( returnResult ); if ( mSnapMode == QgsSnapper::SnapWithOneResult ) { //return only a single result, nothing more to do } else if ( mSnapMode == QgsSnapper::SnapWithResultsForSamePosition ) { //take all snapping results within a certain tolerance because rounding differences may occur double tolerance = 0.000001; for ( evalIt = snappingResultList.begin(); evalIt != snappingResultList.end(); ++evalIt ) { if ( returnResult.snappedVertex.sqrDist( evalIt.value().snappedVertex ) < tolerance*tolerance ) { snappingResult.push_back( evalIt.value() ); } } } else //take all results { for ( evalIt = snappingResultList.begin(); evalIt != snappingResultList.end(); ++evalIt ) { snappingResult.push_back( evalIt.value() ); } } return 0; }
void QgsSelectedFeature::deleteSelectedVertexes() { int nSelected = 0; foreach ( QgsVertexEntry *entry, mVertexMap ) { if ( entry->isSelected() ) nSelected++; } if ( nSelected == 0 ) return; int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ); QMultiMap<double, QgsSnappingResult> currentResultList; mVlayer->beginEditCommand( QObject::tr( "Deleted vertices" ) ); beginGeometryChange(); int count = 0; for ( int i = mVertexMap.size() - 1; i > -1; i-- ) { if ( mVertexMap[i]->isSelected() ) { if ( mVertexMap[i]->equals() != -1 ) { // to avoid try to delete some vertex twice mVertexMap[ mVertexMap[i]->equals()]->setSelected( false ); nSelected--; } if ( topologicalEditing ) { // snap from current vertex currentResultList.clear(); mVlayer->snapWithContext( mVertexMap[i]->point(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex ); } // only last update should trigger the geometry update // as vertex selection gets lost on the update if ( --nSelected == 0 ) endGeometryChange(); if ( !mVlayer->deleteVertex( mFeatureId, i ) ) { count = 0; QgsDebugMsg( QString( "Deleting vertex %1 failed - resetting" ).arg( i ) ); break; } count++; if ( topologicalEditing ) { QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin(); for ( ; resultIt != currentResultList.end(); ++resultIt ) { // move all other if ( mFeatureId != resultIt.value().snappedAtGeometry ) mVlayer->deleteVertex( resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr ); } } } } if ( count > 0 ) { mVlayer->endEditCommand(); } else { mVlayer->destroyEditCommand(); } }
void ThesaurusDatabaseType::clear(){ if (buffer) delete buffer; buffer=0; thesaurus.clear(); fileName.clear(); }
void QgsSelectedFeature::deleteSelectedVertexes() { int nSelected = 0; Q_FOREACH ( QgsVertexEntry *entry, mVertexMap ) { if ( entry->isSelected() ) nSelected++; } if ( nSelected == 0 ) return; int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ); QMultiMap<double, QgsSnappingResult> currentResultList; mVlayer->beginEditCommand( QObject::tr( "Deleted vertices" ) ); beginGeometryChange(); bool success = false; QgsVectorLayer::EditResult res = QgsVectorLayer::Success; for ( int i = mVertexMap.size() - 1; i > -1 && nSelected > 0; i-- ) { if ( mVertexMap.at( i )->isSelected() ) { if ( topologicalEditing ) { // snap from current vertex currentResultList.clear(); mVlayer->snapWithContext( mVertexMap.at( i )->pointV1(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex ); } // only last update should trigger the geometry update // as vertex selection gets lost on the update if ( --nSelected == 0 ) endGeometryChange(); if ( res != QgsVectorLayer::EmptyGeometry ) res = mVlayer->deleteVertexV2( mFeatureId, i ); if ( res != QgsVectorLayer::Success && res != QgsVectorLayer::EmptyGeometry ) { success = false; QgsDebugMsg( QString( "Deleting vertex %1 failed - resetting" ).arg( i ) ); break; } success = true; if ( topologicalEditing ) { QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin(); for ( ; resultIt != currentResultList.end(); ++resultIt ) { // move all other if ( mFeatureId != resultIt.value().snappedAtGeometry ) mVlayer->deleteVertexV2( resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr ); } } if ( res == QgsVectorLayer::EmptyGeometry ) { //geometry has been cleared as a result of deleting vertices (eg not enough vertices left to leave a valid geometry), //so nothing more to do QgsGeometry empty; geometryChanged( mFeatureId, empty ); break; } } } if ( nSelected > 0 ) endGeometryChange(); if ( success ) { mVlayer->endEditCommand(); } else { mVlayer->destroyEditCommand(); } }
QList<BookmarksModel::BookmarkMatch> BookmarksModel::findBookmarks(const QString &prefix) const { QList<BookmarksItem*> matchedBookmarks; QList<BookmarksModel::BookmarkMatch> allMatches; QList<BookmarksModel::BookmarkMatch> currentMatches; QMultiMap<QDateTime, BookmarksModel::BookmarkMatch> matchesMap; QHash<QString, BookmarksItem*>::const_iterator keywordsIterator; for (keywordsIterator = m_keywords.constBegin(); keywordsIterator != m_keywords.constEnd(); ++keywordsIterator) { if (keywordsIterator.key().startsWith(prefix, Qt::CaseInsensitive)) { BookmarksModel::BookmarkMatch match; match.bookmark = keywordsIterator.value(); match.match = keywordsIterator.key(); matchesMap.insert(match.bookmark->data(TimeVisitedRole).toDateTime(), match); matchedBookmarks.append(match.bookmark); } } currentMatches = matchesMap.values(); matchesMap.clear(); for (int i = (currentMatches.count() - 1); i >= 0; --i) { allMatches.append(currentMatches.at(i)); } QHash<QUrl, QList<BookmarksItem*> >::const_iterator urlsIterator; for (urlsIterator = m_urls.constBegin(); urlsIterator != m_urls.constEnd(); ++urlsIterator) { if (urlsIterator.value().isEmpty() || matchedBookmarks.contains(urlsIterator.value().first())) { continue; } const QString result = Utils::matchUrl(urlsIterator.key(), prefix); if (!result.isEmpty()) { BookmarkMatch match; match.bookmark = urlsIterator.value().first(); match.match = result; matchesMap.insert(match.bookmark->data(TimeVisitedRole).toDateTime(), match); matchedBookmarks.append(match.bookmark); } } currentMatches = matchesMap.values(); matchesMap.clear(); for (int i = (currentMatches.count() - 1); i >= 0; --i) { allMatches.append(currentMatches.at(i)); } return allMatches; }
void QgsMapRendererParallelJob::renderLayerStatic( LayerRenderJob& job ) { if ( job.context.renderingStopped() ) return; if ( job.cached ) return; #ifdef QGISDEBUG static QSet<QString> running; static QMultiMap<int, QString> elapsed; QSettings settings; bool log = settings.value( "/Map/logCanvasRefreshEvent", false ).toBool(); QTime t; t.start(); QgsDebugMsg( QString( "job %1 start" ).arg( reinterpret_cast< ulong >( &job ), 0, 16 ) ); if ( log ) { QgsMessageLog::logMessage( tr( "Layer %1 job started" ).arg( job.layerId ), tr( "Rendering" ) ); Q_ASSERT( !running.contains( job.layerId ) ); running << job.layerId; } #endif try { job.renderer->render(); } catch ( QgsException & e ) { QgsDebugMsg( "Caught unhandled QgsException: " + e.what() ); } catch ( std::exception & e ) { QgsDebugMsg( "Caught unhandled std::exception: " + QString::fromAscii( e.what() ) ); } catch ( ... ) { QgsDebugMsg( "Caught unhandled unknown exception" ); } #ifdef QGISDEBUG int tt = t.elapsed(); QgsDebugMsg( QString( "job %1 end [%2 ms]" ).arg( reinterpret_cast< ulong >( &job ), 0, 16 ).arg( tt ) ); if ( log ) { running.remove( job.layerId ); elapsed.insert( tt, job.layerId ); QgsMessageLog::logMessage( tr( "Layer %1 job ended (%2 ms; still running:%3)" ).arg( job.layerId ).arg( tt ).arg( QStringList( running.values() ).join( ", " ) ), tr( "Rendering" ) ); if ( running.isEmpty() ) { QList<int> tt( elapsed.keys() ); qSort( tt.begin(), tt.end(), qGreater<int>() ); Q_FOREACH ( int t, tt ) { QgsMessageLog::logMessage( tr( "%1 ms: %2" ).arg( t ).arg( QStringList( elapsed.values( t ) ).join( ", " ) ), tr( "Rendering" ) ); } QgsMessageLog::logMessage( "---", tr( "Rendering" ) ); elapsed.clear(); }
void updateScancodes() { #ifdef QT_MAC_USE_COCOA TISInputSourceRef layout = TISCopyCurrentKeyboardLayoutInputSource(); if (!layout) { qWarning() << "Error retrieving current layout"; return; } if (layout == lastLayout) { CFRelease(layout); } else { // keyboard layout changed #ifndef NDEBUG const void *name = TISGetInputSourceProperty(layout, kTISPropertyLocalizedName); qDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef)name, 0); #endif lastLayout = layout; scancodes.clear(); CFDataRef data = static_cast<CFDataRef>(TISGetInputSourceProperty(layout, kTISPropertyUnicodeKeyLayoutData)); const UCKeyboardLayout *ucData = data ? reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)) : 0; if (!ucData) { qWarning() << "Error retrieving current layout character data"; return; } for (int i = 0; i < 128; ++i) { UInt32 tmpState = 0; UniChar str[4]; UniCharCount actualLength = 0; OSStatus err = UCKeyTranslate(ucData, i, kUCKeyActionDown, 0, LMGetKbdType(), kUCKeyTranslateNoDeadKeysMask, &tmpState, 4, &actualLength, str); if (err != noErr) { qWarning() << "Error translating unicode key" << err; } else { if (str[0] && str[0] != kFunctionKeyCharCode) { scancodes.insert(str[0], i); } } } } #else KeyboardLayoutRef layout; if (KLGetCurrentKeyboardLayout(&layout) != noErr) { qWarning() << "Error retrieving current layout"; } if (layout != lastLayout) { #ifndef NDEBUG void *name; KLGetKeyboardLayoutProperty(layout, kKLName, const_cast<const void **>(&name)); qDebug() << "Layout changed to: " << CFStringGetCStringPtr((CFStringRef) name, 0); #endif lastLayout = layout; scancodes.clear(); void *kchr; if (KLGetKeyboardLayoutProperty(layout, kKLKCHRData, const_cast<const void **>(&kchr)) != noErr) { qWarning() << "Couldn't load active keyboard layout"; } else { for (int i = 0; i < 128; i++) { UInt32 tmpState = 0; UInt32 chr = KeyTranslate(kchr, i, &tmpState); if (chr && chr != kFunctionKeyCharCode) { scancodes.insert(chr, i); } } } } #endif }