bool QgsMemoryProvider::changeAttributeValues( const QgsChangedAttributesMap & attr_map ) { for ( QgsChangedAttributesMap::const_iterator it = attr_map.begin(); it != attr_map.end(); ++it ) { QgsFeatureMap::iterator fit = mFeatures.find( it.key() ); if ( fit == mFeatures.end() ) continue; const QgsAttributeMap& attrs = it.value(); for ( QgsAttributeMap::const_iterator it2 = attrs.begin(); it2 != attrs.end(); ++it2 ) fit->changeAttribute( it2.key(), it2.value() ); } return TRUE; }
bool QgsGPXProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map ) { QgsChangedAttributesMap::const_iterator aIter = attr_map.begin(); if ( mFeatureType == WaypointType ) { QgsGPSData::WaypointIterator wIter = data->waypointsBegin(); for ( ; wIter != data->waypointsEnd() && aIter != attr_map.end(); ++wIter ) { if ( wIter->id == aIter.key() ) { changeAttributeValues( *wIter, aIter.value() ); ++aIter; } } } else if ( mFeatureType == RouteType ) { QgsGPSData::RouteIterator rIter = data->routesBegin(); for ( ; rIter != data->routesEnd() && aIter != attr_map.end(); ++rIter ) { if ( rIter->id == aIter.key() ) { changeAttributeValues( *rIter, aIter.value() ); ++aIter; } } } if ( mFeatureType == TrackType ) { QgsGPSData::TrackIterator tIter = data->tracksBegin(); for ( ; tIter != data->tracksEnd() && aIter != attr_map.end(); ++tIter ) { if ( tIter->id == aIter.key() ) { changeAttributeValues( *tIter, aIter.value() ); ++aIter; } } } // write back to file QFile file( mFileName ); if ( !file.open( QIODevice::WriteOnly ) ) return false; QTextStream ostr( &file ); data->writeXML( ostr ); return true; }
void QgsFeaturePool::updateFeature( QgsFeature& feature ) { QgsGeometryMap geometryMap; geometryMap.insert( feature.id(), QgsGeometry( feature.geometry()->geometry()->clone() ) ); QgsChangedAttributesMap changedAttributesMap; QgsAttributeMap attribMap; for ( int i = 0, n = feature.attributes().size(); i < n; ++i ) { attribMap.insert( i, feature.attributes().at( i ) ); } changedAttributesMap.insert( feature.id(), attribMap ); mLayerMutex.lock(); mFeatureCache.remove( feature.id() ); // Remove to force reload on next get() mLayer->dataProvider()->changeGeometryValues( geometryMap ); mLayer->dataProvider()->changeAttributeValues( changedAttributesMap ); mLayerMutex.unlock(); mIndexMutex.lock(); mIndex.deleteFeature( feature ); mIndex.insertFeature( feature ); mIndexMutex.unlock(); }
/*! \fn OptVectorLayer:: changeAttribute(QgsFeature& feature, int field, QVariant attr) */ bool OptVectorLayer:: changeAttribute(QgsFeature& feature, int field, QVariant attr) { if ( !isEditable() ) { startEditing(); } if ( isModified() ) { commitChanges(); } QgsChangedAttributesMap attributeChanges; QgsAttributeMap newAttMap; newAttMap.insert(field, attr ); attributeChanges.insert(feature.id(), newAttMap); //{zhangliye2715} ;api changed // commitAttributeChanges(QgsAttributeIds(), // QgsNewAttributesMap(), // attributeChanges); dataProvider()->changeAttributeValues(attributeChanges); //commit or rollBack the change if ( isModified() ) { commitChanges(); } else { rollBack(); return false; } //make the layer still editable for the next adding operation startEditing(); return true; }
void QgsOfflineEditing::committedAttributeValuesChanges( const QString& qgisLayerId, const QgsChangedAttributesMap& changedAttrsMap ) { sqlite3* db = openLoggingDb(); if ( db == NULL ) { return; } // insert log int layerId = getOrCreateLayerId( db, qgisLayerId ); int commitNo = getCommitNo( db ); for ( QgsChangedAttributesMap::const_iterator cit = changedAttrsMap.begin(); cit != changedAttrsMap.end(); ++cit ) { QgsFeatureId fid = cit.key(); if ( isAddedFeature( db, layerId, fid ) ) { // skip added features continue; } QgsAttributeMap attrMap = cit.value(); for ( QgsAttributeMap::const_iterator it = attrMap.begin(); it != attrMap.end(); ++it ) { QString sql = QString( "INSERT INTO 'log_feature_updates' VALUES ( %1, %2, %3, %4, '%5' )" ) .arg( layerId ) .arg( commitNo ) .arg( fid ) .arg( it.key() ) // attr .arg( it.value().toString() ); // value sqlExec( db, sql ); } } increaseCommitNo( db ); sqlite3_close( db ); }
int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QgsWkbTypes::PolygonGeometry ) { return 1; } QgsVectorDataProvider *vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } if ( !mRasterLayer ) { return 3; } if ( mRasterLayer->bandCount() < mRasterBand ) { return 4; } mRasterProvider = mRasterLayer->dataProvider(); mInputNodataValue = mRasterProvider->sourceNoDataValue( mRasterBand ); //get geometry info about raster layer int nCellsXProvider = mRasterProvider->xSize(); int nCellsYProvider = mRasterProvider->ySize(); double cellsizeX = mRasterLayer->rasterUnitsPerPixelX(); if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = mRasterLayer->rasterUnitsPerPixelY(); if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox = mRasterProvider->extent(); //add the new fields to the provider QList<QgsField> newFieldList; QString countFieldName; if ( mStatistics & QgsZonalStatistics::Count ) { countFieldName = getUniqueFieldName( mAttributePrefix + "count", newFieldList ); QgsField countField( countFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( countField ); } QString sumFieldName; if ( mStatistics & QgsZonalStatistics::Sum ) { sumFieldName = getUniqueFieldName( mAttributePrefix + "sum", newFieldList ); QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( sumField ); } QString meanFieldName; if ( mStatistics & QgsZonalStatistics::Mean ) { meanFieldName = getUniqueFieldName( mAttributePrefix + "mean", newFieldList ); QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( meanField ); } QString medianFieldName; if ( mStatistics & QgsZonalStatistics::Median ) { medianFieldName = getUniqueFieldName( mAttributePrefix + "median", newFieldList ); QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( medianField ); } QString stdevFieldName; if ( mStatistics & QgsZonalStatistics::StDev ) { stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev", newFieldList ); QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( stdField ); } QString minFieldName; if ( mStatistics & QgsZonalStatistics::Min ) { minFieldName = getUniqueFieldName( mAttributePrefix + "min", newFieldList ); QgsField minField( minFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( minField ); } QString maxFieldName; if ( mStatistics & QgsZonalStatistics::Max ) { maxFieldName = getUniqueFieldName( mAttributePrefix + "max", newFieldList ); QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( maxField ); } QString rangeFieldName; if ( mStatistics & QgsZonalStatistics::Range ) { rangeFieldName = getUniqueFieldName( mAttributePrefix + "range", newFieldList ); QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( rangeField ); } QString minorityFieldName; if ( mStatistics & QgsZonalStatistics::Minority ) { minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority", newFieldList ); QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( minorityField ); } QString majorityFieldName; if ( mStatistics & QgsZonalStatistics::Majority ) { majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority", newFieldList ); QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( majField ); } QString varietyFieldName; if ( mStatistics & QgsZonalStatistics::Variety ) { varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety", newFieldList ); QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) ); newFieldList.push_back( varietyField ); } QString varianceFieldName; if ( mStatistics & QgsZonalStatistics::Variance ) { varianceFieldName = getUniqueFieldName( mAttributePrefix + "variance", newFieldList ); QgsField varianceField( varianceFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( varianceField ); } vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1; int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1; int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1; int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1; int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1; int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1; int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1; int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1; int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1; int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1; int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1; int varianceIndex = mStatistics & QgsZonalStatistics::Variance ? vectorProvider->fieldNameIndex( varianceFieldName ) : -1; if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 ) || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variance && varianceIndex == -1 ) ) { //failed to create a required field return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) || ( mStatistics & QgsZonalStatistics::StDev ) || ( mStatistics & QgsZonalStatistics::Variance ); bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) || ( mStatistics & QgsZonalStatistics::Majority ); FeatureStats featureStats( statsStoreValues, statsStoreValueCount ); int featureCounter = 0; QgsChangedAttributesMap changeMap; while ( fi.nextFeature( f ) ) { if ( feedback && feedback->isCanceled() ) { break; } if ( feedback ) { feedback->setProgress( 100.0 * static_cast< double >( featureCounter ) / featureCount ); } if ( !f.hasGeometry() ) { ++featureCounter; continue; } QgsGeometry featureGeometry = f.geometry(); QgsRectangle featureRect = featureGeometry.boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if ( ( offsetX + nCellsX ) > nCellsXProvider ) { nCellsX = nCellsXProvider - offsetX; } if ( ( offsetY + nCellsY ) > nCellsYProvider ) { nCellsY = nCellsYProvider - offsetY; } statisticsFromMiddlePointTest( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); if ( featureStats.count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); } //write the statistics value to the vector data provider QgsAttributeMap changeAttributeMap; if ( mStatistics & QgsZonalStatistics::Count ) changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) ); if ( mStatistics & QgsZonalStatistics::Sum ) changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) ); if ( featureStats.count > 0 ) { double mean = featureStats.sum / featureStats.count; if ( mStatistics & QgsZonalStatistics::Mean ) changeAttributeMap.insert( meanIndex, QVariant( mean ) ); if ( mStatistics & QgsZonalStatistics::Median ) { std::sort( featureStats.values.begin(), featureStats.values.end() ); int size = featureStats.values.count(); bool even = ( size % 2 ) < 1; double medianValue; if ( even ) { medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2; } else //odd { medianValue = featureStats.values.at( ( size + 1 ) / 2 - 1 ); } changeAttributeMap.insert( medianIndex, QVariant( medianValue ) ); } if ( mStatistics & QgsZonalStatistics::StDev || mStatistics & QgsZonalStatistics::Variance ) { double sumSquared = 0; for ( int i = 0; i < featureStats.values.count(); ++i ) { double diff = featureStats.values.at( i ) - mean; sumSquared += diff * diff; } double variance = sumSquared / featureStats.values.count(); if ( mStatistics & QgsZonalStatistics::StDev ) { double stdev = std::pow( variance, 0.5 ); changeAttributeMap.insert( stdevIndex, QVariant( stdev ) ); } if ( mStatistics & QgsZonalStatistics::Variance ) changeAttributeMap.insert( varianceIndex, QVariant( variance ) ); } if ( mStatistics & QgsZonalStatistics::Min ) changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Max ) changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) ); if ( mStatistics & QgsZonalStatistics::Range ) changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority ) { QList<int> vals = featureStats.valueCount.values(); std::sort( vals.begin(), vals.end() ); if ( mStatistics & QgsZonalStatistics::Minority ) { float minorityKey = featureStats.valueCount.key( vals.first() ); changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) ); } if ( mStatistics & QgsZonalStatistics::Majority ) { float majKey = featureStats.valueCount.key( vals.last() ); changeAttributeMap.insert( majorityIndex, QVariant( majKey ) ); } } if ( mStatistics & QgsZonalStatistics::Variety ) changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) ); } changeMap.insert( f.id(), changeAttributeMap ); ++featureCounter; } vectorProvider->changeAttributeValues( changeMap ); if ( feedback ) { feedback->setProgress( 100 ); } mPolygonLayer->updateFields(); if ( feedback && feedback->isCanceled() ) { return 9; } return 0; }
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( mRasterFilePath.toLocal8Bit().data(), GA_ReadOnly ); if ( inputDataset == NULL ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( rasterBand == NULL ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, NULL ); //get geometry info about raster layer int nCellsX = GDALGetRasterXSize( inputDataset ); int nCellsY = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsY * cellsizeY ), geoTransform[0] + ( nCellsX * cellsizeX ), geoTransform[3] ); //add the new count, sum, mean fields to the provider QList<QgsField> newFieldList; QgsField countField( mAttributePrefix + "count", QVariant::Double ); QgsField sumField( mAttributePrefix + "sum", QVariant::Double ); QgsField meanField( mAttributePrefix + "mean", QVariant::Double ); newFieldList.push_back( countField ); newFieldList.push_back( sumField ); newFieldList.push_back( meanField ); if ( !vectorProvider->addAttributes( newFieldList ) ) { return 7; } //index of the new fields int countIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "count" ); int sumIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "sum" ); int meanIndex = vectorProvider->fieldNameIndex( mAttributePrefix + "mean" ); if ( countIndex == -1 || sumIndex == -1 || meanIndex == -1 ) { return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon vectorProvider->select( QgsAttributeList(), QgsRectangle(), true, false ); vectorProvider->rewind(); QgsFeature f; double count = 0; double sum = 0; double mean = 0; int featureCounter = 0; while ( vectorProvider->nextFeature( f ) ) { qWarning( "%d", featureCounter ); if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } QgsGeometry* featureGeometry = f.geometry(); if ( !featureGeometry ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureGeometry->boundingBox(), cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } statisticsFromMiddlePointTest_improved( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); if ( count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, sum, count ); } if ( count == 0 ) { mean = 0; } else { mean = sum / count; } //write the statistics value to the vector data provider QgsChangedAttributesMap changeMap; QgsAttributeMap changeAttributeMap; changeAttributeMap.insert( countIndex, QVariant( count ) ); changeAttributeMap.insert( sumIndex, QVariant( sum ) ); changeAttributeMap.insert( meanIndex, QVariant( mean ) ); changeMap.insert( f.id(), changeAttributeMap ); vectorProvider->changeAttributeValues( changeMap ); ++featureCounter; } if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); return 0; }
bool QgsWFSProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map ) { //find out typename from uri and strip namespace prefix QString tname = mShared->mURI.typeName(); if ( tname.isNull() ) { return false; } //create <Transaction> xml QDomDocument transactionDoc; QDomElement transactionElem = createTransactionElement( transactionDoc ); transactionDoc.appendChild( transactionElem ); QgsChangedAttributesMap::const_iterator attIt = attr_map.constBegin(); for ( ; attIt != attr_map.constEnd(); ++attIt ) { QString gmlid = mShared->findGmlId( attIt.key() ); if ( gmlid.isEmpty() ) { QgsDebugMsg( QString( "Cannot identify feature of id %1" ).arg( attIt.key() ) ); continue; } QDomElement updateElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, "Update" ); updateElem.setAttribute( "typeName", tname ); QgsAttributeMap::const_iterator attMapIt = attIt.value().constBegin(); for ( ; attMapIt != attIt.value().constEnd(); ++attMapIt ) { QString fieldName = mShared->mFields.at( attMapIt.key() ).name(); QDomElement propertyElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, "Property" ); QDomElement nameElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, "Name" ); QDomText nameText = transactionDoc.createTextNode( fieldName ); nameElem.appendChild( nameText ); propertyElem.appendChild( nameElem ); QDomElement valueElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, "Value" ); QDomText valueText = transactionDoc.createTextNode( attMapIt.value().toString() ); valueElem.appendChild( valueText ); propertyElem.appendChild( valueElem ); updateElem.appendChild( propertyElem ); } //Filter QDomElement filterElem = transactionDoc.createElementNS( QgsWFSConstants::OGC_NAMESPACE, "Filter" ); QDomElement featureIdElem = transactionDoc.createElementNS( QgsWFSConstants::OGC_NAMESPACE, "FeatureId" ); featureIdElem.setAttribute( "fid", gmlid ); filterElem.appendChild( featureIdElem ); updateElem.appendChild( filterElem ); transactionElem.appendChild( updateElem ); } QDomDocument serverResponse; bool success = sendTransactionDocument( transactionDoc, serverResponse ); if ( !success ) { return false; } if ( transactionSuccess( serverResponse ) ) { mShared->changeAttributeValues( attr_map ); return true; } else { handleException( serverResponse ); return false; } }
int QgsZonalStatistics::calculateStatistics( QProgressDialog* p ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QGis::Polygon ) { return 1; } QgsVectorDataProvider* vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } //open the raster layer and the raster band GDALAllRegister(); GDALDatasetH inputDataset = GDALOpen( TO8F( mRasterFilePath ), GA_ReadOnly ); if ( !inputDataset ) { return 3; } if ( GDALGetRasterCount( inputDataset ) < ( mRasterBand - 1 ) ) { GDALClose( inputDataset ); return 4; } GDALRasterBandH rasterBand = GDALGetRasterBand( inputDataset, mRasterBand ); if ( !rasterBand ) { GDALClose( inputDataset ); return 5; } mInputNodataValue = GDALGetRasterNoDataValue( rasterBand, nullptr ); //get geometry info about raster layer int nCellsXGDAL = GDALGetRasterXSize( inputDataset ); int nCellsYGDAL = GDALGetRasterYSize( inputDataset ); double geoTransform[6]; if ( GDALGetGeoTransform( inputDataset, geoTransform ) != CE_None ) { GDALClose( inputDataset ); return 6; } double cellsizeX = geoTransform[1]; if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = geoTransform[5]; if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox( geoTransform[0], geoTransform[3] - ( nCellsYGDAL * cellsizeY ), geoTransform[0] + ( nCellsXGDAL * cellsizeX ), geoTransform[3] ); //add the new fields to the provider QList<QgsField> newFieldList; QString countFieldName; if ( mStatistics & QgsZonalStatistics::Count ) { countFieldName = getUniqueFieldName( mAttributePrefix + "count" ); QgsField countField( countFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( countField ); } QString sumFieldName; if ( mStatistics & QgsZonalStatistics::Sum ) { sumFieldName = getUniqueFieldName( mAttributePrefix + "sum" ); QgsField sumField( sumFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( sumField ); } QString meanFieldName; if ( mStatistics & QgsZonalStatistics::Mean ) { meanFieldName = getUniqueFieldName( mAttributePrefix + "mean" ); QgsField meanField( meanFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( meanField ); } QString medianFieldName; if ( mStatistics & QgsZonalStatistics::Median ) { medianFieldName = getUniqueFieldName( mAttributePrefix + "median" ); QgsField medianField( medianFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( medianField ); } QString stdevFieldName; if ( mStatistics & QgsZonalStatistics::StDev ) { stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev" ); QgsField stdField( stdevFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( stdField ); } QString minFieldName; if ( mStatistics & QgsZonalStatistics::Min ) { minFieldName = getUniqueFieldName( mAttributePrefix + "min" ); QgsField minField( minFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( minField ); } QString maxFieldName; if ( mStatistics & QgsZonalStatistics::Max ) { maxFieldName = getUniqueFieldName( mAttributePrefix + "max" ); QgsField maxField( maxFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( maxField ); } QString rangeFieldName; if ( mStatistics & QgsZonalStatistics::Range ) { rangeFieldName = getUniqueFieldName( mAttributePrefix + "range" ); QgsField rangeField( rangeFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( rangeField ); } QString minorityFieldName; if ( mStatistics & QgsZonalStatistics::Minority ) { minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority" ); QgsField minorityField( minorityFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( minorityField ); } QString majorityFieldName; if ( mStatistics & QgsZonalStatistics::Majority ) { majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority" ); QgsField majField( majorityFieldName, QVariant::Double, "double precision" ); newFieldList.push_back( majField ); } QString varietyFieldName; if ( mStatistics & QgsZonalStatistics::Variety ) { varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety" ); QgsField varietyField( varietyFieldName, QVariant::Int, "int" ); newFieldList.push_back( varietyField ); } vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1; int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1; int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1; int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1; int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1; int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1; int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1; int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1; int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1; int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1; int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1; if (( mStatistics & QgsZonalStatistics::Count && countIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 ) || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 ) ) { //failed to create a required field return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); if ( p ) { p->setMaximum( featureCount ); } //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) || ( mStatistics & QgsZonalStatistics::StDev ); bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) || ( mStatistics & QgsZonalStatistics::Majority ); FeatureStats featureStats( statsStoreValues, statsStoreValueCount ); int featureCounter = 0; QgsChangedAttributesMap changeMap; while ( fi.nextFeature( f ) ) { if ( p ) { p->setValue( featureCounter ); } if ( p && p->wasCanceled() ) { break; } if ( !f.constGeometry() ) { ++featureCounter; continue; } const QgsGeometry* featureGeometry = f.constGeometry(); QgsRectangle featureRect = featureGeometry->boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if (( offsetX + nCellsX ) > nCellsXGDAL ) { nCellsX = nCellsXGDAL - offsetX; } if (( offsetY + nCellsY ) > nCellsYGDAL ) { nCellsY = nCellsYGDAL - offsetY; } statisticsFromMiddlePointTest( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); if ( featureStats.count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( rasterBand, featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); } //write the statistics value to the vector data provider QgsAttributeMap changeAttributeMap; if ( mStatistics & QgsZonalStatistics::Count ) changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) ); if ( mStatistics & QgsZonalStatistics::Sum ) changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) ); if ( featureStats.count > 0 ) { double mean = featureStats.sum / featureStats.count; if ( mStatistics & QgsZonalStatistics::Mean ) changeAttributeMap.insert( meanIndex, QVariant( mean ) ); if ( mStatistics & QgsZonalStatistics::Median ) { qSort( featureStats.values.begin(), featureStats.values.end() ); int size = featureStats.values.count(); bool even = ( size % 2 ) < 1; double medianValue; if ( even ) { medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2; } else //odd { medianValue = featureStats.values.at(( size + 1 ) / 2 - 1 ); } changeAttributeMap.insert( medianIndex, QVariant( medianValue ) ); } if ( mStatistics & QgsZonalStatistics::StDev ) { double sumSquared = 0; for ( int i = 0; i < featureStats.values.count(); ++i ) { double diff = featureStats.values.at( i ) - mean; sumSquared += diff * diff; } double stdev = qPow( sumSquared / featureStats.values.count(), 0.5 ); changeAttributeMap.insert( stdevIndex, QVariant( stdev ) ); } if ( mStatistics & QgsZonalStatistics::Min ) changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Max ) changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) ); if ( mStatistics & QgsZonalStatistics::Range ) changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority ) { QList<int> vals = featureStats.valueCount.values(); qSort( vals.begin(), vals.end() ); if ( mStatistics & QgsZonalStatistics::Minority ) { float minorityKey = featureStats.valueCount.key( vals.first() ); changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) ); } if ( mStatistics & QgsZonalStatistics::Majority ) { float majKey = featureStats.valueCount.key( vals.last() ); changeAttributeMap.insert( majorityIndex, QVariant( majKey ) ); } } if ( mStatistics & QgsZonalStatistics::Variety ) changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) ); } changeMap.insert( f.id(), changeAttributeMap ); ++featureCounter; } vectorProvider->changeAttributeValues( changeMap ); if ( p ) { p->setValue( featureCount ); } GDALClose( inputDataset ); mPolygonLayer->updateFields(); if ( p && p->wasCanceled() ) { return 9; } return 0; }
bool QgsDb2Provider::changeAttributeValues( const QgsChangedAttributesMap &attr_map ) { QgsDebugMsg( "Entering" ); if ( attr_map.isEmpty() ) return true; if ( mFidColName.isEmpty() ) return false; for ( QgsChangedAttributesMap::const_iterator it = attr_map.begin(); it != attr_map.end(); ++it ) { QgsFeatureId fid = it.key(); // skip added features if ( FID_IS_NEW( fid ) ) continue; const QgsAttributeMap& attrs = it.value(); if ( attrs.isEmpty() ) continue; QString statement = QString( "UPDATE %1.%2 SET " ).arg( mSchemaName, mTableName ); bool first = true; if ( !mDatabase.isOpen() ) { QString errMsg; mDatabase = getDatabase( mConnInfo, errMsg ); if ( !errMsg.isEmpty() ) { return false; } } QSqlQuery query = QSqlQuery( mDatabase ); query.setForwardOnly( true ); for ( QgsAttributeMap::const_iterator it2 = attrs.begin(); it2 != attrs.end(); ++it2 ) { QgsField fld = mAttributeFields.at( it2.key() ); if ( fld.typeName().endsWith( " identity", Qt::CaseInsensitive ) ) continue; // skip identity field if ( fld.name().isEmpty() ) continue; // invalid if ( !first ) statement += ','; else first = false; statement += QString( "%1=?" ).arg( fld.name() ); } if ( first ) return true; // no fields have been changed // set attribute filter statement += QString( " WHERE %1=%2" ).arg( mFidColName, FID_TO_STRING( fid ) ); // use prepared statement to prevent from sql injection if ( !query.prepare( statement ) ) { QgsDebugMsg( query.lastError().text() ); return false; } QgsDebugMsg( statement ); for ( QgsAttributeMap::const_iterator it2 = attrs.begin(); it2 != attrs.end(); ++it2 ) { QgsField fld = mAttributeFields.at( it2.key() ); if ( fld.name().isEmpty() ) continue; // invalid QVariant::Type type = fld.type(); if ( it2->isNull() || !it2->isValid() ) { // binding null values if ( type == QVariant::Date || type == QVariant::DateTime ) query.addBindValue( QVariant( QVariant::String ) ); else query.addBindValue( QVariant( type ) ); } else if ( type == QVariant::Int ) { // binding an INTEGER value query.addBindValue( it2->toInt() ); } else if ( type == QVariant::Double ) { // binding a DOUBLE value query.addBindValue( it2->toDouble() ); } else if ( type == QVariant::String ) { // binding a TEXT value query.addBindValue( it2->toString() ); } else if ( type == QVariant::DateTime ) { // binding a DATETIME value query.addBindValue( it2->toDateTime().toString( Qt::ISODate ) ); } else if ( type == QVariant::Date ) { // binding a DATE value query.addBindValue( it2->toDate().toString( Qt::ISODate ) ); } else if ( type == QVariant::Time ) { // binding a TIME value query.addBindValue( it2->toTime().toString( Qt::ISODate ) ); } else { query.addBindValue( *it2 ); } } if ( !query.exec() ) { QgsDebugMsg( query.lastError().text() ); return false; } } return true; }