QgsGeometry::OperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry *geom, std::unique_ptr<QgsAbstractGeometry> part ) { if ( !geom ) { return QgsGeometry::InvalidBaseGeometry; } if ( !part ) { return QgsGeometry::InvalidInput; } //multitype? QgsGeometryCollection *geomCollection = qgsgeometry_cast<QgsGeometryCollection *>( geom ); if ( !geomCollection ) { return QgsGeometry::AddPartNotMultiGeometry; } bool added = false; if ( QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiSurface || QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiPolygon ) { QgsCurve *curve = qgsgeometry_cast<QgsCurve *>( part.get() ); if ( curve && curve->isClosed() && curve->numPoints() >= 4 ) { std::unique_ptr<QgsCurvePolygon> poly; if ( QgsWkbTypes::flatType( curve->wkbType() ) == QgsWkbTypes::LineString ) { poly = qgis::make_unique< QgsPolygonV2 >(); } else { poly = qgis::make_unique< QgsCurvePolygon >(); } // Ownership is still with part, curve points to the same object and is transferred // to poly here. part.release(); poly->setExteriorRing( curve ); added = geomCollection->addGeometry( poly.release() ); } else if ( QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::Polygon ) { added = geomCollection->addGeometry( part.release() ); } else if ( QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiPolygon ) { std::unique_ptr<QgsGeometryCollection> parts( static_cast<QgsGeometryCollection *>( part.release() ) ); int i; int n = geomCollection->numGeometries(); for ( i = 0; i < parts->numGeometries() && geomCollection->addGeometry( parts->geometryN( i )->clone() ); i++ ) ; added = i == parts->numGeometries(); if ( !added ) { while ( geomCollection->numGeometries() > n ) geomCollection->removeGeometry( n ); return QgsGeometry::InvalidInput; } } else { return QgsGeometry::InvalidInput; } } else { added = geomCollection->addGeometry( part.release() ); } return added ? QgsGeometry::Success : QgsGeometry::InvalidInput; }
void QgsCompoundCurve::addVertex( const QgsPoint &pt ) { if ( mCurves.isEmpty() || mWkbType == QgsWkbTypes::Unknown ) { setZMTypeFromSubGeometry( &pt, QgsWkbTypes::CompoundCurve ); } //is last curve QgsLineString QgsCurve *lastCurve = nullptr; if ( !mCurves.isEmpty() ) { lastCurve = mCurves.at( mCurves.size() - 1 ); } QgsLineString *line = nullptr; if ( !lastCurve || QgsWkbTypes::flatType( lastCurve->wkbType() ) != QgsWkbTypes::LineString ) { line = new QgsLineString(); mCurves.append( line ); if ( lastCurve ) { line->addVertex( lastCurve->endPoint() ); } lastCurve = line; } else //create new QgsLineString* with point in it { line = static_cast<QgsLineString *>( lastCurve ); } line->addVertex( pt ); clearCache(); }