void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mLayer ); if ( !vlayer ) //if no given layer take the current from canvas vlayer = currentVectorLayer(); if ( !vlayer ) { notifyNotVectorLayer(); return; } QgsWkbTypes::Type layerWKBType = vlayer->wkbType(); QgsVectorDataProvider *provider = vlayer->dataProvider(); if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) ) { emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), Qgis::Warning ); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } // POINT CAPTURING if ( mode() == CapturePoint ) { if ( e->button() != Qt::LeftButton ) return; //check we only use this tool for point/multipoint layers if ( vlayer->geometryType() != QgsWkbTypes::PointGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), Qgis::Warning ); return; } QgsPoint savePoint; //point in layer coordinates bool isMatchPointZ = false; try { QgsPoint fetchPoint; int res; res = fetchLayerPoint( e->mapPointMatch(), fetchPoint ); if ( QgsWkbTypes::hasZ( fetchPoint.wkbType() ) ) isMatchPointZ = true; if ( res == 0 ) { if ( isMatchPointZ ) savePoint = fetchPoint; else savePoint = QgsPoint( fetchPoint.x(), fetchPoint.y() ); } else { QgsPointXY layerPoint = toLayerCoordinates( vlayer, e->mapPoint() ); if ( isMatchPointZ ) savePoint = QgsPoint( QgsWkbTypes::PointZ, layerPoint.x(), layerPoint.y(), fetchPoint.z() ); else savePoint = QgsPoint( layerPoint.x(), layerPoint.y() ); } } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::Warning ); return; } //only do the rest for provider with feature addition support //note that for the grass provider, this will return false since //grass provider has its own mechanism of feature addition if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) { QgsFeature f( vlayer->fields(), 0 ); QgsGeometry g; if ( layerWKBType == QgsWkbTypes::Point ) { g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) ); } else if ( !QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) ) { g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) ); } else if ( QgsWkbTypes::isMultiType( layerWKBType ) && !QgsWkbTypes::hasZ( layerWKBType ) ) { g = QgsGeometry::fromMultiPointXY( QgsMultiPointXY() << savePoint ); } else if ( QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) ) { QgsMultiPoint *mp = new QgsMultiPoint(); mp->addGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) ); g.set( mp ); } else { // if layer supports more types (mCheckGeometryType is false) g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) ); } if ( QgsWkbTypes::hasM( layerWKBType ) ) { g.get()->addMValue(); } f.setGeometry( g ); f.setValid( true ); digitized( f ); // we are done with digitizing for now so instruct advanced digitizing dock to reset its CAD points cadDockWidget()->clearPoints(); } } // LINE AND POLYGON CAPTURING else if ( mode() == CaptureLine || mode() == CapturePolygon ) { //check we only use the line tool for line/multiline layers if ( mode() == CaptureLine && vlayer->geometryType() != QgsWkbTypes::LineGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), Qgis::Warning ); return; } //check we only use the polygon tool for polygon/multipolygon layers if ( mode() == CapturePolygon && vlayer->geometryType() != QgsWkbTypes::PolygonGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), Qgis::Warning ); return; } //add point to list and to rubber band if ( e->button() == Qt::LeftButton ) { int error = addVertex( e->mapPoint(), e->mapPointMatch() ); if ( error == 1 ) { //current layer is not a vector layer return; } else if ( error == 2 ) { //problem with coordinate transformation emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::Warning ); return; } startCapturing(); } else if ( e->button() == Qt::RightButton ) { // End of string deleteTempRubberBand(); //lines: bail out if there are not at least two vertices if ( mode() == CaptureLine && size() < 2 ) { stopCapturing(); return; } //polygons: bail out if there are not at least two vertices if ( mode() == CapturePolygon && size() < 3 ) { stopCapturing(); return; } if ( mode() == CapturePolygon ) { closePolygon(); } //create QgsFeature with wkb representation std::unique_ptr< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) ); //does compoundcurve contain circular strings? //does provider support circular strings? bool hasCurvedSegments = captureCurve()->hasCurvedSegments(); bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries; QList<QgsPointLocator::Match> snappingMatchesList; QgsCurve *curveToAdd = nullptr; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { curveToAdd = captureCurve()->clone(); } else { curveToAdd = captureCurve()->curveToLine(); snappingMatchesList = snappingMatches(); } if ( mode() == CaptureLine ) { QgsGeometry g( curveToAdd ); f->setGeometry( g ); } else { QgsCurvePolygon *poly = nullptr; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { poly = new QgsCurvePolygon(); } else { poly = new QgsPolygon(); } poly->setExteriorRing( curveToAdd ); QgsGeometry g( poly ); f->setGeometry( g ); QgsGeometry featGeom = f->geometry(); int avoidIntersectionsReturn = featGeom.avoidIntersections( QgsProject::instance()->avoidIntersectionsLayers() ); f->setGeometry( featGeom ); if ( avoidIntersectionsReturn == 1 ) { //not a polygon type. Impossible to get there } if ( f->geometry().isEmpty() ) //avoid intersection might have removed the whole geometry { emit messageEmitted( tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ), Qgis::Critical ); stopCapturing(); return; } } f->setValid( true ); digitized( *f ); stopCapturing(); } } }
bool QgsGeometryAnalyzer::centroids( QgsVectorLayer* layer, const QString& shapefileName, bool onlySelectedFeatures, QProgressDialog* p ) { if ( !layer ) { return false; } QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } QGis::WkbType outputType = QGis::WKBPoint; const QgsCoordinateReferenceSystem crs = layer->crs(); QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), dp->fields(), outputType, &crs ); QgsFeature currentFeature; //take only selection if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId const QgsFeatureIds selection = layer->selectedFeaturesIds(); if ( p ) { p->setMaximum( selection.size() ); } int processedFeatures = 0; QgsFeatureIds::const_iterator it = selection.constBegin(); for ( ; it != selection.constEnd(); ++it ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } if ( !layer->featureAtId( *it, currentFeature, true, true ) ) { continue; } centroidFeature( currentFeature, &vWriter ); ++processedFeatures; } if ( p ) { p->setValue( selection.size() ); } } //take all features else { layer->select( layer->pendingAllAttributesList(), QgsRectangle(), true, false ); int featureCount = layer->featureCount(); if ( p ) { p->setMaximum( featureCount ); } int processedFeatures = 0; while ( layer->nextFeature( currentFeature ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } centroidFeature( currentFeature, &vWriter ); ++processedFeatures; } if ( p ) { p->setValue( featureCount ); } } return true; }
QDomDocument QgsWFSServer::describeFeatureType() { QgsDebugMsg( "Entering." ); QDomDocument doc; //xsd:schema QDomElement schemaElement = doc.createElement( "schema"/*xsd:schema*/ ); schemaElement.setAttribute( "xmlns", "http://www.w3.org/2001/XMLSchema" ); schemaElement.setAttribute( "xmlns:xsd", "http://www.w3.org/2001/XMLSchema" ); schemaElement.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" ); schemaElement.setAttribute( "xmlns:gml", "http://www.opengis.net/gml" ); schemaElement.setAttribute( "xmlns:qgs", "http://www.qgis.org/gml" ); schemaElement.setAttribute( "targetNamespace", "http://www.qgis.org/gml" ); doc.appendChild( schemaElement ); //xsd:import QDomElement importElement = doc.createElement( "import"/*xsd:import*/ ); importElement.setAttribute( "namespace", "http://www.opengis.net/gml" ); importElement.setAttribute( "schemaLocation", "http://schemas.opengis.net/gml/2.1.2/feature.xsd" ); schemaElement.appendChild( importElement ); //read TYPENAME QString typeName; QMap<QString, QString>::const_iterator type_name_it = mParameterMap.find( "TYPENAME" ); if ( type_name_it != mParameterMap.end() ) { typeName = type_name_it.value(); } else { return doc; } QStringList wfsLayersId = mConfigParser->wfsLayers(); QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo(); QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes(); QList<QgsMapLayer*> layerList; QgsMapLayer* currentLayer = 0; layerList = mConfigParser->mapLayerFromStyle( typeName, "" ); currentLayer = layerList.at( 0 ); QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( currentLayer ); if ( layer && wfsLayersId.contains( layer->id() ) ) { //is there alias info for this vector layer? QMap< int, QString > layerAliasInfo; QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() ); if ( aliasIt != aliasInfo.constEnd() ) { layerAliasInfo = aliasIt.value(); } //hidden attributes for this layer QSet<QString> layerHiddenAttributes; QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() ); if ( hiddenIt != hiddenAttributes.constEnd() ) { layerHiddenAttributes = hiddenIt.value(); } //do a select with searchRect and go through all the features QgsVectorDataProvider* provider = layer->dataProvider(); if ( !provider ) { return doc; } typeName = typeName.replace( QString( " " ), QString( "_" ) ); //xsd:element QDomElement elementElem = doc.createElement( "element"/*xsd:element*/ ); elementElem.setAttribute( "name", typeName ); elementElem.setAttribute( "type", "qgs:" + typeName + "Type" ); elementElem.setAttribute( "substitutionGroup", "gml:_Feature" ); schemaElement.appendChild( elementElem ); //xsd:complexType QDomElement complexTypeElem = doc.createElement( "complexType"/*xsd:complexType*/ ); complexTypeElem.setAttribute( "name", typeName + "Type" ); schemaElement.appendChild( complexTypeElem ); //xsd:complexType QDomElement complexContentElem = doc.createElement( "complexContent"/*xsd:complexContent*/ ); complexTypeElem.appendChild( complexContentElem ); //xsd:extension QDomElement extensionElem = doc.createElement( "extension"/*xsd:extension*/ ); extensionElem.setAttribute( "base", "gml:AbstractFeatureType" ); complexContentElem.appendChild( extensionElem ); //xsd:sequence QDomElement sequenceElem = doc.createElement( "sequence"/*xsd:sequence*/ ); extensionElem.appendChild( sequenceElem ); //xsd:element QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); geomElem.setAttribute( "name", "geometry" ); geomElem.setAttribute( "type", "gml:GeometryPropertyType" ); geomElem.setAttribute( "minOccurs", "0" ); geomElem.setAttribute( "maxOccurs", "1" ); sequenceElem.appendChild( geomElem ); const QgsFieldMap& fields = provider->fields(); for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it ) { QString attributeName = it.value().name(); //skip attribute if it has edit type 'hidden' if ( layerHiddenAttributes.contains( attributeName ) ) { continue; } //xsd:element QDomElement geomElem = doc.createElement( "element"/*xsd:element*/ ); geomElem.setAttribute( "name", attributeName ); if ( it.value().type() == 2 ) geomElem.setAttribute( "type", "integer" ); else if ( it.value().type() == 6 ) geomElem.setAttribute( "type", "double" ); else geomElem.setAttribute( "type", "string" ); sequenceElem.appendChild( geomElem ); //check if the attribute name should be replaced with an alias QMap<int, QString>::const_iterator aliasIt = layerAliasInfo.find( it.key() ); if ( aliasIt != layerAliasInfo.constEnd() ) { geomElem.setAttribute( "alias", aliasIt.value() ); } } } return doc; }
int QgsWFSServer::getFeature( QgsRequestHandler& request, const QString& format ) { QgsDebugMsg( "Info format is:" + format ); //read TYPENAME QMap<QString, QString>::const_iterator type_name_it = mParameterMap.find( "TYPENAME" ); if ( type_name_it != mParameterMap.end() ) { mTypeName = type_name_it.value(); } else { return 1; } QStringList wfsLayersId = mConfigParser->wfsLayers(); QMap< QString, QMap< int, QString > > aliasInfo = mConfigParser->layerAliasInfo(); QMap< QString, QSet<QString> > hiddenAttributes = mConfigParser->hiddenAttributes(); QList<QgsMapLayer*> layerList; QgsMapLayer* currentLayer = 0; layerList = mConfigParser->mapLayerFromStyle( mTypeName, "" ); currentLayer = layerList.at( 0 ); QgsVectorLayer* layer = dynamic_cast<QgsVectorLayer*>( currentLayer ); if ( layer && wfsLayersId.contains( layer->id() ) ) { //is there alias info for this vector layer? QMap< int, QString > layerAliasInfo; QMap< QString, QMap< int, QString > >::const_iterator aliasIt = aliasInfo.find( currentLayer->id() ); if ( aliasIt != aliasInfo.constEnd() ) { layerAliasInfo = aliasIt.value(); } //hidden attributes for this layer QSet<QString> layerHiddenAttributes; QMap< QString, QSet<QString> >::const_iterator hiddenIt = hiddenAttributes.find( currentLayer->id() ); if ( hiddenIt != hiddenAttributes.constEnd() ) { layerHiddenAttributes = hiddenIt.value(); } //do a select with searchRect and go through all the features QgsVectorDataProvider* provider = layer->dataProvider(); if ( !provider ) { return 2; } QgsFeature feature; QgsAttributeMap featureAttributes; const QgsFieldMap& fields = provider->fields(); //map extent QgsRectangle searchRect = layer->extent(); //read FEATUREDID bool fidOk = false; QString fid; QMap<QString, QString>::const_iterator fidIt = mParameterMap.find( "FEATUREID" ); if ( fidIt != mParameterMap.end() ) { fidOk = true; fid = fidIt.value(); } //read FILTER bool filterOk = false; QDomDocument filter; QMap<QString, QString>::const_iterator filterIt = mParameterMap.find( "FILTER" ); if ( filterIt != mParameterMap.end() ) { try { QString errorMsg; if ( !filter.setContent( filterIt.value(), true, &errorMsg ) ) { QgsDebugMsg( "soap request parse error" ); QgsDebugMsg( "error message: " + errorMsg ); QgsDebugMsg( "the xml string was:" ); QgsDebugMsg( filterIt.value() ); } else { filterOk = true; } } catch ( QgsMapServiceException& e ) { Q_UNUSED( e ); filterOk = false; } } bool conversionSuccess; double minx, miny, maxx, maxy; bool bboxOk = false; //read BBOX QMap<QString, QString>::const_iterator bbIt = mParameterMap.find( "BBOX" ); if ( bbIt == mParameterMap.end() ) { minx = 0; miny = 0; maxx = 0; maxy = 0; } else { bboxOk = true; QString bbString = bbIt.value(); minx = bbString.section( ",", 0, 0 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} miny = bbString.section( ",", 1, 1 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} maxx = bbString.section( ",", 2, 2 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} maxy = bbString.section( ",", 3, 3 ).toDouble( &conversionSuccess ); if ( !conversionSuccess ) {bboxOk = false;} } //read MAXFEATURES long maxFeat = layer->featureCount(); long featureCounter = 0; QMap<QString, QString>::const_iterator mfIt = mParameterMap.find( "MAXFEATURES" ); if ( mfIt != mParameterMap.end() ) { QString mfString = mfIt.value(); bool mfOk; maxFeat = mfString.toLong( &mfOk, 10 ); if ( !mfOk ) { maxFeat = layer->featureCount(); } } //read PROPERTYNAME mWithGeom = true; QgsAttributeList attrIndexes = provider->attributeIndexes(); QMap<QString, QString>::const_iterator pnIt = mParameterMap.find( "PROPERTYNAME" ); if ( pnIt != mParameterMap.end() ) { QStringList attrList = pnIt.value().split( "," ); if ( attrList.size() > 0 ) { mWithGeom = false; QStringList::const_iterator alstIt; QList<int> idxList; QMap<QString, int> fieldMap = provider->fieldNameMap(); QMap<QString, int>::const_iterator fieldIt; QString fieldName; for ( alstIt = attrList.begin(); alstIt != attrList.end(); ++alstIt ) { fieldName = *alstIt; fieldIt = fieldMap.find( fieldName ); if ( fieldIt != fieldMap.end() ) { idxList.append( fieldIt.value() ); } else if ( fieldName == "geometry" ) { mWithGeom = true; } } if ( idxList.size() > 0 || mWithGeom ) { attrIndexes = idxList; } else { mWithGeom = true; } } } QgsCoordinateReferenceSystem layerCrs = layer->crs(); startGetFeature( request, format ); if ( fidOk ) { provider->featureAtId( fid.toInt(), feature, mWithGeom, attrIndexes ); sendGetFeature( request, format, &feature, 0, layerCrs, fields, layerHiddenAttributes ); } else if ( filterOk ) { provider->select( attrIndexes, searchRect, mWithGeom, true ); try { QgsFilter* mFilter = QgsFilter::createFilterFromXml( filter.firstChild().toElement().firstChild().toElement(), layer ); while ( provider->nextFeature( feature ) && featureCounter < maxFeat ) { if ( mFilter ) { if ( mFilter->evaluate( feature ) ) { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } else { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } delete mFilter; } catch ( QgsMapServiceException& e ) { Q_UNUSED( e ); while ( provider->nextFeature( feature ) && featureCounter < maxFeat ) { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } } else { if ( bboxOk ) searchRect.set( minx, miny, maxx, maxy ); provider->select( attrIndexes, searchRect, mWithGeom, true ); while ( provider->nextFeature( feature ) && featureCounter < maxFeat ) { sendGetFeature( request, format, &feature, featureCounter, layerCrs, fields, layerHiddenAttributes ); ++featureCounter; } } endGetFeature( request, format ); } else { return 2; } return 0; }
bool QgsVectorLayerEditBuffer::commitChanges( QStringList& commitErrors ) { QgsVectorDataProvider* provider = L->dataProvider(); commitErrors.clear(); int cap = provider->capabilities(); bool success = true; // geometry updates attribute updates // yes no => changeGeometryValues // no yes => changeAttributeValues // yes yes => changeFeatures // // update geometries // if ( !mChangedGeometries.isEmpty() && (( cap & QgsVectorDataProvider::ChangeFeatures ) == 0 || mChangedAttributeValues.isEmpty() ) ) { if ( provider->changeGeometryValues( mChangedGeometries ) ) { commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() ); emit committedGeometriesChanges( L->id(), mChangedGeometries ); mChangedGeometries.clear(); } else { commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() ); success = false; } } QgsFields oldFields = L->fields(); // // delete attributes // bool attributesChanged = false; if ( !mDeletedAttributeIds.isEmpty() ) { if (( cap & QgsVectorDataProvider::DeleteAttributes ) && provider->deleteAttributes( mDeletedAttributeIds.toSet() ) ) { commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() ); emit committedAttributesDeleted( L->id(), mDeletedAttributeIds ); mDeletedAttributeIds.clear(); attributesChanged = true; } else { commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() ); #if 0 QString list = "ERROR: Pending attribute deletes:"; Q_FOREACH ( int idx, mDeletedAttributeIds ) { list.append( ' ' + L->pendingFields().at( idx ).name() ); } commitErrors << list; #endif success = false; } }
void QgsMapToolAddFeature::canvasMapReleaseEvent( QgsMapMouseEvent* e ) { QgsDebugMsg( "entered." ); QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ); if ( !vlayer ) { notifyNotVectorLayer(); return; } QGis::WkbType layerWKBType = vlayer->wkbType(); QgsVectorDataProvider* provider = vlayer->dataProvider(); if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) ) { emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), QgsMessageBar::WARNING ); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } // POINT CAPTURING if ( mode() == CapturePoint ) { if ( e->button() != Qt::LeftButton ) return; //check we only use this tool for point/multipoint layers if ( vlayer->geometryType() != QGis::Point ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } QgsPoint savePoint; //point in layer coordinates try { savePoint = toLayerCoordinates( vlayer, e->mapPoint() ); QgsDebugMsg( "savePoint = " + savePoint.toString() ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING ); return; } //only do the rest for provider with feature addition support //note that for the grass provider, this will return false since //grass provider has its own mechanism of feature addition if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) { QgsFeature f( vlayer->pendingFields(), 0 ); QgsGeometry *g = 0; if ( layerWKBType == QGis::WKBPoint || layerWKBType == QGis::WKBPoint25D ) { g = QgsGeometry::fromPoint( savePoint ); } else if ( layerWKBType == QGis::WKBMultiPoint || layerWKBType == QGis::WKBMultiPoint25D ) { g = QgsGeometry::fromMultiPoint( QgsMultiPoint() << savePoint ); } f.setGeometry( g ); addFeature( vlayer, &f, false ); mCanvas->refresh(); } } // LINE AND POLYGON CAPTURING else if ( mode() == CaptureLine || mode() == CapturePolygon ) { //check we only use the line tool for line/multiline layers if ( mode() == CaptureLine && vlayer->geometryType() != QGis::Line ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } //check we only use the polygon tool for polygon/multipolygon layers if ( mode() == CapturePolygon && vlayer->geometryType() != QGis::Polygon ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } //add point to list and to rubber band if ( e->button() == Qt::LeftButton ) { int error = addVertex( e->mapPoint() ); if ( error == 1 ) { //current layer is not a vector layer return; } else if ( error == 2 ) { //problem with coordinate transformation emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING ); return; } startCapturing(); } else if ( e->button() == Qt::RightButton ) { // End of string deleteTempRubberBand(); //lines: bail out if there are not at least two vertices if ( mode() == CaptureLine && size() < 2 ) { stopCapturing(); return; } //polygons: bail out if there are not at least two vertices if ( mode() == CapturePolygon && size() < 3 ) { stopCapturing(); return; } //create QgsFeature with wkb representation QgsFeature* f = new QgsFeature( vlayer->pendingFields(), 0 ); QgsGeometry *g; if ( mode() == CaptureLine ) { if ( layerWKBType == QGis::WKBLineString || layerWKBType == QGis::WKBLineString25D ) { g = QgsGeometry::fromPolyline( points().toVector() ); } else if ( layerWKBType == QGis::WKBMultiLineString || layerWKBType == QGis::WKBMultiLineString25D ) { g = QgsGeometry::fromMultiPolyline( QgsMultiPolyline() << points().toVector() ); } else { emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL ); stopCapturing(); return; //unknown wkbtype } f->setGeometry( g ); } else // polygon { if ( layerWKBType == QGis::WKBPolygon || layerWKBType == QGis::WKBPolygon25D ) { g = QgsGeometry::fromPolygon( QgsPolygon() << points().toVector() ); } else if ( layerWKBType == QGis::WKBMultiPolygon || layerWKBType == QGis::WKBMultiPolygon25D ) { g = QgsGeometry::fromMultiPolygon( QgsMultiPolygon() << ( QgsPolygon() << points().toVector() ) ); } else { emit messageEmitted( tr( "Cannot add feature. Unknown WKB type" ), QgsMessageBar::CRITICAL ); stopCapturing(); return; //unknown wkbtype } if ( !g ) { stopCapturing(); delete f; return; // invalid geometry; one possibility is from duplicate points } f->setGeometry( g ); int avoidIntersectionsReturn = f->geometry()->avoidIntersections(); if ( avoidIntersectionsReturn == 1 ) { //not a polygon type. Impossible to get there } #if 0 else if ( avoidIntersectionsReturn == 2 ) //MH120131: disable this error message until there is a better way to cope with the single type / multi type problem { //bail out... emit messageEmitted( tr( "The feature could not be added because removing the polygon intersections would change the geometry type" ), QgsMessageBar::CRITICAL ); delete f; stopCapturing(); return; } #endif else if ( avoidIntersectionsReturn == 3 ) { emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL ); } if ( !f->geometry()->asWkb() ) //avoid intersection might have removed the whole geometry { QString reason; if ( avoidIntersectionsReturn != 2 ) { reason = tr( "The feature cannot be added because it's geometry is empty" ); } else { reason = tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ); } emit messageEmitted( reason, QgsMessageBar::CRITICAL ); delete f; stopCapturing(); return; } } if ( addFeature( vlayer, f, false ) ) { //add points to other features to keep topology up-to-date int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ); //use always topological editing for avoidIntersection. //Otherwise, no way to guarantee the geometries don't have a small gap in between. QStringList intersectionLayers = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList" ); bool avoidIntersection = !intersectionLayers.isEmpty(); if ( avoidIntersection ) //try to add topological points also to background layers { QStringList::const_iterator lIt = intersectionLayers.constBegin(); for ( ; lIt != intersectionLayers.constEnd(); ++lIt ) { QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( *lIt ); QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( ml ); //can only add topological points if background layer is editable... if ( vl && vl->geometryType() == QGis::Polygon && vl->isEditable() ) { vl->addTopologicalPoints( f->geometry() ); } } } else if ( topologicalEditing ) { vlayer->addTopologicalPoints( f->geometry() ); } } stopCapturing(); } } }
void QgsInterpolationDialog::on_buttonBox_accepted() { if ( !mInterpolatorDialog ) { return; } QgsRectangle outputBBox = currentBoundingBox(); if ( outputBBox.isEmpty() ) { return; } //warn the user if there isn't any input layer if ( mLayersTreeWidget->topLevelItemCount() < 1 ) { QMessageBox::information( nullptr, tr( "No input data for interpolation" ), tr( "Please add one or more input layers" ) ); return; } //read file name QString fileName = mOutputFileLineEdit->text(); QFileInfo theFileInfo( fileName ); if ( fileName.isEmpty() || !theFileInfo.dir().exists() ) { QMessageBox::information( nullptr, tr( "Output file name invalid" ), tr( "Please enter a valid output file name" ) ); return; } //add .asc suffix if the user did not provider it already QString suffix = theFileInfo.suffix(); if ( suffix.isEmpty() ) { fileName.append( ".asc" ); } int nLayers = mLayersTreeWidget->topLevelItemCount(); QList< QgsInterpolator::LayerData > inputLayerList; for ( int i = 0; i < nLayers; ++i ) { QString layerName = mLayersTreeWidget->topLevelItem( i )->text( 0 ); QgsVectorLayer* theVectorLayer = vectorLayerFromName( layerName ); if ( !theVectorLayer ) { continue; } QgsVectorDataProvider* theProvider = theVectorLayer->dataProvider(); if ( !theProvider ) { continue; } QgsInterpolator::LayerData currentLayerData; currentLayerData.vectorLayer = theVectorLayer; QString interpolationAttString = mLayersTreeWidget->topLevelItem( i )->text( 1 ); if ( interpolationAttString == "Z_COORD" ) { currentLayerData.zCoordInterpolation = true; currentLayerData.interpolationAttribute = -1; } else { currentLayerData.zCoordInterpolation = false; int attributeIndex = theProvider->fieldNameIndex( interpolationAttString ); currentLayerData.interpolationAttribute = attributeIndex; } //type (point/structure line/ breakline) QComboBox* itemCombo = qobject_cast<QComboBox *>( mLayersTreeWidget->itemWidget( mLayersTreeWidget->topLevelItem( i ), 2 ) ); if ( itemCombo ) { QString typeString = itemCombo->currentText(); if ( typeString == tr( "Break lines" ) ) { currentLayerData.mInputType = QgsInterpolator::BREAK_LINES; } else if ( typeString == tr( "Structure lines" ) ) { currentLayerData.mInputType = QgsInterpolator::STRUCTURE_LINES; } else //Points { currentLayerData.mInputType = QgsInterpolator::POINTS; } } else { currentLayerData.mInputType = QgsInterpolator::POINTS; } inputLayerList.push_back( currentLayerData ); } mInterpolatorDialog->setInputData( inputLayerList ); QgsInterpolator* theInterpolator = mInterpolatorDialog->createInterpolator(); if ( !theInterpolator ) { return; } //create grid file writer QgsGridFileWriter theWriter( theInterpolator, fileName, outputBBox, mNumberOfColumnsSpinBox->value(), mNumberOfRowsSpinBox->value(), mCellsizeXSpinBox->value(), mCellSizeYSpinBox->value() ); if ( theWriter.writeFile( true ) == 0 ) { if ( mAddResultToProjectCheckBox->isChecked() ) { mIface->addRasterLayer( fileName, QFileInfo( fileName ).baseName() ); } accept(); } delete theInterpolator; }
QgsVectorLayerImport::QgsVectorLayerImport( const QString &uri, const QString &providerKey, const QgsFields& fields, QGis::WkbType geometryType, const QgsCoordinateReferenceSystem* crs, bool overwrite, const QMap<QString, QVariant> *options, QProgressDialog *progress ) : mErrorCount( 0 ) , mAttributeCount( -1 ) , mProgress( progress ) { mProvider = NULL; QgsProviderRegistry * pReg = QgsProviderRegistry::instance(); QLibrary *myLib = pReg->providerLibrary( providerKey ); if ( !myLib ) { mError = ErrInvalidProvider; mErrorMessage = QObject::tr( "Unable to load %1 provider" ).arg( providerKey ); return; } createEmptyLayer_t * pCreateEmpty = ( createEmptyLayer_t * ) cast_to_fptr( myLib->resolve( "createEmptyLayer" ) ); if ( !pCreateEmpty ) { delete myLib; mError = ErrProviderUnsupportedFeature; mErrorMessage = QObject::tr( "Provider %1 has no %2 method" ).arg( providerKey ).arg( "createEmptyLayer" ); return; } delete myLib; // create an empty layer QString errMsg; mError = pCreateEmpty( uri, fields, geometryType, crs, overwrite, &mOldToNewAttrIdx, &errMsg, options ); if ( hasError() ) { mErrorMessage = errMsg; return; } foreach ( int idx, mOldToNewAttrIdx.values() ) { if ( idx > mAttributeCount ) mAttributeCount = idx; } mAttributeCount++; QgsDebugMsg( "Created empty layer" ); QgsVectorDataProvider *vectorProvider = ( QgsVectorDataProvider* ) pReg->provider( providerKey, uri ); if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & QgsVectorDataProvider::AddFeatures ) == 0 ) { mError = ErrInvalidLayer; mErrorMessage = QObject::tr( "Loading of layer failed" ); if ( vectorProvider ) delete vectorProvider; return; } mProvider = vectorProvider; mError = NoError; }
bool QgsGeometryAnalyzer::buffer( QgsVectorLayer* layer, const QString& shapefileName, double bufferDistance, bool onlySelectedFeatures, bool dissolve, int bufferDistanceField, QProgressDialog* p ) { if ( !layer ) { return false; } QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } QGis::WkbType outputType = QGis::WKBPolygon; if ( dissolve ) { outputType = QGis::WKBMultiPolygon; } QgsCoordinateReferenceSystem crs = layer->crs(); QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), layer->fields(), outputType, &crs ); QgsFeature currentFeature; QgsGeometry *dissolveGeometry = nullptr; //dissolve geometry (if dissolve enabled) //take only selection if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId const QgsFeatureIds selection = layer->selectedFeaturesIds(); if ( p ) { p->setMaximum( selection.size() ); } int processedFeatures = 0; QgsFeatureIds::const_iterator it = selection.constBegin(); for ( ; it != selection.constEnd(); ++it ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( *it ) ).nextFeature( currentFeature ) ) { continue; } bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField ); ++processedFeatures; } if ( p ) { p->setValue( selection.size() ); } } //take all features else { QgsFeatureIterator fit = layer->getFeatures(); int featureCount = layer->featureCount(); if ( p ) { p->setMaximum( featureCount ); } int processedFeatures = 0; while ( fit.nextFeature( currentFeature ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField ); ++processedFeatures; } if ( p ) { p->setValue( featureCount ); } } if ( dissolve ) { QgsFeature dissolveFeature; if ( !dissolveGeometry ) { QgsDebugMsg( "no dissolved geometry - should not happen" ); return false; } dissolveFeature.setGeometry( dissolveGeometry ); vWriter.addFeature( dissolveFeature ); } return true; }
bool QgsGeometryAnalyzer::dissolve( QgsVectorLayer* layer, const QString& shapefileName, bool onlySelectedFeatures, int uniqueIdField, QProgressDialog* p ) { if ( !layer ) { return false; } QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } bool useField = false; if ( uniqueIdField == -1 ) { uniqueIdField = 0; } else { useField = true; } QGis::WkbType outputType = dp->geometryType(); QgsCoordinateReferenceSystem crs = layer->crs(); QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), layer->fields(), outputType, &crs ); QgsFeature currentFeature; QMultiMap<QString, QgsFeatureId> map; if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId const QgsFeatureIds selection = layer->selectedFeaturesIds(); QgsFeatureIds::const_iterator it = selection.constBegin(); for ( ; it != selection.constEnd(); ++it ) { if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( *it ) ).nextFeature( currentFeature ) ) { continue; } map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() ); } } else { QgsFeatureIterator fit = layer->getFeatures(); while ( fit.nextFeature( currentFeature ) ) { map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() ); } } QgsGeometry *dissolveGeometry = nullptr; //dissolve geometry QMultiMap<QString, QgsFeatureId>::const_iterator jt = map.constBegin(); QgsFeature outputFeature; while ( jt != map.constEnd() ) { QString currentKey = jt.key(); int processedFeatures = 0; bool first = true; //take only selection if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId const QgsFeatureIds selection = layer->selectedFeaturesIds(); if ( p ) { p->setMaximum( selection.size() ); } while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p && p->wasCanceled() ) { break; } if ( selection.contains( jt.value() ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( jt.value() ) ).nextFeature( currentFeature ) ) { continue; } if ( first ) { outputFeature.setAttributes( currentFeature.attributes() ); first = false; } dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry ); ++processedFeatures; } ++jt; } } //take all features else { int featureCount = layer->featureCount(); if ( p ) { p->setMaximum( featureCount ); } while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( jt.value() ) ).nextFeature( currentFeature ) ) { continue; } { outputFeature.setAttributes( currentFeature.attributes() ); first = false; } dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry ); ++processedFeatures; ++jt; } } outputFeature.setGeometry( dissolveGeometry ); vWriter.addFeature( outputFeature ); } return true; }
bool QgsGeometryAnalyzer::convexHull( QgsVectorLayer* layer, const QString& shapefileName, bool onlySelectedFeatures, int uniqueIdField, QProgressDialog* p ) { if ( !layer ) { return false; } QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } bool useField = false; if ( uniqueIdField == -1 ) { uniqueIdField = 0; } else { useField = true; } QgsFields fields; fields.append( QgsField( QString( "UID" ), QVariant::String ) ); fields.append( QgsField( QString( "AREA" ), QVariant::Double ) ); fields.append( QgsField( QString( "PERIM" ), QVariant::Double ) ); QGis::WkbType outputType = QGis::WKBPolygon; QgsCoordinateReferenceSystem crs = layer->crs(); QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), fields, outputType, &crs ); QgsFeature currentFeature; QgsGeometry* dissolveGeometry = nullptr; //dissolve geometry QMultiMap<QString, QgsFeatureId> map; if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId const QgsFeatureIds selection = layer->selectedFeaturesIds(); QgsFeatureIds::const_iterator it = selection.constBegin(); for ( ; it != selection.constEnd(); ++it ) { #if 0 if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { // break; // it may be better to do something else here? return false; } #endif if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( *it ) ).nextFeature( currentFeature ) ) { continue; } map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() ); } } else { QgsFeatureIterator fit = layer->getFeatures(); while ( fit.nextFeature( currentFeature ) ) { #if 0 if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { // break; // it may be better to do something else here? return false; } #endif map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() ); } } QMultiMap<QString, QgsFeatureId>::const_iterator jt = map.constBegin(); while ( jt != map.constEnd() ) { QString currentKey = jt.key(); int processedFeatures = 0; //take only selection if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId const QgsFeatureIds selection = layer->selectedFeaturesIds(); if ( p ) { p->setMaximum( selection.size() ); } processedFeatures = 0; while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p && p->wasCanceled() ) { break; } if ( selection.contains( jt.value() ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( jt.value() ) ).nextFeature( currentFeature ) ) { continue; } convexFeature( currentFeature, processedFeatures, &dissolveGeometry ); ++processedFeatures; } ++jt; } QList<double> values; if ( !dissolveGeometry ) { QgsDebugMsg( "no dissolved geometry - should not happen" ); return false; } dissolveGeometry = dissolveGeometry->convexHull(); values = simpleMeasure( dissolveGeometry ); QgsAttributes attributes( 3 ); attributes[0] = QVariant( currentKey ); attributes[1] = values.at( 0 ); attributes[2] = values.at( 1 ); QgsFeature dissolveFeature; dissolveFeature.setAttributes( attributes ); dissolveFeature.setGeometry( dissolveGeometry ); vWriter.addFeature( dissolveFeature ); } //take all features else { int featureCount = layer->featureCount(); if ( p ) { p->setMaximum( featureCount ); } processedFeatures = 0; while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( jt.value() ) ).nextFeature( currentFeature ) ) { continue; } convexFeature( currentFeature, processedFeatures, &dissolveGeometry ); ++processedFeatures; ++jt; } QList<double> values; // QgsGeometry* tmpGeometry = 0; if ( !dissolveGeometry ) { QgsDebugMsg( "no dissolved geometry - should not happen" ); return false; } dissolveGeometry = dissolveGeometry->convexHull(); // values = simpleMeasure( tmpGeometry ); values = simpleMeasure( dissolveGeometry ); QgsAttributes attributes; attributes[0] = QVariant( currentKey ); attributes[1] = QVariant( values[ 0 ] ); attributes[2] = QVariant( values[ 1 ] ); QgsFeature dissolveFeature; dissolveFeature.setAttributes( attributes ); dissolveFeature.setGeometry( dissolveGeometry ); vWriter.addFeature( dissolveFeature ); } } return true; }
bool QgsGeometryAnalyzer::simplify( QgsVectorLayer* layer, const QString& shapefileName, double tolerance, bool onlySelectedFeatures, QProgressDialog *p ) { if ( !layer ) { return false; } QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } QGis::WkbType outputType = dp->geometryType(); QgsCoordinateReferenceSystem crs = layer->crs(); QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), layer->fields(), outputType, &crs ); QgsFeature currentFeature; //take only selection if ( onlySelectedFeatures ) { //use QgsVectorLayer::featureAtId const QgsFeatureIds selection = layer->selectedFeaturesIds(); if ( p ) { p->setMaximum( selection.size() ); } int processedFeatures = 0; QgsFeatureIds::const_iterator it = selection.constBegin(); for ( ; it != selection.constEnd(); ++it ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } if ( !layer->getFeatures( QgsFeatureRequest().setFilterFid( *it ) ).nextFeature( currentFeature ) ) { continue; } simplifyFeature( currentFeature, &vWriter, tolerance ); ++processedFeatures; } if ( p ) { p->setValue( selection.size() ); } } //take all features else { QgsFeatureIterator fit = layer->getFeatures(); int featureCount = layer->featureCount(); if ( p ) { p->setMaximum( featureCount ); } int processedFeatures = 0; while ( fit.nextFeature( currentFeature ) ) { if ( p ) { p->setValue( processedFeatures ); } if ( p && p->wasCanceled() ) { break; } simplifyFeature( currentFeature, &vWriter, tolerance ); ++processedFeatures; } if ( p ) { p->setValue( featureCount ); } } return true; }
bool QgsGeometryAnalyzer::extent( QgsVectorLayer* layer, const QString& shapefileName, bool onlySelectedFeatures, QProgressDialog * ) { if ( !layer ) { return false; } QgsVectorDataProvider* dp = layer->dataProvider(); if ( !dp ) { return false; } QGis::WkbType outputType = QGis::WKBPolygon; QgsCoordinateReferenceSystem crs = layer->crs(); QgsFields fields; fields.append( QgsField( QString( "MINX" ), QVariant::Double ) ); fields.append( QgsField( QString( "MINY" ), QVariant::Double ) ); fields.append( QgsField( QString( "MAXX" ), QVariant::Double ) ); fields.append( QgsField( QString( "MAXY" ), QVariant::Double ) ); fields.append( QgsField( QString( "CNTX" ), QVariant::Double ) ); fields.append( QgsField( QString( "CNTY" ), QVariant::Double ) ); fields.append( QgsField( QString( "AREA" ), QVariant::Double ) ); fields.append( QgsField( QString( "PERIM" ), QVariant::Double ) ); fields.append( QgsField( QString( "HEIGHT" ), QVariant::Double ) ); fields.append( QgsField( QString( "WIDTH" ), QVariant::Double ) ); QgsVectorFileWriter vWriter( shapefileName, dp->encoding(), fields, outputType, &crs ); QgsRectangle rect; if ( onlySelectedFeatures ) // take only selection { rect = layer->boundingBoxOfSelected(); } else { rect = layer->extent(); } double minx = rect.xMinimum(); double miny = rect.yMinimum(); double maxx = rect.xMaximum(); double maxy = rect.yMaximum(); double height = rect.height(); double width = rect.width(); double cntx = minx + ( width / 2.0 ); double cnty = miny + ( height / 2.0 ); double area = width * height; double perim = ( 2 * width ) + ( 2 * height ); QgsFeature feat; QgsAttributes attrs( 10 ); attrs[0] = QVariant( minx ); attrs[1] = QVariant( miny ); attrs[2] = QVariant( maxx ); attrs[3] = QVariant( maxy ); attrs[4] = QVariant( cntx ); attrs[5] = QVariant( cnty ); attrs[6] = QVariant( area ); attrs[7] = QVariant( perim ); attrs[8] = QVariant( height ); attrs[9] = QVariant( width ); feat.setAttributes( attrs ); feat.setGeometry( QgsGeometry::fromRect( rect ) ); vWriter.addFeature( feat ); return true; }