QgsFeatureAttribute class has been removed and QVariant is used instead (supports arbitrary data types).

All providers and python bindings have been updated accordingly.
Currently supported variant types by providers are String, Int and Double.

Other API changes:
- QgsField
  - type info as QString is now typeName() and setTypeName()
  - added variant type (QVariant::Type) info: type(), setType()
- QgsFeature
  - removed fields() - use QgsVectorDataProvider::fields()
  - removed boundingBox() - use QgsGeometry::boundingBox()
- QgsVectorLayer - removed fields(), fieldCount(), getDefaultValue() - use directly QgsVectorDataProvider
- QgsVectorDataProvider - getDefaultValue() - field now addressed by id, returns variant
- QgsLabel - setLabelField() - field now addressed by id


git-svn-id: http://svn.osgeo.org/qgis/trunk@6833 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
wonder 2007-03-24 22:40:10 +00:00
parent 39f11cf0b1
commit 00a43bc7dc
62 changed files with 731 additions and 2150 deletions

View File

@ -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

View File

@ -22,7 +22,7 @@ class QgsFeature
want a copy of the "current" feature, not the on-disk feature.
*/
QgsFeature( const QgsFeature & rhs,
const QMap<int, QMap<int, QgsFeatureAttribute> >& changedAttributes,
const QMap<int, QMap<int, QVariant> >& changedAttributes,
const QMap<int, QgsGeometry> & 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<int, QgsFeatureAttribute> & attributeMap() const;
const QMap<int, QVariant> & 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<int, QString> 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

View File

@ -1,53 +0,0 @@
/** \class QgsFeatureAttribute - Feature attribute class.
* \brief Encapsulates a single feature attribute.
*@author Gary E.Sherman
*/
class QgsFeatureAttribute
{
%TypeHeaderCode
#include <qgsfeatureattribute.h>
%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

View File

@ -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

View File

@ -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 );

View File

@ -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<int, QMap<int, QgsFeatureAttribute> > & attr_map);
virtual bool changeAttributeValues(const QMap<int, QMap<int, QVariant> > & 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

View File

@ -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<int, QgsField> & 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<int>& deleted,
const QMap<QString, QString>& added,
const QMap<int, QMap<int, QgsFeatureAttribute> >& changed);
const QMap<int, QMap<int, QVariant> >& changed);
/** Draws the layer using coordinate transformation
* @return FALSE if an error occurred during drawing
@ -308,7 +294,7 @@ public:
QSet<int>& deletedFeatureIds();
/** returns array of features with changed attributes */
QMap<int, QMap<int, QgsFeatureAttribute> >& changedAttributes();
QMap<int, QMap<int, QVariant> >& changedAttributes();
/** Sets whether some features are modified or not */
void setModified(bool modified = TRUE, bool onlyGeometryWasModified = FALSE);

View File

@ -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 );
}
}
}

View File

@ -16,12 +16,13 @@
***************************************************************************/
/* $Id$ */
#include "qgsattributedialog.h"
#include "qgsfeatureattribute.h"
#include "qgsfield.h"
#include "qgslogger.h"
#include <QTableWidgetItem>
#include <QSettings>
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;
}

View File

@ -26,12 +26,15 @@
class QDialog;
class QgsFeature;
class QgsField;
typedef QMap<int, QgsField> 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.

View File

@ -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;

View File

@ -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());
}

View File

@ -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");

View File

@ -21,11 +21,13 @@
#define QGSCLIPBOARD_H
#include <QList>
#include <QMap>
class QgsFeature;
class QgsField;
typedef QList<QgsFeature> QgsFeatureList;
typedef QMap<int, QgsField> 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,

View File

@ -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);

View File

@ -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<double>& result
while(provider->getNextFeature(currentFeature, false, attList))
{
currentAttributeMap = currentFeature.attributeMap();
currentValue = currentAttributeMap[attributeIndex].fieldValue().toDouble();
currentValue = currentAttributeMap[attributeIndex].toDouble();
attributeValues[index] = currentValue;
++index;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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()));

View File

@ -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++;
}

View File

@ -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<QgsField> mFields;
//! Map that holds field information, keyed by field name
std::map<QString, QgsField> mFieldMap;
QMap<QString, int> mFieldMap;
};
#endif //QGSSEARCHQUERYBUILDER_H

View File

@ -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())
{

View File

@ -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 += "</th>";
myMetadataQString += "<th bgcolor=\"black\">";
myMetadataQString += "<font color=\"white\">" + tr("Comment") + "</font>";
myMetadataQString += "</th>";
myMetadataQString += "</th>";
myMetadataQString += "<tr>";
//get info for each field by looping through them
@ -547,7 +547,7 @@ QString QgsVectorLayerProperties::getMetadata()
myMetadataQString += myField.name();
myMetadataQString += "</td>";
myMetadataQString += "<td bgcolor=\"white\">";
myMetadataQString += myField.type();
myMetadataQString += myField.typeName();
myMetadataQString += "</td>";
myMetadataQString += "<td bgcolor=\"white\">";
myMetadataQString += QString("%1").arg(myField.length());

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -19,14 +19,14 @@ email : sherman at mrcc.com
#include <QMap>
#include <QString>
#include <QVariant>
class QgsFeatureAttribute;
class QgsGeometry;
class QgsRect;
// key = field index, value = field name and attribute value
typedef QMap<int, QgsFeatureAttribute> QgsAttributeMap;
// key = field index, value = field value
typedef QMap<int, QVariant> QgsAttributeMap;
// key = feature id, value = changed attributes
typedef QMap<int, QgsAttributeMap> 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

View File

@ -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;
}

View File

