void QgsOSMDatabase::exportSpatiaLiteNodes( const QString& tableName, const QStringList& tagKeys, const QStringList& notNullTagKeys ) { QString sqlInsertPoint = QString( "INSERT INTO %1 VALUES (?" ).arg( quotedIdentifier( tableName ) ); for ( int i = 0; i < tagKeys.count(); ++i ) sqlInsertPoint += QString( ",?" ); sqlInsertPoint += ", GeomFromWKB(?, 4326))"; sqlite3_stmt* stmtInsert; if ( sqlite3_prepare_v2( mDatabase, sqlInsertPoint.toUtf8().constData(), -1, &stmtInsert, nullptr ) != SQLITE_OK ) { mError = "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 ); } sqlite3_bind_blob( stmtInsert, ++col, geom.asWkb(), ( int ) geom.wkbSize(), SQLITE_STATIC ); int insertRes = sqlite3_step( stmtInsert ); if ( insertRes != SQLITE_DONE ) { mError = QString( "Error inserting node %1 [%2]" ).arg( n.id() ).arg( insertRes ); break; } sqlite3_reset( stmtInsert ); sqlite3_clear_bindings( stmtInsert ); } sqlite3_finalize( stmtInsert ); }
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 QgsConstWkbPtr wkbPtr( lineGeom.asWkb(), lineGeom.wkbSize() ); 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 ); } }
//! Simplifies the specified geometry bool QgsTopologyPreservingSimplifier::simplifyGeometry( QgsGeometry* geometry ) const { QgsGeometry* g = geometry->simplify( mTolerance ); if ( g ) { int wkbSize = g->wkbSize(); unsigned char *wkb = new unsigned char[ wkbSize ]; memcpy( wkb, g->asWkb(), wkbSize ); geometry->fromWkb( wkb, wkbSize ); delete g; return true; } return false; }
void QgsLabel::labelPoint( std::vector<labelpoint>& points, QgsFeature & feature ) { QgsGeometry *geometry = feature.geometry(); const unsigned char *geom = geometry->asWkb(); size_t geomlen = geometry->wkbSize(); QGis::WkbType wkbType = geometry->wkbType(); labelpoint point; switch ( wkbType ) { case QGis::WKBPoint25D: case QGis::WKBPoint: case QGis::WKBLineString25D: case QGis::WKBLineString: case QGis::WKBPolygon25D: case QGis::WKBPolygon: { labelPoint( point, geom, geomlen ); points.push_back( point ); } break; case QGis::WKBMultiPoint25D: case QGis::WKBMultiPoint: case QGis::WKBMultiLineString25D: case QGis::WKBMultiLineString: case QGis::WKBMultiPolygon25D: case QGis::WKBMultiPolygon: // Return a position for each individual in the multi-feature { Q_ASSERT( 1 + sizeof( wkbType ) + sizeof( int ) <= geomlen ); geom += 1 + sizeof( wkbType ); int nFeatures = *( unsigned int * )geom; geom += sizeof( int ); const unsigned char *feature = geom; for ( int i = 0; i < nFeatures && feature; ++i ) { feature = labelPoint( point, feature, geom + geomlen - feature ); points.push_back( point ); } } break; default: QgsDebugMsg( "Unknown geometry type of " + QString::number( wkbType ) ); } }
void QgsGeometryAnalyzer::dissolveFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry** dissolveGeometry ) { QgsGeometry* featureGeometry = f.geometry(); if ( !featureGeometry ) { return; } if ( nProcessedFeatures == 0 ) { int geomSize = featureGeometry->wkbSize(); *dissolveGeometry = new QgsGeometry(); unsigned char* wkb = new unsigned char[geomSize]; memcpy( wkb, featureGeometry->asWkb(), geomSize ); ( *dissolveGeometry )->fromWkb( wkb, geomSize ); } else { *dissolveGeometry = ( *dissolveGeometry )->combine( featureGeometry ); } }
void QgsOSMDatabase::exportSpatiaLiteWays( bool closed, const QString& tableName, const QStringList& tagKeys, const QStringList& notNullTagKeys ) { Q_UNUSED( tagKeys ); QString sqlInsertLine = QString( "INSERT INTO %1 VALUES (?" ).arg( quotedIdentifier( tableName ) ); for ( int i = 0; i < tagKeys.count(); ++i ) sqlInsertLine += QString( ",?" ); sqlInsertLine += ", GeomFromWKB(?, 4326))"; sqlite3_stmt* stmtInsert; if ( sqlite3_prepare_v2( mDatabase, sqlInsertLine.toUtf8().constData(), -1, &stmtInsert, nullptr ) != SQLITE_OK ) { mError = "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( "highway" ) || t.contains( "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( "area" ) != "yes" && !t.contains( "amenity" ) && !t.contains( "landuse" ) && !t.contains( "building" ) && !t.contains( "natural" ) && !t.contains( "leisure" ) && !t.contains( "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.isEmpty() ) sqlite3_bind_blob( stmtInsert, ++col, geom.asWkb(), ( int ) geom.wkbSize(), SQLITE_STATIC ); else sqlite3_bind_null( stmtInsert, ++col ); int insertRes = sqlite3_step( stmtInsert ); if ( insertRes != SQLITE_DONE ) { mError = QString( "Error inserting way %1 [%2]" ).arg( w.id() ).arg( insertRes ); break; } sqlite3_reset( stmtInsert ); sqlite3_clear_bindings( stmtInsert ); } sqlite3_finalize( stmtInsert ); }
void QgsPointDisplacementRenderer::drawGroup( const DisplacementGroup& group, QgsRenderContext& context ) { const QgsFeature& feature = group.begin().value().first; bool selected = mSelectedFeatures.contains( feature.id() ); // maybe we should highlight individual features instead of the whole group? //get list of labels and symbols QStringList labelAttributeList; QList< QgsMarkerSymbolV2* > symbolList; QgsFeatureList featureList; QgsMultiPointV2* groupMultiPoint = new QgsMultiPointV2(); for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt ) { labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) : QString() ); symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second ); featureList << attIt.value().first; groupMultiPoint->addGeometry( attIt.value().first.constGeometry()->geometry()->clone() ); } //calculate centroid of all points, this will be center of group QgsGeometry groupGeom( groupMultiPoint ); QgsGeometry* centroid = groupGeom.centroid(); QPointF pt; QgsConstWkbPtr wkbPtr( centroid->asWkb(), centroid->wkbSize() ); _getPoint( pt, context, wkbPtr ); delete centroid; //calculate max diagonal size from all symbols in group double diagonal = 0; Q_FOREACH ( QgsMarkerSymbolV2* symbol, symbolList ) { if ( symbol ) { diagonal = qMax( diagonal, QgsSymbolLayerV2Utils::convertToPainterUnits( context, M_SQRT2 * symbol->size(), symbol->sizeUnit(), symbol->sizeMapUnitScale() ) ); } } QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected ); QList<QPointF> symbolPositions; QList<QPointF> labelPositions; double circleRadius = -1.0; calculateSymbolAndLabelPositions( symbolContext, pt, symbolList.size(), diagonal, symbolPositions, labelPositions, circleRadius ); //draw Circle if ( circleRadius > 0 ) drawCircle( circleRadius, symbolContext, pt, symbolList.size() ); //draw mid point if ( labelAttributeList.size() > 1 ) { if ( mCenterSymbol ) { mCenterSymbol->renderPoint( pt, &feature, context, -1, selected ); } else { context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) ); } } //draw symbols on the circle drawSymbols( featureList, context, symbolList, symbolPositions, selected ); //and also the labels drawLabels( pt, symbolContext, labelPositions, labelAttributeList ); }
bool QgsDb2Provider::addFeatures( QgsFeatureList & flist ) { 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 = QString( "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 QgsVectorLayerImport // 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 += QString( "%1" ).arg( fld.name() ); values += QString( "?" ); } // append geometry column name if ( !mGeometryColName.isEmpty() ) { if ( !first ) { statement += ','; values += ','; } statement += QString( "%1" ).arg( mGeometryColName ); values += QString( "db2gse.%1(CAST (%2 AS BLOB(2M)),%3)" ) .arg( mGeometryColType, QString( "?" ), 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 = QByteArray(( char* )geom.asWkb(), ( int ) geom.wkbSize() ); 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; } } 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->setFeatureId( 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( "Commit of new features failed" ); return false; } return true; }
void QgsOSMDatabase::exportSpatiaLiteWays( bool closed, const QString& tableName, const QStringList& tagKeys ) { Q_UNUSED( tagKeys ); QString sqlInsertLine = QString( "INSERT INTO %1 VALUES (?" ).arg( quotedIdentifier( tableName ) ); for ( int i = 0; i < tagKeys.count(); ++i ) sqlInsertLine += QString( ",?" ); sqlInsertLine += ", GeomFromWKB(?, 4326))"; sqlite3_stmt* stmtInsert; if ( sqlite3_prepare_v2( mDatabase, sqlInsertLine.toUtf8().constData(), -1, &stmtInsert, 0 ) != SQLITE_OK ) { mError = "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? // some closed ways are not really areas if ( isArea && ( t.contains( "highway" ) || t.contains( "barrier" ) ) ) { if ( t.value( "area" ) != "yes" ) // even though "highway" is line by default, "area"="yes" may override that isArea = false; } if ( closed != isArea ) continue; // skip if it's not what we're looking for 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 ); } sqlite3_bind_blob( stmtInsert, ++col, geom->asWkb(), geom->wkbSize(), SQLITE_STATIC ); int insertRes = sqlite3_step( stmtInsert ); if ( insertRes != SQLITE_DONE ) { mError = QString( "Error inserting way %1 [%2]" ).arg( w.id() ).arg( insertRes ); break; } sqlite3_reset( stmtInsert ); sqlite3_clear_bindings( stmtInsert ); delete geom; } sqlite3_finalize( stmtInsert ); }