diff --git a/python/core/core.sip b/python/core/core.sip index 39f4bb62603..ce478f7c4a4 100644 --- a/python/core/core.sip +++ b/python/core/core.sip @@ -16,7 +16,6 @@ %Include qgsdatasourceuri.sip %Include qgsdistancearea.sip %Include qgsfeature.sip -%Include qgsfeatureattribute.sip %Include qgsfield.sip %Include qgsgeometry.sip %Include qgsgeometryvertexindex.sip diff --git a/python/core/qgsfeature.sip b/python/core/qgsfeature.sip index 1bedd393ad0..0804ab93b98 100644 --- a/python/core/qgsfeature.sip +++ b/python/core/qgsfeature.sip @@ -22,7 +22,7 @@ class QgsFeature want a copy of the "current" feature, not the on-disk feature. */ QgsFeature( const QgsFeature & rhs, - const QMap >& changedAttributes, + const QMap >& changedAttributes, const QMap & changedGeometries ); /** copy ctor needed due to internal pointer */ @@ -58,12 +58,12 @@ class QgsFeature * Get the attributes for this feature. * @return A std::map containing the field name/value mapping */ - const QMap & attributeMap() const; + const QMap & attributeMap() const; /** * Add an attribute to the map */ - void addAttribute(int field, QgsFeatureAttribute attr); + void addAttribute(int field, QVariant attr); /**Deletes an attribute and its value*/ void deleteAttribute(int field); @@ -71,13 +71,7 @@ class QgsFeature /**Changes an existing attribute value @param field index of the field @param attr attribute name and value to be set */ - void changeAttribute(int field, QgsFeatureAttribute attr); - - /** - * Get the fields for this feature - * @return A std::map containing field position (index) and field name - */ - QMap fields() const; + void changeAttribute(int field, QVariant attr); /** * Return the validity of this feature. This is normally set by @@ -125,9 +119,6 @@ class QgsFeature */ void setGeometryAndOwnership(unsigned char * geom, size_t length); - /**Returns the bounding box of this feature*/ - QgsRect boundingBox() const; - }; // class QgsFeature diff --git a/python/core/qgsfeatureattribute.sip b/python/core/qgsfeatureattribute.sip deleted file mode 100644 index 55aefd3c86b..00000000000 --- a/python/core/qgsfeatureattribute.sip +++ /dev/null @@ -1,53 +0,0 @@ - -/** \class QgsFeatureAttribute - Feature attribute class. - * \brief Encapsulates a single feature attribute. - *@author Gary E.Sherman - */ - -class QgsFeatureAttribute -{ -%TypeHeaderCode -#include -%End - -public: - - //! Constructor - QgsFeatureAttribute(const QString & field = 0, const QString & value = 0, bool num = false); - - //! Destructor - ~QgsFeatureAttribute(); - - /** - * Get the field name for this feature attribute - * @return Field name - */ - const QString & fieldName() const; - - - /** - * Get the field value for this feature attribute - * @return Field value - */ - const QString & fieldValue() const; - - /** - * Returns whether value is numeric or not - * @return Numeric flag - */ - bool isNumeric() const; - - void setFieldName(QString name); - - void setFieldValue(QString thevalue); - - void setNumeric(bool num = true); - - SIP_PYOBJECT __repr__(); -%MethodCode - QString str = sipCpp->fieldName() + " = " + sipCpp->fieldValue(); - sipRes = PyString_FromString(str.toLocal8Bit().data()); -%End - -}; // class QgsFeatureAttribute - diff --git a/python/core/qgsfield.sip b/python/core/qgsfield.sip index 3f5f77811a9..afce2ed646b 100644 --- a/python/core/qgsfield.sip +++ b/python/core/qgsfield.sip @@ -17,25 +17,33 @@ class QgsField public: /** Constructor. Constructs a new QgsField object. * @param nam Field name - * @param typ Field type (eg. char, varchar, text, int, serial, double). + * @param type Field variant type, currently supported: String / Int / Double + * @param typeName Field type (eg. char, varchar, text, int, serial, double). Field types are usually unique to the source and are stored exactly as returned from the data store. * @param len Field length * @param prec Field precision. Usually decimal places but may also be * used in conjunction with other fields types (eg. variable character fields) - * @param num Has to be true if field contains numeric values. + * @param comment Comment for the field */ - QgsField(QString nam = "", QString typ = "", int len = 0, int prec = 0, bool num = false); + + QgsField(QString name = QString(), + QVariant::Type type = QVariant::Invalid, + QString typeName = QString(), + int len = 0, + int prec = 0, + QString comment = QString()); //! Destructor ~QgsField(); - bool operator==(const QgsField other) const; - bool operator!=(const QgsField other) const; + bool operator==(const QgsField& other) const; //! Gets the name of the field const QString & name() const; + //! Gets variant type of the field as it will be retreived from data source + QVariant::Type type() const; /** Gets the field type. Field types vary depending on the data source. Examples @@ -43,7 +51,7 @@ public: the data store reports it, with no attenpt to standardize the value. @return QString containing the field type */ - const QString & type() const; + const QString & typeName() const; /** @@ -59,23 +67,27 @@ public: */ int precision() const; - /** - Returns true if field contains numeric values. This information is set by provider. - */ - bool isNumeric() const; - + /** + Returns the field comment + */ + const QString & comment() const; /** Set the field name. @param nam Name of the field */ void setName(const QString & nam); + + /** + Set variant type. + */ + void setType(QVariant::Type type); /** Set the field type. @param typ Field type */ - void setType(const QString & typ); + void setTypeName(const QString & typ); /** Set the field length. @@ -89,10 +101,11 @@ public: */ void setPrecision(int prec); + /** - Set whether field is numeric + Set the field comment */ - void setNumeric(bool num); + void setComment(const QString & comment); }; // class QgsField diff --git a/python/core/qgslabel.sip b/python/core/qgslabel.sip index 0cf77959c82..9cc76df8aa3 100644 --- a/python/core/qgslabel.sip +++ b/python/core/qgslabel.sip @@ -69,7 +69,7 @@ public: QgsLabelAttributes *layerAttributes ( ); //! Set label field - void setLabelField ( int attr, const QString str ); + void setLabelField ( int attr, int fieldId ); //! label field QString labelField ( int attr ); diff --git a/python/core/qgsvectordataprovider.sip b/python/core/qgsvectordataprovider.sip index 07e2f886225..2f56de40916 100644 --- a/python/core/qgsvectordataprovider.sip +++ b/python/core/qgsvectordataprovider.sip @@ -343,12 +343,12 @@ class QgsVectorDataProvider : QgsDataProvider * @param attr_map a map containing changed attributes * @return true in case of success and false in case of failure */ - virtual bool changeAttributeValues(const QMap > & attr_map); + virtual bool changeAttributeValues(const QMap > & attr_map); /** - * Returns the default value for attribute @c attr for feature @c f. + * Returns the default value for field specified by @c fieldId */ - virtual QString getDefaultValue(const QString & attr, QgsFeature* f); + virtual QVariant getDefaultValue(int fieldId); /** * Changes geometries of existing features diff --git a/python/core/qgsvectorlayer.sip b/python/core/qgsvectorlayer.sip index b694e8414f7..ec0564e5e90 100644 --- a/python/core/qgsvectorlayer.sip +++ b/python/core/qgsvectorlayer.sip @@ -151,17 +151,6 @@ public: */ virtual QString subsetString(); - /** - * Number of attribute fields for a feature in the layer - */ - virtual int fieldCount() const; - - /** - Return a list of field names for this layer - @return vector of field names - */ - virtual const QMap & fields() const; - /** Adds a feature @param lastFeatureInBatch If True, will also go to the effort of e.g. updating the extents. @return Irue in case of success and False in case of error @@ -194,9 +183,6 @@ public: */ bool deleteSelectedFeatures(); - /** Returns the default value for the attribute @c attr for the feature @c f. */ - QString getDefaultValue(const QString& attr, QgsFeature* f); - /** Set labels on */ void setLabelOn( bool on ); @@ -270,7 +256,7 @@ public: */ bool commitAttributeChanges(const QSet& deleted, const QMap& added, - const QMap >& changed); + const QMap >& changed); /** Draws the layer using coordinate transformation * @return FALSE if an error occurred during drawing @@ -308,7 +294,7 @@ public: QSet& deletedFeatureIds(); /** returns array of features with changed attributes */ - QMap >& changedAttributes(); + QMap >& changedAttributes(); /** Sets whether some features are modified or not */ void setModified(bool modified = TRUE, bool onlyGeometryWasModified = FALSE); diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 1cee9bff521..c19aea2c496 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -3437,7 +3437,7 @@ void QgisApp::editCut(QgsMapLayer * layerContainingSelection) if (selectionVectorLayer != 0) { QgsFeatureList features = selectionVectorLayer->selectedFeatures(); - clipboard()->replaceWithCopyOf( features ); + clipboard()->replaceWithCopyOf( selectionVectorLayer->getDataProvider()->fields(), features ); selectionVectorLayer->deleteSelectedFeatures(); } } @@ -3458,7 +3458,7 @@ void QgisApp::editCopy(QgsMapLayer * layerContainingSelection) if (selectionVectorLayer != 0) { QgsFeatureList features = selectionVectorLayer->selectedFeatures(); - clipboard()->replaceWithCopyOf( features ); + clipboard()->replaceWithCopyOf( selectionVectorLayer->getDataProvider()->fields(), features ); } } } diff --git a/src/app/qgsattributedialog.cpp b/src/app/qgsattributedialog.cpp index 235402e0ab3..c6112a74798 100644 --- a/src/app/qgsattributedialog.cpp +++ b/src/app/qgsattributedialog.cpp @@ -16,12 +16,13 @@ ***************************************************************************/ /* $Id$ */ #include "qgsattributedialog.h" -#include "qgsfeatureattribute.h" +#include "qgsfield.h" #include "qgslogger.h" + #include #include -QgsAttributeDialog::QgsAttributeDialog(const QgsAttributeMap& attributes) +QgsAttributeDialog::QgsAttributeDialog(const QgsFieldMap& fields, const QgsAttributeMap& attributes) : QDialog(), _settingsPath("/Windows/AttributeDialog/"), mRowIsDirty(attributes.size(), FALSE) @@ -35,14 +36,16 @@ QgsAttributeDialog::QgsAttributeDialog(const QgsAttributeMap& attributes) for (QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it) { // set attribute name + + QString fieldName = fields[it.key()].name(); - QTableWidgetItem * myFieldItem = new QTableWidgetItem((*it).fieldName()); + QTableWidgetItem * myFieldItem = new QTableWidgetItem(fieldName); myFieldItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); mTable->setItem(index, 0, myFieldItem); // set attribute value - QTableWidgetItem * myValueItem = new QTableWidgetItem((*it).fieldValue()); + QTableWidgetItem * myValueItem = new QTableWidgetItem((*it).toString()); mTable->setItem(index, 1, myValueItem); ++index; @@ -72,16 +75,16 @@ bool QgsAttributeDialog::isDirty(int row) return mRowIsDirty.at(row); } -bool QgsAttributeDialog::queryAttributes(QgsFeature& f) +bool QgsAttributeDialog::queryAttributes(const QgsFieldMap& fields, QgsFeature& f) { QgsAttributeMap featureAttributes = f.attributeMap(); - QgsAttributeDialog attdialog(featureAttributes); + QgsAttributeDialog attdialog(fields, featureAttributes); if (attdialog.exec() == QDialog::Accepted) { for (int i = 0; i < featureAttributes.size(); ++i) { - f.changeAttribute(i, QgsFeatureAttribute(featureAttributes[i].fieldName(), attdialog.value(i))); + f.changeAttribute(i, QVariant(attdialog.value(i)) ); } return true; } diff --git a/src/app/qgsattributedialog.h b/src/app/qgsattributedialog.h index 057a7c60c7b..1992fae55fb 100644 --- a/src/app/qgsattributedialog.h +++ b/src/app/qgsattributedialog.h @@ -26,12 +26,15 @@ class QDialog; class QgsFeature; +class QgsField; +typedef QMap QgsFieldMap; + class QgsAttributeDialog: public QDialog, private Ui::QgsAttributeDialogBase { Q_OBJECT public: - QgsAttributeDialog(const QgsAttributeMap& attributes); + QgsAttributeDialog(const QgsFieldMap& fields, const QgsAttributeMap& attributes); ~QgsAttributeDialog(); @@ -45,7 +48,7 @@ class QgsAttributeDialog: public QDialog, private Ui::QgsAttributeDialogBase attribute values are set to the feature if the dialog is accepted. \retval true if accepted \retval false if canceled */ - static bool queryAttributes(QgsFeature& f); + static bool queryAttributes(const QgsFieldMap& fields, QgsFeature& f); // Saves and restores the size and position from the last time // this dialog box was used. diff --git a/src/app/qgsattributetable.cpp b/src/app/qgsattributetable.cpp index 4bdce56b98f..d94dc922237 100644 --- a/src/app/qgsattributetable.cpp +++ b/src/app/qgsattributetable.cpp @@ -27,7 +27,6 @@ #include "qgsattributetable.h" #include "qgsfeature.h" -#include "qgsfeatureattribute.h" #include "qgsfield.h" #include "qgslogger.h" #include "qgsvectordataprovider.h" @@ -512,7 +511,7 @@ void QgsAttributeTable::putFeatureInTable(int row, QgsFeature& fet) for (int i = 0; i < attr.size(); i++) { // get the field values - setText(row, i + 1, attr[i].fieldValue()); + setText(row, i + 1, attr[i].toString()); } } @@ -535,7 +534,7 @@ void QgsAttributeTable::storeChangedValue(int row, int column) } uint index = mFields.key(attribute); - mChangedValues[id].insert(index, QgsFeatureAttribute(attribute, text(row,column)) ); + mChangedValues[id].insert(index, QVariant(text(row,column)) ); QgsDebugMsg("value: " + text(row,column)); mEdited=true; diff --git a/src/app/qgsattributetabledisplay.cpp b/src/app/qgsattributetabledisplay.cpp index 72196e899d3..48cdb837095 100644 --- a/src/app/qgsattributetabledisplay.cpp +++ b/src/app/qgsattributetabledisplay.cpp @@ -250,7 +250,8 @@ void QgsAttributeTableDisplay::search() QgsVectorDataProvider* provider = mLayer->getDataProvider(); int item = mSearchColumns->currentItem(); - bool numeric = provider->fields()[item].isNumeric(); + QVariant::Type type = provider->fields()[item].type(); + bool numeric = (type == QVariant::Int || type == QVariant::Double); QString str; str = mSearchColumns->currentText(); @@ -328,10 +329,11 @@ void QgsAttributeTableDisplay::doSearch(const QString& searchString) QgsVectorDataProvider* provider = mLayer->getDataProvider(); provider->reset(); mSearchIds.clear(); + const QgsFieldMap& fields = provider->fields(); QgsAttributeList all = provider->allAttributesList(); while (provider->getNextFeature(fet, false, all)) { - if (searchTree->checkAgainst(fet.attributeMap())) + if (searchTree->checkAgainst(fields, fet.attributeMap())) { mSearchIds.insert(fet.featureId()); } diff --git a/src/app/qgsclipboard.cpp b/src/app/qgsclipboard.cpp index aa203e6be57..3eee47563e7 100644 --- a/src/app/qgsclipboard.cpp +++ b/src/app/qgsclipboard.cpp @@ -27,10 +27,11 @@ #include "qgsclipboard.h" #include "qgsfeature.h" -#include "qgsfeatureattribute.h" +#include "qgsfield.h" #include "qgsgeometry.h" #include "qgslogger.h" + QgsClipboard::QgsClipboard() : mFeatureClipboard() { @@ -40,7 +41,7 @@ QgsClipboard::~QgsClipboard() { } -void QgsClipboard::replaceWithCopyOf( QgsFeatureList& features ) +void QgsClipboard::replaceWithCopyOf( const QgsFieldMap& fields, QgsFeatureList& features ) { // Replace the QGis clipboard. @@ -54,27 +55,22 @@ void QgsClipboard::replaceWithCopyOf( QgsFeatureList& features ) QStringList textLines; QStringList textFields; - bool firstFeature = TRUE; + // first do the field names + textFields += "wkt_geom"; + for (QgsFieldMap::const_iterator fit = fields.begin(); fit != fields.end(); ++fit) + { + textFields += fit->name(); + } + textLines += textFields.join(","); + textFields.clear(); + + // then the field contents for (QgsFeatureList::iterator it = features.begin(); it != features.end(); ++it) { QgsAttributeMap attributes = it->attributeMap(); - // first do the field names - if (firstFeature) - { - textFields += "wkt_geom"; - - for (QgsAttributeMap::iterator it2 = attributes.begin(); it2 != attributes.end(); ++it2) - { - textFields += it2->fieldName(); - } - - textLines += textFields.join(","); - textFields.clear(); - } - // TODO: Set up Paste Transformations to specify the order in which fields are added. @@ -93,13 +89,11 @@ void QgsClipboard::replaceWithCopyOf( QgsFeatureList& features ) // << (it2->fieldName()).toLocal8Bit().data() // << "'." << std::endl; #endif - textFields += it2->fieldValue(); + textFields += it2->toString(); } textLines += textFields.join(","); textFields.clear(); - - firstFeature = FALSE; } QString textCopy = textLines.join("\n"); diff --git a/src/app/qgsclipboard.h b/src/app/qgsclipboard.h index f0605dcc93a..cf49507e9a4 100644 --- a/src/app/qgsclipboard.h +++ b/src/app/qgsclipboard.h @@ -21,11 +21,13 @@ #define QGSCLIPBOARD_H #include +#include class QgsFeature; +class QgsField; typedef QList QgsFeatureList; - +typedef QMap QgsFieldMap; /** @@ -64,7 +66,7 @@ public: * Place a copy of features on the internal clipboard, * destroying the previous contents. */ - void replaceWithCopyOf( QgsFeatureList& features ); + void replaceWithCopyOf( const QgsFieldMap& fields, QgsFeatureList& features ); /* * Returns a copy of features on the internal clipboard, diff --git a/src/app/qgscontinuouscolordialog.cpp b/src/app/qgscontinuouscolordialog.cpp index fb932c388e7..5c1fdbe5bb5 100644 --- a/src/app/qgscontinuouscolordialog.cpp +++ b/src/app/qgscontinuouscolordialog.cpp @@ -48,8 +48,8 @@ QgsContinuousColorDialog::QgsContinuousColorDialog(QgsVectorLayer * layer) for (QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it) { - QString type = (*it).type(); - if (type != "String" && type != "varchar" && type != "geometry") + QVariant::Type type = (*it).type(); + if (type == QVariant::Int || type == QVariant::Double) { str = (*it).name(); classificationComboBox->insertItem(str); diff --git a/src/app/qgsgraduatedsymboldialog.cpp b/src/app/qgsgraduatedsymboldialog.cpp index 09f7757e281..1c596aa6b79 100644 --- a/src/app/qgsgraduatedsymboldialog.cpp +++ b/src/app/qgsgraduatedsymboldialog.cpp @@ -17,7 +17,6 @@ /* $Id$ */ #include "qgsgraduatedsymboldialog.h" -#include "qgsfeatureattribute.h" #include "qgsfield.h" #include "qgsgraduatedsymbolrenderer.h" #include "qgsludialog.h" @@ -50,8 +49,8 @@ QgsGraduatedSymbolDialog::QgsGraduatedSymbolDialog(QgsVectorLayer * layer): QDia it != fields.end(); ++it) { - QString type = (*it).type(); - if (type != "String" && type != "varchar" && type != "geometry") + QVariant::Type type = (*it).type(); + if (type == QVariant::Int || type == QVariant::Double) { str = (*it).name(); classificationComboBox->insertItem(str); @@ -482,7 +481,7 @@ int QgsGraduatedSymbolDialog::quantilesFromVectorLayer(std::list& result while(provider->getNextFeature(currentFeature, false, attList)) { currentAttributeMap = currentFeature.attributeMap(); - currentValue = currentAttributeMap[attributeIndex].fieldValue().toDouble(); + currentValue = currentAttributeMap[attributeIndex].toDouble(); attributeValues[index] = currentValue; ++index; } diff --git a/src/app/qgslabeldialog.cpp b/src/app/qgslabeldialog.cpp index d7d26120de8..b9fc22dfe51 100644 --- a/src/app/qgslabeldialog.cpp +++ b/src/app/qgslabeldialog.cpp @@ -386,20 +386,30 @@ void QgsLabelDialog::apply() //TODO - transparency attributes for buffers //set the label props that are data bound to a field in the attributes tbl - mLabel->setLabelField( QgsLabel::Text, cboLabelField->currentText() ); - mLabel->setLabelField( QgsLabel::Family, cboFontField->currentText() ); - mLabel->setLabelField( QgsLabel::Bold, cboBoldField->currentText() ); - mLabel->setLabelField( QgsLabel::Italic, cboItalicField->currentText() ); - mLabel->setLabelField( QgsLabel::Underline, cboUnderlineField->currentText() ); - mLabel->setLabelField( QgsLabel::Size, cboFontSizeField->currentText() ); - mLabel->setLabelField( QgsLabel::BufferSize, cboBufferSizeField->currentText() ); + mLabel->setLabelField( QgsLabel::Text, fieldIndexFromName(cboLabelField->currentText()) ); + mLabel->setLabelField( QgsLabel::Family, fieldIndexFromName(cboFontField->currentText()) ); + mLabel->setLabelField( QgsLabel::Bold, fieldIndexFromName(cboBoldField->currentText()) ); + mLabel->setLabelField( QgsLabel::Italic, fieldIndexFromName(cboItalicField->currentText()) ); + mLabel->setLabelField( QgsLabel::Underline, fieldIndexFromName(cboUnderlineField->currentText()) ); + mLabel->setLabelField( QgsLabel::Size, fieldIndexFromName(cboFontSizeField->currentText()) ); + mLabel->setLabelField( QgsLabel::BufferSize, fieldIndexFromName(cboBufferSizeField->currentText()) ); //mLabel->setLabelField( QgsLabel::BufferTransparency, cboBufferTransparencyField->currentText() ); - mLabel->setLabelField( QgsLabel::XCoordinate, cboXCoordinateField->currentText() ); - mLabel->setLabelField( QgsLabel::YCoordinate, cboYCoordinateField->currentText() ); - mLabel->setLabelField( QgsLabel::XOffset, cboXOffsetField->currentText() ); - mLabel->setLabelField( QgsLabel::YOffset, cboYOffsetField->currentText() ); - mLabel->setLabelField( QgsLabel::Alignment, cboAlignmentField->currentText() ); - mLabel->setLabelField( QgsLabel::Angle, cboAngleField->currentText() ); + mLabel->setLabelField( QgsLabel::XCoordinate, fieldIndexFromName(cboXCoordinateField->currentText()) ); + mLabel->setLabelField( QgsLabel::YCoordinate, fieldIndexFromName(cboYCoordinateField->currentText()) ); + mLabel->setLabelField( QgsLabel::XOffset, fieldIndexFromName(cboXOffsetField->currentText()) ); + mLabel->setLabelField( QgsLabel::YOffset, fieldIndexFromName(cboYOffsetField->currentText()) ); + mLabel->setLabelField( QgsLabel::Alignment, fieldIndexFromName(cboAlignmentField->currentText()) ); + mLabel->setLabelField( QgsLabel::Angle, fieldIndexFromName(cboAngleField->currentText()) ); } +int QgsLabelDialog::fieldIndexFromName(QString name) +{ + const QgsFieldMap& fields = mLabel->fields(); + for (QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it) + { + if (it->name() == name) + return it.key(); + } + return -1; +} diff --git a/src/app/qgslabeldialog.h b/src/app/qgslabeldialog.h index a4dab5f821f..eb570aec9d2 100644 --- a/src/app/qgslabeldialog.h +++ b/src/app/qgslabeldialog.h @@ -77,8 +77,10 @@ public slots: /* emitted when anitem in label source list is chosen */ void labelSourceSet(); -protected slots: +protected: + /** return field index based on field's name, -1 if not found */ + int fieldIndexFromName(QString name); private: QgsLabel *mLabel; diff --git a/src/app/qgsmaptoolcapture.cpp b/src/app/qgsmaptoolcapture.cpp index d47669d8e22..7c7c1fb9b32 100644 --- a/src/app/qgsmaptoolcapture.cpp +++ b/src/app/qgsmaptoolcapture.cpp @@ -18,7 +18,6 @@ #include "qgsattributedialog.h" #include "qgscoordinatetransform.h" #include "qgsfield.h" -#include "qgsfeatureattribute.h" #include "qgsmaptoolcapture.h" #include "qgsmapcanvas.h" #include "qgsmaprender.h" @@ -61,7 +60,9 @@ void QgsMapToolCapture::canvasReleaseEvent(QMouseEvent * e) return; } - if(!(vlayer->getDataProvider()->capabilities() & QgsVectorDataProvider::AddFeatures)) + QgsVectorDataProvider* provider = vlayer->getDataProvider(); + + if(!(provider->capabilities() & QgsVectorDataProvider::AddFeatures)) { QMessageBox::information(0, QObject::tr("Layer cannot be added to"), QObject::tr("The data provider for this layer does not support the addition of features.")); @@ -97,7 +98,7 @@ void QgsMapToolCapture::canvasReleaseEvent(QMouseEvent * e) //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(vlayer->getDataProvider()->capabilities()&QgsVectorDataProvider::AddFeatures) + if(provider->capabilities() & QgsVectorDataProvider::AddFeatures) { QgsFeature* f = new QgsFeature(0,"WKBPoint"); // project to layer's SRS @@ -147,15 +148,14 @@ void QgsMapToolCapture::canvasReleaseEvent(QMouseEvent * e) f->setGeometryAndOwnership(&wkb[0],size); // add the fields to the QgsFeature - const QgsFieldMap& fields=vlayer->fields(); + const QgsFieldMap& fields=provider->fields(); for(QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it) { - QString name = it->name(); - f->addAttribute(it.key(), QgsFeatureAttribute(name, vlayer->getDefaultValue(name,f))); + f->addAttribute(it.key(), provider->getDefaultValue(it.key()) ); } // show the dialog to enter attribute values - if (QgsAttributeDialog::queryAttributes(*f)) + if (QgsAttributeDialog::queryAttributes(fields, *f)) vlayer->addFeature(*f); else delete f; @@ -371,14 +371,13 @@ void QgsMapToolCapture::canvasReleaseEvent(QMouseEvent * e) f->setGeometryAndOwnership(&wkb[0],size); // add the fields to the QgsFeature - const QgsFieldMap& fields = vlayer->fields(); + const QgsFieldMap& fields = provider->fields(); for(QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it) { - QString name = it->name(); - f->addAttribute(it.key(), QgsFeatureAttribute(name, vlayer->getDefaultValue(name, f))); + f->addAttribute(it.key(), provider->getDefaultValue(it.key())); } - if (QgsAttributeDialog::queryAttributes(*f)) + if (QgsAttributeDialog::queryAttributes(fields, *f)) vlayer->addFeature(*f); else delete f; diff --git a/src/app/qgsmaptoolidentify.cpp b/src/app/qgsmaptoolidentify.cpp index 02c315656cd..a39903e87fd 100644 --- a/src/app/qgsmaptoolidentify.cpp +++ b/src/app/qgsmaptoolidentify.cpp @@ -14,6 +14,7 @@ ***************************************************************************/ /* $Id$ */ +#include "qgsfield.h" #include "qgsmessageviewer.h" #include "qgsmaptoolidentify.h" #include "qgsmapcanvas.h" @@ -25,7 +26,6 @@ #include "qgsidentifyresults.h" #include "qgsdistancearea.h" #include "qgsfeature.h" -#include "qgsfeatureattribute.h" #include "qgslogger.h" #include "qgsattributedialog.h" #include "qgscursors.h" @@ -210,6 +210,7 @@ void QgsMapToolIdentify::identifyVectorLayer(QgsVectorLayer* layer, const QgsPoi QString fieldIndex = layer->displayField(); QgsVectorDataProvider* dataProvider = layer->getDataProvider(); QgsAttributeList allAttributes = dataProvider->allAttributesList(); + const QgsFieldMap& fields = dataProvider->fields(); dataProvider->select(r, true); @@ -251,13 +252,13 @@ void QgsMapToolIdentify::identifyVectorLayer(QgsVectorLayer* layer, const QgsPoi for (QgsAttributeMap::const_iterator it = attr.begin(); it != attr.end(); ++it) { - QgsDebugMsg(it->fieldName() + " == " + fieldIndex); + //QgsDebugMsg(it->fieldName() + " == " + fieldIndex); - if (it->fieldName().lower() == fieldIndex) + if (fields[it.key()].name() == fieldIndex) { - featureNode->setText(1, it->fieldValue()); + featureNode->setText(1, it->toString()); } - mResults->addAttribute(featureNode, it->fieldName(), it->fieldValue()); + mResults->addAttribute(featureNode, fields[it.key()].name(), it->toString()); } // Calculate derived attributes and insert: @@ -350,7 +351,7 @@ void QgsMapToolIdentify::identifyVectorLayer(QgsVectorLayer* layer, const QgsPoi QApplication::restoreOverrideCursor(); // Show the attribute value editing dialog - QgsAttributeDialog ad( old ); + QgsAttributeDialog ad( dataProvider->fields(), old ); if (ad.exec() == QDialog::Accepted) { @@ -369,7 +370,7 @@ void QgsMapToolIdentify::identifyVectorLayer(QgsVectorLayer* layer, const QgsPoi << "." << std::endl; #endif QgsAttributeMap& chattr = changedAttributes[ feat.featureId() ]; - chattr[i] = QgsFeatureAttribute(oldit->fieldName(), ad.value(i)); + chattr[i] = ad.value(i); // propagate "dirtyness" to the layer layer->setModified(); diff --git a/src/app/qgspgquerybuilder.cpp b/src/app/qgspgquerybuilder.cpp index 26cde1ad271..07b14dcedd6 100644 --- a/src/app/qgspgquerybuilder.cpp +++ b/src/app/qgspgquerybuilder.cpp @@ -121,7 +121,7 @@ void QgsPgQueryBuilder::populateFields() int fldtyp = PQftype(result, i); QString typOid = QString().setNum(fldtyp); QgsLogger::debug("typOid is: " + typOid); - int fieldModifier = PQfmod(result, i); + //int fieldModifier = PQfmod(result, i); QString sql = "select typelem from pg_type where typelem = " + typOid + " and typlen = -1"; // //--std::cout << sql << std::endl; PGresult *oidResult = PQexec(mPgConnection, @@ -148,8 +148,8 @@ void QgsPgQueryBuilder::populateFields() std::cerr << "Field parms: Name = " << fieldName.toLocal8Bit().data() << ", Type = " << fieldType.toLocal8Bit().data() << std::endl; #endif - mFieldMap[fieldName] = QgsField(fieldName, fieldType, - fieldSize.toInt(), fieldModifier); + QVariant::Type type = QVariant::String; // TODO: should be set correctly [MD] + mFieldMap[fieldName] = QgsField(fieldName, type, fieldType); lstFields->insertItem(fieldName); } }else @@ -191,7 +191,7 @@ void QgsPgQueryBuilder::on_btnSampleValues_clicked() lstValues->clear(); // determine the field type QgsField field = mFieldMap[lstFields->currentText()]; - bool isCharField = field.type().find("char") > -1; + bool isCharField = field.typeName().find("char") > -1; PGresult *result = PQexec(mPgConnection, (const char *) (sql.utf8())); if (PQresultStatus(result) == PGRES_TUPLES_OK) @@ -229,7 +229,7 @@ void QgsPgQueryBuilder::on_btnGetAllValues_clicked() lstValues->clear(); // determine the field type QgsField field = mFieldMap[lstFields->currentText()]; - bool isCharField = field.type().find("char") > -1; + bool isCharField = field.typeName().find("char") > -1; PGresult *result = PQexec(mPgConnection, (const char *) (sql.utf8())); diff --git a/src/app/qgssearchquerybuilder.cpp b/src/app/qgssearchquerybuilder.cpp index bb1ec1955da..23aa5422ecf 100644 --- a/src/app/qgssearchquerybuilder.cpp +++ b/src/app/qgssearchquerybuilder.cpp @@ -53,12 +53,12 @@ QgsSearchQueryBuilder::~QgsSearchQueryBuilder() void QgsSearchQueryBuilder::populateFields() { - const QgsFieldMap& fields = mLayer->fields(); + const QgsFieldMap& fields = mLayer->getDataProvider()->fields(); for (QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it) { - QgsField f = it.value(); - QString fieldName = f.name(); - mFieldMap[fieldName] = f; + QString fieldName = it->name(); + + mFieldMap[fieldName] = it.key(); lstFields->insertItem(fieldName); } } @@ -68,28 +68,24 @@ void QgsSearchQueryBuilder::getFieldValues(uint limit) // clear the values list lstValues->clear(); + QgsVectorDataProvider* provider = mLayer->getDataProvider(); + // determine the field type - QgsField field = mFieldMap[lstFields->currentText()]; - QString fieldName = field.name().lower(); - bool numeric = field.isNumeric(); + QString fieldName = lstFields->currentText(); + int fieldIndex = mFieldMap[fieldName]; + QgsField field = provider->fields()[fieldIndex]; + bool numeric = (field.type() == QVariant::Int || field.type() == QVariant::Double); QgsFeature feat; QString value; - QgsVectorDataProvider* provider = mLayer->getDataProvider(); provider->reset(); - QgsAttributeList allAttributes = provider->allAttributesList(); - while (provider->getNextFeature(feat, false, allAttributes) && + QgsAttributeList attrs; + attrs.append(fieldIndex); + while (provider->getNextFeature(feat, false, attrs) && (limit == 0 || lstValues->count() != limit)) { const QgsAttributeMap& attributes = feat.attributeMap(); - for (QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++) - { - if ( (*it).fieldName().lower() == fieldName) - { - value = (*it).fieldValue(); - break; - } - } + value = attributes[fieldIndex].toString(); if (!numeric) { @@ -154,11 +150,12 @@ long QgsSearchQueryBuilder::countRecords(QString searchString) int count = 0; QgsFeature feat; QgsVectorDataProvider* provider = mLayer->getDataProvider(); + const QgsFieldMap& fields = provider->fields(); provider->reset(); QgsAttributeList allAttributes = provider->allAttributesList(); while (provider->getNextFeature(feat, false, allAttributes)) { - if (searchTree->checkAgainst(feat.attributeMap())) + if (searchTree->checkAgainst(fields, feat.attributeMap())) { count++; } diff --git a/src/app/qgssearchquerybuilder.h b/src/app/qgssearchquerybuilder.h index 2d66947b518..c02ecd64c08 100644 --- a/src/app/qgssearchquerybuilder.h +++ b/src/app/qgssearchquerybuilder.h @@ -111,11 +111,8 @@ class QgsSearchQueryBuilder : public QDialog, private Ui::QgsPgQueryBuilderBase //! Layer for which is the query builder opened QgsVectorLayer* mLayer; - //! Vector of QgsField objects - std::vector mFields; - //! Map that holds field information, keyed by field name - std::map mFieldMap; + QMap mFieldMap; }; #endif //QGSSEARCHQUERYBUILDER_H diff --git a/src/app/qgsuniquevaluedialog.cpp b/src/app/qgsuniquevaluedialog.cpp index e19f1629ffc..9238275667c 100644 --- a/src/app/qgsuniquevaluedialog.cpp +++ b/src/app/qgsuniquevaluedialog.cpp @@ -19,7 +19,6 @@ #include "qgsuniquevaluedialog.h" #include "qgsfeature.h" #include "qgsfield.h" -#include "qgsfeatureattribute.h" #include "qgssymbol.h" #include "qgsuniquevaluerenderer.h" #include "qgsvectordataprovider.h" @@ -148,8 +147,8 @@ void QgsUniqueValueDialog::changeClassificationAttribute() mClassListWidget->clear(); while(provider->getNextFeature(feat, false, attlist)) { - const QgsAttributeMap& vec = feat.attributeMap(); - value=vec[nr].fieldValue(); + const QgsAttributeMap& attrs = feat.attributeMap(); + value = attrs[nr].toString(); if(mValues.find(value)==mValues.end()) { diff --git a/src/app/qgsvectorlayerproperties.cpp b/src/app/qgsvectorlayerproperties.cpp index b23b78ecd3e..4dbb80f868d 100644 --- a/src/app/qgsvectorlayerproperties.cpp +++ b/src/app/qgsvectorlayerproperties.cpp @@ -228,7 +228,7 @@ void QgsVectorLayerProperties::reset( void ) QObject::connect(legendtypecombobox, SIGNAL(activated(const QString &)), this, SLOT(alterLayerDialog(const QString &))); // reset fields in label dialog - layer->label()->setFields ( layer->fields() ); + layer->label()->setFields ( layer->getDataProvider()->fields() ); //set the metadata contents teMetadata->setText(getMetadata()); @@ -533,7 +533,7 @@ QString QgsVectorLayerProperties::getMetadata() myMetadataQString += ""; myMetadataQString += ""; myMetadataQString += "" + tr("Comment") + ""; - myMetadataQString += ""; + myMetadataQString += ""; myMetadataQString += ""; //get info for each field by looping through them @@ -547,7 +547,7 @@ QString QgsVectorLayerProperties::getMetadata() myMetadataQString += myField.name(); myMetadataQString += ""; myMetadataQString += ""; - myMetadataQString += myField.type(); + myMetadataQString += myField.typeName(); myMetadataQString += ""; myMetadataQString += ""; myMetadataQString += QString("%1").arg(myField.length()); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9e896013821..6db4a61ac98 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -14,7 +14,6 @@ qgsdatasourceuri.cpp qgsdistancearea.cpp qgsexception.cpp qgsfeature.cpp -qgsfeatureattribute.cpp qgsfield.cpp qgsgeometry.cpp qgsgeometryvertexindex.cpp @@ -173,7 +172,6 @@ qgsdatasourceuri.h qgsdistancearea.h qgsexception.h qgsfeature.h -qgsfeatureattribute.h qgsfield.h qgsgeometry.h qgsgeometryvertexindex.h diff --git a/src/core/qgsfeature.cpp b/src/core/qgsfeature.cpp index 5a120cc6713..af6d3633283 100644 --- a/src/core/qgsfeature.cpp +++ b/src/core/qgsfeature.cpp @@ -15,7 +15,6 @@ email : sherman at mrcc.com /* $Id$ */ #include "qgsfeature.h" -#include "qgsfeatureattribute.h" #include "qgsgeometry.h" #include "qgsrect.h" @@ -174,7 +173,7 @@ const QgsAttributeMap& QgsFeature::attributeMap() const /** * Add an attribute to the map */ -void QgsFeature::addAttribute(int field, QgsFeatureAttribute attr) +void QgsFeature::addAttribute(int field, QVariant attr) { mAttributes.insert(field, attr); } @@ -186,7 +185,7 @@ void QgsFeature::deleteAttribute(int field) } -void QgsFeature::changeAttribute(int field, QgsFeatureAttribute attr) +void QgsFeature::changeAttribute(int field, QVariant attr) { mAttributes[field] = attr; } @@ -196,6 +195,8 @@ void QgsFeature::changeAttribute(int field, QgsFeatureAttribute attr) * Get the fields for this feature * @return A std::map containing field position (index) and field name */ +/* +TODO: delete - QgsVectorDataProvider::fields() should be used [MD] QgsFieldNameMap QgsFeature::fields() const { QgsFieldNameMap fieldNames; @@ -208,7 +209,7 @@ QgsFieldNameMap QgsFeature::fields() const return fieldNames; } - +*/ QgsGeometry * QgsFeature::geometry() { @@ -281,354 +282,6 @@ void QgsFeature::setGeometryAndOwnership(unsigned char *geom, size_t length) } -// /** Set the pointer to the modified feature geometry -// */ -// void QgsFeature::setModifiedGeometry(unsigned char *geom, size_t length) -// { -// // delete any existing WKB geometry before assigning new one -// if ( modifiedGeometry ) -// { -// delete [] modifiedGeometry; -// } -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::setModifiedGeometry: setting modified geometry for " << featureId() << "." << std::endl; -// #endif -// -// modifiedGeometry = geom; -// modifiedGeometrySize = length; -// mDirty = TRUE; -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::setModifiedGeometry: modifiedGeometrySize = " << modifiedGeometrySize -// << ", mDirty = " << mDirty << "." << std::endl; -// #endif -// #ifdef QGISDEBUG -// exportToWKT(geometry); -// std::cout << "QgsFeature::setModifiedGeometry: Original: " << mWKT << "." << std::endl; -// #endif -// #ifdef QGISDEBUG -// exportToWKT(modifiedGeometry); -// std::cout << "QgsFeature::setModifiedGeometry: Modified: " << mWKT << "." << std::endl; -// #endif -// -// } - - -// bool QgsFeature::insertVertexBefore(double x, double y, int beforeVertex, int atRing, int atItem) -// { -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: Entered with " -// << "x " << x << ", y " << y -// << "beforeVertex " << beforeVertex << ", atRing " << atRing << ", atItem" -// << " " << atItem -// << "." << std::endl; -// #endif -// -// // make sure we're using the latest version -// unsigned char * localGeometry = getGeometry(); -// size_t localGeometrySize = getGeometrySize(); -// -// if (localGeometry) -// { -// int wkbType; -// // double *x,*y; -// -// memcpy(&wkbType, (localGeometry+1), sizeof(int)); -// switch (wkbType) -// { -// case QGis::WKBPoint: -// { -// // Meaningless -// return FALSE; -// break; -// } -// case QGis::WKBLineString: -// { -// unsigned char *ptr; -// int *nPoints; -// int idx; -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: in QGis::WKBLineString." << std::endl; -// #endif -// -// // get number of points in the line -// ptr = localGeometry + 5; // now at localGeometry.numPoints -// nPoints = (int *) ptr; -// -// /* -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: old number of points is " -// << (*nPoints) -// << "." << std::endl; -// #endif -// */ -// // silently adjust any overflow "beforeVertex" values to mean -// // "append to end of string" -// if (*nPoints < beforeVertex) -// { -// beforeVertex = *nPoints; // beforeVertex is 0 based, *nPoints is 1 based -// } -// -// // create new geometry expanded by 2 doubles -// unsigned char *newWKB = new unsigned char[localGeometrySize + 16]; -// memset(newWKB, '\0', localGeometrySize + 16); // just in case -// /* -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: newWKB at " << newWKB << "." << std::endl; -// #endif -// -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: done initial newWKB of " -// << (localGeometrySize + 16) -// << " bytes." << std::endl; -// #endif -// */ -// // copy section before splice -// memcpy(newWKB, localGeometry, 9 + (16 * beforeVertex) ); -// /* -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: done pre memcpy of " -// << (9 + (16 * beforeVertex)) -// << " bytes." << std::endl; -// #endif -// #ifdef QGISDEBUG -// exportToWKT(newWKB); -// std::cout << "QgsFeature::insertVertexBefore: newWKB: " << mWKT << "." << std::endl; -// #endif -// */ -// // adjust number of points -// (*nPoints)++; -// ptr = newWKB + 5; // now at newWKB.numPoints -// memcpy(ptr, nPoints, 4); -// /* -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: new number of points is " -// << (*nPoints) -// << "." << std::endl; -// #endif -// */ -// -// // copy vertex to be spliced -// ptr += 4; // now at newWKB.points[] -// #ifdef QGISDEBUG -// // std::cout << "QgsFeature::insertVertexBefore: ptr at " << ptr << "." << std::endl; -// #endif -// ptr += (16 * beforeVertex); -// #ifdef QGISDEBUG -// // std::cout << "QgsFeature::insertVertexBefore: going to add x " << x << "." << std::endl; -// // std::cout << "QgsFeature::insertVertexBefore: ptr at " << ptr << ", going to add x " << x << "." << std::endl; -// #endif -// memcpy(ptr, &x, 8); -// // memcpy(ptr, x, 8); -// ptr += 8; -// #ifdef QGISDEBUG -// // std::cout << "QgsFeature::insertVertexBefore: going to add y " << y << "." << std::endl; -// // std::cout << "QgsFeature::insertVertexBefore: ptr at " << ptr << ", going to add y " << y << "." << std::endl; -// #endif -// memcpy(ptr, &y, 8); -// // memcpy(ptr, y, 8); -// ptr += 8; -// -// /* -// #ifdef QGISDEBUG -// exportToWKT(newWKB); -// std::cout << "QgsFeature::insertVertexBefore: newWKB: " << mWKT << "." << std::endl; -// #endif -// */ -// -// // copy section after splice -// memcpy(ptr, localGeometry + 9 + (16 * beforeVertex), (16 * (*nPoints - beforeVertex)) ); -// -// /* -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: done post memcpy of " -// << (16 * (*nPoints - beforeVertex)) -// << " bytes." << std::endl; -// #endif -// */ -// #ifdef QGISDEBUG -// exportToWKT(newWKB); -// std::cout << "QgsFeature::insertVertexBefore: newWKB: " << mWKT << "." << std::endl; -// #endif -// -// // set new geomtry to this object -// setModifiedGeometry(newWKB, localGeometrySize + 16); -// -// break; -// } -// case QGis::WKBPolygon: -// { -// // TODO -// return false; -// break; -// } -// case QGis::WKBMultiPoint: -// { -// // TODO -// return false; -// break; -// } -// -// case QGis::WKBMultiLineString: -// { -// // TODO -// return false; -// break; -// } -// -// case QGis::WKBMultiPolygon: -// { -// // TODO -// return false; -// break; -// } -// default: -// #ifdef QGISDEBUG -// qWarning("error: feature type not recognized in QgsFeature::insertVertexBefore"); -// #endif -// return false; -// break; -// } -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::insertVertexBefore: Exiting successfully." << std::endl; -// #endif -// -// return true; -// -// } -// else -// { -// #ifdef QGISDEBUG -// qWarning("error: no geometry pointer in QgsFeature::insertVertexBefore"); -// #endif -// return false; -// } -// -// -// -// } -// -// -// bool QgsFeature::moveVertexAt(double x, double y, int atVertex, int atRing, int atItem) -// { -// } -// -// -// bool QgsFeature::vertexAt(double &x, double &y, int atVertex, int atRing, int atItem) const -// { -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::vertexAt: Entered with " -// << "atVertex " << atVertex << ", atRing " << atRing << ", atItem" -// << " " << atItem -// << "." << std::endl; -// #endif -// -// if(geometry) -// { -// int wkbType; -// -// memcpy(&wkbType, (geometry+1), sizeof(int)); -// switch (wkbType) -// { -// case QGis::WKBPoint: -// { -// // TODO -// return FALSE; -// break; -// } -// case QGis::WKBLineString: -// { -// unsigned char *ptr; -// int *nPoints; -// int idx; -// -// // get number of points in the line -// ptr = geometry + 5; // now at geometry.numPoints -// nPoints = (int *) ptr; -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::vertexAt: Number of points in WKBLineString is " << *nPoints -// << "." << std::endl; -// #endif -// -// // silently adjust any overflow "atVertex" values to mean -// // "append to end of string" -// if (*nPoints <= atVertex) -// { -// atVertex = (*nPoints - 1); // atVertex is 0 based, *nPoints is 1 based -// } -// -// // copy the vertex coordinates -// ptr = geometry + 9 + (atVertex * 16); -// memcpy(&x, ptr, 8); -// ptr += 8; -// memcpy(&y, ptr, 8); -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::vertexAt: Point is (" << x << ", " << y << ")" -// << "." << std::endl; -// #endif -// -// break; -// } -// case QGis::WKBPolygon: -// { -// // TODO -// return false; -// break; -// } -// case QGis::WKBMultiPoint: -// { -// // TODO -// return false; -// break; -// } -// -// case QGis::WKBMultiLineString: -// { -// // TODO -// return false; -// break; -// } -// -// case QGis::WKBMultiPolygon: -// { -// // TODO -// return false; -// break; -// } -// default: -// #ifdef QGISDEBUG -// qWarning("error: feature type not recognized in QgsFeature::vertexAt"); -// #endif -// return false; -// break; -// } -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::vertexAt: Exiting TRUE." << std::endl; -// #endif -// -// return true; -// -// } -// else -// { -// #ifdef QGISDEBUG -// qWarning("error: no geometry pointer in QgsFeature::vertexAt"); -// #endif -// return false; -// } -// -// -// } - - bool QgsFeature::isValid() const { return mValid; @@ -649,627 +302,8 @@ void QgsFeature::resetDirty() mDirty = FALSE; } -// bool QgsFeature::intersects(QgsRect* r) const -// { -// bool returnval=false; -// -// GEOS_GEOM::GeometryFactory *gf = new GEOS_GEOM::GeometryFactory(); -// GEOS_IO::WKTReader *wktReader = new GEOS_IO::WKTReader(gf); -// GEOS_GEOM::Geometry *geosGeom = wktReader->read( qstrdup(wellKnownText()) ); -// -// //write the selection rectangle to wkt by hand -// QString rectwkt="POLYGON(("; -// rectwkt+=QString::number(r->xMin(),'f',3); -// rectwkt+=" "; -// rectwkt+=QString::number(r->yMin(),'f',3); -// rectwkt+=","; -// rectwkt+=QString::number(r->xMax(),'f',3); -// rectwkt+=" "; -// rectwkt+=QString::number(r->yMin(),'f',3); -// rectwkt+=","; -// rectwkt+=QString::number(r->xMax(),'f',3); -// rectwkt+=" "; -// rectwkt+=QString::number(r->yMax(),'f',3); -// rectwkt+=","; -// rectwkt+=QString::number(r->xMin(),'f',3); -// rectwkt+=" "; -// rectwkt+=QString::number(r->yMax(),'f',3); -// rectwkt+=","; -// rectwkt+=QString::number(r->xMin(),'f',3); -// rectwkt+=" "; -// rectwkt+=QString::number(r->yMin(),'f',3); -// rectwkt+="))"; -// -// GEOS_GEOM::Geometry *geosRect = wktReader->read( qstrdup(rectwkt) ); -// if(geosGeom->intersects(geosRect)) -// { -// returnval=true; -// } -// -// delete geosGeom; -// delete geosRect; -// delete gf; -// delete wktReader; -// return returnval; -// } -// -// -// bool QgsFeature::exportToWKT(unsigned char * geom) const -// { -// if(geom) -// { -// int wkbType; -// double *x,*y; -// -// mWKT=""; -// memcpy(&wkbType, (geom+1), sizeof(int)); -// switch (wkbType) -// { -// case QGis::WKBPoint: -// { -// mWKT+="POINT("; -// x = (double *) (geom + 5); -// mWKT+=QString::number(*x,'f',3); -// mWKT+=" "; -// y = (double *) (geom + 5 + sizeof(double)); -// mWKT+=QString::number(*y,'f',3); -// mWKT+=")"; -// break; -// } -// case QGis::WKBLineString: -// { -// unsigned char *ptr; -// int *nPoints; -// int idx; -// -// mWKT+="LINESTRING("; -// // get number of points in the line -// ptr = geom + 5; -// nPoints = (int *) ptr; -// ptr = geom + 1 + 2 * sizeof(int); -// for (idx = 0; idx < *nPoints; ++idx) -// { -// if(idx!=0) -// { -// mWKT+=", "; -// } -// x = (double *) ptr; -// mWKT+=QString::number(*x,'f',3); -// mWKT+=" "; -// ptr += sizeof(double); -// y = (double *) ptr; -// mWKT+=QString::number(*y,'f',3); -// ptr += sizeof(double); -// } -// mWKT+=")"; -// break; -// } -// case QGis::WKBPolygon: -// { -// unsigned char *ptr; -// int idx, jdx; -// int *numRings, *nPoints; -// -// mWKT+="POLYGON("; -// // get number of rings in the polygon -// numRings = (int *)(geom + 1 + sizeof(int)); -// if (!(*numRings)) // sanity check for zero rings in polygon -// { -// break; -// } -// int *ringStart; // index of first point for each ring -// int *ringNumPoints; // number of points in each ring -// ringStart = new int[*numRings]; -// ringNumPoints = new int[*numRings]; -// ptr = geom+1+2*sizeof(int); // set pointer to the first ring -// for (idx = 0; idx < *numRings; idx++) -// { -// if(idx!=0) -// { -// mWKT+=","; -// } -// mWKT+="("; -// // get number of points in the ring -// nPoints = (int *) ptr; -// ringNumPoints[idx] = *nPoints; -// ptr += 4; -// -// for(jdx=0;jdx<*nPoints;jdx++) -// { -// if(jdx!=0) -// { -// mWKT+=","; -// } -// x = (double *) ptr; -// mWKT+=QString::number(*x,'f',3); -// mWKT+=" "; -// ptr += sizeof(double); -// y = (double *) ptr; -// mWKT+=QString::number(*y,'f',3); -// ptr += sizeof(double); -// } -// mWKT+=")"; -// } -// mWKT+=")"; -// delete [] ringStart; -// delete [] ringNumPoints; -// break; -// } -// case QGis::WKBMultiPoint: -// { -// unsigned char *ptr; -// int idx; -// int *nPoints; -// -// mWKT+="MULTIPOINT("; -// nPoints=(int*)(geom+5); -// ptr=geom+5+sizeof(int); -// for(idx=0;idx<*nPoints;++idx) -// { -// if(idx!=0) -// { -// mWKT+=", "; -// } -// x = (double *) (ptr); -// mWKT+=QString::number(*x,'f',3); -// mWKT+=" "; -// ptr+=sizeof(double); -// y= (double *) (ptr); -// mWKT+=QString::number(*y,'f',3); -// ptr+=sizeof(double); -// } -// mWKT+=")"; -// break; -// } -// -// case QGis::WKBMultiLineString: -// { -// unsigned char *ptr; -// int idx, jdx, numLineStrings; -// int *nPoints; -// -// mWKT+="MULTILINESTRING("; -// numLineStrings = (int) (geom[5]); -// ptr = geom + 9; -// for (jdx = 0; jdx < numLineStrings; jdx++) -// { -// if(jdx!=0) -// { -// mWKT+=", "; -// } -// mWKT+="("; -// ptr += 5; // skip type since we know its 2 -// nPoints = (int *) ptr; -// ptr += sizeof(int); -// for (idx = 0; idx < *nPoints; idx++) -// { -// if(idx!=0) -// { -// mWKT+=", "; -// } -// x = (double *) ptr; -// mWKT+=QString::number(*x,'f',3); -// ptr += sizeof(double); -// mWKT+=" "; -// y = (double *) ptr; -// mWKT+=QString::number(*y,'f',3); -// ptr += sizeof(double); -// } -// mWKT+=")"; -// } -// mWKT+=")"; -// break; -// } -// -// case QGis::WKBMultiPolygon: -// { -// unsigned char *ptr; -// int idx, jdx, kdx; -// int *numPolygons, *numRings, *nPoints; -// -// mWKT+="MULTIPOLYGON("; -// ptr = geom + 5; -// numPolygons = (int *) ptr; -// ptr = geom + 9; -// for (kdx = 0; kdx < *numPolygons; kdx++) -// { -// if(kdx!=0) -// { -// mWKT+=","; -// } -// mWKT+="("; -// ptr+=5; -// numRings = (int *) ptr; -// ptr += 4; -// for (idx = 0; idx < *numRings; idx++) -// { -// if(idx!=0) -// { -// mWKT+=","; -// } -// mWKT+="("; -// nPoints = (int *) ptr; -// ptr += 4; -// for (jdx = 0; jdx < *nPoints; jdx++) -// { -// x = (double *) ptr; -// mWKT+=QString::number(*x,'f',3); -// ptr += sizeof(double); -// mWKT+=" "; -// y = (double *) ptr; -// mWKT+=QString::number(*y,'f',3); -// ptr += sizeof(double); -// } -// mWKT+=")"; -// } -// mWKT+=")"; -// } -// mWKT+=")"; -// break; -// } -// default: -// #ifdef QGISDEBUG -// qWarning("error: feature type not recognized in QgsFeature::exportToWKT"); -// #endif -// return false; -// break; -// } -// return true; -// -// } -// else -// { -// #ifdef QGISDEBUG -// qWarning("error: no geom pointer in QgsFeature::exportToWKT"); -// #endif -// return false; -// } -// -// } -// -// -// bool QgsFeature::exportToWKT() const -// { -// return exportToWKT( mGeometry.wkbBuffer() ); -// } -// - /* -QgsPoint QgsFeature::closestVertex(const QgsPoint& point) const -{ - if(mGeometry) - { - int wkbType; - double actdist = std::numeric_limits::max(); - double x,y; - double *tempx,*tempy; - memcpy(&wkbType, (mGeometry+1), sizeof(int)); - switch (wkbType) - { - case QGis::WKBPoint: - x = *((double *) (mGeometry + 5)); - y = *((double *) (mGeometry + 5 + sizeof(double))); - break; - - case QGis::WKBLineString: - { - unsigned char* ptr=mGeometry+5; - int* npoints=(int*)ptr; - ptr+=sizeof(int); - for(int index=0;index<*npoints;++index) - { - tempx = (double*)ptr; - ptr+=sizeof(double); - tempy = (double*)ptr; - if(point.sqrDist(*tempx,*tempy) 1.0) -// { -// xn = *x2; -// yn = *y2; -// } -// else -// { -// xn = *x1 + t * ( *x2 - *x1 ); -// yn = *y1 + t * ( *y2 - *y1 ); -// } -// -// } -// -// minDistPoint.set(xn, yn); -// -// return ( -// ( xn - point.x() ) * ( xn - point.x() ) + -// ( yn - point.y() ) * ( yn - point.y() ) -// ); -// -// } -// - - -// TODO: Wrap WKB processing into its own class - -// QgsPoint QgsFeature::closestSegmentWithContext(QgsPoint& point, -// int& beforeVertex, int& atRing, int& atItem, -// double& minSqrDist) -// //QgsPoint QgsFeature::closestSegment(QgsPoint& point, -// // QgsPoint& segStart, QgsPoint& segStop, -// // double& minSqrDist) -// { -// -// #ifdef QGISDEBUG -// // std::cout << "QgsFeature::closestSegment: Entered" -// // << "." << std::endl; -// #endif -// -// QgsPoint minDistPoint; -// -// int wkbType; -// double x,y; -// double *thisx,*thisy; -// double *prevx,*prevy; -// double testdist; -// -// // Initialise some stuff -// beforeVertex = -1; -// atRing = -1; -// atItem = -1; -// minSqrDist = DBL_MAX; -// -// if (mGeometry) -// { -// // int wkbType; -// // double x,y; -// // double *thisx,*thisy; -// // double *prevx,*prevy; -// // double testdist; -// -// memcpy(&wkbType, (mGeometry+1), sizeof(int)); -// -// switch (wkbType) -// { -// case QGis::WKBPoint: -// // Points have no lines -// return QgsPoint(0,0); -// -// case QGis::WKBLineString: -// unsigned char* ptr = mGeometry + 5; -// int* npoints = (int*) ptr; -// ptr += sizeof(int); -// for (int index=0; index < *npoints; ++index) -// { -// if (index > 0) -// { -// prevx = thisx; -// prevy = thisy; -// } -// -// thisx = (double*) ptr; -// ptr += sizeof(double); -// thisy = (double*) ptr; -// -// if (index > 0) -// { -// if ( -// ( -// testdist = distanceSquaredPointToSegment(point, -// prevx, prevy, -// thisx, thisy, -// minDistPoint) -// ) -// < minSqrDist ) -// { -// #ifdef QGISDEBUG -// // std::cout << "QgsFeature::closestSegment: testDist " -// // << testdist << ", minSqrDist" -// // << minSqrDist -// // << "." << std::endl; -// #endif -// -// beforeVertex = index; -// atRing = 0; -// atItem = 0; -// -// minSqrDist = testdist; -// } -// } -// -// ptr += sizeof(double); -// } -// break; -// -// // TODO: Other geometry types -// -// } // switch (wkbType) -// -// } // if (mGeometry) -// -// #ifdef QGISDEBUG -// std::cout << "QgsFeature::closestSegment: Exiting on feature " << mFid << " with beforeVertex " -// << beforeVertex << ", minSqrDist from " -// << point.stringRep() << " is " -// << minSqrDist -// << "." << std::endl; -// #endif -// -// return minDistPoint; -// -// } -// -// +TODO: delete - use QgsGeometry::boundingBox() instead [MD] QgsRect QgsFeature::boundingBox() const { if(mGeometry) @@ -1279,213 +313,4 @@ QgsRect QgsFeature::boundingBox() const QgsRect nullRect; return nullRect; } -// QgsRect QgsFeature::boundingBox() const -// { -// double xmin=DBL_MAX; -// double ymin=DBL_MAX; -// double xmax=-DBL_MAX; -// double ymax=-DBL_MAX; -// -// double *x; -// double *y; -// int *nPoints; -// int *numRings; -// int *numPolygons; -// int numPoints; -// int numLineStrings; -// int idx, jdx, kdx; -// unsigned char *ptr; -// char lsb; -// QgsPoint pt; -// QPointArray *pa; -// int wkbType; -// unsigned char *feature; -// -// feature = this->getGeometry(); -// if(feature) -// { -// wkbType=(int) feature[1]; -// switch (wkbType) -// { -// case QGis::WKBPoint: -// x = (double *) (feature + 5); -// y = (double *) (feature + 5 + sizeof(double)); -// if (*x < xmin) -// { -// xmin=*x; -// } -// if (*x > xmax) -// { -// xmax=*x; -// } -// if (*y < ymin) -// { -// ymin=*y; -// } -// if (*y > ymax) -// { -// ymax=*y; -// } -// break; -// -// case QGis::WKBLineString: -// // get number of points in the line -// ptr = feature + 5; -// nPoints = (int *) ptr; -// ptr = feature + 1 + 2 * sizeof(int); -// for (idx = 0; idx < *nPoints; idx++) -// { -// x = (double *) ptr; -// ptr += sizeof(double); -// y = (double *) ptr; -// ptr += sizeof(double); -// if (*x < xmin) -// { -// xmin=*x; -// } -// if (*x > xmax) -// { -// xmax=*x; -// } -// if (*y < ymin) -// { -// ymin=*y; -// } -// if (*y > ymax) -// { -// ymax=*y; -// } -// } -// break; -// -// case QGis::WKBMultiLineString: -// numLineStrings = (int) (feature[5]); -// ptr = feature + 9; -// for (jdx = 0; jdx < numLineStrings; jdx++) -// { -// // each of these is a wbklinestring so must handle as such -// lsb = *ptr; -// ptr += 5; // skip type since we know its 2 -// nPoints = (int *) ptr; -// ptr += sizeof(int); -// for (idx = 0; idx < *nPoints; idx++) -// { -// x = (double *) ptr; -// ptr += sizeof(double); -// y = (double *) ptr; -// ptr += sizeof(double); -// if (*x < xmin) -// { -// xmin=*x; -// } -// if (*x > xmax) -// { -// xmax=*x; -// } -// if (*y < ymin) -// { -// ymin=*y; -// } -// if (*y > ymax) -// { -// ymax=*y; -// } -// } -// } -// break; -// -// case QGis::WKBPolygon: -// // get number of rings in the polygon -// numRings = (int *) (feature + 1 + sizeof(int)); -// ptr = feature + 1 + 2 * sizeof(int); -// for (idx = 0; idx < *numRings; idx++) -// { -// // get number of points in the ring -// nPoints = (int *) ptr; -// ptr += 4; -// for (jdx = 0; jdx < *nPoints; jdx++) -// { -// // add points to a point array for drawing the polygon -// x = (double *) ptr; -// ptr += sizeof(double); -// y = (double *) ptr; -// ptr += sizeof(double); -// if (*x < xmin) -// { -// xmin=*x; -// } -// if (*x > xmax) -// { -// xmax=*x; -// } -// if (*y < ymin) -// { -// ymin=*y; -// } -// if (*y > ymax) -// { -// ymax=*y; -// } -// } -// } -// break; -// -// case QGis::WKBMultiPolygon: -// // get the number of polygons -// ptr = feature + 5; -// numPolygons = (int *) ptr; -// for (kdx = 0; kdx < *numPolygons; kdx++) -// { -// //skip the endian and feature type info and -// // get number of rings in the polygon -// ptr = feature + 14; -// numRings = (int *) ptr; -// ptr += 4; -// for (idx = 0; idx < *numRings; idx++) -// { -// // get number of points in the ring -// nPoints = (int *) ptr; -// ptr += 4; -// for (jdx = 0; jdx < *nPoints; jdx++) -// { -// // add points to a point array for drawing the polygon -// x = (double *) ptr; -// ptr += sizeof(double); -// y = (double *) ptr; -// ptr += sizeof(double); -// if (*x < xmin) -// { -// xmin=*x; -// } -// if (*x > xmax) -// { -// xmax=*x; -// } -// if (*y < ymin) -// { -// ymin=*y; -// } -// if (*y > ymax) -// { -// ymax=*y; -// } -// } -// } -// } -// break; -// -// default: -// #ifdef QGISDEBUG -// std::cout << "UNKNOWN WKBTYPE ENCOUNTERED\n"; -// #endif -// break; -// -// } -// return QgsRect(xmin,ymin,xmax,ymax); -// } -// else -// { -// return QgsRect(0,0,0,0); -// } -// } -// +*/ diff --git a/src/core/qgsfeature.h b/src/core/qgsfeature.h index 9e026dc1424..3b6eac56e14 100644 --- a/src/core/qgsfeature.h +++ b/src/core/qgsfeature.h @@ -19,14 +19,14 @@ email : sherman at mrcc.com #include #include +#include -class QgsFeatureAttribute; class QgsGeometry; class QgsRect; -// key = field index, value = field name and attribute value -typedef QMap QgsAttributeMap; +// key = field index, value = field value +typedef QMap QgsAttributeMap; // key = feature id, value = changed attributes typedef QMap QgsChangedAttributesMap; @@ -104,7 +104,7 @@ class CORE_EXPORT QgsFeature { /** * Add an attribute to the map */ - void addAttribute(int field, QgsFeatureAttribute attr); + void addAttribute(int field, QVariant attr); /**Deletes an attribute and its value*/ void deleteAttribute(int field); @@ -112,13 +112,7 @@ class CORE_EXPORT QgsFeature { /**Changes an existing attribute value @param field index of the field @param attr attribute name and value to be set */ - void changeAttribute(int field, QgsFeatureAttribute attr); - - /** - * Get the fields for this feature - * @return A std::map containing field position (index) and field name - */ - QgsFieldNameMap fields() const; + void changeAttribute(int field, QVariant attr); /** * Return the validity of this feature. This is normally set by @@ -166,58 +160,6 @@ class CORE_EXPORT QgsFeature { */ void setGeometryAndOwnership(unsigned char * geom, size_t length); - /** Set bulk-modified WKB geometry - \note this function assumes the Geometry is not committed. - */ -/* void setModifiedGeometry(unsigned char * geom, size_t length);*/ - - /** Insert a new vertex before the given vertex number, - * ring and item (first number is index 0) - * Not meaningful for Point geometries - */ -// bool insertVertexBefore(double x, double y, int beforeVertex = 0, int atRing = 0, int atItem = 0); - - /** Moves the vertex at the given position number, - * ring and item (first number is index 0) - * to the given coordinates - */ -/* bool moveVertexAt(double x, double y, int atVertex = 0, int atRing = 0, int atItem = 0);*/ - - /** - * Modifies x and y to indicate the location of - * the vertex at the given position number, - * ring and item (first number is index 0) - * to the given coordinates - */ -/* bool vertexAt(double &x, double &y, int atVertex = 0, int atRing = 0, int atItem = 0) const;*/ - -// /**Test for intersection with a rectangle (uses GEOS)*/ -// bool intersects(QgsRect* r) const; - - /**Returns the Vertex closest to a given point*/ -// QgsPoint closestVertex(const QgsPoint& point) const; - - /** Returns the line segment closest to the given point in beforeVertex, atRing and atItem - Returns the SQUARE of the closest distance in minDist. - Returns the closest point on the line segment to the given point - - - TODO: point handling - TODO: const correctness - */ -// QgsPoint closestSegment(QgsPoint& point, -// QgsPoint& segStart, QgsPoint& segStop, -// double& minSqrDist); - -// QgsPoint QgsFeature::closestSegmentWithContext(QgsPoint& point, -// int& beforeVertex, int& atRing, int& atItem, -// double& minSqrDist); -// -// - /**Returns the bounding box of this feature*/ - QgsRect boundingBox() const; -// - private: //! feature id @@ -237,41 +179,17 @@ class CORE_EXPORT QgsFeature { */ bool mOwnsGeometry; -// /** pointer to modified (dirty / uncommitted) geometry in binary WKB format -// This is only valid if isDirty(). -// */ -// unsigned char * modifiedGeometry; -// -// /** size of geometry */ -// size_t geometrySize; -// -// /** size of modified geometry */ -// size_t modifiedGeometrySize; - //! Flag to indicate if this feature is valid + // TODO: still applies? [MD] bool mValid; //! Flag to indicate if this feature is dirty (e.g. geometry has been modified in-memory) + // TODO: still applies? [MD] bool mDirty; /// feature type name QString mTypeName; -// /**WKT representation of the geometry*/ -// mutable QString mWKT; -// -// /**Exports the current WKB to mWKT -// @return true in case of success and false else*/ -// bool exportToWKT(unsigned char * geom) const; -// bool exportToWKT() const; -// -// /** Squared distance from point to the given line segment -// * TODO: Perhaps move this to QgsPoint -// */ -// double distanceSquaredPointToSegment(QgsPoint& point, -// double *x1, double *y1, -// double *x2, double *y2, -// QgsPoint& minDistPoint); }; // class QgsFeature diff --git a/src/core/qgsfeatureattribute.cpp b/src/core/qgsfeatureattribute.cpp deleted file mode 100644 index 6c417fb1ecd..00000000000 --- a/src/core/qgsfeatureattribute.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - qgsfeatureattribute.cpp - description - ------------------- - begin : Mon Sep 01 2003 - copyright : (C) 2003 by Gary E.Sherman - email : sherman at mrcc.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -/* $Id$ */ - -#include "qgsfeatureattribute.h" - -QgsFeatureAttribute::QgsFeatureAttribute(QString const & fld, QString const & val, bool num) - : field(fld), value(val), numeric(num) -{ -} - -QgsFeatureAttribute::~QgsFeatureAttribute() -{ -} - - -QString const & QgsFeatureAttribute::fieldName() const -{ - return field; -} - - -QString const & QgsFeatureAttribute::fieldValue() const -{ - return value; -} - -bool QgsFeatureAttribute::isNumeric() const -{ - return numeric; -} diff --git a/src/core/qgsfeatureattribute.h b/src/core/qgsfeatureattribute.h deleted file mode 100644 index c05b4b005d3..00000000000 --- a/src/core/qgsfeatureattribute.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - qgsfeatureattribute.h - description - ------------------- - begin : Mon Sep 01 2003 - copyright : (C) 2003 by Gary E.Sherman - email : sherman at mrcc.com - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -/* $Id$ */ -#ifndef QGSFEATUREATTRIBUTE_H -#define QGSFEATUREATTRIBUTE_H - -#include - -/** \class QgsFeatureAttribute - Feature attribute class. - * \brief Encapsulates a single feature attribute. - *@author Gary E.Sherman - */ - -class CORE_EXPORT QgsFeatureAttribute -{ -public: - - //! Constructor - QgsFeatureAttribute(QString const & field = 0, QString const & value = 0, bool num = false); - - //! Destructor - ~QgsFeatureAttribute(); - - /** - * Get the field name for this feature attribute - * @return Field name - */ - QString const & fieldName() const; - - - /** - * Get the field value for this feature attribute - * @return Field value - */ - QString const & fieldValue() const; - - /** - * Returns whether value is numeric or not - * @return Numeric flag - */ - bool isNumeric() const; - - void setFieldName(QString name){field=name;} - - void setFieldValue(QString thevalue){value=thevalue;} - - void setNumeric(bool num = true) { numeric=num; } - -private: - - //! attribute field name - QString field; - - //! attribute field value - QString value; - - //! flag whether field is numeric - bool numeric; - -}; // class QgsFeatureAttribute - -#endif diff --git a/src/core/qgsfield.cpp b/src/core/qgsfield.cpp index 5c9c302772f..1c99491c712 100644 --- a/src/core/qgsfield.cpp +++ b/src/core/qgsfield.cpp @@ -24,7 +24,7 @@ static const char * const ident_ = "$Id$"; - +/* QgsField::QgsField(QString nam, QString typ, int len, int prec, bool num, QString comment) :mName(nam), mType(typ), mLength(len), mPrecision(prec), mNumeric(num), @@ -35,33 +35,40 @@ QgsField::QgsField(QString nam, QString typ, int len, int prec, bool num, // attribute actions getting confused between uppercase and // lowercase versions of the attribute names, so just leave the // names how they are now. +}*/ + +QgsField::QgsField(QString name, QVariant::Type type, QString typeName, int len, int prec, QString comment) + : mName(name), mType(type), mTypeName(typeName), + mLength(len), mPrecision(prec), mComment(comment) +{ } + QgsField::~QgsField() { } -bool QgsField::operator==(const QgsField other) const +bool QgsField::operator==(const QgsField& other) const { - return ((mName == other.mName) && (mType == other.mType) + return ((mName == other.mName) && (mType == other.mType) && (mTypeName == other.mTypeName) && (mLength == other.mLength) && (mPrecision == other.mPrecision)); } -bool QgsField::operator!=(const QgsField other) const -{ - return !(*this == other); -} - -QString const & QgsField::name() const +const QString & QgsField::name() const { return mName; } -QString const & QgsField::type() const +QVariant::Type QgsField::type() const { return mType; } +const QString & QgsField::typeName() const +{ + return mTypeName; +} + int QgsField::length() const { return mLength; @@ -72,25 +79,26 @@ int QgsField::precision() const return mPrecision; } -bool QgsField::isNumeric() const -{ - return mNumeric; -} - -QString const & QgsField::comment() const +const QString & QgsField::comment() const { return mComment; } -void QgsField::setName(QString const & nam) +void QgsField::setName(const QString & nam) { mName = nam; } -void QgsField::setType(QString const & typ) +void QgsField::setType(QVariant::Type type) { - mType = typ; + mType = type; } + +void QgsField::setTypeName(const QString & typeName) +{ + mTypeName = typeName; +} + void QgsField::setLength(int len) { mLength = len; @@ -99,11 +107,8 @@ void QgsField::setPrecision(int prec) { mPrecision = prec; } -void QgsField::setNumeric(bool num) -{ - mNumeric = num; -} -void QgsField::setComment(QString comment) + +void QgsField::setComment(const QString & comment) { mComment = comment; } diff --git a/src/core/qgsfield.h b/src/core/qgsfield.h index 914dcb44334..ece2e9e2d8f 100644 --- a/src/core/qgsfield.h +++ b/src/core/qgsfield.h @@ -17,7 +17,8 @@ #ifndef QGSFIELD_H #define QGSFIELD_H -#include +#include +#include /** \class QgsField @@ -32,25 +33,33 @@ class CORE_EXPORT QgsField public: /** Constructor. Constructs a new QgsField object. * @param nam Field name - * @param typ Field type (eg. char, varchar, text, int, serial, double). + * @param type Field variant type, currently supported: String / Int / Double + * @param typeName Field type (eg. char, varchar, text, int, serial, double). Field types are usually unique to the source and are stored exactly as returned from the data store. * @param len Field length * @param prec Field precision. Usually decimal places but may also be * used in conjunction with other fields types (eg. variable character fields) - * @param num Has to be true if field contains numeric values. + * @param comment Comment for the field */ - QgsField(QString nam = "", QString typ = "", int len = 0, int prec = 0, bool num = false, QString comment = ""); + + QgsField(QString name = QString(), + QVariant::Type type = QVariant::Invalid, + QString typeName = QString(), + int len = 0, + int prec = 0, + QString comment = QString()); //! Destructor ~QgsField(); - bool operator==(const QgsField other) const; - bool operator!=(const QgsField other) const; + bool operator==(const QgsField& other) const; //! Gets the name of the field - QString const & name() const; + const QString & name() const; + //! Gets variant type of the field as it will be retreived from data source + QVariant::Type type() const; /** Gets the field type. Field types vary depending on the data source. Examples @@ -58,7 +67,7 @@ public: the data store reports it, with no attenpt to standardize the value. @return QString containing the field type */ - QString const & type() const; + const QString & typeName() const; /** @@ -74,28 +83,27 @@ public: */ int precision() const; - /** - Returns true if field contains numeric values. This information is set by provider. - */ - bool isNumeric() const; - - /** Returns the field comment */ - QString const & comment() const; + const QString & comment() const; /** Set the field name. @param nam Name of the field */ - void setName(QString const & nam); + void setName(const QString & nam); + + /** + Set variant type. + */ + void setType(QVariant::Type type); /** Set the field type. @param typ Field type */ - void setType(QString const & typ); + void setTypeName(const QString & typ); /** Set the field length. @@ -109,23 +117,22 @@ public: */ void setPrecision(int prec); - /** - Set whether field is numeric - */ - void setNumeric(bool num); /** Set the field comment */ - void setComment(QString comment); + void setComment(const QString & comment); private: //! Name QString mName; + + //! Variant type + QVariant::Type mType; - //! Type - QString mType; + //! Type name from provider + QString mTypeName; //! Length int mLength; @@ -133,9 +140,6 @@ private: //! Precision int mPrecision; - //! Numeric - bool mNumeric; - //! Comment QString mComment; diff --git a/src/core/qgslabel.cpp b/src/core/qgslabel.cpp index dcc74055a8d..fae858fb631 100644 --- a/src/core/qgslabel.cpp +++ b/src/core/qgslabel.cpp @@ -27,7 +27,6 @@ #include "qgis.h" #include "qgsfeature.h" -#include "qgsfeatureattribute.h" #include "qgsgeometry.h" #include "qgsfield.h" #include "qgsrect.h" @@ -51,11 +50,9 @@ QgsLabel::QgsLabel( const QgsFieldMap & fields ) { mField = fields; - mLabelField.resize ( LabelFieldCount ); mLabelFieldIdx.resize ( LabelFieldCount ); for ( int i = 0; i < LabelFieldCount; i++ ) { - mLabelField[i] = ""; mLabelFieldIdx[i] = -1; } mLabelAttributes = new QgsLabelAttributes ( true ); @@ -68,21 +65,22 @@ QgsLabel::~QgsLabel() QString QgsLabel::fieldValue ( int attr, QgsFeature &feature ) { - if ( mLabelField[attr].isEmpty() ) - { - return QString(); - } - - const QgsAttributeMap& attrs = feature.attributeMap(); - QgsAttributeMap::const_iterator it; - - for (it = attrs.begin(); it != attrs.end(); it++) + if (mLabelFieldIdx[attr] == -1) { - if (it.value().fieldName() == mLabelField[attr]) - return it.value().fieldValue(); + return QString(); } - return QString(); + const QgsAttributeMap& attrs = feature.attributeMap(); + QgsAttributeMap::const_iterator it = attrs.find(mLabelFieldIdx[attr]); + + if (it != attrs.end()) + { + return it->toString(); + } + else + { + return QString(); + } } void QgsLabel::renderLabel( QPainter * painter, QgsRect &viewExtent, @@ -426,22 +424,13 @@ QgsFieldMap & QgsLabel::fields ( void ) return mField; } -void QgsLabel::setLabelField ( int attr, const QString str ) +void QgsLabel::setLabelField ( int attr, int fieldIndex ) { if ( attr >= LabelFieldCount ) return; - - mLabelField[attr] = str; - - mLabelFieldIdx[attr] = -1; - for ( int i = 0; i < mField.size(); i++ ) - { - if ( mField[i].name().compare(str) == 0 ) - { - mLabelFieldIdx[attr] = i; - } - } + mLabelFieldIdx[attr] = fieldIndex; + std::cout << "setLabelField: " << attr << " -> " << fieldIndex << std::endl; // %%% } QString QgsLabel::labelField ( int attr ) @@ -449,7 +438,8 @@ QString QgsLabel::labelField ( int attr ) if ( attr > LabelFieldCount ) return QString(); - return mLabelField[attr]; + int fieldIndex = mLabelFieldIdx[attr]; + return mField[fieldIndex].name(); } QgsLabelAttributes *QgsLabel::layerAttributes ( void ) @@ -677,7 +667,7 @@ void QgsLabel::readXML( const QDomNode& node ) { el = scratchNode.toElement(); mLabelAttributes->setText ( el.attribute("text","") ); - setLabelField ( Text, el.attribute("field","") ); + setLabelField ( Text, el.attribute("field","").toInt() ); } /* Family */ @@ -691,7 +681,7 @@ void QgsLabel::readXML( const QDomNode& node ) { el = scratchNode.toElement(); mLabelAttributes->setFamily ( el.attribute("name","") ); - setLabelField ( Family, el.attribute("field","") ); + setLabelField ( Family, el.attribute("field","").toInt() ); } /* Size */ @@ -706,7 +696,7 @@ void QgsLabel::readXML( const QDomNode& node ) el = scratchNode.toElement(); type = QgsLabelAttributes::unitsCode( el.attribute("units","") ); mLabelAttributes->setSize ( el.attribute("value", "0.0").toDouble(), type ); - setLabelField ( Size, el.attribute("field","") ); + setLabelField ( Size, el.attribute("field","").toInt() ); } /* Bold */ @@ -720,7 +710,7 @@ void QgsLabel::readXML( const QDomNode& node ) { el = scratchNode.toElement(); mLabelAttributes->setBold ( (bool)el.attribute("on","0").toInt() ); - setLabelField ( Bold, el.attribute("field","") ); + setLabelField ( Bold, el.attribute("field","").toInt() ); } /* Italic */ @@ -734,7 +724,7 @@ void QgsLabel::readXML( const QDomNode& node ) { el = scratchNode.toElement(); mLabelAttributes->setItalic ( (bool)el.attribute("on","0").toInt() ); - setLabelField ( Italic, el.attribute("field","") ); + setLabelField ( Italic, el.attribute("field","").toInt() ); } /* Underline */ @@ -748,7 +738,7 @@ void QgsLabel::readXML( const QDomNode& node ) { el = scratchNode.toElement(); mLabelAttributes->setUnderline ( (bool)el.attribute("on","0").toInt() ); - setLabelField ( Underline, el.attribute("field","") ); + setLabelField ( Underline, el.attribute("field","").toInt() ); } /* Color */ @@ -768,7 +758,7 @@ void QgsLabel::readXML( const QDomNode& node ) mLabelAttributes->setColor( QColor(red, green, blue) ); - setLabelField ( Color, el.attribute("field","") ); + setLabelField ( Color, el.attribute("field","").toInt() ); } /* X */ @@ -781,7 +771,7 @@ void QgsLabel::readXML( const QDomNode& node ) else { el = scratchNode.toElement(); - setLabelField ( XCoordinate, el.attribute("field","") ); + setLabelField ( XCoordinate, el.attribute("field","").toInt() ); } /* Y */ @@ -794,7 +784,7 @@ void QgsLabel::readXML( const QDomNode& node ) else { el = scratchNode.toElement(); - setLabelField ( YCoordinate, el.attribute("field","") ); + setLabelField ( YCoordinate, el.attribute("field","").toInt() ); } @@ -816,8 +806,8 @@ void QgsLabel::readXML( const QDomNode& node ) yoffset = el.attribute("y","0.0").toDouble(); mLabelAttributes->setOffset ( xoffset, yoffset, type ); - setLabelField ( XOffset, el.attribute("xfield","0") ); - setLabelField ( YOffset, el.attribute("yfield","0") ); + setLabelField ( XOffset, el.attribute("xfield","0").toInt() ); + setLabelField ( YOffset, el.attribute("yfield","0").toInt() ); } /* Angle */ @@ -831,7 +821,7 @@ void QgsLabel::readXML( const QDomNode& node ) { el = scratchNode.toElement(); mLabelAttributes->setAngle ( el.attribute("value","0.0").toDouble() ); - setLabelField ( Angle, el.attribute("field","0.0") ); + setLabelField ( Angle, el.attribute("field","0").toInt() ); } /* Alignment */ @@ -845,7 +835,7 @@ void QgsLabel::readXML( const QDomNode& node ) { el = scratchNode.toElement(); mLabelAttributes->setAlignment ( QgsLabelAttributes::alignmentCode(el.attribute("value","")) ); - setLabelField ( Alignment, el.attribute("field","") ); + setLabelField ( Alignment, el.attribute("field","").toInt() ); } @@ -865,7 +855,7 @@ void QgsLabel::readXML( const QDomNode& node ) blue = el.attribute("blue","0").toInt(); mLabelAttributes->setBufferColor( QColor(red, green, blue) ); - setLabelField ( BufferColor, el.attribute("field","") ); + setLabelField ( BufferColor, el.attribute("field","").toInt() ); } scratchNode = node.namedItem("buffersize"); @@ -880,7 +870,7 @@ void QgsLabel::readXML( const QDomNode& node ) type = QgsLabelAttributes::unitsCode( el.attribute("units","") ); mLabelAttributes->setBufferSize ( el.attribute("value","0.0").toDouble(), type ); - setLabelField ( BufferSize, el.attribute("field","") ); + setLabelField ( BufferSize, el.attribute("field","").toInt() ); } scratchNode = node.namedItem("bufferenabled"); @@ -894,7 +884,7 @@ void QgsLabel::readXML( const QDomNode& node ) el = scratchNode.toElement(); mLabelAttributes->setBufferEnabled ( (bool)el.attribute("on","0").toInt() ); - setLabelField ( BufferEnabled, el.attribute("field","") ); + setLabelField ( BufferEnabled, el.attribute("field","").toInt() ); } } // QgsLabel::readXML() @@ -906,43 +896,60 @@ void QgsLabel::writeXML(std::ostream& xml) xml << "\t\t\n"; - // else - if ( mLabelAttributes->textIsSet() && !mLabelField[Text].isEmpty() ) + // Text + if (mLabelAttributes->textIsSet()) { - xml << "\t\t\t