Exemplo n.º 1
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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;
    }
  }
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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();
}