int QgsInterpolator::addVerticesToCache( const QgsGeometry& geom, bool zCoord, double attributeValue )
{
  if ( geom.isEmpty() )
    return 1;

  bool hasZValue = false;
  QByteArray wkb( geom.exportToWkb() );
  QgsConstWkbPtr currentWkbPtr( wkb );
  currentWkbPtr.readHeader();
  vertexData theVertex; //the current vertex

  QgsWkbTypes::Type wkbType = geom.wkbType();
  switch ( wkbType )
  {
    case QgsWkbTypes::Point25D:
      hasZValue = true;
      //intentional fall-through
      FALLTHROUGH;
    case QgsWkbTypes::Point:
    {
      currentWkbPtr >> theVertex.x >> theVertex.y;
      if ( zCoord && hasZValue )
      {
        currentWkbPtr >> theVertex.z;
      }
      else
      {
        theVertex.z = attributeValue;
      }
      mCachedBaseData.push_back( theVertex );
      break;
    }
QgsGeometry QgsGeometryAnalyzer::locateBetweenMeasures( double fromMeasure, double toMeasure, const QgsGeometry& lineGeom )
{
  if ( lineGeom.isEmpty() )
  {
    return QgsGeometry();
  }

  QgsMultiPolyline resultGeom;

  //need to go with WKB and z coordinate until QgsGeometry supports M values
  QByteArray wkb( lineGeom.exportToWkb() );
  QgsConstWkbPtr wkbPtr( wkb );
  wkbPtr.readHeader();

  QgsWkbTypes::Type wkbType = lineGeom.wkbType();
  if ( wkbType != QgsWkbTypes::LineString25D && wkbType != QgsWkbTypes::MultiLineString25D )
  {
    return QgsGeometry();
  }

  if ( wkbType == QgsWkbTypes::LineString25D )
  {
    locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
  }
  else if ( wkbType == QgsWkbTypes::MultiLineString25D )
  {
    int nLines;
    wkbPtr >> nLines;
    for ( int i = 0; i < nLines; ++i )
    {
      wkbPtr.readHeader();
      wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
    }
  }
//
// Convert a QgsGeometry into a SpatiaLite geometry BLOB
void qgsGeometryToSpatialiteBlob( const QgsGeometry &geom, int32_t srid, char *&blob, int &size )
{
  const int header_len = SpatialiteBlobHeader::LENGTH;

  QByteArray wkb( geom.exportToWkb() );

  const int wkb_size = wkb.length();
  size = header_len + wkb_size;
  blob = new char[size];

  char *p = blob;

  // write the header
  SpatialiteBlobHeader pHeader;
  QgsRectangle bbox = const_cast<QgsGeometry &>( geom ).boundingBox(); // boundingBox should be const
  pHeader.srid = srid;
  pHeader.mbrMinX = bbox.xMinimum();
  pHeader.mbrMinY = bbox.yMinimum();
  pHeader.mbrMaxX = bbox.xMaximum();
  pHeader.mbrMaxY = bbox.yMaximum();
  pHeader.writeTo( blob );

  p += header_len;

  // wkb of the geometry is
  // name         size    value
  // endianness     1      01
  // type           4      int

  // blob geometry = header + wkb[1:] + 'end'

  // copy wkb
  memcpy( p, wkb.constData() + 1, wkb_size - 1 );
  p += wkb_size - 1;

  // end marker
  *p = '\xFE';
}
int QgsTINInterpolator::insertData( QgsFeature* f, bool zCoord, int attr, InputType type )
{
  if ( !f )
  {
    return 1;
  }

  QgsGeometry g = f->geometry();
  {
    if ( g.isNull() )
    {
      return 2;
    }
  }

  //check attribute value
  double attributeValue = 0;
  bool attributeConversionOk = false;
  if ( !zCoord )
  {
    QVariant attributeVariant = f->attribute( attr );
    if ( !attributeVariant.isValid() ) //attribute not found, something must be wrong (e.g. NULL value)
    {
      return 3;
    }
    attributeValue = attributeVariant.toDouble( &attributeConversionOk );
    if ( !attributeConversionOk || qIsNaN( attributeValue ) ) //don't consider vertices with attributes like 'nan' for the interpolation
    {
      return 4;
    }
  }

  //parse WKB. It is ugly, but we cannot use the methods with QgsPoint because they don't contain z-values for 25D types
  bool hasZValue = false;
  double x, y, z;
  QByteArray wkb( g.exportToWkb() );
  QgsConstWkbPtr currentWkbPtr( wkb );
  currentWkbPtr.readHeader();
  //maybe a structure or break line
  Line3D* line = nullptr;

  QgsWkbTypes::Type wkbType = g.wkbType();
  switch ( wkbType )
  {
    case QgsWkbTypes::Point25D:
      hasZValue = true;
      FALLTHROUGH;
    case QgsWkbTypes::Point:
    {
      currentWkbPtr >> x >> y;
      if ( zCoord && hasZValue )
      {
        currentWkbPtr >> z;
      }
      else
      {
        z = attributeValue;
      }
      Point3D* thePoint = new Point3D( x, y, z );
      if ( mTriangulation->addPoint( thePoint ) == -100 )
      {
        return -1;
      }
      break;
    }
Exemple #5
0
void QgsOSMDatabase::exportSpatiaLiteWays( bool closed, const QString &tableName,
    const QStringList &tagKeys,
    const QStringList &notNullTagKeys )
{
  Q_UNUSED( tagKeys );

  QString sqlInsertLine = QStringLiteral( "INSERT INTO %1 VALUES (?" ).arg( quotedIdentifier( tableName ) );
  for ( int i = 0; i < tagKeys.count(); ++i )
    sqlInsertLine += QStringLiteral( ",?" );
  sqlInsertLine += QLatin1String( ", GeomFromWKB(?, 4326))" );
  sqlite3_stmt *stmtInsert = nullptr;
  if ( sqlite3_prepare_v2( mDatabase, sqlInsertLine.toUtf8().constData(), -1, &stmtInsert, nullptr ) != SQLITE_OK )
  {
    mError = QStringLiteral( "Prepare SELECT FROM ways failed." );
    return;
  }

  QgsOSMWayIterator ways = listWays();
  QgsOSMWay w;
  while ( ( w = ways.next() ).isValid() )
  {
    QgsOSMTags t = tags( true, w.id() );

    QgsPolyline polyline = wayPoints( w.id() );

    if ( polyline.count() < 2 )
      continue; // invalid way

    bool isArea = ( polyline.first() == polyline.last() ); // closed way?
    // filter out closed way that are not areas through tags
    if ( isArea && ( t.contains( QStringLiteral( "highway" ) ) || t.contains( QStringLiteral( "barrier" ) ) ) )
    {
      // make sure tags that indicate areas are taken into consideration when deciding on a closed way is or isn't an area
      // and allow for a closed way to be exported both as a polygon and a line in case both area and non-area tags are present
      if ( ( t.value( QStringLiteral( "area" ) ) != QLatin1String( "yes" ) && !t.contains( QStringLiteral( "amenity" ) ) && !t.contains( QStringLiteral( "landuse" ) ) && !t.contains( QStringLiteral( "building" ) ) && !t.contains( QStringLiteral( "natural" ) ) && !t.contains( QStringLiteral( "leisure" ) ) && !t.contains( QStringLiteral( "aeroway" ) ) ) || !closed )
        isArea = false;
    }

    if ( closed != isArea )
      continue; // skip if it's not what we're looking for

    //check not null tags
    bool skipNull = false;
    for ( int i = 0; i < notNullTagKeys.count() && !skipNull; ++i )
      if ( !t.contains( notNullTagKeys[i] ) )
        skipNull = true;

    if ( skipNull )
      continue;

    QgsGeometry geom = closed ? QgsGeometry::fromPolygon( QgsPolygon() << polyline ) : QgsGeometry::fromPolyline( polyline );
    int col = 0;
    sqlite3_bind_int64( stmtInsert, ++col, w.id() );

    // tags
    for ( int i = 0; i < tagKeys.count(); ++i )
    {
      if ( t.contains( tagKeys[i] ) )
        sqlite3_bind_text( stmtInsert, ++col, t.value( tagKeys[i] ).toUtf8().constData(), -1, SQLITE_TRANSIENT );
      else
        sqlite3_bind_null( stmtInsert, ++col );
    }

    if ( !geom.isNull() )
    {
      QByteArray wkb( geom.exportToWkb() );
      sqlite3_bind_blob( stmtInsert, ++col, wkb.constData(), wkb.length(), SQLITE_STATIC );
    }
    else
      sqlite3_bind_null( stmtInsert, ++col );

    int insertRes = sqlite3_step( stmtInsert );
    if ( insertRes != SQLITE_DONE )
    {
      mError = QStringLiteral( "Error inserting way %1 [%2]" ).arg( w.id() ).arg( insertRes );
      break;
    }

    sqlite3_reset( stmtInsert );
    sqlite3_clear_bindings( stmtInsert );
  }

  sqlite3_finalize( stmtInsert );
}
Exemple #6
0
void QgsOSMDatabase::exportSpatiaLiteNodes( const QString &tableName, const QStringList &tagKeys, const QStringList &notNullTagKeys )
{
  QString sqlInsertPoint = QStringLiteral( "INSERT INTO %1 VALUES (?" ).arg( quotedIdentifier( tableName ) );
  for ( int i = 0; i < tagKeys.count(); ++i )
    sqlInsertPoint += QStringLiteral( ",?" );
  sqlInsertPoint += QLatin1String( ", GeomFromWKB(?, 4326))" );
  sqlite3_stmt *stmtInsert = nullptr;
  if ( sqlite3_prepare_v2( mDatabase, sqlInsertPoint.toUtf8().constData(), -1, &stmtInsert, nullptr ) != SQLITE_OK )
  {
    mError = QStringLiteral( "Prepare SELECT FROM nodes failed." );
    return;
  }

  QgsOSMNodeIterator nodes = listNodes();
  QgsOSMNode n;
  while ( ( n = nodes.next() ).isValid() )
  {
    QgsOSMTags t = tags( false, n.id() );

    // skip untagged nodes: probably they form a part of ways
    if ( t.count() == 0 )
      continue;

    //check not null tags
    bool skipNull = false;
    for ( int i = 0; i < notNullTagKeys.count() && !skipNull; ++i )
      if ( !t.contains( notNullTagKeys[i] ) )
        skipNull = true;

    if ( skipNull )
      continue;

    QgsGeometry geom = QgsGeometry::fromPoint( n.point() );
    int col = 0;
    sqlite3_bind_int64( stmtInsert, ++col, n.id() );

    // tags
    for ( int i = 0; i < tagKeys.count(); ++i )
    {
      if ( t.contains( tagKeys[i] ) )
        sqlite3_bind_text( stmtInsert, ++col, t.value( tagKeys[i] ).toUtf8().constData(), -1, SQLITE_TRANSIENT );
      else
        sqlite3_bind_null( stmtInsert, ++col );
    }

    QByteArray wkb( geom.exportToWkb() );
    sqlite3_bind_blob( stmtInsert, ++col, wkb.constData(), wkb.length(), SQLITE_STATIC );

    int insertRes = sqlite3_step( stmtInsert );
    if ( insertRes != SQLITE_DONE )
    {
      mError = QStringLiteral( "Error inserting node %1 [%2]" ).arg( n.id() ).arg( insertRes );
      break;
    }

    sqlite3_reset( stmtInsert );
    sqlite3_clear_bindings( stmtInsert );
  }

  sqlite3_finalize( stmtInsert );
}
Exemple #7
0
bool QgsDb2Provider::addFeatures( QgsFeatureList &flist, Flags flags )
{
  QgsDebugMsg( "mGeometryColType: " + mGeometryColType );
  int writeCount = 0;
  bool copyOperation = false;

  if ( !mDatabase.isOpen() )
  {
    QString errMsg;
    mDatabase = getDatabase( mConnInfo, errMsg );
    if ( !errMsg.isEmpty() )
    {
      QgsDebugMsg( "getDatabase failed: " + errMsg );
      return false;
    }
  }
  if ( !mDatabase.transaction() )
  {
    QgsDebugMsg( "transaction failed" );
    return false;
  }
  QSqlQuery query = QSqlQuery( mDatabase );
  query.setForwardOnly( true );
  QSqlQuery queryFid = QSqlQuery( mDatabase );
  queryFid.setForwardOnly( true );

  QgsFeature it = flist.at( 0 );
  QString statement;
  QString values;
  statement = QStringLiteral( "INSERT INTO %1.%2 (" ).arg( mSchemaName, mTableName );

  bool first = true;

// Get the first geometry and its wkbType as when we are doing drag/drop,
// the wkbType is not passed to the DB2 provider from QgsVectorLayerExporter
// Can't figure out how to resolved "unreferenced" wkbType compile message
// Don't really do anything with it at this point
#if 0
  QgsGeometry *geom = it.geometry();
  QgsWkbTypes::Type wkbType = geom->wkbType();
  QgsDebugMsg( QString( "wkbType: %1" ).arg( wkbType ) );
  QgsDebugMsg( QString( "mWkbType: %1" ).arg( mWkbType ) );
#endif

  QgsAttributes attrs = it.attributes();
  QgsDebugMsg( QString( "attrs.count: %1" ).arg( attrs.count() ) );
  QgsDebugMsg( QString( "fields.count: %1" ).arg( mAttributeFields.count() ) );
  if ( mAttributeFields.count() == ( attrs.count() + 1 ) )
  {
    copyOperation = true; // FID is first field but no attribute in attrs
  }
  else if ( mAttributeFields.count() !=  attrs.count() )
  {
    QgsDebugMsg( "Count mismatch - failing" );
    return false;
  }


  if ( attrs.count() != mAttributeFields.count() )
  {
    QgsDebugMsg( "field counts don't match" );
//  return false;
  }

  for ( int i = 0; i < mAttributeFields.count(); ++i )
  {
    QgsField fld = mAttributeFields.at( i );
    QgsDebugMsg( QString( "i: %1; got field: %2" ).arg( i ).arg( fld.name() ) );

    if ( fld.name().isEmpty() )
      continue; // invalid

    if ( mFidColName == fld.name() )
      continue; // skip identity field

//      if ( mDefaultValues.contains( i ) && mDefaultValues[i] == attrs.at( i ) )
//        continue; // skip fields having default values

    if ( !first )
    {
      statement += ',';
      values += ',';
    }
    else
      first = false;

    statement += QStringLiteral( "%1" ).arg( fld.name() );
    values += QStringLiteral( "?" );
  }

  // append geometry column name
  if ( !mGeometryColName.isEmpty() )
  {
    if ( !first )
    {
      statement += ',';
      values += ',';
    }

    statement += QStringLiteral( "%1" ).arg( mGeometryColName );

    values += QStringLiteral( "db2gse.%1(CAST (%2 AS BLOB(2M)),%3)" )
              .arg( mGeometryColType,
                    QStringLiteral( "?" ),
                    QString::number( mSRId ) );
  }

  QgsDebugMsg( statement );
  QgsDebugMsg( values );
  statement += ") VALUES (" + values + ')';
  QgsDebugMsg( statement );

  QgsDebugMsg( "Prepare statement" );
  // use prepared statement to prevent from sql injection
  if ( !query.prepare( statement ) )
  {
    QString msg = query.lastError().text();
    QgsDebugMsg( msg );
    pushError( msg );
    return false;
  }


  for ( QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it )
  {
    attrs = it->attributes();

    int fieldIdx = 0;
    if ( copyOperation )
    {
      fieldIdx = 1;  // skip first (FID) field if copying from shapefile
    }
    int bindIdx = 0;
    for ( int i = 0; i < attrs.count(); i++ )
    {
      QgsField fld = mAttributeFields.at( fieldIdx++ );
      if ( fld.name().isEmpty() )
        continue; // invalid

      if ( mFidColName == fld.name() )
        continue; // skip identity field

//      if ( mDefaultValues.contains( i ) && mDefaultValues[i] == attrs.at( i ) )
//        continue; // skip fields having default values

      QVariant::Type type = fld.type();
      if ( attrs.at( i ).isNull() || !attrs.at( i ).isValid() )
      {
        // binding null values
        if ( type == QVariant::Date || type == QVariant::DateTime )
          query.bindValue( bindIdx,  QVariant( QVariant::String ) );
        else
          query.bindValue( bindIdx,  QVariant( type ) );
      }
      else if ( type == QVariant::Int )
      {
        // binding an INTEGER value
        query.bindValue( bindIdx,  attrs.at( i ).toInt() );
      }
      else if ( type == QVariant::Double )
      {
        // binding a DOUBLE value
        query.bindValue( bindIdx,  attrs.at( i ).toDouble() );
      }
      else if ( type == QVariant::String )
      {
        // binding a TEXT value
        query.bindValue( bindIdx,  attrs.at( i ).toString() );
      }
      else if ( type == QVariant::Time )
      {
        // binding a TIME value
        query.bindValue( bindIdx,  attrs.at( i ).toTime().toString( Qt::ISODate ) );
      }
      else if ( type == QVariant::Date )
      {
        // binding a DATE value
        query.bindValue( bindIdx,  attrs.at( i ).toDate().toString( Qt::ISODate ) );
      }
      else if ( type == QVariant::DateTime )
      {
        // binding a DATETIME value
        query.bindValue( bindIdx,  attrs.at( i ).toDateTime().toString( Qt::ISODate ) );
      }
      else
      {
        query.bindValue( bindIdx,  attrs.at( i ) );
      }

#if 0
      QgsDebugMsg( QString( "bound i: %1; name: %2; value: %3; bindIdx: %4" ).
                   arg( i ).arg( fld.name() ).arg( attrs.at( i ).toString() ).arg( bindIdx ) );
#endif
      bindIdx++;
    }

    if ( !mGeometryColName.isEmpty() )
    {
      QgsGeometry geom = it->geometry();

      QByteArray bytea = geom.exportToWkb();
      query.bindValue( bindIdx,  bytea, QSql::In | QSql::Binary );
    }

    QList<QVariant> list = query.boundValues().values();

// Show bound values
#if 0
    for ( int i = 0; i < list.size(); ++i )
    {
      QgsDebugMsg( QString( "i: %1; value: %2; type: %3" )
                   .arg( i ).arg( list.at( i ).toString().toLatin1().data() ).arg( list.at( i ).typeName() ) );
    }
#endif
    if ( !query.exec() )
    {
      QString msg = query.lastError().text();
      QgsDebugMsg( msg );
      if ( !mSkipFailures )
      {
        pushError( msg );
        return false;
      }
    }

    if ( !( flags & QgsFeatureSink::FastInsert ) )
    {
      statement = QString( "select IDENTITY_VAL_LOCAL() AS IDENTITY "
                           "FROM SYSIBM.SYSDUMMY1" );
//    QgsDebugMsg( statement );
      if ( !queryFid.exec( statement ) )
      {
        QString msg = query.lastError().text();
        QgsDebugMsg( msg );
        if ( !mSkipFailures )
        {
          pushError( msg );
          return false;
        }
      }

      if ( !queryFid.next() )
      {
        QString msg = query.lastError().text();
        QgsDebugMsg( msg );
        if ( !mSkipFailures )
        {
          pushError( msg );
          return false;
        }
      }
      it->setId( queryFid.value( 0 ).toLongLong() );
    }
    writeCount++;
//    QgsDebugMsg( QString( "count: %1; featureId: %2" ).arg( writeCount ).arg( queryFid.value( 0 ).toLongLong() ) );
  }
  bool commitStatus = mDatabase.commit();
  QgsDebugMsg( QString( "commitStatus: %1; write count: %2; featureId: %3" )
               .arg( commitStatus ).arg( writeCount ).arg( queryFid.value( 0 ).toLongLong() ) );
  if ( !commitStatus )
  {
    pushError( QStringLiteral( "Commit of new features failed" ) );
    return false;
  }
  return true;
}