void QgsCurvePolygon::setExteriorRing( QgsCurve *ring ) { if ( !ring ) { return; } mExteriorRing.reset( ring ); //set proper wkb type if ( QgsWkbTypes::flatType( wkbType() ) == QgsWkbTypes::Polygon ) { setZMTypeFromSubGeometry( ring, QgsWkbTypes::Polygon ); } else if ( QgsWkbTypes::flatType( wkbType() ) == QgsWkbTypes::CurvePolygon ) { setZMTypeFromSubGeometry( ring, QgsWkbTypes::CurvePolygon ); } //match dimensionality for rings for ( QgsCurve *ring : qgis::as_const( mInteriorRings ) ) { if ( is3D() ) ring->addZValue(); else ring->dropZValue(); if ( isMeasure() ) ring->addMValue(); else ring->dropMValue(); } clearCache(); }
bool QgsGeometryCollection::fromCollectionWkt( const QString &wkt, const QVector<QgsAbstractGeometry *> &subtypes, const QString &defaultChildWkbType ) { clear(); QPair<QgsWkbTypes::Type, QString> parts = QgsGeometryUtils::wktReadBlock( wkt ); if ( QgsWkbTypes::flatType( parts.first ) != QgsWkbTypes::flatType( wkbType() ) ) { qDeleteAll( subtypes ); return false; } mWkbType = parts.first; QString defChildWkbType = QStringLiteral( "%1%2%3 " ).arg( defaultChildWkbType, is3D() ? QStringLiteral( "Z" ) : QString(), isMeasure() ? QStringLiteral( "M" ) : QString() ); const QStringList blocks = QgsGeometryUtils::wktGetChildBlocks( parts.second, defChildWkbType ); for ( const QString &childWkt : blocks ) { QPair<QgsWkbTypes::Type, QString> childParts = QgsGeometryUtils::wktReadBlock( childWkt ); bool success = false; for ( const QgsAbstractGeometry *geom : subtypes ) { if ( QgsWkbTypes::flatType( childParts.first ) == QgsWkbTypes::flatType( geom->wkbType() ) ) { mGeometries.append( geom->clone() ); if ( mGeometries.back()->fromWkt( childWkt ) ) { success = true; break; } } } if ( !success ) { clear(); qDeleteAll( subtypes ); return false; } } qDeleteAll( subtypes ); //scan through geometries and check if dimensionality of geometries is different to collection. //if so, update the type dimensionality of the collection to match bool hasZ = false; bool hasM = false; for ( QgsAbstractGeometry *geom : qgis::as_const( mGeometries ) ) { hasZ = hasZ || geom->is3D(); hasM = hasM || geom->isMeasure(); if ( hasZ && hasM ) break; } if ( hasZ ) addZValue( 0 ); if ( hasM ) addMValue( 0 ); return true; }
QByteArray QgsGeometryCollection::asWkb() const { int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 ); QVector<QByteArray> wkbForGeometries; for ( const QgsAbstractGeometry *geom : mGeometries ) { if ( geom ) { QByteArray wkb( geom->asWkb() ); binarySize += wkb.length(); wkbForGeometries << wkb; } } QByteArray wkbArray; wkbArray.resize( binarySize ); QgsWkbPtr wkb( wkbArray ); wkb << static_cast<char>( QgsApplication::endian() ); wkb << static_cast<quint32>( wkbType() ); wkb << static_cast<quint32>( wkbForGeometries.count() ); for ( const QByteArray &wkbForGeometry : qgis::as_const( wkbForGeometries ) ) { wkb << wkbForGeometry; } return wkbArray; }
QByteArray QgsCurvePolygon::asWkb() const { int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 ); QVector<QByteArray> wkbForRings; wkbForRings.reserve( 1 + mInteriorRings.size() ); if ( mExteriorRing ) { QByteArray wkb( mExteriorRing->asWkb() ); binarySize += wkb.length(); wkbForRings << wkb; } for ( const QgsCurve *curve : mInteriorRings ) { QByteArray wkb( curve->asWkb() ); binarySize += wkb.length(); wkbForRings << wkb; } QByteArray wkbArray; wkbArray.resize( binarySize ); QgsWkbPtr wkbPtr( wkbArray ); wkbPtr << static_cast<char>( QgsApplication::endian() ); wkbPtr << static_cast<quint32>( wkbType() ); wkbPtr << static_cast<quint32>( wkbForRings.count() ); for ( const QByteArray &wkb : qgis::as_const( wkbForRings ) ) { wkbPtr << wkb; } return wkbArray; }
QByteArray QgsPolygonV2::asWkb() const { int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 ); // Endianness and WkbType is not stored for LinearRings if ( mExteriorRing ) { binarySize += sizeof( quint32 ) + mExteriorRing->numPoints() * ( 2 + mExteriorRing->is3D() + mExteriorRing->isMeasure() ) * sizeof( double ); } for ( const QgsCurve *curve : mInteriorRings ) { binarySize += sizeof( quint32 ) + curve->numPoints() * ( 2 + curve->is3D() + curve->isMeasure() ) * sizeof( double ); } QByteArray wkbArray; wkbArray.resize( binarySize ); QgsWkbPtr wkb( wkbArray ); wkb << static_cast<char>( QgsApplication::endian() ); wkb << static_cast<quint32>( wkbType() ); wkb << static_cast<quint32>( ( nullptr != mExteriorRing ) + mInteriorRings.size() ); if ( mExteriorRing ) { QgsPointSequence pts; mExteriorRing->points( pts ); QgsGeometryUtils::pointsToWKB( wkb, pts, mExteriorRing->is3D(), mExteriorRing->isMeasure() ); } for ( const QgsCurve *curve : mInteriorRings ) { QgsPointSequence pts; curve->points( pts ); QgsGeometryUtils::pointsToWKB( wkb, pts, curve->is3D(), curve->isMeasure() ); } return wkbArray; }
unsigned char* QgsLineStringV2::asWkb( int& binarySize ) const { binarySize = wkbSize(); unsigned char* geomPtr = new unsigned char[binarySize]; QgsWkbPtr wkb( geomPtr ); wkb << static_cast<char>( QgsApplication::endian() ); wkb << static_cast<quint32>( wkbType() ); QList<QgsPointV2> pts; points( pts ); QgsGeometryUtils::pointsToWKB( wkb, pts, is3D(), isMeasure() ); return geomPtr; }
QByteArray QgsCircularString::asWkb() const { int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 ); binarySize += numPoints() * ( 2 + is3D() + isMeasure() ) * sizeof( double ); QByteArray wkbArray; wkbArray.resize( binarySize ); QgsWkbPtr wkb( wkbArray ); wkb << static_cast<char>( QgsApplication::endian() ); wkb << static_cast<quint32>( wkbType() ); QgsPointSequence pts; points( pts ); QgsGeometryUtils::pointsToWKB( wkb, pts, is3D(), isMeasure() ); return wkbArray; }
unsigned char* QgsGeometryCollectionV2::asWkb( int& binarySize ) const { binarySize = wkbSize(); unsigned char* geomPtr = new unsigned char[binarySize]; QgsWkbPtr wkb( geomPtr ); wkb << static_cast<char>( QgsApplication::endian() ); wkb << static_cast<quint32>( wkbType() ); wkb << static_cast<quint32>( mGeometries.size() ); Q_FOREACH ( const QgsAbstractGeometryV2 *geom, mGeometries ) { int geomWkbLen = 0; if ( geom ) { unsigned char* geomWkb = geom->asWkb( geomWkbLen ); memcpy( wkb, geomWkb, geomWkbLen ); wkb += geomWkbLen; delete[] geomWkb; } }
QByteArray QgsCompoundCurve::asWkb() const { int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 ); QVector<QByteArray> wkbForCurves; for ( const QgsCurve *curve : mCurves ) { QByteArray wkbForCurve = curve->asWkb(); binarySize += wkbForCurve.length(); wkbForCurves << wkbForCurve; } QByteArray wkbArray; wkbArray.resize( binarySize ); QgsWkbPtr wkb( wkbArray ); wkb << static_cast<char>( QgsApplication::endian() ); wkb << static_cast<quint32>( wkbType() ); wkb << static_cast<quint32>( mCurves.size() ); for ( const QByteArray &wkbForCurve : qgis::as_const( wkbForCurves ) ) { wkb << wkbForCurve; } return wkbArray; }
QgsVectorLayer *QgsFeatureSource::materialize( const QgsFeatureRequest &request, QgsFeedback *feedback ) { QgsWkbTypes::Type outWkbType = request.flags() & QgsFeatureRequest::NoGeometry ? QgsWkbTypes::NoGeometry : wkbType(); QgsCoordinateReferenceSystem crs = request.destinationCrs().isValid() ? request.destinationCrs() : sourceCrs(); QgsAttributeList requestedAttrs = request.subsetOfAttributes(); QgsFields outFields; if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes ) { int i = 0; const QgsFields sourceFields = fields(); for ( const QgsField &field : sourceFields ) { if ( requestedAttrs.contains( i ) ) outFields.append( field ); i++; } } else { outFields = fields(); } std::unique_ptr< QgsVectorLayer > layer( QgsMemoryProviderUtils::createMemoryLayer( sourceName(), outFields, outWkbType, crs ) ); QgsFeature f; QgsFeatureIterator it = getFeatures( request ); int fieldCount = fields().count(); while ( it.nextFeature( f ) ) { if ( feedback && feedback->isCanceled() ) break; if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes ) { // remove unused attributes QgsAttributes attrs; for ( int i = 0; i < fieldCount; ++i ) { if ( requestedAttrs.contains( i ) ) { attrs.append( f.attributes().at( i ) ); } } f.setAttributes( attrs ); } layer->dataProvider()->addFeature( f, QgsFeatureSink::FastInsert ); } return layer.release(); }