void testPointInPolygon() { QgsPointLocator loc( mVL ); QgsPointLocator::MatchList mValid = loc.pointInPolygon( QgsPointXY( 0.8, 0.8 ) ); QCOMPARE( mValid.count(), 1 ); QgsPointLocator::Match m = mValid[0]; QVERIFY( m.isValid() ); QVERIFY( m.hasArea() ); QCOMPARE( m.layer(), mVL ); QCOMPARE( m.featureId(), ( QgsFeatureId )1 ); QgsPointLocator::MatchList mInvalid = loc.pointInPolygon( QgsPointXY( 0, 0 ) ); QCOMPARE( mInvalid.count(), 0 ); }
void QgsMapToolOffsetCurve::canvasReleaseEvent( QgsMapMouseEvent *e ) { mCtrlHeldOnFirstClick = false; if ( e->button() == Qt::RightButton ) { cancel(); return; } if ( mOriginalGeometry.isNull() ) { // first click, get feature to modify deleteRubberBandAndGeometry(); mGeometryModified = false; QgsPointLocator::Match match = mCanvas->snappingUtils()->snapToCurrentLayer( e->pos(), QgsPointLocator::Types( QgsPointLocator::Edge | QgsPointLocator::Area ) ); if ( ( match.hasEdge() || match.hasArea() ) && match.layer() ) { mLayer = match.layer(); QgsFeature fet; if ( match.layer()->getFeatures( QgsFeatureRequest( match.featureId() ) ).nextFeature( fet ) ) { mCtrlHeldOnFirstClick = ( e->modifiers() & Qt::ControlModifier ); //no geometry modification if ctrl is pressed prepareGeometry( match, fet ); mRubberBand = createRubberBand(); if ( mRubberBand ) { mRubberBand->setToGeometry( mManipulatedGeometry, match.layer() ); } mModifiedFeature = fet.id(); createUserInputWidget(); bool hasZ = QgsWkbTypes::hasZ( mLayer->wkbType() ); bool hasM = QgsWkbTypes::hasZ( mLayer->wkbType() ); if ( hasZ || hasM ) { emit messageEmitted( QStringLiteral( "layer %1 has %2%3%4 geometry. %2%3%4 values be set to 0 when using offset tool." ) .arg( mLayer->name() ) .arg( hasZ ? "Z" : "" ) .arg( hasZ && hasM ? "/" : "" ) .arg( hasM ? "M" : "" ) , Qgis::Warning ); } } } if ( mOriginalGeometry.isNull() ) { emit messageEmitted( tr( "Could not find a nearby feature in any vector layer." ) ); cancel(); notifyNotVectorLayer(); } } else { // second click - apply changes double offset = calculateOffset( e->snapPoint() ); applyOffset( offset, e->modifiers() ); } }
void QgsMapToolOffsetCurve::prepareGeometry( const QgsPointLocator::Match &match, QgsFeature &snappedFeature ) { QgsVectorLayer *vl = match.layer(); if ( !vl ) { return; } mOriginalGeometry = QgsGeometry(); mManipulatedGeometry = QgsGeometry(); mModifiedPart = -1; mModifiedRing = -1; //assign feature part by vertex number (snap to vertex) or by before vertex number (snap to segment) QgsGeometry geom = snappedFeature.geometry(); if ( geom.isNull() ) { return; } mOriginalGeometry = geom; QgsWkbTypes::Type geomType = geom.wkbType(); if ( QgsWkbTypes::geometryType( geomType ) == QgsWkbTypes::LineGeometry ) { if ( !match.hasEdge() ) { return; } if ( !geom.isMultipart() ) { mManipulatedGeometry = geom; } else { int vertex = match.vertexIndex(); QgsVertexId vertexId; geom.vertexIdFromVertexNr( vertex, vertexId ); mModifiedPart = vertexId.part; QgsMultiPolylineXY multiLine = geom.asMultiPolyline(); mManipulatedGeometry = QgsGeometry::fromPolylineXY( multiLine.at( mModifiedPart ) ); } } else if ( QgsWkbTypes::geometryType( geomType ) == QgsWkbTypes::PolygonGeometry ) { if ( !match.hasEdge() && match.hasArea() ) { if ( !geom.isMultipart() ) { mManipulatedGeometry = geom; } else { // get the correct part QgsMultiPolygonXY mpolygon = geom.asMultiPolygon(); for ( int part = 0; part < mpolygon.count(); part++ ) // go through the polygons { const QgsPolygonXY &polygon = mpolygon[part]; QgsGeometry partGeo = QgsGeometry::fromPolygonXY( polygon ); const QgsPointXY layerCoords = match.point(); if ( partGeo.contains( &layerCoords ) ) { mModifiedPart = part; mManipulatedGeometry = partGeo; } } } } else if ( match.hasEdge() ) { int vertex = match.vertexIndex(); QgsVertexId vertexId; geom.vertexIdFromVertexNr( vertex, vertexId ); QgsDebugMsg( QStringLiteral( "%1" ).arg( vertexId.ring ) ); if ( !geom.isMultipart() ) { QgsPolygonXY poly = geom.asPolygon(); // if has rings if ( poly.count() > 0 ) { mModifiedRing = vertexId.ring; mManipulatedGeometry = QgsGeometry::fromPolygonXY( QgsPolygonXY() << poly.at( mModifiedRing ) ); } else { mManipulatedGeometry = QgsGeometry::fromPolygonXY( poly ); } } else { mModifiedPart = vertexId.part; // get part, get ring QgsMultiPolygonXY multiPoly = geom.asMultiPolygon(); // if has rings if ( multiPoly.at( mModifiedPart ).count() > 0 ) { mModifiedRing = vertexId.ring; mManipulatedGeometry = QgsGeometry::fromPolygonXY( QgsPolygonXY() << multiPoly.at( mModifiedPart ).at( mModifiedRing ) ); } else { mManipulatedGeometry = QgsGeometry::fromPolygonXY( multiPoly.at( mModifiedPart ) ); } } } } }