mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
Add QgsRelation::getReferencedFeature to access parent feature
This commit is contained in:
parent
740e3abcb9
commit
d01424ae4b
@ -118,13 +118,22 @@ class QgsRelation
|
||||
*/
|
||||
QgsFeatureRequest getRelatedFeaturesRequest( const QgsFeature& feature ) const;
|
||||
|
||||
const QString name() const;
|
||||
QgsFeatureRequest getReferencedFeatureRequest( const QgsFeature& feature ) const;
|
||||
|
||||
QgsFeature getReferencedFeature( const QgsFeature& child ) const;
|
||||
|
||||
/**
|
||||
* The id
|
||||
* @return
|
||||
*/
|
||||
const QString& id() const;
|
||||
QString name() const;
|
||||
|
||||
/**
|
||||
* A (project-wide) unique id for this relation
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
QString id() const;
|
||||
|
||||
/**
|
||||
* Access the referencing (child) layer's id
|
||||
@ -182,5 +191,4 @@ class QgsRelation
|
||||
|
||||
protected:
|
||||
void updateRelationStatus();
|
||||
void runChecks();
|
||||
};
|
||||
|
@ -97,7 +97,7 @@ void QgsRelation::writeXML( QDomNode &node, QDomDocument &doc ) const
|
||||
elem.setAttribute( "referencingLayer", mReferencingLayerId );
|
||||
elem.setAttribute( "referencedLayer", mReferencedLayerId );
|
||||
|
||||
foreach ( FieldPair fields, mFieldPairs )
|
||||
Q_FOREACH ( FieldPair fields, mFieldPairs )
|
||||
{
|
||||
QDomElement referenceElem = doc.createElement( "fieldRef" );
|
||||
referenceElem.setAttribute( "referencingField", fields.first );
|
||||
@ -153,22 +153,20 @@ QgsFeatureRequest QgsRelation::getRelatedFeaturesRequest( const QgsFeature& feat
|
||||
{
|
||||
QStringList conditions;
|
||||
|
||||
foreach ( const QgsRelation::FieldPair& fieldPair, mFieldPairs )
|
||||
Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mFieldPairs )
|
||||
{
|
||||
int referencingIdx = referencingLayer()->pendingFields().indexFromName( fieldPair.referencingField() );
|
||||
QgsField referencingField = referencingLayer()->pendingFields().at( referencingIdx );
|
||||
|
||||
switch ( referencingField.type() )
|
||||
if ( referencingField.type() == QVariant::String )
|
||||
{
|
||||
case QVariant::String:
|
||||
// Use quotes
|
||||
conditions << QString( "\"%1\" = '%2'" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
|
||||
break;
|
||||
|
||||
default:
|
||||
// No quotes
|
||||
conditions << QString( "\"%1\" = %2" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
|
||||
break;
|
||||
// Use quotes
|
||||
conditions << QString( "\"%1\" = '%2'" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// No quotes
|
||||
conditions << QString( "\"%1\" = %2" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,12 +179,58 @@ QgsFeatureRequest QgsRelation::getRelatedFeaturesRequest( const QgsFeature& feat
|
||||
return myRequest;
|
||||
}
|
||||
|
||||
const QString QgsRelation::name() const
|
||||
QgsFeatureRequest QgsRelation::getReferencedFeatureRequest( const QgsAttributes& attributes ) const
|
||||
{
|
||||
QStringList conditions;
|
||||
|
||||
Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mFieldPairs )
|
||||
{
|
||||
int referencedIdx = referencedLayer()->pendingFields().indexFromName( fieldPair.referencedField() );
|
||||
int referencingIdx = referencingLayer()->pendingFields().indexFromName( fieldPair.referencingField() );
|
||||
|
||||
QgsField referencedField = referencedLayer()->pendingFields().at( referencedIdx );
|
||||
|
||||
if ( referencedField.type() == QVariant::String )
|
||||
{
|
||||
// Use quotes
|
||||
conditions << QString( "\"%1\" = '%2'" ).arg( fieldPair.referencedField(), attributes[referencingIdx].toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// No quotes
|
||||
conditions << QString( "\"%1\" = %2" ).arg( fieldPair.referencedField(), attributes[referencingIdx].toString() );
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureRequest myRequest;
|
||||
|
||||
QgsDebugMsg( QString( "Filter conditions: '%1'" ).arg( conditions.join( " AND " ) ) );
|
||||
|
||||
myRequest.setFilterExpression( conditions.join( " AND " ) );
|
||||
|
||||
return myRequest;
|
||||
}
|
||||
|
||||
QgsFeatureRequest QgsRelation::getReferencedFeatureRequest( const QgsFeature& feature ) const
|
||||
{
|
||||
return getReferencedFeatureRequest( feature.attributes() );
|
||||
}
|
||||
|
||||
QgsFeature QgsRelation::getReferencedFeature( const QgsFeature& child ) const
|
||||
{
|
||||
QgsFeatureRequest request = getReferencedFeatureRequest( child );
|
||||
|
||||
QgsFeature f;
|
||||
mReferencedLayer->getFeatures( request ).nextFeature( f );
|
||||
return f;
|
||||
}
|
||||
|
||||
QString QgsRelation::name() const
|
||||
{
|
||||
return mRelationName;
|
||||
}
|
||||
|
||||
const QString& QgsRelation::id() const
|
||||
QString QgsRelation::id() const
|
||||
{
|
||||
return mRelationId;
|
||||
}
|
||||
@ -251,8 +295,3 @@ void QgsRelation::updateRelationStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRelation::runChecks()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -138,17 +138,55 @@ class CORE_EXPORT QgsRelation
|
||||
*
|
||||
* @param feature A feature from the referenced (parent) layer
|
||||
*
|
||||
* @return An request for all the referenced features
|
||||
* @return A request for all the referencing features
|
||||
*/
|
||||
QgsFeatureRequest getRelatedFeaturesRequest( const QgsFeature& feature ) const;
|
||||
|
||||
const QString name() const;
|
||||
/**
|
||||
* Creates a request to return the feature on the referenced (parent) layer
|
||||
* which is referenced by the provided feature.
|
||||
*
|
||||
* @param attributes An attribute vector containing the foreign key
|
||||
*
|
||||
* @return A request the referenced feature
|
||||
*/
|
||||
QgsFeatureRequest getReferencedFeatureRequest( const QgsAttributes& attributes ) const;
|
||||
|
||||
/**
|
||||
* The id
|
||||
* @return
|
||||
* Creates a request to return the feature on the referenced (parent) layer
|
||||
* which is referenced by the provided feature.
|
||||
*
|
||||
* @param feature A feature from the referencing (child) layer
|
||||
*
|
||||
* @return A request the referenced feature
|
||||
*/
|
||||
const QString& id() const;
|
||||
QgsFeatureRequest getReferencedFeatureRequest( const QgsFeature& feature ) const;
|
||||
|
||||
/**
|
||||
* Creates a request to return the feature on the referenced (parent) layer
|
||||
* which is referenced by the provided feature.
|
||||
*
|
||||
* @param feature A feature from the referencing (child) layer
|
||||
*
|
||||
* @return A request the referenced feature
|
||||
*/
|
||||
QgsFeature getReferencedFeature( const QgsFeature& child ) const;
|
||||
|
||||
/**
|
||||
* Returns a human readable name for this relation. Mostly used as title for the children.
|
||||
*
|
||||
* @see id()
|
||||
*
|
||||
* @return A name
|
||||
*/
|
||||
QString name() const;
|
||||
|
||||
/**
|
||||
* A (project-wide) unique id for this relation
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
QString id() const;
|
||||
|
||||
/**
|
||||
* Access the referencing (child) layer's id
|
||||
@ -198,7 +236,6 @@ class CORE_EXPORT QgsRelation
|
||||
|
||||
protected:
|
||||
void updateRelationStatus();
|
||||
void runChecks();
|
||||
|
||||
private:
|
||||
/** Unique Id */
|
||||
|
@ -25,110 +25,122 @@ from utilities import (getQgisTestApp,
|
||||
TestCase,
|
||||
unittest
|
||||
)
|
||||
|
||||
QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp()
|
||||
|
||||
|
||||
def createReferencingLayer():
|
||||
layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer",
|
||||
"referencinglayer", "memory")
|
||||
pr = layer.dataProvider()
|
||||
f1 = QgsFeature()
|
||||
f1.setFields( layer.pendingFields() )
|
||||
f1.setFields(layer.pendingFields())
|
||||
f1.setAttributes(["test1", 123])
|
||||
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(100,200)))
|
||||
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200)))
|
||||
f2 = QgsFeature()
|
||||
f2.setFields( layer.pendingFields() )
|
||||
f2.setFields(layer.pendingFields())
|
||||
f2.setAttributes(["test2", 123])
|
||||
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(101,201)))
|
||||
assert pr.addFeatures([f1,f2])
|
||||
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(101, 201)))
|
||||
assert pr.addFeatures([f1, f2])
|
||||
return layer
|
||||
|
||||
|
||||
def createReferencedLayer():
|
||||
layer = QgsVectorLayer(
|
||||
"Point?field=x:string&field=y:integer&field=z:integer",
|
||||
"referencedlayer", "memory")
|
||||
pr = layer.dataProvider()
|
||||
f1 = QgsFeature()
|
||||
f1.setFields( layer.pendingFields() )
|
||||
f1.setFields(layer.pendingFields())
|
||||
f1.setAttributes(["foo", 123, 321])
|
||||
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1,1)))
|
||||
f1.setGeometry(QgsGeometry.fromPoint(QgsPoint(1, 1)))
|
||||
f2 = QgsFeature()
|
||||
f2.setFields( layer.pendingFields() )
|
||||
f2.setFields(layer.pendingFields())
|
||||
f2.setAttributes(["bar", 456, 654])
|
||||
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2,2)))
|
||||
f2.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 2)))
|
||||
f3 = QgsFeature()
|
||||
f3.setFields( layer.pendingFields() )
|
||||
f3.setFields(layer.pendingFields())
|
||||
f3.setAttributes(["foobar", 789, 554])
|
||||
f3.setGeometry(QgsGeometry.fromPoint(QgsPoint(2,3)))
|
||||
f3.setGeometry(QgsGeometry.fromPoint(QgsPoint(2, 3)))
|
||||
assert pr.addFeatures([f1, f2, f3])
|
||||
return layer
|
||||
|
||||
def formatAttributes(attrs):
|
||||
return repr([ unicode(a) for a in attrs ])
|
||||
|
||||
class TestQgsRelation( TestCase ):
|
||||
def formatAttributes(attrs):
|
||||
return repr([unicode(a) for a in attrs])
|
||||
|
||||
|
||||
class TestQgsRelation(TestCase):
|
||||
def setUp(self):
|
||||
self.referencedLayer = createReferencedLayer()
|
||||
self.referencingLayer = createReferencingLayer()
|
||||
QgsMapLayerRegistry.instance().addMapLayers([self.referencedLayer, self.referencingLayer])
|
||||
|
||||
def tearDown(self):
|
||||
QgsMapLayerRegistry.instance().removeAllMapLayers()
|
||||
|
||||
def test_isValid(self):
|
||||
referencedLayer = createReferencedLayer()
|
||||
referencingLayer = createReferencingLayer()
|
||||
QgsMapLayerRegistry.instance().addMapLayers([referencedLayer,referencingLayer])
|
||||
|
||||
rel = QgsRelation()
|
||||
assert not rel.isValid()
|
||||
|
||||
rel.setRelationId( 'rel1' )
|
||||
rel.setRelationId('rel1')
|
||||
assert not rel.isValid()
|
||||
|
||||
rel.setRelationName( 'Relation Number One' )
|
||||
rel.setRelationName('Relation Number One')
|
||||
assert not rel.isValid()
|
||||
|
||||
rel.setReferencingLayer( referencingLayer.id() )
|
||||
rel.setReferencingLayer(self.referencingLayer.id())
|
||||
assert not rel.isValid()
|
||||
|
||||
rel.setReferencedLayer( referencedLayer.id() )
|
||||
rel.setReferencedLayer(self.referencedLayer.id())
|
||||
assert not rel.isValid()
|
||||
|
||||
rel.addFieldPair( 'foreignkey', 'y' )
|
||||
rel.addFieldPair('foreignkey', 'y')
|
||||
assert rel.isValid()
|
||||
|
||||
QgsMapLayerRegistry.instance().removeAllMapLayers()
|
||||
|
||||
def test_getRelatedFeatures(self):
|
||||
referencedLayer = createReferencedLayer()
|
||||
referencingLayer = createReferencingLayer()
|
||||
QgsMapLayerRegistry.instance().addMapLayers([referencedLayer,referencingLayer])
|
||||
|
||||
rel = QgsRelation()
|
||||
|
||||
rel.setRelationId( 'rel1' )
|
||||
rel.setRelationName( 'Relation Number One' )
|
||||
rel.setReferencingLayer( referencingLayer.id() )
|
||||
rel.setReferencedLayer( referencedLayer.id() )
|
||||
rel.addFieldPair( 'foreignkey', 'y' )
|
||||
rel.setRelationId('rel1')
|
||||
rel.setRelationName('Relation Number One')
|
||||
rel.setReferencingLayer(self.referencingLayer.id())
|
||||
rel.setReferencedLayer(self.referencedLayer.id())
|
||||
rel.addFieldPair('foreignkey', 'y')
|
||||
|
||||
feat = referencedLayer.getFeatures().next()
|
||||
feat = self.referencedLayer.getFeatures().next()
|
||||
|
||||
it = rel.getRelatedFeatures( feat )
|
||||
it = rel.getRelatedFeatures(feat)
|
||||
|
||||
[ a.attributes() for a in it ] == [[u'test1', 123], [u'test2', 123]]
|
||||
assert [a.attributes() for a in it] == [[u'test1', 123], [u'test2', 123]]
|
||||
|
||||
def test_getReferencedFeature(self):
|
||||
rel = QgsRelation()
|
||||
rel.setRelationId('rel1')
|
||||
rel.setRelationName('Relation Number One')
|
||||
rel.setReferencingLayer(self.referencingLayer.id())
|
||||
rel.setReferencedLayer(self.referencedLayer.id())
|
||||
rel.addFieldPair('foreignkey', 'y')
|
||||
|
||||
feat = self.referencingLayer.getFeatures().next()
|
||||
|
||||
f = rel.getReferencedFeature(feat)
|
||||
|
||||
assert f.isValid()
|
||||
assert f[0] == 'foo'
|
||||
|
||||
QgsMapLayerRegistry.instance().removeAllMapLayers()
|
||||
|
||||
def test_fieldPairs(self):
|
||||
referencedLayer = createReferencedLayer()
|
||||
referencingLayer = createReferencingLayer()
|
||||
QgsMapLayerRegistry.instance().addMapLayers([referencedLayer,referencingLayer])
|
||||
|
||||
rel = QgsRelation()
|
||||
|
||||
rel.setRelationId( 'rel1' )
|
||||
rel.setRelationName( 'Relation Number One' )
|
||||
rel.setReferencingLayer( referencingLayer.id() )
|
||||
rel.setReferencedLayer( referencedLayer.id() )
|
||||
rel.addFieldPair( 'foreignkey', 'y' )
|
||||
rel.setRelationId('rel1')
|
||||
rel.setRelationName('Relation Number One')
|
||||
rel.setReferencingLayer(self.referencingLayer.id())
|
||||
rel.setReferencedLayer(self.referencedLayer.id())
|
||||
rel.addFieldPair('foreignkey', 'y')
|
||||
|
||||
assert( rel.fieldPairs() == { 'foreignkey': 'y'} )
|
||||
|
||||
QgsMapLayerRegistry.instance().removeAllMapLayers()
|
||||
assert (rel.fieldPairs() == {'foreignkey': 'y'})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
x
Reference in New Issue
Block a user