static QgsPointLocator::Match _findClosestSegmentIntersection( const QgsPoint& pt, const QgsPointLocator::MatchList& segments ) { if ( segments.isEmpty() ) return QgsPointLocator::Match(); QSet<QgsPoint> endpoints; // make a geometry QList<QgsGeometry*> geoms; Q_FOREACH ( const QgsPointLocator::Match& m, segments ) { if ( m.hasEdge() ) { QgsPolyline pl( 2 ); m.edgePoints( pl[0], pl[1] ); geoms << QgsGeometry::fromPolyline( pl ); endpoints << pl[0] << pl[1]; } } QgsGeometry* g = QgsGeometry::unaryUnion( geoms ); qDeleteAll( geoms ); // get intersection points QList<QgsPoint> newPoints; if ( g->wkbType() == QGis::WKBLineString ) { Q_FOREACH ( const QgsPoint& p, g->asPolyline() ) { if ( !endpoints.contains( p ) ) newPoints << p; } }
static QgsPointLocator::Match _findClosestSegmentIntersection( const QgsPointXY &pt, const QgsPointLocator::MatchList &segments ) { if ( segments.isEmpty() ) return QgsPointLocator::Match(); QSet<QgsPointXY> endpoints; // make a geometry QVector<QgsGeometry> geoms; Q_FOREACH ( const QgsPointLocator::Match &m, segments ) { if ( m.hasEdge() ) { QgsPolylineXY pl( 2 ); m.edgePoints( pl[0], pl[1] ); geoms << QgsGeometry::fromPolylineXY( pl ); endpoints << pl[0] << pl[1]; } } QgsGeometry g = QgsGeometry::unaryUnion( geoms ); // get intersection points QList<QgsPointXY> newPoints; if ( g.wkbType() == QgsWkbTypes::LineString ) { Q_FOREACH ( const QgsPointXY &p, g.asPolyline() ) { if ( !endpoints.contains( p ) ) newPoints << p; } }
bool QgsMapToolReshape::isBindingLine( QgsVectorLayer *vlayer, const QgsRectangle &bbox ) const { if ( vlayer->geometryType() != QgsWkbTypes::LineGeometry ) return false; bool begin = false; bool end = false; const QgsPointXY beginPoint = points().first(); const QgsPointXY endPoint = points().last(); QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) ); QgsFeature f; // check that extremities of the new line are contained by features while ( fit.nextFeature( f ) ) { const QgsGeometry geom = f.geometry(); if ( !geom.isNull() ) { const QgsPolylineXY line = geom.asPolyline(); if ( line.contains( beginPoint ) ) begin = true; else if ( line.contains( endPoint ) ) end = true; } } return end && begin; }
bool QgsSimplifyFeature::simplifyLine( QgsFeature& lineFeature, double tolerance ) { QgsGeometry* line = lineFeature.geometry(); if ( line->type() != QGis::Line ) { return false; } QVector<QgsPoint> resultPoints = simplifyPoints( line->asPolyline(), tolerance ); lineFeature.setGeometry( QgsGeometry::fromPolyline( resultPoints ) ); return true; }
QVector<QgsPoint> QgsMapToolSimplify::getPointList( QgsFeature& f ) { QgsGeometry* line = f.geometry(); if (( line->type() != QGis::Line && line->type() != QGis::Polygon ) || line->isMultipart() ) { return QVector<QgsPoint>(); } if (( line->type() == QGis::Line ) ) { return line->asPolyline(); } else { if ( line->asPolygon().size() > 1 ) { return QVector<QgsPoint>(); } return line->asPolygon()[0]; } }
bool TopolError::fixSnap() { bool ok; QgsFeature f1, f2; FeatureLayer fl = mFeaturePairs.at( 1 ); ok = fl.layer->getFeatures( ( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ) ).nextFeature( f2 ); fl = mFeaturePairs.first(); ok = ok && fl.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ).nextFeature( f1 ); if ( !ok ) return false; QgsGeometry ge = f1.geometry(); QgsPolylineXY line = ge.asPolyline(); QgsPolylineXY conflictLine = mConflict.asPolyline(); line.last() = conflictLine.last(); QgsGeometry newG = QgsGeometry::fromPolylineXY( line ); bool ret = fl.layer->changeGeometry( f1.id(), newG ); return ret; }
void QgsRubberBand::addGeometry( const QgsGeometry& geom, QgsVectorLayer* layer ) { if ( geom.isEmpty() ) { return; } //maprender object of canvas const QgsMapSettings& ms = mMapCanvas->mapSettings(); int idx = mPoints.size(); switch ( geom.wkbType() ) { case QgsWkbTypes::Point: case QgsWkbTypes::Point25D: { QgsPoint pt; if ( layer ) { pt = ms.layerToMapCoordinates( layer, geom.asPoint() ); } else { pt = geom.asPoint(); } addPoint( pt, false, idx ); removeLastPoint( idx, false ); } break; case QgsWkbTypes::MultiPoint: case QgsWkbTypes::MultiPoint25D: { QgsMultiPoint mpt = geom.asMultiPoint(); for ( int i = 0; i < mpt.size(); ++i, ++idx ) { QgsPoint pt = mpt[i]; if ( layer ) { addPoint( ms.layerToMapCoordinates( layer, pt ), false, idx ); removeLastPoint( idx, false ); } else { addPoint( pt, false, idx ); removeLastPoint( idx, false ); } } } break; case QgsWkbTypes::LineString: case QgsWkbTypes::LineString25D: { QgsPolyline line = geom.asPolyline(); for ( int i = 0; i < line.count(); i++ ) { if ( layer ) { addPoint( ms.layerToMapCoordinates( layer, line[i] ), false, idx ); } else { addPoint( line[i], false, idx ); } } } break; case QgsWkbTypes::MultiLineString: case QgsWkbTypes::MultiLineString25D: { QgsMultiPolyline mline = geom.asMultiPolyline(); for ( int i = 0; i < mline.size(); ++i, ++idx ) { QgsPolyline line = mline[i]; if ( line.isEmpty() ) { --idx; } for ( int j = 0; j < line.size(); ++j ) { if ( layer ) { addPoint( ms.layerToMapCoordinates( layer, line[j] ), false, idx ); } else { addPoint( line[j], false, idx ); } } } } break; case QgsWkbTypes::Polygon: case QgsWkbTypes::Polygon25D: { QgsPolygon poly = geom.asPolygon(); QgsPolyline line = poly[0]; for ( int i = 0; i < line.count(); i++ ) { if ( layer ) { addPoint( ms.layerToMapCoordinates( layer, line[i] ), false, idx ); } else { addPoint( line[i], false, idx ); } } } break; case QgsWkbTypes::MultiPolygon: case QgsWkbTypes::MultiPolygon25D: { QgsMultiPolygon multipoly = geom.asMultiPolygon(); for ( int i = 0; i < multipoly.size(); ++i, ++idx ) { QgsPolygon poly = multipoly[i]; QgsPolyline line = poly[0]; for ( int j = 0; j < line.count(); ++j ) { if ( layer ) { addPoint( ms.layerToMapCoordinates( layer, line[j] ), false, idx ); } else { addPoint( line[j], false, idx ); } } } } break; case QgsWkbTypes::Unknown: default: return; } setVisible( true ); updateRect(); update(); }
void QgsMapToolReshape::reshape( QgsVectorLayer *vlayer ) { QgsPointXY firstPoint = points().at( 0 ); QgsRectangle bbox( firstPoint.x(), firstPoint.y(), firstPoint.x(), firstPoint.y() ); for ( int i = 1; i < size(); ++i ) { bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() ); } QgsLineString reshapeLineString( points() ); if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) ) reshapeLineString.addZValue( defaultZValue() ); //query all the features that intersect bounding box of capture line QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setSubsetOfAttributes( QgsAttributeList() ) ); QgsFeature f; int reshapeReturn; bool reshapeDone = false; bool isBinding = isBindingLine( vlayer, bbox ); vlayer->beginEditCommand( tr( "Reshape" ) ); while ( fit.nextFeature( f ) ) { //query geometry //call geometry->reshape(mCaptureList) //register changed geometry in vector layer QgsGeometry geom = f.geometry(); if ( !geom.isNull() ) { // in case of a binding line, we just want to update the line from // the starting point and not both side if ( isBinding && !geom.asPolyline().contains( points().first() ) ) continue; reshapeReturn = geom.reshapeGeometry( reshapeLineString ); if ( reshapeReturn == 0 ) { //avoid intersections on polygon layers if ( vlayer->geometryType() == QgsWkbTypes::PolygonGeometry ) { //ignore all current layer features as they should be reshaped too QHash<QgsVectorLayer *, QSet<QgsFeatureId> > ignoreFeatures; ignoreFeatures.insert( vlayer, vlayer->allFeatureIds() ); if ( geom.avoidIntersections( QgsProject::instance()->avoidIntersectionsLayers(), ignoreFeatures ) != 0 ) { emit messageEmitted( tr( "An error was reported during intersection removal" ), Qgis::Critical ); vlayer->destroyEditCommand(); stopCapturing(); return; } if ( geom.isEmpty() ) //intersection removal might have removed the whole geometry { emit messageEmitted( tr( "The feature cannot be reshaped because the resulting geometry is empty" ), Qgis::Critical ); vlayer->destroyEditCommand(); return; } } vlayer->changeGeometry( f.id(), geom ); reshapeDone = true; } } } if ( reshapeDone ) { vlayer->endEditCommand(); } else { vlayer->destroyEditCommand(); } }
bool QgsTransectSample::closestSegmentPoints( const QgsGeometry& g1, const QgsGeometry& g2, double& dist, QgsPoint& pt1, QgsPoint& pt2 ) { QgsWkbTypes::Type t1 = g1.wkbType(); if ( t1 != QgsWkbTypes::LineString && t1 != QgsWkbTypes::LineString25D ) { return false; } QgsWkbTypes::Type t2 = g2.wkbType(); if ( t2 != QgsWkbTypes::LineString && t2 != QgsWkbTypes::LineString25D ) { return false; } QgsPolyline pl1 = g1.asPolyline(); QgsPolyline pl2 = g2.asPolyline(); if ( pl1.size() < 2 || pl2.size() < 2 ) { return false; } QgsPoint p11 = pl1.at( 0 ); QgsPoint p12 = pl1.at( 1 ); QgsPoint p21 = pl2.at( 0 ); QgsPoint p22 = pl2.at( 1 ); double p1x = p11.x(); double p1y = p11.y(); double v1x = p12.x() - p11.x(); double v1y = p12.y() - p11.y(); double p2x = p21.x(); double p2y = p21.y(); double v2x = p22.x() - p21.x(); double v2y = p22.y() - p21.y(); double denominatorU = v2x * v1y - v2y * v1x; double denominatorT = v1x * v2y - v1y * v2x; if ( qgsDoubleNear( denominatorU, 0 ) || qgsDoubleNear( denominatorT, 0 ) ) { //lines are parallel //project all points on the other segment and take the one with the smallest distance QgsPoint minDistPoint1; double d1 = p11.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), minDistPoint1 ); QgsPoint minDistPoint2; double d2 = p12.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), minDistPoint2 ); QgsPoint minDistPoint3; double d3 = p21.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), minDistPoint3 ); QgsPoint minDistPoint4; double d4 = p22.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), minDistPoint4 ); if ( d1 <= d2 && d1 <= d3 && d1 <= d4 ) { dist = sqrt( d1 ); pt1 = p11; pt2 = minDistPoint1; return true; } else if ( d2 <= d1 && d2 <= d3 && d2 <= d4 ) { dist = sqrt( d2 ); pt1 = p12; pt2 = minDistPoint2; return true; } else if ( d3 <= d1 && d3 <= d2 && d3 <= d4 ) { dist = sqrt( d3 ); pt1 = p21; pt2 = minDistPoint3; return true; } else { dist = sqrt( d4 ); pt1 = p21; pt2 = minDistPoint4; return true; } } double u = ( p1x * v1y - p1y * v1x - p2x * v1y + p2y * v1x ) / denominatorU; double t = ( p2x * v2y - p2y * v2x - p1x * v2y + p1y * v2x ) / denominatorT; if ( u >= 0 && u <= 1.0 && t >= 0 && t <= 1.0 ) { dist = 0; pt1.setX( p2x + u * v2x ); pt1.setY( p2y + u * v2y ); pt2 = pt1; dist = 0; return true; } if ( t > 1.0 ) { pt1.setX( p12.x() ); pt1.setY( p12.y() ); } else if ( t < 0.0 ) { pt1.setX( p11.x() ); pt1.setY( p11.y() ); } if ( u > 1.0 ) { pt2.setX( p22.x() ); pt2.setY( p22.y() ); } if ( u < 0.0 ) { pt2.setX( p21.x() ); pt2.setY( p21.y() ); } if ( t >= 0.0 && t <= 1.0 ) { //project pt2 onto g1 pt2.sqrDistToSegment( p11.x(), p11.y(), p12.x(), p12.y(), pt1 ); } if ( u >= 0.0 && u <= 1.0 ) { //project pt1 onto g2 pt1.sqrDistToSegment( p21.x(), p21.y(), p22.x(), p22.y(), pt2 ); } dist = sqrt( pt1.sqrDist( pt2 ) ); return true; }
void QgsDxfExport::addFeature( const QgsSymbolV2RenderContext& ctx, const QString& layer, const QgsSymbolLayerV2* symbolLayer, const QgsSymbolV2* symbol ) { const QgsFeature* fet = ctx.feature(); if ( !fet ) { return; } QgsGeometry* geom = fet->geometry(); if ( geom ) { int c = 0; if ( mSymbologyExport != NoSymbology ) { c = colorFromSymbolLayer( symbolLayer, ctx ); } double width = -1; if ( mSymbologyExport != NoSymbology && symbolLayer ) { width = symbolLayer->dxfWidth( *this, ctx ); } QString lineStyleName = "CONTINUOUS"; if ( mSymbologyExport != NoSymbology ) { lineStyleName = lineStyleFromSymbolLayer( symbolLayer ); } QGis::WkbType geometryType = geom->wkbType(); //single point if ( geometryType == QGis::WKBPoint || geometryType == QGis::WKBPoint25D ) { writePoint( geom->asPoint(), layer, c, fet, symbolLayer, symbol ); } //multipoint if ( geometryType == QGis::WKBMultiPoint || geometryType == QGis::WKBMultiPoint25D ) { QgsMultiPoint multiPoint = geom->asMultiPoint(); QgsMultiPoint::const_iterator it = multiPoint.constBegin(); for ( ; it != multiPoint.constEnd(); ++it ) { writePoint( *it, layer, c, fet, symbolLayer, symbol ); } } //single line if ( geometryType == QGis::WKBLineString || geometryType == QGis::WKBLineString25D ) { writePolyline( geom->asPolyline(), layer, lineStyleName, c, width, false ); } //multiline if ( geometryType == QGis::WKBMultiLineString || geometryType == QGis::WKBMultiLineString25D ) { QgsMultiPolyline multiLine = geom->asMultiPolyline(); QgsMultiPolyline::const_iterator lIt = multiLine.constBegin(); for ( ; lIt != multiLine.constEnd(); ++lIt ) { writePolyline( *lIt, layer, lineStyleName, c, width, false ); } } //polygon if ( geometryType == QGis::WKBPolygon || geometryType == QGis::WKBPolygon25D ) { QgsPolygon polygon = geom->asPolygon(); QgsPolygon::const_iterator polyIt = polygon.constBegin(); for ( ; polyIt != polygon.constEnd(); ++polyIt ) //iterate over rings { writePolyline( *polyIt, layer, lineStyleName, c, width, true ); } } //multipolygon or polygon if ( geometryType == QGis::WKBMultiPolygon || geometryType == QGis::WKBMultiPolygon25D ) { QgsMultiPolygon mp = geom->asMultiPolygon(); QgsMultiPolygon::const_iterator mpIt = mp.constBegin(); for ( ; mpIt != mp.constEnd(); ++mpIt ) { QgsPolygon::const_iterator polyIt = mpIt->constBegin(); for ( ; polyIt != mpIt->constEnd(); ++polyIt ) { writePolyline( *polyIt, layer, lineStyleName, c, width, true ); } } } } }
int QgsVectorLayerEditUtils::addTopologicalPoints( const QgsGeometry& geom ) { if ( !L->hasGeometryType() ) return 1; if ( geom.isEmpty() ) { return 1; } int returnVal = 0; QgsWkbTypes::Type wkbType = geom.wkbType(); switch ( wkbType ) { //line case QgsWkbTypes::LineString25D: case QgsWkbTypes::LineString: { QgsPolyline theLine = geom.asPolyline(); QgsPolyline::const_iterator line_it = theLine.constBegin(); for ( ; line_it != theLine.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } break; } //multiline case QgsWkbTypes::MultiLineString25D: case QgsWkbTypes::MultiLineString: { QgsMultiPolyline theMultiLine = geom.asMultiPolyline(); QgsPolyline currentPolyline; for ( int i = 0; i < theMultiLine.size(); ++i ) { QgsPolyline::const_iterator line_it = currentPolyline.constBegin(); for ( ; line_it != currentPolyline.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } } break; } //polygon case QgsWkbTypes::Polygon25D: case QgsWkbTypes::Polygon: { QgsPolygon thePolygon = geom.asPolygon(); QgsPolyline currentRing; for ( int i = 0; i < thePolygon.size(); ++i ) { currentRing = thePolygon.at( i ); QgsPolyline::const_iterator line_it = currentRing.constBegin(); for ( ; line_it != currentRing.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } } break; } //multipolygon case QgsWkbTypes::MultiPolygon25D: case QgsWkbTypes::MultiPolygon: { QgsMultiPolygon theMultiPolygon = geom.asMultiPolygon(); QgsPolygon currentPolygon; QgsPolyline currentRing; for ( int i = 0; i < theMultiPolygon.size(); ++i ) { currentPolygon = theMultiPolygon.at( i ); for ( int j = 0; j < currentPolygon.size(); ++j ) { currentRing = currentPolygon.at( j ); QgsPolyline::const_iterator line_it = currentRing.constBegin(); for ( ; line_it != currentRing.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } } } break; } default: break; } return returnVal; }
int QgsVectorLayerEditUtils::addTopologicalPoints( const QgsGeometry &geom ) { if ( !mLayer->isSpatial() ) return 1; if ( geom.isNull() ) { return 1; } int returnVal = 0; QgsWkbTypes::Type wkbType = geom.wkbType(); switch ( QgsWkbTypes::geometryType( wkbType ) ) { //line case QgsWkbTypes::LineGeometry: { if ( !QgsWkbTypes::isMultiType( wkbType ) ) { QgsPolylineXY line = geom.asPolyline(); QgsPolylineXY::const_iterator line_it = line.constBegin(); for ( ; line_it != line.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } } else { QgsMultiPolylineXY multiLine = geom.asMultiPolyline(); QgsPolylineXY currentPolyline; for ( int i = 0; i < multiLine.size(); ++i ) { QgsPolylineXY::const_iterator line_it = currentPolyline.constBegin(); for ( ; line_it != currentPolyline.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } } } break; } case QgsWkbTypes::PolygonGeometry: { if ( !QgsWkbTypes::isMultiType( wkbType ) ) { QgsPolygonXY polygon = geom.asPolygon(); QgsPolylineXY currentRing; for ( int i = 0; i < polygon.size(); ++i ) { currentRing = polygon.at( i ); QgsPolylineXY::const_iterator line_it = currentRing.constBegin(); for ( ; line_it != currentRing.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } } } else { QgsMultiPolygonXY multiPolygon = geom.asMultiPolygon(); QgsPolygonXY currentPolygon; QgsPolylineXY currentRing; for ( int i = 0; i < multiPolygon.size(); ++i ) { currentPolygon = multiPolygon.at( i ); for ( int j = 0; j < currentPolygon.size(); ++j ) { currentRing = currentPolygon.at( j ); QgsPolylineXY::const_iterator line_it = currentRing.constBegin(); for ( ; line_it != currentRing.constEnd(); ++line_it ) { if ( addTopologicalPoints( *line_it ) != 0 ) { returnVal = 2; } } } } } break; } case QgsWkbTypes::PointGeometry: case QgsWkbTypes::UnknownGeometry: case QgsWkbTypes::NullGeometry: break; } return returnVal; }