@ -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 <qstring.h>
/** \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

View File

@ -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;
}

View File

@ -17,7 +17,8 @@
#ifndef QGSFIELD_H
#define QGSFIELD_H
#include <qstring.h>
#include <QString>
#include <QVariant>
/**
\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;

View File

@ -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<labelattributes>\n";
// else
if ( mLabelAttributes->textIsSet() && !mLabelField[Text].isEmpty() )
// Text
if (mLabelAttributes->textIsSet())
{
xml << "\t\t\t<label text=\"" << (const char*)(mLabelAttributes->text().utf8()) << "\" field=\"" << (const char*)(mLabelField[Text].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->textIsSet() )
{
xml << "\t\t\t<label text=\"" << (const char*)(mLabelAttributes->text().utf8()) << "\" field=\"\" />\n";
if (mLabelFieldIdx[Text] != -1)
{
xml << "\t\t\t<label text=\"" << (const char*)(mLabelAttributes->text().utf8())
<< "\" field=\"" << mLabelFieldIdx[Text] << "\" />\n";
}
else
{
xml << "\t\t\t<label text=\"" << (const char*)(mLabelAttributes->text().utf8())
<< "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<label text=\"" << (const char*)(mLabelAttributes->text().utf8()) << "\" field=\"" << (const char*)(mLabelField[Text].utf8()) << "\" />\n";
xml << "\t\t\t<label text=\"" << (const char*)(mLabelAttributes->text().utf8())
<< "\" field=\"\" />\n";
}
if ( mLabelAttributes->familyIsSet() && ! mLabelAttributes->family().isNull() && mLabelField[Family].isNull())
// Family
if (mLabelAttributes->familyIsSet() && !mLabelAttributes->family().isNull())
{
xml << "\t\t\t<family name=\"" << mLabelAttributes->family().utf8().data() << "\" field=\"" << (const char*)(mLabelField[Family].utf8().data()) << "\" />\n";
}
else if ( mLabelAttributes->familyIsSet() && ! mLabelAttributes->family().isNull() )
{
xml << "\t\t\t<family name=\"" << mLabelAttributes->family().utf8().data() << "\" field=\"\" />\n";
if (mLabelFieldIdx[Family] != -1)
{
xml << "\t\t\t<family name=\"" << mLabelAttributes->family().utf8().data()
<< "\" field=\"" << mLabelFieldIdx[Family] << "\" />\n";
}
else
{
xml << "\t\t\t<family name=\"" << mLabelAttributes->family().utf8().data()
<< "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<family name=\"Arial\" field=\"\" />\n";
}
//size and units
if ( mLabelAttributes->sizeIsSet() && !mLabelField[Size].isEmpty())
// size and units
if (mLabelAttributes->sizeIsSet())
{
xml << "\t\t\t<size value=\"" << mLabelAttributes->size() << "\" units=\""
<< (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->sizeType()).utf8() << "\" field=\"" << (const char*)(mLabelField[Size].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->sizeIsSet() )
{
xml << "\t\t\t<size value=\"" << mLabelAttributes->size() << "\" units=\""
<< (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->sizeType()).utf8() << "\" field=\"\" />\n";
if (mLabelFieldIdx[Size] != -1)
{
xml << "\t\t\t<size value=\"" << mLabelAttributes->size()
<< "\" units=\"" << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->sizeType()).utf8()
<< "\" field=\"" << mLabelFieldIdx[Size] << "\" />\n";
}
else
{
xml << "\t\t\t<size value=\"" << mLabelAttributes->size()
<< "\" units=\"" << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->sizeType()).utf8()
<< "\" field=\"\" />\n";
}
}
else
{
@ -950,57 +957,80 @@ void QgsLabel::writeXML(std::ostream& xml)
}
//bold
if ( mLabelAttributes->boldIsSet() && !mLabelField[Bold].isEmpty() )
// bold
if (mLabelAttributes->boldIsSet())
{
xml << "\t\t\t<bold on=\"" << mLabelAttributes->bold() << "\" field=\"" << (const char*)(mLabelField[Bold].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->boldIsSet() )
{
xml << "\t\t\t<bold on=\"" << mLabelAttributes->bold() << "\" field=\"\" />\n";
if (mLabelFieldIdx[Bold] != -1)
{
xml << "\t\t\t<bold on=\"" << mLabelAttributes->bold()
<< "\" field=\"" << mLabelFieldIdx[Bold] << "\" />\n";
}
else
{
xml << "\t\t\t<bold on=\"" << mLabelAttributes->bold()
<< "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<bold on=\"0\" field=\"0\" />\n";
}
//italics
if ( mLabelAttributes->italicIsSet() && ! mLabelField[Italic].isEmpty())
// italics
if (mLabelAttributes->italicIsSet())
{
xml << "\t\t\t<italic on=\"" << mLabelAttributes->italic() << "\" field=\"" << (const char*)(mLabelField[Italic].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->italicIsSet() )
{
xml << "\t\t\t<italic on=\"" << mLabelAttributes->italic() << "\" field=\"\" />\n";
if (mLabelFieldIdx[Italic] != -1)
{
xml << "\t\t\t<italic on=\"" << mLabelAttributes->italic()
<< "\" field=\"" << mLabelFieldIdx[Italic] << "\" />\n";
}
else
{
xml << "\t\t\t<italic on=\"" << mLabelAttributes->italic()
<< "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<italic on=\"0\" field=\"\" />\n";
}
//underline
if ( mLabelAttributes->underlineIsSet() && !mLabelField[Underline].isEmpty())
// underline
if (mLabelAttributes->underlineIsSet())
{
xml << "\t\t\t<underline on=\"" << mLabelAttributes->underline() << "\" field=\"" << (const char*)(mLabelField[Underline].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->underlineIsSet() )
{
xml << "\t\t\t<underline on=\"" << mLabelAttributes->underline() << "\" field=\"\" />\n";
if (mLabelFieldIdx[Underline] != -1)
{
xml << "\t\t\t<underline on=\"" << mLabelAttributes->underline()
<< "\" field=\"" << mLabelFieldIdx[Underline] << "\" />\n";
}
else
{
xml << "\t\t\t<underline on=\"" << mLabelAttributes->underline()
<< "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<underline on=\"0\" field=\"\" />\n";
}
if ( mLabelAttributes->colorIsSet() && ! mLabelField[Color].isNull() )
// color
if (mLabelAttributes->colorIsSet())
{
xml << "\t\t\t<color red=\"" << mLabelAttributes->color().red() << "\" green=\"" << mLabelAttributes->color().green()
<< "\" blue=\"" << mLabelAttributes->color().blue() << "\" field=\"" << (const char*)(mLabelField[Color].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->colorIsSet() )
{
xml << "\t\t\t<color red=\"" << mLabelAttributes->color().red() << "\" green=\"" << mLabelAttributes->color().green()
<< "\" blue=\"" << mLabelAttributes->color().blue() << "\" field=\"\" />\n";
if (mLabelFieldIdx[Color] != -1)
{
xml << "\t\t\t<color red=\"" << mLabelAttributes->color().red()
<< "\" green=\"" << mLabelAttributes->color().green()
<< "\" blue=\"" << mLabelAttributes->color().blue()
<< "\" field=\"" << mLabelFieldIdx[Color] << "\" />\n";
}
else
{
xml << "\t\t\t<color red=\"" << mLabelAttributes->color().red()
<< "\" green=\"" << mLabelAttributes->color().green()
<< "\" blue=\"" << mLabelAttributes->color().blue()
<< "\" field=\"\" />\n";
}
}
else
{
@ -1009,97 +1039,116 @@ void QgsLabel::writeXML(std::ostream& xml)
/* X */
if (! mLabelField[XCoordinate].isEmpty() )
if (mLabelFieldIdx[XCoordinate] != -1)
{
xml << "\t\t\t<x field=\"" << (const char*)(mLabelField[XCoordinate].utf8()) << "\" />\n";
xml << "\t\t\t<x field=\"" << mLabelFieldIdx[XCoordinate] << "\" />\n";
}
else
{
xml << "\t\t\t<x field=\"" << "\" />\n";
xml << "\t\t\t<x field=\"\" />\n";
}
/* Y */
if (! mLabelField[YCoordinate].isEmpty() )
if (mLabelFieldIdx[YCoordinate] != -1)
{
xml << "\t\t\t<y field=\"" << (const char*)(mLabelField[YCoordinate].utf8()) << "\" />\n";
xml << "\t\t\t<y field=\"" << mLabelFieldIdx[YCoordinate] << "\" />\n";
}
else
{
xml << "\t\t\t<y field=\"" << "\" />\n";
xml << "\t\t\t<y field=\"\" />\n";
}
// offset
if ( mLabelAttributes->offsetIsSet() )
{
xml << "\t\t\t<offset units=\"" << QgsLabelAttributes::unitsName(mLabelAttributes->offsetType()).utf8().data()
<< "\" x=\"" << mLabelAttributes->xOffset() << "\" xfield=\"" << (const char*)(mLabelField[XOffset].utf8().data())
<< "\" y=\"" << mLabelAttributes->yOffset() << "\" yfield=\"" << (const char*)(mLabelField[YOffset].utf8().data())
<< "\" x=\"" << mLabelAttributes->xOffset() << "\" xfield=\"" << mLabelFieldIdx[XOffset]
<< "\" y=\"" << mLabelAttributes->yOffset() << "\" yfield=\"" << mLabelFieldIdx[YOffset]
<< "\" />\n";
}
// Angle
if ( mLabelAttributes->angleIsSet() )
{
xml << "\t\t\t<angle value=\"" << mLabelAttributes->angle() << "\" field=\"" << (const char*)(mLabelField[Angle].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->angleIsSet() )
{
xml << "\t\t\t<angle value=\"" << mLabelAttributes->angle() << "\" field=\"" << "\" />\n";
if (mLabelFieldIdx[Angle] != -1)
{
xml << "\t\t\t<angle value=\"" << mLabelAttributes->angle()
<< "\" field=\"" << mLabelFieldIdx[Angle] << "\" />\n";
}
else
{
xml << "\t\t\t<angle value=\"" << mLabelAttributes->angle() << "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<angle value=\"" << "\" field=\"" << "\" />\n";
xml << "\t\t\t<angle value=\"\" field=\"\" />\n";
}
// alignment
if ( mLabelAttributes->alignmentIsSet() )
{
xml << "\t\t\t<alignment value=\"" << QgsLabelAttributes::alignmentName(mLabelAttributes->alignment()).utf8().data()
<< "\" field=\"" << (const char*)(mLabelField[Alignment].utf8().data()) << "\" />\n";
<< "\" field=\"" << mLabelFieldIdx[Alignment] << "\" />\n";
}
if ( mLabelAttributes->bufferColorIsSet() && ! mLabelField[BufferColor].isNull() )
// buffer color
if (mLabelAttributes->bufferColorIsSet())
{
xml << "\t\t\t<buffercolor red=\"" << mLabelAttributes->bufferColor().red() << "\" green=\"" << mLabelAttributes->bufferColor().green()
<< "\" blue=\"" << mLabelAttributes->bufferColor().blue() << "\" field=\"" << (const char*)(mLabelField[BufferColor].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->bufferColorIsSet() )
{
xml << "\t\t\t<buffercolor red=\"" << mLabelAttributes->bufferColor().red() << "\" green=\"" << mLabelAttributes->bufferColor().green()
<< "\" blue=\"" << mLabelAttributes->bufferColor().blue() << "\" field=\"" << "\" />\n";
if (mLabelFieldIdx[BufferColor] != -1)
{
xml << "\t\t\t<buffercolor red=\"" << mLabelAttributes->bufferColor().red()
<< "\" green=\"" << mLabelAttributes->bufferColor().green()
<< "\" blue=\"" << mLabelAttributes->bufferColor().blue()
<< "\" field=\"" << mLabelFieldIdx[BufferColor] << "\" />\n";
}
else
{
xml << "\t\t\t<buffercolor red=\"" << mLabelAttributes->bufferColor().red()
<< "\" green=\"" << mLabelAttributes->bufferColor().green()
<< "\" blue=\"" << mLabelAttributes->bufferColor().blue()
<< "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<buffercolor red=\"" << "\" green=\""
<< "\" blue=\"" << "\" field=\"" << "\" />\n";
xml << "\t\t\t<buffercolor red=\"\" green=\"\" blue=\"\" field=\"\" />\n";
}
if ( mLabelAttributes->bufferSizeIsSet() && ! mLabelField[BufferSize].isNull() )
// buffer size
if (mLabelAttributes->bufferSizeIsSet())
{
xml << "\t\t\t<buffersize value=\"" << mLabelAttributes->bufferSize() << "\" units=\""
<< (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->bufferSizeType()).utf8() << "\" field=\"" << (const char*)(mLabelField[BufferSize].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->bufferSizeIsSet() )
{
xml << "\t\t\t<buffersize value=\"" << mLabelAttributes->bufferSize() << "\" units=\""
<< (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->bufferSizeType()).utf8() << "\" field=\"" << "\" />\n";
if (mLabelFieldIdx[BufferSize] != -1)
{
xml << "\t\t\t<buffersize value=\"" << mLabelAttributes->bufferSize()
<< "\" units=\"" << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->bufferSizeType()).utf8()
<< "\" field=\"" << mLabelFieldIdx[BufferSize] << "\" />\n";
}
else
{
xml << "\t\t\t<buffersize value=\"" << mLabelAttributes->bufferSize()
<< "\" units=\"" << (const char *)QgsLabelAttributes::unitsName(mLabelAttributes->bufferSizeType()).utf8()
<< "\" field=\"\" />\n";
}
}
else
{
xml << "\t\t\t<buffersize value=\"" << "\" units=\""
<< "\" field=\"" << "\" />\n";
xml << "\t\t\t<buffersize value=\"\" units=\"\" field=\"\" />\n";
}
if ( mLabelAttributes->bufferEnabled() && ! mLabelField[BufferEnabled].isNull() )
// buffer enabled
if (mLabelAttributes->bufferEnabled())
{
xml << "\t\t\t<bufferenabled on=\"" << mLabelAttributes->bufferEnabled() << "\" field=\"" << (const char*)(mLabelField[BufferEnabled].utf8()) << "\" />\n";
}
else if ( mLabelAttributes->bufferEnabled())
{
xml << "\t\t\t<bufferenabled on=\"" << mLabelAttributes->bufferEnabled() << "\" field=\"" << "\" />\n";
if (mLabelFieldIdx[BufferEnabled] != -1)
{
xml << "\t\t\t<bufferenabled on=\"" << mLabelAttributes->bufferEnabled()
<< "\" field=\"" << mLabelFieldIdx[BufferEnabled] << "\" />\n";
}
else
{
xml << "\t\t\t<bufferenabled on=\"" << mLabelAttributes->bufferEnabled()
<< "\" field=\"\" />\n";
}
}
else
{

View File

@ -104,7 +104,7 @@ public:
QgsLabelAttributes *layerAttributes ( void );
//! Set label field
void setLabelField ( int attr, const QString str );
void setLabelField ( int attr, int fieldIndex );
//! label field
QString labelField ( int attr );

View File

@ -23,7 +23,6 @@
#include <QFileInfo>
#include <QSettings> // TODO: get rid of it [MD]
#include "qgsfield.h"
#include "qgslogger.h"
#include "qgsmaptopixel.h"
#include "qgsrect.h"

View File

@ -18,9 +18,10 @@
/* $Id$ */
#include "qgslogger.h"
#include "qgsfield.h"
#include "qgssearchtreenode.h"
#include <qregexp.h>
#include <qobject.h>
#include <QRegExp>
#include <QObject>
#include <iostream>
@ -180,7 +181,7 @@ QString QgsSearchTreeNode::makeSearchString()
}
bool QgsSearchTreeNode::checkAgainst(const QgsAttributeMap& attributes)
bool QgsSearchTreeNode::checkAgainst(const QgsFieldMap& fields, const QgsAttributeMap& attributes)
{
QgsDebugMsgLevel("checkAgainst: " + makeSearchString(), 2);
@ -199,17 +200,17 @@ bool QgsSearchTreeNode::checkAgainst(const QgsAttributeMap& attributes)
switch (mOp)
{
case opNOT:
return !mLeft->checkAgainst(attributes);
return !mLeft->checkAgainst(fields, attributes);
case opAND:
if (!mLeft->checkAgainst(attributes))
if (!mLeft->checkAgainst(fields, attributes))
return false;
return mRight->checkAgainst(attributes);
return mRight->checkAgainst(fields, attributes);
case opOR:
if (mLeft->checkAgainst(attributes))
if (mLeft->checkAgainst(fields, attributes))
return true;
return mRight->checkAgainst(attributes);
return mRight->checkAgainst(fields, attributes);
case opEQ:
case opNE:
@ -218,7 +219,7 @@ bool QgsSearchTreeNode::checkAgainst(const QgsAttributeMap& attributes)
case opGE:
case opLE:
if (!getValue(value1, mLeft, attributes) || !getValue(value2, mRight, attributes))
if (!getValue(value1, mLeft, fields, attributes) || !getValue(value2, mRight, fields, attributes))
return false;
res = QgsSearchTreeValue::compare(value1, value2);
@ -239,7 +240,7 @@ bool QgsSearchTreeNode::checkAgainst(const QgsAttributeMap& attributes)
case opRegexp:
case opLike:
{
if (!getValue(value1, mLeft, attributes) || !getValue(value2, mRight, attributes))
if (!getValue(value1, mLeft, fields, attributes) || !getValue(value2, mRight, fields, attributes))
return false;
// value1 is string to be matched
@ -277,9 +278,9 @@ bool QgsSearchTreeNode::checkAgainst(const QgsAttributeMap& attributes)
return false; // will never get there
}
bool QgsSearchTreeNode::getValue(QgsSearchTreeValue& value, QgsSearchTreeNode* node, const QgsAttributeMap& attributes)
bool QgsSearchTreeNode::getValue(QgsSearchTreeValue& value, QgsSearchTreeNode* node, const QgsFieldMap& fields, const QgsAttributeMap& attributes)
{
value = node->valueAgainst(attributes);
value = node->valueAgainst(fields, attributes);
if (value.isError())
{
switch ((int)value.number())
@ -310,7 +311,7 @@ bool QgsSearchTreeNode::getValue(QgsSearchTreeValue& value, QgsSearchTreeNode* n
return true;
}
QgsSearchTreeValue QgsSearchTreeNode::valueAgainst(const QgsAttributeMap& attributes)
QgsSearchTreeValue QgsSearchTreeNode::valueAgainst(const QgsFieldMap& fields, const QgsAttributeMap& attributes)
{
QgsDebugMsgLevel("valueAgainst: " + makeSearchString(), 2);
@ -328,37 +329,42 @@ QgsSearchTreeValue QgsSearchTreeNode::valueAgainst(const QgsAttributeMap& attrib
case tColumnRef:
{
QgsDebugMsgLevel("column (" + mText.lower() + "): ", 2);
// find value for the column
QgsAttributeMap::const_iterator it;
for (it = attributes.begin(); it != attributes.end(); it++)
// find field index for the column
QgsFieldMap::const_iterator it;
for (it = fields.begin(); it != fields.end(); it++)
{
if ( it->fieldName().lower() == mText.lower()) // TODO: optimize
{
QString value = it->fieldValue();
if (it->isNumeric())
{
QgsDebugMsgLevel(" number: " + QString::number(value.toDouble()), 2);
return QgsSearchTreeValue(value.toDouble());
}
else
{
QgsDebugMsgLevel(" text: " + EVAL_STR(value), 2);
return QgsSearchTreeValue(value);
}
}
if ( it->name().lower() == mText.lower()) // TODO: optimize
break;
}
// else report missing column
QgsDebugMsgLevel("ERROR!", 2);
return QgsSearchTreeValue(1, mText);
if (it == fields.end())
{
// report missing column if not found
QgsDebugMsgLevel("ERROR!", 2);
return QgsSearchTreeValue(1, mText);
}
// get the value
QVariant val = attributes[it.key()];
if (val.type() == QVariant::Bool || val.type() == QVariant::Int || val.type() == QVariant::Double)
{
QgsDebugMsgLevel(" number: " + QString::number(val.toDouble()), 2);
return QgsSearchTreeValue(val.toDouble());
}
else
{
QgsDebugMsgLevel(" text: " + EVAL_STR(val.toString()), 2);
return QgsSearchTreeValue(val.toString());
}
}
// arithmetic operators
case tOperator:
{
QgsSearchTreeValue value1, value2;
if (!getValue(value1, mLeft, attributes)) return value1;
if (!getValue(value2, mRight, attributes)) return value2;
if (!getValue(value1, mLeft, fields, attributes)) return value1;
if (!getValue(value2, mRight, fields, attributes)) return value2;
// convert to numbers if needed
double val1, val2;

View File

@ -22,14 +22,13 @@
#include <QMap>
#include <QString>
#include "qgsfeatureattribute.h"
// forward declaration due recursive declaration
class QgsFeatureAttribute;
#include <QVariant>
class QgsSearchTreeValue;
class QgsField;
typedef QMap<int, QgsFeatureAttribute> QgsAttributeMap;
typedef QMap<int, QgsField> QgsFieldMap;
typedef QMap<int, QVariant> QgsAttributeMap;
/**
* QgsSearchTreeNode
@ -112,7 +111,7 @@ public:
QString makeSearchString();
//! checks whether the node tree is valid against supplied attributes
bool checkAgainst(const QgsAttributeMap& attributes);
bool checkAgainst(const QgsFieldMap& fields, const QgsAttributeMap& attributes);
//! checks if there were errors during evaluation
bool hasError() { return (!mError.isEmpty()); }
@ -123,11 +122,11 @@ public:
protected:
//! returns scalar value of node
QgsSearchTreeValue valueAgainst(const QgsAttributeMap& attributes);
QgsSearchTreeValue valueAgainst(const QgsFieldMap& fields, const QgsAttributeMap& attributes);
//! wrapper around valueAgainst()
bool getValue(QgsSearchTreeValue& value, QgsSearchTreeNode* node,
const QgsAttributeMap& attributes);
const QgsFieldMap& fields, const QgsAttributeMap& attributes);
//! strips mText when node is of string type
void stripText();

View File

@ -89,9 +89,9 @@ bool QgsVectorDataProvider::changeAttributeValues(const QgsChangedAttributesMap
return false;
}
QString QgsVectorDataProvider::getDefaultValue(const QString& attr, QgsFeature* f)
QVariant QgsVectorDataProvider::getDefaultValue(int fieldId)
{
return "";
return QVariant();
}
bool QgsVectorDataProvider::changeGeometryValues(QgsGeometryMap & geometry_map)
@ -221,7 +221,7 @@ int QgsVectorDataProvider::indexFromFieldName(const QString& fieldName) const
for (QgsFieldMap::const_iterator it = theFields.begin(); it != theFields.end(); ++it)
{
if(*it == fieldName)
if(it->name() == fieldName)
{
return counter;
}

View File

@ -217,9 +217,9 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider
virtual bool changeAttributeValues(const QgsChangedAttributesMap & 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

View File

@ -20,7 +20,6 @@
#include "qgsapplication.h"
#include "qgsfield.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgslogger.h"
#include "qgsspatialrefsys.h"
#include "qgsvectorfilewriter.h"
@ -483,7 +482,7 @@ QString QgsVectorFileWriter::writeVectorLayerAsShapefile(QString shapefileName,
QgsDebugMsg("created layer");
const QgsFieldMap & attributeFields = layer->fields();
const QgsFieldMap & attributeFields = layer->getDataProvider()->fields();
// TODO: calculate the field lengths
//int *lengths = getFieldLengths();
@ -536,7 +535,7 @@ QString QgsVectorFileWriter::writeVectorLayerAsShapefile(QString shapefileName,
for (it = attributes.begin(); it != attributes.end(); it++)
{
QString value = it.value().fieldValue();
QString value = it.value().toString();
uint i = it.key();
if (!value.isNull())
{

View File

@ -53,7 +53,6 @@
#include "qgsapplication.h"
#include "qgscoordinatetransform.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgsgeometryvertexindex.h"
@ -1063,7 +1062,7 @@ QgsRect QgsVectorLayer::boundingBoxOfSelected()
{
if(fet.geometry())
{
r=fet.boundingBox();
r=fet.geometry()->boundingBox();
retval.combineExtentWith(&r);
}
}
@ -1196,7 +1195,7 @@ void QgsVectorLayer::updateExtents()
{
if (fet.geometry())
{
bb = fet.boundingBox();
bb = fet.geometry()->boundingBox();
mLayerExtent.combineExtentWith(&bb);
}
}
@ -1211,7 +1210,7 @@ void QgsVectorLayer::updateExtents()
// also consider the not commited features
for(QgsFeatureList::iterator iter = mAddedFeatures.begin(); iter != mAddedFeatures.end(); ++iter)
{
QgsRect bb = (*iter).boundingBox();
QgsRect bb = iter->geometry()->boundingBox();
mLayerExtent.combineExtentWith(&bb);
}
@ -1250,29 +1249,6 @@ void QgsVectorLayer::setSubsetString(QString subset)
emit recalculateExtents();
}
int QgsVectorLayer::fieldCount() const
{
if ( ! mDataProvider )
{
QgsLogger::warning(" QgsVectorLayer::fieldCount() invoked with null mDataProvider");
return 0;
}
return mDataProvider->fieldCount();
} // QgsVectorLayer::fieldCount
const QgsFieldMap & QgsVectorLayer::fields() const
{
if ( ! mDataProvider )
{
QgsLogger::warning(" QgsVectorLayer::fields() invoked with null mDataProvider");
assert(false);
}
return mDataProvider->fields();
} // QgsVectorLayer::fields()
bool QgsVectorLayer::addFeature(QgsFeature& f, bool alsoUpdateExtent)
{
@ -1298,18 +1274,6 @@ bool QgsVectorLayer::addFeature(QgsFeature& f, bool alsoUpdateExtent)
QgsDebugMsg("Assigned feature id " + QString::number(addedIdLowWaterMark));
// Change the fields on the feature to suit the destination
// in the paste transformation transfer.
// TODO: Could be done more efficiently for large pastes
QgsFieldNameMap fields = f.fields();
QgsDebugMsg("QgsVectorLayer::addFeature: about to traverse fields.");
for (QgsFieldNameMap::iterator it = fields.begin(); it != fields.end(); ++it)
{
QgsDebugMsg("QgsVectorLayer::addFeature: inspecting field '" + *it + "'.");
}
// Force a feature ID (to keep other functions in QGIS happy,
// providers will use their own new feature ID when we commit the new feature)
// and add to the known added features.
@ -1417,12 +1381,6 @@ bool QgsVectorLayer::deleteVertexAt(int atFeatureId,
}
QString QgsVectorLayer::getDefaultValue(const QString& attr,
QgsFeature* f)
{
return mDataProvider->getDefaultValue(attr, f);
}
bool QgsVectorLayer::deleteSelectedFeatures()
{
if(!(mDataProvider->capabilities() & QgsVectorDataProvider::DeleteFeatures))

View File

@ -210,16 +210,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 QgsFieldMap & fields() const;
/** Adds a feature
@param lastFeatureInBatch If True, will also go to the effort of e.g. updating the extents.
@ -253,8 +243,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 );

View File

@ -17,7 +17,6 @@
/* $Id: qgscontinuouscolorrenderer.cpp 5371 2006-04-25 01:52:13Z wonder $ */
#include "qgscontinuouscolorrenderer.h"
#include "qgsfeatureattribute.h"
#include "qgsmarkercatalogue.h"
#include "qgssymbol.h"
#include "qgssymbologyutils.h"
@ -80,7 +79,7 @@ void QgsContinuousColorRenderer::renderFeature(QPainter * p, QgsFeature & f, QIm
{
//first find out the value for the classification attribute
const QgsAttributeMap& attrs = f.attributeMap();
double fvalue = attrs[mClassificationField].fieldValue().toDouble();
double fvalue = attrs[mClassificationField].toDouble();
//double fvalue = vec[mClassificationField].fieldValue().toDouble();
double minvalue = mMinimumSymbol->lowerValue().toDouble();

View File

@ -19,7 +19,6 @@
#include "qgis.h"
#include "qgslogger.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgsgraduatedsymbolrenderer.h"
#include "qgssymbol.h"
#include "qgssymbologyutils.h"
@ -148,7 +147,7 @@ QgsSymbol* QgsGraduatedSymbolRenderer::symbolForFeature(const QgsFeature* f)
{
//first find out the value for the classification attribute
const QgsAttributeMap& attrs = f->attributeMap();
double value = attrs[mClassificationField].fieldValue().toDouble();
double value = attrs[mClassificationField].toDouble();
std::list < QgsSymbol* >::iterator it;
//find the first render item which contains the feature

View File

@ -17,7 +17,6 @@
/* $Id: qgsuniquevaluerenderer.cpp 5371 2006-04-25 01:52:13Z wonder $ */
#include "qgsuniquevaluerenderer.h"
#include "qgsfeatureattribute.h"
#include "qgsfeature.h"
#include "qgsvectorlayer.h"
#include "qgssymbol.h"
@ -154,7 +153,7 @@ QgsSymbol* QgsUniqueValueRenderer::symbolForFeature(const QgsFeature* f)
{
//first find out the value
const QgsAttributeMap& attrs = f->attributeMap();
QString value = attrs[mClassificationField].fieldValue();
QString value = attrs[mClassificationField].toString();
std::map<QString,QgsSymbol*>::iterator it=mSymbols.find(value);
if(it == mSymbols.end())

View File

@ -140,7 +140,7 @@ void QgsPgGeoprocessing::buffer()
QgsFieldMap flds = dp->fields();
for (QgsFieldMap::iterator it = flds.begin(); it != flds.end(); ++it) {
// check the field type -- if its int we can use it
if (it->type().find("int") > -1) {
if (it->typeName().find("int") > -1) {
bb->addFieldItem(it->name());
}
}

View File

@ -45,7 +45,6 @@
#include "qgsvectorlayer.h"
#include "qgsdataprovider.h"
#include "qgsmaptopixel.h"
#include "qgsfeatureattribute.h"
extern "C" {
#include <grass/gis.h>

View File

@ -55,7 +55,6 @@
#include "qgsmaptoolpan.h"
#include "qgsmaptopixel.h"
#include "qgsfield.h"
#include "qgsfeatureattribute.h"
#include "qgsvertexmarker.h"
#include "qgsrubberband.h"
#include "qgsproject.h"
@ -576,7 +575,7 @@ void QgsGrassEdit::setAttributeTable ( int field )
ti->setEnabled( false );
mAttributeTable->setItem ( c, 0, ti );
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, col.type() );
ti = new Q3TableItem( mAttributeTable, Q3TableItem::Never, col.typeName() );
ti->setEnabled( false );
mAttributeTable->setItem ( c, 1, ti );
@ -1081,9 +1080,9 @@ int QgsGrassEdit::writeLine ( int type, struct line_pnts *Points )
QString *key = mProvider->key ( field );
if ( !key->isEmpty() ) { // Database link defined
std::vector<QgsFeatureAttribute> *atts = mProvider->attributes ( field, cat );
QgsAttributeMap *atts = mProvider->attributes ( field, cat );
if ( atts->size() == 0 ) { // Nothing selected
if ( atts->count() == 0 ) { // Nothing selected
QString *error = mProvider->insertAttributes ( field, cat );
if ( !error->isEmpty() ) {
@ -1398,26 +1397,25 @@ void QgsGrassEdit::addAttributes ( int field, int cat )
str.setNum( field );
QMessageBox::warning( 0, tr("Warning"), tr("Cannot describe table for field ") + str );
} else {
std::vector<QgsFeatureAttribute> *atts =
mProvider->attributes ( field, cat );
QgsAttributeMap *atts = mProvider->attributes ( field, cat );
if ( atts->size() == 0 ) { // cannot select attributes
mAttributes->addTextRow ( tab, "WARNING: ATTRIBUTES MISSING" );
} else {
int size;
if ( atts->size() < cols->size() )
if ( atts->size() < (int) cols->size() )
size = atts->size();
else
size = cols->size();
for ( unsigned int j = 0; j < cols->size(); j++ ) {
QgsField col = (*cols)[j];
QgsFeatureAttribute att = (*atts)[j];
QVariant att = (*atts)[j];
std::cerr << " name = " << col.name().toLocal8Bit().data() << std::endl;
if ( col.name() != *key ) {
std::cerr << " value = " << att.fieldValue().toLocal8Bit().data() << std::endl;
mAttributes->addAttribute ( tab, col.name(), att.fieldValue(), col.type() );
std::cerr << " value = " << att.toString().toLocal8Bit().data() << std::endl;
mAttributes->addAttribute ( tab, col.name(), att.toString(), col.typeName() );
}
}
}
@ -1448,7 +1446,7 @@ void QgsGrassEdit::addCat ( int line )
QString *key = mProvider->key ( field );
if ( !key->isEmpty() ) { // Database link defined
std::vector<QgsFeatureAttribute> *atts = mProvider->attributes ( field, cat );
QgsAttributeMap *atts = mProvider->attributes ( field, cat );
if ( atts->size() == 0 ) { // Nothing selected
QString *error = mProvider->insertAttributes ( field, cat );

View File

@ -52,7 +52,6 @@
#include "qgsvectorlayer.h"
#include "qgsdataprovider.h"
#include "qgsfield.h"
#include "qgsfeatureattribute.h"
extern "C" {
#include <grass/gis.h>

View File

@ -35,7 +35,6 @@
#include "qgis.h"
#include "qgsapplication.h"
#include "qgsfeatureattribute.h" // TODO: remove - this is only for qgsgrassprovider.h
extern "C" {
#include <grass/gis.h>

View File

@ -78,7 +78,6 @@
#include "qgsdataprovider.h"
#include "qgsfield.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
extern "C" {
#include <grass/gis.h>
@ -2328,7 +2327,7 @@ void QgsGrassModuleInput::updateQgisLayers()
mVectorLayerNames.push_back ( grassLayer );
// convert from QgsFieldMap to std::vector<QgsField>
QgsFieldMap flds = vector->fields();
QgsFieldMap flds = vector->getDataProvider()->fields();
std::vector<QgsField> fields;
for (QgsFieldMap::iterator it = flds.begin(); it != flds.end(); ++it)
fields.push_back(it.value());
@ -2915,7 +2914,7 @@ void QgsGrassModuleSelection::updateSelection()
if ( attr.size() > keyField )
{
if ( i > 0 ) cats.append( "," );
cats.append( attr[keyField].fieldValue() );
cats.append( attr[keyField].toString() );
i++;
}
delete feature;

View File

@ -22,7 +22,6 @@
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"
#include "qgsdataprovider.h"
#include "qgsfeatureattribute.h"
#include "qgsproviderregistry.h"
#include <qgsrasterlayer.h>

View File

@ -56,7 +56,6 @@
#include "qgsvectorlayer.h"
#include "qgsdataprovider.h"
#include "qgsfield.h"
#include "qgsfeatureattribute.h"
extern "C" {
#include <grass/gis.h>

View File

@ -35,7 +35,6 @@
#include "qgsapplication.h"
#include "qgsdataprovider.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgsfield.h"
#include "qgsmessageoutput.h"
#include "qgsrect.h"
@ -145,7 +144,7 @@ QgsDelimitedTextProvider::QgsDelimitedTextProvider(QString uri)
QString field = *it;
if (field.length() > 0)
{
attributeFields[fieldPos] = QgsField(*it, "Text");
attributeFields[fieldPos] = QgsField(*it, QVariant::String, "Text");
fieldPositions[*it] = fieldPos++;
// check to see if this field matches either the x or y field
if (mXField == *it)
@ -426,7 +425,7 @@ QgsDelimitedTextProvider::getNextFeature_( QgsFeature & feature,
i != desiredAttributes.end();
++i )
{
feature.addAttribute(*i, QgsFeatureAttribute(attributeFields[*i].name(), tokens[*i]));
feature.addAttribute(*i, QVariant(tokens[*i]) );
}
}
@ -587,7 +586,7 @@ void QgsDelimitedTextProvider::fillMinMaxCash()
{
for (uint i = 0; i < fieldCount(); i++)
{
double value = (f.attributeMap())[i].fieldValue().toDouble();
double value = (f.attributeMap())[i].toDouble();
if (value < mMinMaxCache[i][0])
{
mMinMaxCache[i][0] = value;

View File

@ -36,7 +36,6 @@
#include "qgsapplication.h"
#include "qgsdataprovider.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgsspatialrefsys.h"
@ -84,19 +83,19 @@ QgsGPXProvider::QgsGPXProvider(QString uri) :
(typeStr == "route" ? RouteType : TrackType));
// set up the attributes and the geometry type depending on the feature type
attributeFields[NameAttr] = QgsField(attr[NameAttr], "text");
attributeFields[NameAttr] = QgsField(attr[NameAttr], QVariant::String, "text");
if (mFeatureType == WaypointType) {
attributeFields[EleAttr] = QgsField(attr[EleAttr], "text");
attributeFields[SymAttr] = QgsField(attr[SymAttr], "text");
attributeFields[EleAttr] = QgsField(attr[EleAttr], QVariant::Double, "double");
attributeFields[SymAttr] = QgsField(attr[SymAttr], QVariant::String, "text");
}
else if (mFeatureType == RouteType || mFeatureType == TrackType) {
attributeFields[NumAttr] = QgsField(attr[NumAttr], "text");
attributeFields[NumAttr] = QgsField(attr[NumAttr], QVariant::Int, "int");
}
attributeFields[CmtAttr] = QgsField(attr[CmtAttr], "text");
attributeFields[DscAttr] = QgsField(attr[DscAttr], "text");
attributeFields[SrcAttr] = QgsField(attr[SrcAttr], "text");
attributeFields[URLAttr] = QgsField(attr[URLAttr], "text");
attributeFields[URLNameAttr] = QgsField(attr[URLNameAttr], "text");
attributeFields[CmtAttr] = QgsField(attr[CmtAttr], QVariant::String, "text");
attributeFields[DscAttr] = QgsField(attr[DscAttr], QVariant::String, "text");
attributeFields[SrcAttr] = QgsField(attr[SrcAttr], QVariant::String, "text");
attributeFields[URLAttr] = QgsField(attr[URLAttr], QVariant::String, "text");
attributeFields[URLNameAttr] = QgsField(attr[URLNameAttr], QVariant::String, "text");
mFileName = uri.left(fileNameEnd);
// set the selection rectangle to null
@ -174,31 +173,31 @@ bool QgsGPXProvider::getNextFeature(QgsFeature& feature,
for (iter = attlist.begin(); iter != attlist.end(); ++iter) {
switch (*iter) {
case 0:
feature.addAttribute(0, QgsFeatureAttribute(attr[NameAttr], wpt->name));
feature.addAttribute(0, QVariant(wpt->name));
break;
case 1:
if (wpt->ele == -std::numeric_limits<double>::max())
feature.addAttribute(1, QgsFeatureAttribute(attr[EleAttr], ""));
feature.addAttribute(1, QVariant());
else
feature.addAttribute(1, QgsFeatureAttribute(attr[EleAttr], QString("%1").arg(wpt->ele)));
feature.addAttribute(1, QVariant(wpt->ele));
break;
case 2:
feature.addAttribute(2, QgsFeatureAttribute(attr[SymAttr], wpt->sym));
feature.addAttribute(2, QVariant(wpt->sym));
break;
case 3:
feature.addAttribute(3, QgsFeatureAttribute(attr[CmtAttr], wpt->cmt));
feature.addAttribute(3, QVariant(wpt->cmt));
break;
case 4:
feature.addAttribute(4, QgsFeatureAttribute(attr[DscAttr], wpt->desc));
feature.addAttribute(4, QVariant(wpt->desc));
break;
case 5:
feature.addAttribute(5, QgsFeatureAttribute(attr[SrcAttr], wpt->src));
feature.addAttribute(5, QVariant(wpt->src));
break;
case 6:
feature.addAttribute(6, QgsFeatureAttribute(attr[URLAttr], wpt->url));
feature.addAttribute(6, QVariant(wpt->url));
break;
case 7:
feature.addAttribute(7, QgsFeatureAttribute(attr[URLNameAttr], wpt->urlname));
feature.addAttribute(7, QVariant(wpt->urlname));
break;
}
}
@ -241,23 +240,23 @@ bool QgsGPXProvider::getNextFeature(QgsFeature& feature,
// add attributes if they are wanted
for (iter = attlist.begin(); iter != attlist.end(); ++iter) {
if (*iter == 0)
feature.addAttribute(0, QgsFeatureAttribute(attr[NameAttr], rte->name));
feature.addAttribute(0, QVariant(rte->name));
else if (*iter == 1) {
if (rte->number == std::numeric_limits<int>::max())
feature.addAttribute(1, QgsFeatureAttribute(attr[NumAttr], ""));
feature.addAttribute(1, QVariant());
else
feature.addAttribute(1, QgsFeatureAttribute(attr[NumAttr], QString("%1").arg(rte->number)));
feature.addAttribute(1, QVariant(rte->number));
}
else if (*iter == 2)
feature.addAttribute(2, QgsFeatureAttribute(attr[CmtAttr], rte->cmt));
feature.addAttribute(2, QVariant(rte->cmt));
else if (*iter == 3)
feature.addAttribute(3, QgsFeatureAttribute(attr[DscAttr], rte->desc));
feature.addAttribute(3, QVariant(rte->desc));
else if (*iter == 4)
feature.addAttribute(4, QgsFeatureAttribute(attr[SrcAttr], rte->src));
feature.addAttribute(4, QVariant(rte->src));
else if (*iter == 5)
feature.addAttribute(5, QgsFeatureAttribute(attr[URLAttr], rte->url));
feature.addAttribute(5, QVariant(rte->url));
else if (*iter == 6)
feature.addAttribute(6, QgsFeatureAttribute(attr[URLNameAttr], rte->urlname));
feature.addAttribute(6, QVariant(rte->urlname));
}
++mRteIter;
@ -300,23 +299,23 @@ bool QgsGPXProvider::getNextFeature(QgsFeature& feature,
// add attributes if they are wanted
for (iter = attlist.begin(); iter != attlist.end(); ++iter) {
if (*iter == 0)
feature.addAttribute(0, QgsFeatureAttribute(attr[NameAttr], trk->name));
feature.addAttribute(0, QVariant(trk->name));
else if (*iter == 1) {
if (trk->number == std::numeric_limits<int>::max())
feature.addAttribute(1, QgsFeatureAttribute(attr[NumAttr], ""));
feature.addAttribute(1, QVariant());
else
feature.addAttribute(1, QgsFeatureAttribute(attr[NumAttr], QString("%1").arg(trk->number)));
feature.addAttribute(1, QVariant(trk->number));
}
else if (*iter == 2)
feature.addAttribute(2, QgsFeatureAttribute(attr[CmtAttr], trk->cmt));
feature.addAttribute(2, QVariant(trk->cmt));
else if (*iter == 3)
feature.addAttribute(3, QgsFeatureAttribute(attr[DscAttr], trk->desc));
feature.addAttribute(3, QVariant(trk->desc));
else if (*iter == 4)
feature.addAttribute(4, QgsFeatureAttribute(attr[SrcAttr], trk->src));
feature.addAttribute(4, QVariant(trk->src));
else if (*iter == 5)
feature.addAttribute(5, QgsFeatureAttribute(attr[URLAttr], trk->url));
feature.addAttribute(5, QVariant(trk->url));
else if (*iter == 6)
feature.addAttribute(6, QgsFeatureAttribute(attr[URLNameAttr], trk->urlname));
feature.addAttribute(6, QVariant(trk->urlname));
}
++mTrkIter;
@ -449,7 +448,7 @@ void QgsGPXProvider::fillMinMaxCash()
getNextFeature(f, true);
do {
for(uint i=0;i<fieldCount();i++) {
double value=(f.attributeMap())[i].fieldValue().toDouble();
double value=(f.attributeMap())[i].toDouble();
if(value<mMinMaxCache[i][0]) {
mMinMaxCache[i][0]=value;
}
@ -497,6 +496,7 @@ bool QgsGPXProvider::addFeature(QgsFeature& f)
bool success = false;
GPSObject* obj = NULL;
const QgsAttributeMap& attrs(f.attributeMap());
QgsAttributeMap::const_iterator it;
// is it a waypoint?
if (mFeatureType == WaypointType && geo != NULL && wkbType == QGis::WKBPoint) {
@ -507,15 +507,15 @@ bool QgsGPXProvider::addFeature(QgsFeature& f)
std::memcpy(&wpt.lat, geo+13, sizeof(double));
// add waypoint-specific attributes
for (int i = 0; i < attrs.size(); ++i) {
if (attrs[i].fieldName() == attr[EleAttr]) {
for (it = attrs.begin(); it != attrs.end(); ++it) {
if (attributeFields[it.key()].name() == attr[EleAttr]) {
bool eleIsOK;
double ele = attrs[i].fieldValue().toDouble(&eleIsOK);
double ele = it->toDouble(&eleIsOK);
if (eleIsOK)
wpt.ele = ele;
}
else if (attrs[i].fieldName() == attr[SymAttr]) {
wpt.sym = attrs[i].fieldValue();
else if (attributeFields[it.key()].name() == attr[SymAttr]) {
wpt.sym = it->toString();
}
}
@ -553,10 +553,10 @@ bool QgsGPXProvider::addFeature(QgsFeature& f)
}
// add route-specific attributes
for (int i = 0; i < attrs.size(); ++i) {
if (attrs[i].fieldName() == attr[NumAttr]) {
for (it = attrs.begin(); it != attrs.end(); ++it) {
if (attributeFields[it.key()].name() == attr[NumAttr]) {
bool numIsOK;
long num = attrs[i].fieldValue().toLong(&numIsOK);
long num = it->toInt(&numIsOK);
if (numIsOK)
rte.number = num;
}
@ -597,10 +597,10 @@ bool QgsGPXProvider::addFeature(QgsFeature& f)
}
// add track-specific attributes
for (int i = 0; i < attrs.size(); ++i) {
if (attrs[i].fieldName() == attr[NumAttr]) {
for (it = attrs.begin(); it != attrs.end(); ++it) {
if (attributeFields[it.key()].name() == attr[NumAttr]) {
bool numIsOK;
long num = attrs[i].fieldValue().toLong(&numIsOK);
long num = it->toInt(&numIsOK);
if (numIsOK)
trk.number = num;
}
@ -615,24 +615,25 @@ bool QgsGPXProvider::addFeature(QgsFeature& f)
// add common attributes
if (obj) {
for (int i = 0; i < attrs.size(); ++i) {
if (attrs[i].fieldName() == attr[NameAttr]) {
obj->name = attrs[i].fieldValue();
for (it = attrs.begin(); it != attrs.end(); ++it) {
QString fieldName = attributeFields[it.key()].name();
if (fieldName == attr[NameAttr]) {
obj->name = it->toString();
}
else if (attrs[i].fieldName() == attr[CmtAttr]) {
obj->cmt = attrs[i].fieldValue();
else if (fieldName == attr[CmtAttr]) {
obj->cmt = it->toString();
}
else if (attrs[i].fieldName() == attr[DscAttr]) {
obj->desc = attrs[i].fieldValue();
else if (fieldName == attr[DscAttr]) {
obj->desc = it->toString();
}
else if (attrs[i].fieldName() == attr[SrcAttr]) {
obj->src = attrs[i].fieldValue();
else if (fieldName == attr[SrcAttr]) {
obj->src = it->toString();
}
else if (attrs[i].fieldName() == attr[URLAttr]) {
obj->url = attrs[i].fieldValue();
else if (fieldName == attr[URLAttr]) {
obj->url = it->toString();
}
else if (attrs[i].fieldName() == attr[URLNameAttr]) {
obj->urlname = attrs[i].fieldValue();
else if (fieldName == attr[URLNameAttr]) {
obj->urlname = it->toString();
}
}
}
@ -707,27 +708,27 @@ void QgsGPXProvider::changeAttributeValues(GPSObject& obj, const QgsAttributeMap
// TODO:
if (attrs.contains(NameAttr))
obj.name = attrs[NameAttr].fieldValue();
obj.name = attrs[NameAttr].toString();
if (attrs.contains(CmtAttr))
obj.cmt = attrs[CmtAttr].fieldValue();
obj.cmt = attrs[CmtAttr].toString();
if (attrs.contains(DscAttr))
obj.desc = attrs[DscAttr].fieldValue();
obj.desc = attrs[DscAttr].toString();
if (attrs.contains(SrcAttr))
obj.src = attrs[SrcAttr].fieldValue();
obj.src = attrs[SrcAttr].toString();
if (attrs.contains(URLAttr))
obj.url = attrs[URLAttr].fieldValue();
obj.url = attrs[URLAttr].toString();
if (attrs.contains(URLNameAttr))
obj.urlname = attrs[URLNameAttr].fieldValue();
obj.urlname = attrs[URLNameAttr].toString();
// waypoint-specific attributes
Waypoint* wpt = dynamic_cast<Waypoint*>(&obj);
if (wpt != NULL) {
if (attrs.contains(SymAttr))
wpt->sym = attrs[SymAttr].fieldValue();
wpt->sym = attrs[SymAttr].toString();
if (attrs.contains(EleAttr))
{
bool eleIsOK;
double ele = attrs[EleAttr].fieldValue().toDouble(&eleIsOK);
double ele = attrs[EleAttr].toDouble(&eleIsOK);
if (eleIsOK)
wpt->ele = ele;
}
@ -739,7 +740,7 @@ void QgsGPXProvider::changeAttributeValues(GPSObject& obj, const QgsAttributeMap
if (attrs.contains(NumAttr))
{
bool eleIsOK;
double ele = attrs[NumAttr].fieldValue().toDouble(&eleIsOK);
double ele = attrs[NumAttr].toDouble(&eleIsOK);
if (eleIsOK)
wpt->ele = ele;
}

View File

@ -31,10 +31,8 @@
#include "qgsapplication.h"
#include "qgsdataprovider.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgsfield.h"
#include "qgsrect.h"
#include "qgsfeatureattribute.h"
#include "qgsspatialrefsys.h"
extern "C" {
@ -739,6 +737,7 @@ void QgsGrassProvider::loadAttributes ( GLAYER &layer )
dbColumn *column = db_get_table_column (databaseTable, i);
int ctype = db_sqltype_to_Ctype ( db_get_column_sqltype(column) );
QVariant::Type qtype;
#ifdef QGISDEBUG
std::cerr << "column = " << db_get_column_name(column)
<< " ctype = " << ctype << std::endl;
@ -748,18 +747,22 @@ void QgsGrassProvider::loadAttributes ( GLAYER &layer )
switch ( ctype ) {
case DB_C_TYPE_INT:
ctypeStr = "integer";
qtype = QVariant::Int;
break;
case DB_C_TYPE_DOUBLE:
ctypeStr = "double";
qtype = QVariant::Double;
break;
case DB_C_TYPE_STRING:
ctypeStr = "string";
qtype = QVariant::String;
break;
case DB_C_TYPE_DATETIME:
ctypeStr = "datetime";
qtype = QVariant::String;
break;
}
layer.fields[i] = QgsField( db_get_column_name(column), ctypeStr,
layer.fields[i] = QgsField( db_get_column_name(column), qtype, ctypeStr,
db_get_column_length(column), db_get_column_precision(column) );
if ( G_strcasecmp ( db_get_column_name(column), layer.fieldInfo->key) == 0 ) {
@ -848,7 +851,7 @@ void QgsGrassProvider::loadAttributes ( GLAYER &layer )
// Add cat if no attribute fields exist (otherwise qgis crashes)
if ( layer.nColumns == 0 ) {
layer.keyColumn = 0;
layer.fields[0] = ( QgsField( "cat", "integer", 10, 0) );
layer.fields[0] = ( QgsField( "cat", QVariant::Int, "integer") );
layer.minmax = new double[1][2];
layer.minmax[0][0] = 0;
layer.minmax[0][1] = 0;
@ -1172,15 +1175,13 @@ void QgsGrassProvider::setFeatureAttributes ( int layerId, int cat, QgsFeature *
for (int i = 0; i < mLayers[layerId].nColumns; i++) {
if ( att != NULL ) {
Q3CString cstr( att->values[i] );
feature->addAttribute (i, QgsFeatureAttribute( mLayers[layerId].fields[i].name(), mEncoding->toUnicode(cstr) ));
feature->addAttribute (i, QVariant(mEncoding->toUnicode(cstr)) );
} else { /* it may happen that attributes are missing -> set to empty string */
feature->addAttribute (i, QgsFeatureAttribute( mLayers[layerId].fields[i].name(), ""));
feature->addAttribute (i, QVariant());
}
}
} else {
QString tmp;
tmp.sprintf("%d", cat );
feature->addAttribute (0, QgsFeatureAttribute("cat", tmp));
feature->addAttribute (0, QVariant(cat));
}
}
@ -1199,15 +1200,13 @@ void QgsGrassProvider::setFeatureAttributes ( int layerId, int cat, QgsFeature *
for (QgsAttributeList::const_iterator iter=attlist.begin(); iter!=attlist.end();++iter) {
if ( att != NULL ) {
Q3CString cstr( att->values[*iter] );
feature->addAttribute (*iter, QgsFeatureAttribute(mLayers[layerId].fields[*iter].name(), mEncoding->toUnicode(cstr) ));
feature->addAttribute (*iter, QVariant( mEncoding->toUnicode(cstr) ));
} else { /* it may happen that attributes are missing -> set to empty string */
feature->addAttribute (*iter, QgsFeatureAttribute(mLayers[layerId].fields[*iter].name(), ""));
feature->addAttribute (*iter, QVariant());
}
}
} else {
QString tmp;
tmp.sprintf("%d", cat );
feature->addAttribute (0, QgsFeatureAttribute("cat", tmp));
feature->addAttribute (0, QVariant(cat));
}
}
@ -1820,21 +1819,26 @@ std::vector<QgsField> *QgsGrassProvider::columns ( int field )
int ctype = db_sqltype_to_Ctype( db_get_column_sqltype (column) );
QString type;
QVariant::Type qtype;
switch ( ctype ) {
case DB_C_TYPE_INT:
type = "int";
qtype = QVariant::Int;
break;
case DB_C_TYPE_DOUBLE:
type = "double";
qtype = QVariant::Double;
break;
case DB_C_TYPE_STRING:
type = "string";
qtype = QVariant::String;
break;
case DB_C_TYPE_DATETIME:
type = "datetime";
qtype = QVariant::String;
break;
}
col->push_back ( QgsField( db_get_column_name (column), type, db_get_column_length(column), 0) );
col->push_back ( QgsField( db_get_column_name (column), qtype, type, db_get_column_length(column), 0) );
}
db_close_database_shutdown_driver ( driver );
@ -1842,13 +1846,13 @@ std::vector<QgsField> *QgsGrassProvider::columns ( int field )
return col;
}
std::vector<QgsFeatureAttribute> *QgsGrassProvider::attributes ( int field, int cat )
QgsAttributeMap *QgsGrassProvider::attributes ( int field, int cat )
{
#ifdef QGISDEBUG
std::cerr << "QgsGrassProvider::attributes() field = " << field << " cat = " << cat << std::endl;
#endif
std::vector<QgsFeatureAttribute> *att = new std::vector<QgsFeatureAttribute>;
QgsAttributeMap *att = new QgsAttributeMap;
struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0
@ -1920,7 +1924,7 @@ std::vector<QgsFeatureAttribute> *QgsGrassProvider::attributes ( int field, int
QString v = mEncoding->toUnicode(db_get_string(&dbstr));
std::cerr << "Value: " << v.toLocal8Bit().data() << std::endl;
att->push_back ( QgsFeatureAttribute( db_get_column_name(column), v ) );
att->insert(i, QVariant( v ) );
}
db_close_cursor (&databaseCursor);

View File

@ -17,7 +17,6 @@
#define QGSGRASSPROVIDER_H
class QgsFeature;
class QgsFeatureAttribute;
class QgsField;
#include <QDateTime>
@ -368,7 +367,7 @@ public:
* @param cat
* @return vector of attributes
*/
std::vector<QgsFeatureAttribute> *attributes ( int field, int cat );
QgsAttributeMap *attributes ( int field, int cat );
/** Key (cat) column name
* @param field

View File

@ -50,7 +50,6 @@ email : sherman at mrcc.com
#include "qgsapplication.h"
#include "qgsdataprovider.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgslogger.h"
@ -213,14 +212,23 @@ void QgsOgrProvider::loadFields()
for(int i=0;i<fdef->GetFieldCount();++i)
{
OGRFieldDefn *fldDef = fdef->GetFieldDefn(i);
OGRFieldType type = fldDef->GetType();
bool numeric = (type == OFTInteger || type == OFTReal);
OGRFieldType ogrType = fldDef->GetType();
QVariant::Type varType;
switch (ogrType)
{
case OFTInteger: varType = QVariant::Int; break;
case OFTReal: varType = QVariant::Double; break;
// unsupported in OGR 1.3
//case OFTDateTime: varType = QVariant::DateTime; break;
case OFTString: varType = QVariant::String; break;
default: varType = QVariant::String; // other unsupported, leave it as a string
}
mAttributeFields.insert(i, QgsField(
mEncoding->toUnicode(fldDef->GetNameRef()),
mEncoding->toUnicode(fldDef->GetFieldTypeName(type)),
mEncoding->toUnicode(fldDef->GetNameRef()), varType,
mEncoding->toUnicode(fldDef->GetFieldTypeName(ogrType)),
fldDef->GetWidth(),
fldDef->GetPrecision(),
numeric));
fldDef->GetPrecision() ));
}
}
}
@ -466,10 +474,21 @@ void QgsOgrProvider::getFeatureAttribute(OGRFeature * ogrFet, QgsFeature & f, in
return;
}
QString fld = mEncoding->toUnicode(fldDef->GetNameRef());
//QString fld = mEncoding->toUnicode(fldDef->GetNameRef());
QByteArray cstr(ogrFet->GetFieldAsString(attindex));
QString str = mEncoding->toUnicode(cstr);
QVariant value;
switch (mAttributeFields[attindex].type())
{
case QVariant::String: value = QVariant(str); break;
case QVariant::Int: value = QVariant(str.toInt()); break;
case QVariant::Double: value = QVariant(str.toDouble()); break;
//case QVariant::DateTime: value = QVariant(QDateTime::fromString(str)); break;
default: assert(NULL && "unsupported field type");
}
f.addAttribute(attindex, QgsFeatureAttribute(fld, mEncoding->toUnicode(cstr)));
f.addAttribute(attindex, value);
}
@ -581,13 +600,18 @@ void QgsOgrProvider::fillMinMaxCash()
minmaxcache[i][1]=-DBL_MAX;
}
// TODO: fetch only numeric columns
QgsFeature f;
QgsAttributeList all = allAttributesList();
while (getNextFeature(f, false, all))
{
for(uint i = 0; i < fieldCount(); i++)
{
double value = (f.attributeMap())[i].fieldValue().toDouble();
const QVariant& varValue = (f.attributeMap())[i];
if (varValue.type() != QVariant::Double && varValue.type() != QVariant::Int)
continue;
double value = varValue.toDouble();
if(value<minmaxcache[i][0])
{
minmaxcache[i][0]=value;
@ -764,40 +788,33 @@ bool QgsOgrProvider::addFeature(QgsFeature& f)
QgsAttributeMap attrs = f.attributeMap();
//add possible attribute information
for(int i = 0; i < attrs.size(); ++i)
for(QgsAttributeMap::iterator it = attrs.begin(); it != attrs.end(); ++it)
{
QString s = attrs[i].fieldValue();
//find a matching field for the new attribute
QString newAttribute = attrs[i].fieldName();
int targetAttributeId = fdef->GetFieldIndex(mEncoding->fromUnicode(newAttribute).constData());
if(targetAttributeId == -1)
{
continue;
}
int targetAttributeId = it.key();
if(!s.isEmpty())
//if(!s.isEmpty())
// continue;
if(fdef->GetFieldDefn(targetAttributeId)->GetType()==OFTInteger)
{
feature->SetField(targetAttributeId,it->toInt());
}
else if(fdef->GetFieldDefn(targetAttributeId)->GetType()==OFTReal)
{
feature->SetField(targetAttributeId,it->toDouble());
}
else if(fdef->GetFieldDefn(targetAttributeId)->GetType()==OFTString)
{
if(fdef->GetFieldDefn(targetAttributeId)->GetType()==OFTInteger)
{
feature->SetField(targetAttributeId,s.toInt());
}
else if(fdef->GetFieldDefn(targetAttributeId)->GetType()==OFTReal)
{
feature->SetField(targetAttributeId,s.toDouble());
}
else if(fdef->GetFieldDefn(targetAttributeId)->GetType()==OFTString)
{
#ifdef QGISDEBUG
std::cerr << "Writing string attribute " << newAttribute.toLocal8Bit().data() <<
" with " << s.toLocal8Bit().data() << ", encoding " << mEncoding->name().data() << "\n";
std::cerr << "Writing string attribute " << targetAttributeId
<< " with " << it->toString().toLocal8Bit().data()
<< ", encoding " << mEncoding->name().data() << std::endl;
#endif
feature->SetField(targetAttributeId,mEncoding->fromUnicode(s).constData());
}
else
{
QgsLogger::warning("QgsOgrProvider::addFeature, no type found");
}
feature->SetField(targetAttributeId,mEncoding->fromUnicode(it->toString()).constData());
}
else
{
QgsLogger::warning("QgsOgrProvider::addFeature, no type found");
}
}
@ -890,8 +907,6 @@ bool QgsOgrProvider::changeAttributeValues(const QgsChangedAttributesMap & attr_
for( QgsAttributeMap::const_iterator it2 = attr.begin(); it2 != attr.end(); ++it2 )
{
int f = it2.key();
QString name = it2->fieldName();
QString value = it2->fieldValue();
OGRFieldDefn *fd = of->GetFieldDefnRef ( f );
if (fd == NULL)
@ -904,13 +919,13 @@ bool QgsOgrProvider::changeAttributeValues(const QgsChangedAttributesMap & attr_
switch ( type )
{
case OFTInteger:
of->SetField ( f, value.toInt() );
of->SetField ( f, it2->toInt() );
break;
case OFTReal:
of->SetField ( f, value.toDouble() );
of->SetField ( f, it2->toDouble() );
break;
case OFTString:
of->SetField ( f, mEncoding->fromUnicode(value).constData() );
of->SetField ( f, mEncoding->fromUnicode(it2->toString()).constData() );
break;
default:
QgsLogger::warning("QgsOgrProvider::changeAttributeValues, Unknown field type, cannot change attribute");

View File

@ -38,7 +38,6 @@
#include <qgis.h>
#include <qgsapplication.h>
#include <qgsfeature.h>
#include <qgsfeatureattribute.h>
#include <qgsfield.h>
#include <qgsgeometry.h>
#include <qgsmessageoutput.h>
@ -207,7 +206,7 @@ QgsPostgresProvider::QgsPostgresProvider(QString const & uri)
"typelem = " + typOid + " AND typlen = -1)";
PGresult* oidResult = PQexec(pd, (const char *) sql);
QString fieldType = PQgetvalue(oidResult, 0, 0);
QString fieldTypeName = PQgetvalue(oidResult, 0, 0);
QString fieldSize = PQgetvalue(oidResult, 0, 1);
PQclear(oidResult);
@ -225,13 +224,20 @@ QgsPostgresProvider::QgsPostgresProvider(QString const & uri)
PQclear(tresult);
QgsDebugMsg("Field: " + attnum + " maps to " + QString::number(i) + " " + fieldName + ", "
+ fieldType + " (" + QString::number(fldtyp) + "), " + fieldSize + ", " + QString::number(fieldModifier));
+ fieldTypeName + " (" + QString::number(fldtyp) + "), " + fieldSize + ", " + QString::number(fieldModifier));
attributeFieldsIdMap[attnum.toInt()] = i;
if(fieldName!=geometryColumn)
{
attributeFields.insert(i, QgsField(fieldName, fieldType, fieldSize.toInt(), fieldModifier, false, fieldComment));
QVariant::Type fieldType;
if (fieldTypeName.find("int") != -1 || fieldTypeName.find("serial") != -1)
fieldType = QVariant::Int;
else if (fieldTypeName == "real" || fieldTypeName == "double precision")
fieldType = QVariant::Double;
else
fieldType = QVariant::String;
attributeFields.insert(i, QgsField(fieldName, fieldType, fieldTypeName, fieldSize.toInt(), fieldModifier, fieldComment));
}
}
PQclear(result);
@ -577,8 +583,21 @@ void QgsPostgresProvider::getFeatureAttributes(int key, int &row, QgsFeature& f)
if(fld != geometryColumn){
// Add the attribute to the feature
//QString val = mEncoding->toUnicode(PQgetvalue(attr,0, i));
QString val = QString::fromUtf8 (PQgetvalue(attr, row, i));
f.addAttribute(i, QgsFeatureAttribute(fld, val));
QString val = QString::fromUtf8 (PQgetvalue(attr, row, i));
switch (attributeFields[i].type())
{
case QVariant::Int:
f.addAttribute(i, val.toInt());
break;
case QVariant::Double:
f.addAttribute(i, val.toDouble());
break;
case QVariant::String:
f.addAttribute(i, val);
break;
default:
assert(0 && "unsupported field type");
}
}
}
PQclear(attr);
@ -606,8 +625,21 @@ void QgsPostgresProvider::getFeatureAttributes(int key, int &row,
if(fld != geometryColumn)
{
// Add the attribute to the feature
QString val = QString::fromUtf8(PQgetvalue(attr, 0, 0));
f.addAttribute(*iter, QgsFeatureAttribute(fld, val));
QString val = QString::fromUtf8(PQgetvalue(attr, 0, 0));
switch (attributeFields[*iter].type())
{
case QVariant::Int:
f.addAttribute(*iter, val.toInt());
break;
case QVariant::Double:
f.addAttribute(*iter, val.toDouble());
break;
case QVariant::String:
f.addAttribute(*iter, val);
break;
default:
assert(0 && "unsupported field type");
}
}
PQclear(attr);
}
@ -1473,31 +1505,18 @@ bool QgsPostgresProvider::addFeature(QgsFeature& f, int primaryKeyHighWater)
for(QgsAttributeMap::const_iterator it = attributevec.begin(); it != attributevec.end(); ++it)
{
QString fieldname=it->fieldName();
QString fieldname;
QgsFieldMap::const_iterator fit = attributeFields.find(it.key());
if (fit != attributeFields.end())
fieldname = fit->name();
QgsDebugMsg("Checking field against: " + fieldname);
//TODO: Check if field exists in this layer
// (Sometimes features will have fields that are not part of this layer since
// they have been pasted from other layers with a different field map)
bool fieldInLayer = FALSE;
for (QgsFieldMap::iterator iter = attributeFields.begin();
iter != attributeFields.end();
++iter)
{
if ( iter->name() == it->fieldName() )
{
fieldInLayer = TRUE;
break;
}
}
if (
(fieldname != "") &&
(fieldname != geometryColumn) &&
(fieldname != primaryKey) &&
(!(it->fieldValue().isEmpty())) &&
(fieldInLayer)
(!(it->isNull()))
)
{
insert+=",\"";
@ -1562,34 +1581,21 @@ bool QgsPostgresProvider::addFeature(QgsFeature& f, int primaryKeyHighWater)
//add the field values to the insert statement
for(QgsAttributeMap::const_iterator it=attributevec.begin();it!=attributevec.end();++it)
{
QString fieldname=it->fieldName();
QString fieldname;
QgsFieldMap::const_iterator fit = attributeFields.find(it.key());
if (fit != attributeFields.end())
fieldname = fit->name();
QgsDebugMsg("Checking field name " + fieldname);
//TODO: Check if field exists in this layer
// (Sometimes features will have fields that are not part of this layer since
// they have been pasted from other layers with a different field map)
bool fieldInLayer = FALSE;
for (QgsFieldMap::iterator iter = attributeFields.begin();
iter != attributeFields.end();
++iter)
{
if ( iter->name() == it->fieldName() )
{
fieldInLayer = TRUE;
break;
}
}
if (
(fieldname != "") &&
(fieldname != geometryColumn) &&
(fieldname != primaryKey) &&
(!(it->fieldValue().isEmpty())) &&
(fieldInLayer)
(!(it->isNull()))
)
{
QString fieldvalue = it->fieldValue();
QString fieldvalue = it->toString();
bool charactertype=false;
insert+=",";
@ -1597,30 +1603,27 @@ bool QgsPostgresProvider::addFeature(QgsFeature& f, int primaryKeyHighWater)
//add quotes if the field is a character or date type and not
//the postgres provided default value
if(fieldvalue != "NULL" && fieldvalue != getDefaultValue(it->fieldName(), f))
if(fieldvalue != "NULL" && fieldvalue != getDefaultValue(it.key()).toString() )
{
for(QgsFieldMap::iterator iter=attributeFields.begin();iter!=attributeFields.end();++iter)
QString typeName = it->typeName();
if (
typeName.contains("char",false) > 0 ||
typeName == "text" ||
typeName == "date" ||
typeName == "interval" ||
typeName.contains("time",false) > 0 // includes time and timestamp
)
{
if(iter->name()==it->fieldName())
{
if (
iter->type().contains("char",false) > 0 ||
iter->type() == "text" ||
iter->type() == "date" ||
iter->type() == "interval" ||
iter->type().contains("time",false) > 0 // includes time and timestamp
)
{
charactertype=true;
break; // no need to continue with this loop
}
}
charactertype=true;
break; // no need to continue with this loop
}
}
// important: escape quotes in field value
fieldvalue.replace("'", "''");
// XXX isn't it better to always escape field value?
if(charactertype)
{
insert+="'";
@ -1654,20 +1657,22 @@ bool QgsPostgresProvider::addFeature(QgsFeature& f, int primaryKeyHighWater)
return true;
}
QString QgsPostgresProvider::getDefaultValue(const QString& attr, QgsFeature& f)
QVariant QgsPostgresProvider::getDefaultValue(int fieldId)
{
// Get the default column value from the Postgres information
// schema. If there is no default we return an empty string.
// Maintaining a cache of the results of this query would be quite
// simple and if this query is called lots, could save some time.
QString fieldName = attributeFields[fieldId].name();
QString sql("SELECT column_default FROM "
"information_schema.columns WHERE "
"column_default IS NOT NULL AND "
"table_schema = '" + mSchemaName + "' AND "
"table_name = '" + mTableName + "' AND "
"column_name = '" + attr + "'");
"column_name = '" + fieldName + "'");
QString defaultValue("");
@ -1867,12 +1872,13 @@ bool QgsPostgresProvider::changeAttributeValues(const QgsChangedAttributesMap &
// cycle through the changed attributes of the feature
for(QgsAttributeMap::const_iterator siter = attrs.begin(); siter != attrs.end(); ++siter)
{
QString val = siter->fieldValue();
QString val = siter->toString();
QString fieldName = attributeFields[siter.key()].name();
// escape quotes
val.replace("'", "''");
QString sql="UPDATE "+mSchemaTableName+" SET "+siter->fieldName()+"='"+val+"' WHERE \"" +primaryKey+"\"="+QString::number(fid);
QString sql="UPDATE "+mSchemaTableName+" SET "+fieldName+"='"+val+"' WHERE \"" +primaryKey+"\"="+QString::number(fid);
QgsDebugMsg(sql);
// s end sql statement and do error handling

View File

@ -220,8 +220,8 @@ class QgsPostgresProvider:public QgsVectorDataProvider
//! get status of PROJ4 capability
bool hasPROJ(PGconn *);
/**Returns the default value for attribute @c attr for feature @c f. */
QString getDefaultValue(const QString& attr, QgsFeature& f);
/**Returns the default value for field specified by @c fieldId */
QVariant getDefaultValue(int fieldId);
/**Adds a list of features
@return true in case of success and false in case of failure*/

View File

@ -1,5 +1,4 @@
#include "qgswfsdata.h"
#include "qgsfeatureattribute.h"
#include "qgsrect.h"
#include "qgsspatialrefsys.h"
#include <QBuffer>
@ -193,7 +192,7 @@ void QgsWFSData::endElement(const XML_Char* el)
//qWarning(mAttributeName.toLocal8Bit().data());
//qWarning(mStringCash.toLocal8Bit().data());
//mCurrentFeature->addAttribute(mAttributeName, mStringCash);
mCurrentFeature->addAttribute(mAttributeIndex, QgsFeatureAttribute(mAttributeName, mStringCash));
mCurrentFeature->addAttribute(mAttributeIndex, QVariant(mStringCash));
++mAttributeIndex;
}
else if(localName == mGeometryAttribute)

View File

@ -17,7 +17,6 @@
#include "qgsapplication.h"
#include "qgsfeature.h"
#include "qgsfeatureattribute.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgshttptransaction.h"
@ -94,7 +93,7 @@ bool QgsWFSProvider::getNextFeature(QgsFeature& feature,
const QgsAttributeMap& attributes = ((QgsFeature*)(*mFeatureIterator))->attributeMap();
for(QgsAttributeList::const_iterator it = attlist.begin(); it != attlist.end(); ++it)
{
feature.addAttribute(*it, QgsFeatureAttribute(attributes[*it].fieldName(), attributes[*it].fieldValue()));
feature.addAttribute(*it, attributes[*it]);
}
++mFeatureIterator;
if(mUseIntersect)
@ -189,7 +188,7 @@ void QgsWFSProvider::fillMinMaxCash()
{
for(i = 0; i < fieldCount; ++i)
{
currentValue = (theFeature.attributeMap())[i].fieldValue().toDouble();
currentValue = (theFeature.attributeMap())[i].toDouble();
if(currentValue < tempMinMax[i].first)
{
tempMinMax[i].first = currentValue;
@ -366,7 +365,7 @@ int QgsWFSProvider::getFeatureGET(const QString& uri, const QString& geometryAtt
GEOS_GEOM::Envelope* geosBBox;
for(std::list<QgsFeature*>::const_iterator it = dataFeatures.begin(); it != dataFeatures.end(); ++it)
{
featureBBox = (*it)->boundingBox();
featureBBox = (*it)->geometry()->boundingBox();
geosBBox = new GEOS_GEOM::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax());
mSpatialIndex.insert(geosBBox, (void*)(*it));
mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, (*it)));
@ -489,7 +488,7 @@ int QgsWFSProvider::describeFeatureTypeFile(const QString& uri, QString& geometr
for(std::list<QString>::const_iterator it = thematicAttributes.begin(); it != thematicAttributes.end(); ++it, ++i)
{
// TODO: is this correct?
fields[i] = QgsField(*it, "unknown");
fields[i] = QgsField(*it, QVariant::String, "unknown");
}
return 0;
}
@ -573,7 +572,7 @@ int QgsWFSProvider::readAttributesFromSchema(QDomDocument& schemaDoc, QString& g
}
else //todo: distinguish between numerical and non-numerical types
{
fields[fields.size()] = QgsField(name, type);
fields[fields.size()] = QgsField(name, QVariant::String, type);
}
}
return 0;
@ -823,7 +822,7 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
{
if((currentAttributeElement.localName()) != geometryAttribute) //a normal attribute
{
f->addAttribute(attr++, QgsFeatureAttribute(currentAttributeElement.localName(), currentAttributeElement.text()));
f->addAttribute(attr++, QVariant(currentAttributeElement.text()));
}
else //a geometry attribute
{
@ -837,7 +836,7 @@ int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement,
if(wkb && wkbSize > 0)
{
//insert bbox and pointer to feature into search tree
featureBBox = f->boundingBox();
featureBBox = f->geometry()->boundingBox();
geosBBox = new GEOS_GEOM::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax());
mSpatialIndex.insert(geosBBox, (void*)f);
mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, f));