581
583
// Only try to draw polygons if there is something to draw
582
584
if ( total_points > 0 )
584
// Store size here and use it in the loop to avoid penalty of
585
// multiple calls to size()
586
int numRings = rings.size();
587
for ( register int i = 0; i < numRings; ++i )
589
// Store the pointer in a variable with a short name so as to make
590
// the following code easier to type and read.
591
ringTypePtr r = rings[i];
592
// only do this once to avoid penalty of additional calls
593
unsigned ringSize = r->first.size();
595
// Transfer points to the array of QPointF
596
QPolygonF pa( ringSize );
597
for ( register unsigned int j = 0; j != ringSize; ++j )
599
pa[j].setX( r->first[j] );
600
pa[j].setY( r->second[j] );
603
path.addPolygon( pa );
605
// Tidy up the pointed to pairs of vectors as we finish with them
610
// A bit of code to aid in working out what values of
611
// QgsClipper::minX, etc cause the X11 zoom bug.
612
int largestX = -std::numeric_limits<int>::max();
613
int smallestX = std::numeric_limits<int>::max();
614
int largestY = -std::numeric_limits<int>::max();
615
int smallestY = std::numeric_limits<int>::max();
617
for ( int i = 0; i < pa.size(); ++i )
619
largestX = std::max( largestX, pa.point( i ).x() );
620
smallestX = std::min( smallestX, pa.point( i ).x() );
621
largestY = std::max( largestY, pa.point( i ).y() );
622
smallestY = std::min( smallestY, pa.point( i ).y() );
624
QgsDebugMsg( QString( "Largest X coordinate was %1" ).arg( largestX ) );
625
QgsDebugMsg( QString( "Smallest X coordinate was %1" ).arg( smallestX ) );
626
QgsDebugMsg( QString( "Largest Y coordinate was %1" ).arg( largestY ) );
627
QgsDebugMsg( QString( "Smallest Y coordinate was %1" ).arg( smallestY ) );
630
586
//preserve a copy of the brush and pen before we start fiddling with it
631
587
QBrush brush = p->brush(); //to be kept as original
632
588
QPen pen = p->pen(); // to be kept original
658
614
p->setBrush( myTransparentBrush );
659
615
p->setPen( myTransparentPen );
667
// draw vertex markers if in editing mode, but only to the main canvas
668
if ( mEditable && renderContext.drawEditingInformation() )
670
for ( int i = 0; i < path.elementCount(); ++i )
672
const QPainterPath::Element & e = path.elementAt( i );
673
drawVertexMarker( e.x, e.y, *p, mCurrentVertexMarkerType, mCurrentVertexMarkerSize );
619
ringTypePtr r = rings[0];
620
unsigned ringSize = r->first.size();
622
QPolygonF pa( ringSize );
623
for ( register unsigned int j = 0; j != ringSize; ++j )
625
pa[j].setX( r->first[j] );
626
pa[j].setY( r->second[j] );
628
p->drawPolygon( pa );
630
// draw vertex markers if in editing mode, but only to the main canvas
631
if ( mEditable && renderContext.drawEditingInformation() )
633
for ( register unsigned int j = 0; j != ringSize; ++j )
635
drawVertexMarker( r->first[j], r->second[j], *p, mCurrentVertexMarkerType, mCurrentVertexMarkerSize );
643
// Store size here and use it in the loop to avoid penalty of
644
// multiple calls to size()
645
int numRings = rings.size();
646
for ( register int i = 0; i < numRings; ++i )
648
// Store the pointer in a variable with a short name so as to make
649
// the following code easier to type and read.
650
ringTypePtr r = rings[i];
651
// only do this once to avoid penalty of additional calls
652
unsigned ringSize = r->first.size();
654
// Transfer points to the array of QPointF
655
QPolygonF pa( ringSize );
656
for ( register unsigned int j = 0; j != ringSize; ++j )
658
pa[j].setX( r->first[j] );
659
pa[j].setY( r->second[j] );
662
path.addPolygon( pa );
664
// Tidy up the pointed to pairs of vectors as we finish with them
669
// A bit of code to aid in working out what values of
670
// QgsClipper::minX, etc cause the X11 zoom bug.
671
int largestX = -std::numeric_limits<int>::max();
672
int smallestX = std::numeric_limits<int>::max();
673
int largestY = -std::numeric_limits<int>::max();
674
int smallestY = std::numeric_limits<int>::max();
676
for ( int i = 0; i < pa.size(); ++i )
678
largestX = qMax( largestX, pa.point( i ).x() );
679
smallestX = qMin( smallestX, pa.point( i ).x() );
680
largestY = qMax( largestY, pa.point( i ).y() );
681
smallestY = qMin( smallestY, pa.point( i ).y() );
683
QgsDebugMsg( QString( "Largest X coordinate was %1" ).arg( largestX ) );
684
QgsDebugMsg( QString( "Smallest X coordinate was %1" ).arg( smallestX ) );
685
QgsDebugMsg( QString( "Largest Y coordinate was %1" ).arg( largestY ) );
686
QgsDebugMsg( QString( "Smallest Y coordinate was %1" ).arg( smallestY ) );
694
// draw vertex markers if in editing mode, but only to the main canvas
695
if ( mEditable && renderContext.drawEditingInformation() )
697
for ( int i = 0; i < path.elementCount(); ++i )
699
const QPainterPath::Element & e = path.elementAt( i );
700
drawVertexMarker( e.x, e.y, *p, mCurrentVertexMarkerType, mCurrentVertexMarkerSize );
688
716
void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool labeling )
718
if ( !hasGeometryType() )
690
721
QSettings settings;
691
722
bool vertexMarkerOnlyForSelection = settings.value( "/qgis/digitizing/marker_only_for_selected", false ).toBool();
693
724
mRendererV2->startRender( rendererContext, this );
695
QgsSingleSymbolRendererV2* selRenderer = NULL;
696
if ( !mSelectedFeatureIds.isEmpty() )
698
selRenderer = new QgsSingleSymbolRendererV2( QgsSymbolV2::defaultSymbol( geometryType() ) );
699
selRenderer->symbol()->setColor( QgsRenderer::selectionColor() );
700
selRenderer->setVertexMarkerAppearance( currentVertexMarkerType(), currentVertexMarkerSize() );
701
selRenderer->startRender( rendererContext, this );
727
int featureCount = 0;
705
731
while ( nextFeature( fet ) )
735
if ( rendererContext.renderingStopped() )
740
#ifndef Q_WS_MAC //MH: disable this on Mac for now to avoid problems with resizing
741
if ( mUpdateThreshold > 0 && 0 == featureCount % mUpdateThreshold )
743
emit screenUpdateRequested();
744
// emit drawingProgress( featureCount, totalFeatures );
745
qApp->processEvents();
747
else if ( featureCount % 1000 == 0 )
749
// emit drawingProgress( featureCount, totalFeatures );
750
qApp->processEvents();
709
754
bool sel = mSelectedFeatureIds.contains( fet.id() );
710
755
bool drawMarker = ( mEditable && ( !vertexMarkerOnlyForSelection || sel ) );
712
757
// render feature
714
selRenderer->renderFeature( fet, rendererContext, -1, drawMarker );
716
mRendererV2->renderFeature( fet, rendererContext, -1, drawMarker );
718
// labeling - register feature
719
if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
720
rendererContext.labelingEngine()->registerFeature( this, fet );
758
mRendererV2->renderFeature( fet, rendererContext, -1, sel, drawMarker );
724
762
// Cache this for the use of (e.g.) modifying the feature's uncommitted geometry.
725
763
mCachedGeometries[fet.id()] = *fet.geometry();
766
// labeling - register feature
767
if ( mRendererV2->symbolForFeature( fet ) != NULL && rendererContext.labelingEngine() )
771
rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
773
if ( mDiagramRenderer )
775
rendererContext.labelingEngine()->registerDiagramFeature( this, fet, rendererContext );
728
779
catch ( const QgsCsException &cse )
730
QString msg( "Failed to transform a point while drawing a feature of type '"
731
+ fet.typeName() + "'. Ignoring this feature." );
733
QgsLogger::warning( msg );
781
QgsDebugMsg( QString( "Failed to transform a point while drawing a feature of type '%1'. Ignoring this feature. %2" )
782
.arg( fet.typeName() ).arg( cse.what() ) );
737
mRendererV2->stopRender( rendererContext );
741
selRenderer->stopRender( rendererContext );
790
QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
746
794
void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bool labeling )
796
if ( !hasGeometryType() )
748
799
QHash< QgsSymbolV2*, QList<QgsFeature> > features; // key = symbol, value = array of features
750
801
QSettings settings;
814
899
int layer = item.layer();
815
900
QList<QgsFeature>& lst = features[item.symbol()];
816
901
QList<QgsFeature>::iterator fit;
817
905
for ( fit = lst.begin(); fit != lst.end(); ++fit )
907
if ( rendererContext.renderingStopped() )
909
stopRendererV2( rendererContext, selRenderer );
913
if ( featureCount % 1000 == 0 )
915
qApp->processEvents();
819
918
bool sel = mSelectedFeatureIds.contains( fit->id() );
820
919
// maybe vertex markers should be drawn only during the last pass...
821
920
bool drawMarker = ( mEditable && ( !vertexMarkerOnlyForSelection || sel ) );
826
selRenderer->renderFeature( *fit, rendererContext, -1, drawMarker );
828
mRendererV2->renderFeature( *fit, rendererContext, layer, drawMarker );
924
mRendererV2->renderFeature( *fit, rendererContext, layer, sel, drawMarker );
830
926
catch ( const QgsCsException &cse )
832
QString msg( "Failed to transform a point while drawing a feature of type '"
833
+ fet.typeName() + "'. Ignoring this feature." );
835
QgsLogger::warning( msg );
928
QgsDebugMsg( QString( "Failed to transform a point while drawing a feature of type '%1'. Ignoring this feature. %2" )
929
.arg( fet.typeName() ).arg( cse.what() ) );
841
mRendererV2->stopRender( rendererContext );
938
stopRendererV2( rendererContext, selRenderer );
941
void QgsVectorLayer::reload()
845
selRenderer->stopRender( rendererContext );
945
mDataProvider->reloadData();
850
949
bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
951
if ( !hasGeometryType() )
954
//set update threshold before each draw to make sure the current setting is picked up
956
mUpdateThreshold = settings.value( "Map/updateThreshold", 0 ).toInt();
852
958
if ( mUsingRendererV2 )
854
960
if ( mRendererV2 == NULL )
857
963
QgsDebugMsg( "rendering v2:\n" + mRendererV2->dump() );
1439
1554
// null/add all attributes that were added, but don't exist in the feature yet
1440
1555
for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
1441
if ( !map.contains( it.key() ) )
1556
if ( !map.contains( it.key() ) && ( all || mFetchAttributes.contains( it.key() ) ) )
1442
1557
f.changeAttribute( it.key(), QVariant( QString::null ) );
1560
void QgsVectorLayer::addJoinedFeatureAttributes( QgsFeature& f, const QgsVectorJoinInfo& joinInfo, const QString& joinFieldName,
1561
const QVariant& joinValue, const QgsAttributeList& attributes, int attributeIndexOffset )
1563
const QHash< QString, QgsAttributeMap>& memoryCache = joinInfo.cachedAttributes;
1564
if ( !memoryCache.isEmpty() ) //use join memory cache
1566
QgsAttributeMap featureAttributes = memoryCache.value( joinValue.toString() );
1567
bool found = !featureAttributes.isEmpty();
1568
QgsAttributeList::const_iterator attIt = attributes.constBegin();
1569
for ( ; attIt != attributes.constEnd(); ++attIt )
1573
f.addAttribute( *attIt + attributeIndexOffset, featureAttributes.value( *attIt ) );
1577
f.addAttribute( *attIt + attributeIndexOffset, QVariant() );
1581
else //work with subset string
1583
QgsVectorLayer* joinLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) );
1589
//no memory cache, query the joined values by setting substring
1590
QString subsetString = joinLayer->dataProvider()->subsetString(); //provider might already have a subset string
1591
QString bkSubsetString = subsetString;
1592
if ( !subsetString.isEmpty() )
1594
subsetString.append( " AND " );
1597
subsetString.append( "\"" + joinFieldName + "\"" + " = " + "\"" + joinValue.toString() + "\"" );
1598
joinLayer->dataProvider()->setSubsetString( subsetString, false );
1600
//select (no geometry)
1601
joinLayer->select( attributes, QgsRectangle(), false, false );
1605
if ( joinLayer->nextFeature( fet ) )
1607
QgsAttributeMap attMap = fet.attributeMap();
1608
QgsAttributeMap::const_iterator attIt = attMap.constBegin();
1609
for ( ; attIt != attMap.constEnd(); ++attIt )
1611
f.addAttribute( attIt.key() + attributeIndexOffset, attIt.value() );
1614
else //no suitable join feature found, insert invalid variants
1616
QgsAttributeList::const_iterator attIt = attributes.constBegin();
1617
for ( ; attIt != attributes.constEnd(); ++attIt )
1619
f.addAttribute( *attIt + attributeIndexOffset, QVariant() );
1623
joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
1445
1627
void QgsVectorLayer::updateFeatureGeometry( QgsFeature &f )
1447
1629
if ( mChangedGeometries.contains( f.id() ) )
1470
1652
//look in the normal features of the provider
1471
1653
if ( mFetchAttributes.size() > 0 )
1655
if ( mEditable || mJoinBuffer->containsJoins() )
1475
// fetch only available field from provider
1476
QgsAttributeList provAttributes;
1657
QgsAttributeList joinFields;
1659
int maxProviderIndex = 0;
1660
if ( mDataProvider )
1662
QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
1665
mJoinBuffer->select( mFetchAttributes, joinFields, maxProviderIndex );
1666
QgsAttributeList::const_iterator joinFieldIt = joinFields.constBegin();
1667
for ( ; joinFieldIt != joinFields.constEnd(); ++joinFieldIt )
1669
if ( !mFetchAttributes.contains( *joinFieldIt ) )
1671
mFetchAttributes.append( *joinFieldIt );
1675
//detect which fields are from the provider
1676
mFetchProvAttributes.clear();
1477
1677
for ( QgsAttributeList::iterator it = mFetchAttributes.begin(); it != mFetchAttributes.end(); it++ )
1479
if ( !mUpdatedFields.contains( *it ) || mAddedAttributeIds.contains( *it ) )
1482
provAttributes << *it;
1679
if ( mDataProvider->fields().contains( *it ) )
1681
mFetchProvAttributes << *it;
1485
mDataProvider->select( provAttributes, rect, fetchGeometries, useIntersect );
1685
mDataProvider->select( mFetchProvAttributes, rect, fetchGeometries, useIntersect );
1488
1689
mDataProvider->select( mFetchAttributes, rect, fetchGeometries, useIntersect );
1692
else //we don't need any attributes at all
1492
1694
mDataProvider->select( QgsAttributeList(), rect, fetchGeometries, useIntersect );
2585
2838
layer_node.appendChild( provider );
2842
mJoinBuffer->writeXml( layer_node, document );
2588
2844
// renderer specific settings
2589
2845
QString errorMsg;
2590
if ( !writeSymbology( layer_node, document, errorMsg ) )
2846
return writeSymbology( layer_node, document, errorMsg );
2596
2847
} // bool QgsVectorLayer::writeXml
2598
2849
bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
2600
// try renderer v2 first
2601
QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
2602
if ( !rendererElement.isNull() )
2604
// using renderer v2
2605
setUsingRendererV2( true );
2607
QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
2615
// using renderer v1
2616
setUsingRendererV2( false );
2618
// create and bind a renderer to this layer
2620
QDomNode singlenode = node.namedItem( "singlesymbol" );
2621
QDomNode graduatednode = node.namedItem( "graduatedsymbol" );
2622
QDomNode continuousnode = node.namedItem( "continuoussymbol" );
2623
QDomNode uniquevaluenode = node.namedItem( "uniquevalue" );
2625
QgsRenderer * renderer = 0;
2628
if ( !singlenode.isNull() )
2630
renderer = new QgsSingleSymbolRenderer( geometryType() );
2631
returnCode = renderer->readXML( singlenode, *this );
2633
else if ( !graduatednode.isNull() )
2635
renderer = new QgsGraduatedSymbolRenderer( geometryType() );
2636
returnCode = renderer->readXML( graduatednode, *this );
2638
else if ( !continuousnode.isNull() )
2640
renderer = new QgsContinuousColorRenderer( geometryType() );
2641
returnCode = renderer->readXML( continuousnode, *this );
2643
else if ( !uniquevaluenode.isNull() )
2645
renderer = new QgsUniqueValueRenderer( geometryType() );
2646
returnCode = renderer->readXML( uniquevaluenode, *this );
2651
errorMessage = tr( "Unknown renderer" );
2655
if ( returnCode == 1 )
2657
errorMessage = tr( "No renderer object" ); delete renderer; return false;
2659
else if ( returnCode == 2 )
2661
errorMessage = tr( "Classification field not found" ); delete renderer; return false;
2664
mRenderer = renderer;
2851
if ( hasGeometryType() )
2853
// try renderer v2 first
2854
QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
2855
if ( !rendererElement.isNull() )
2857
// using renderer v2
2858
setUsingRendererV2( true );
2860
QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
2868
// using renderer v1
2869
setUsingRendererV2( false );
2871
// create and bind a renderer to this layer
2873
QDomNode singlenode = node.namedItem( "singlesymbol" );
2874
QDomNode graduatednode = node.namedItem( "graduatedsymbol" );
2875
QDomNode continuousnode = node.namedItem( "continuoussymbol" );
2876
QDomNode uniquevaluenode = node.namedItem( "uniquevalue" );
2878
QgsRenderer * renderer = 0;
2881
if ( !singlenode.isNull() )
2883
renderer = new QgsSingleSymbolRenderer( geometryType() );
2884
returnCode = renderer->readXML( singlenode, *this );
2886
else if ( !graduatednode.isNull() )
2888
renderer = new QgsGraduatedSymbolRenderer( geometryType() );
2889
returnCode = renderer->readXML( graduatednode, *this );
2891
else if ( !continuousnode.isNull() )
2893
renderer = new QgsContinuousColorRenderer( geometryType() );
2894
returnCode = renderer->readXML( continuousnode, *this );
2896
else if ( !uniquevaluenode.isNull() )
2898
renderer = new QgsUniqueValueRenderer( geometryType() );
2899
returnCode = renderer->readXML( uniquevaluenode, *this );
2904
errorMessage = tr( "Unknown renderer" );
2908
if ( returnCode == 1 )
2910
errorMessage = tr( "No renderer object" ); delete renderer; return false;
2912
else if ( returnCode == 2 )
2914
errorMessage = tr( "Classification field not found" ); delete renderer; return false;
2917
mRenderer = renderer;
2920
// get and set the display field if it exists.
2921
QDomNode displayFieldNode = node.namedItem( "displayfield" );
2922
if ( !displayFieldNode.isNull() )
2924
QDomElement e = displayFieldNode.toElement();
2925
setDisplayField( e.text() );
2928
// use scale dependent visibility flag
2929
QDomElement e = node.toElement();
2930
mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
2931
mLabel->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
2932
mLabel->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
2934
//also restore custom properties (for labeling-ng)
2935
readCustomProperties( node, "labeling" );
2937
// Test if labeling is on or off
2938
QDomNode labelnode = node.namedItem( "label" );
2939
QDomElement element = labelnode.toElement();
2940
int hasLabelsEnabled = element.text().toInt();
2941
if ( hasLabelsEnabled < 1 )
2943
enableLabels( false );
2947
enableLabels( true );
2950
QDomNode labelattributesnode = node.namedItem( "labelattributes" );
2952
if ( !labelattributesnode.isNull() )
2954
QgsDebugMsg( "calling readXML" );
2955
mLabel->readXML( labelattributesnode );
2958
//diagram renderer and diagram layer settings
2959
delete mDiagramRenderer; mDiagramRenderer = 0;
2960
QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
2961
if ( !singleCatDiagramElem.isNull() )
2963
mDiagramRenderer = new QgsSingleCategoryDiagramRenderer();
2964
mDiagramRenderer->readXML( singleCatDiagramElem );
2966
QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
2967
if ( !linearDiagramElem.isNull() )
2969
mDiagramRenderer = new QgsLinearlyInterpolatedDiagramRenderer();
2970
mDiagramRenderer->readXML( linearDiagramElem );
2973
if ( mDiagramRenderer )
2975
QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
2976
if ( !diagramSettingsElem.isNull() )
2978
mDiagramLayerSettings = new QgsDiagramLayerSettings();
2979
mDiagramLayerSettings->readXML( diagramSettingsElem );
2668
2984
// process the attribute actions
2669
2985
mActions->readXML( node );
2671
// get and set the display field if it exists.
2672
QDomNode displayFieldNode = node.namedItem( "displayfield" );
2673
if ( !displayFieldNode.isNull() )
2675
QDomElement e = displayFieldNode.toElement();
2676
setDisplayField( e.text() );
2679
// use scale dependent visibility flag
2680
QDomElement e = node.toElement();
2681
label()->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
2682
label()->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
2683
label()->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
2685
2987
mEditTypes.clear();
2686
2988
QDomNode editTypesNode = node.namedItem( "edittypes" );
2687
2989
if ( !editTypesNode.isNull() )
2737
3041
mEditFormInit = editFormInitNode.toElement().text();
3044
QDomNode annotationFormNode = node.namedItem( "annotationform" );
3045
if ( !annotationFormNode.isNull() )
3047
QDomElement e = annotationFormNode.toElement();
3048
mAnnotationForm = QgsProject::instance()->readPath( e.text() );
2740
3051
mAttributeAliasMap.clear();
2741
3052
QDomNode aliasesNode = node.namedItem( "aliases" );
2742
3053
if ( !aliasesNode.isNull() )
2744
3055
QDomElement aliasElem;
2748
3058
QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( "alias" );
2749
3059
for ( int i = 0; i < aliasNodeList.size(); ++i )
2751
3061
aliasElem = aliasNodeList.at( i ).toElement();
2752
index = aliasElem.attribute( "index" ).toInt();
2753
name = aliasElem.attribute( "name" );
2754
mAttributeAliasMap.insert( index, name );
3064
if ( aliasElem.hasAttribute( "field" ) )
3066
field = aliasElem.attribute( "field" );
3070
int index = aliasElem.attribute( "index" ).toInt();
3072
if ( pendingFields().contains( index ) )
3073
field = pendingFields()[ index ].name();
3076
mAttributeAliasMap.insert( field, aliasElem.attribute( "name" ) );
2758
// Test if labeling is on or off
2759
QDomNode labelnode = node.namedItem( "label" );
2760
QDomElement element = labelnode.toElement();
2761
int hasLabelsEnabled = element.text().toInt();
2762
if ( hasLabelsEnabled < 1 )
2764
enableLabels( false );
2768
enableLabels( true );
2771
QDomNode labelattributesnode = node.namedItem( "labelattributes" );
2773
if ( !labelattributesnode.isNull() )
2775
QgsDebugMsg( "qgsvectorlayer calling label readXML routine" );
2776
mLabel->readXML( labelattributesnode );
2782
3083
bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2784
if ( mUsingRendererV2 )
2786
QDomElement rendererElement = mRendererV2->save( doc );
2787
node.appendChild( rendererElement );
2791
//classification field(s)
2792
QgsAttributeList attributes = mRenderer->classificationAttributes();
2793
const QgsFieldMap providerFields = mDataProvider->fields();
2794
for ( QgsAttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it )
2796
QDomElement classificationElement = doc.createElement( "classificationattribute" );
2797
QDomText classificationText = doc.createTextNode( providerFields[*it].name() );
2798
classificationElement.appendChild( classificationText );
2799
node.appendChild( classificationElement );
2802
// renderer settings
2803
const QgsRenderer * myRenderer = renderer();
2806
if ( !myRenderer->writeXML( node, doc, *this ) )
2808
errorMessage = "renderer failed to save";
2814
QgsDebugMsg( "no renderer" );
2815
errorMessage = "no renderer";
2820
// use scale dependent visibility flag
2821
3085
QDomElement mapLayerNode = node.toElement();
2822
mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", label()->scaleBasedVisibility() ? 1 : 0 );
2823
mapLayerNode.setAttribute( "minLabelScale", label()->minScale() );
2824
mapLayerNode.setAttribute( "maxLabelScale", label()->maxScale() );
3087
if ( hasGeometryType() )
3089
if ( mUsingRendererV2 )
3091
QDomElement rendererElement = mRendererV2->save( doc );
3092
node.appendChild( rendererElement );
3096
// use scale dependent visibility flag
3097
mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
3098
mapLayerNode.setAttribute( "minLabelScale", mLabel->minScale() );
3099
mapLayerNode.setAttribute( "maxLabelScale", mLabel->maxScale() );
3101
//classification field(s)
3102
QgsAttributeList attributes = mRenderer->classificationAttributes();
3103
const QgsFieldMap providerFields = mDataProvider->fields();
3104
for ( QgsAttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it )
3106
QDomElement classificationElement = doc.createElement( "classificationattribute" );
3107
QDomText classificationText = doc.createTextNode( providerFields[*it].name() );
3108
classificationElement.appendChild( classificationText );
3109
node.appendChild( classificationElement );
3112
// renderer settings
3113
const QgsRenderer * myRenderer = renderer();
3116
if ( !myRenderer->writeXML( node, doc, *this ) )
3118
errorMessage = tr( "renderer failed to save" );
3124
QgsDebugMsg( "no renderer" );
3125
errorMessage = tr( "no renderer" );
3130
//save customproperties (for labeling ng)
3131
writeCustomProperties( node, doc );
3133
// add the display field
3134
QDomElement dField = doc.createElement( "displayfield" );
3135
QDomText dFieldText = doc.createTextNode( displayField() );
3136
dField.appendChild( dFieldText );
3137
node.appendChild( dField );
3140
QDomElement labelElem = doc.createElement( "label" );
3141
QDomText labelText = doc.createTextNode( "" );
3143
if ( hasLabelsEnabled() )
3145
labelText.setData( "1" );
3149
labelText.setData( "0" );
3151
labelElem.appendChild( labelText );
3153
node.appendChild( labelElem );
3155
// Now we get to do all that all over again for QgsLabel
3157
QString fieldname = mLabel->labelField( QgsLabel::Text );
3158
if ( fieldname != "" )
3160
dField = doc.createElement( "labelfield" );
3161
dFieldText = doc.createTextNode( fieldname );
3162
dField.appendChild( dFieldText );
3163
node.appendChild( dField );
3166
mLabel->writeXML( node, doc );
3168
if ( mDiagramRenderer )
3170
mDiagramRenderer->writeXML( mapLayerNode, doc );
3171
if ( mDiagramLayerSettings )
3172
mDiagramLayerSettings->writeXML( mapLayerNode, doc );
2827
3177
if ( mEditTypes.size() > 0 )
2834
3184
editTypeElement.setAttribute( "name", it.key() );
2835
3185
editTypeElement.setAttribute( "type", it.value() );
2837
if ( it.value() == ValueMap )
2839
if ( mValueMaps.contains( it.key() ) )
2841
const QMap<QString, QVariant> &map = mValueMaps[ it.key()];
2843
for ( QMap<QString, QVariant>::const_iterator vmit = map.begin(); vmit != map.end(); vmit++ )
2845
QDomElement value = doc.createElement( "valuepair" );
2846
value.setAttribute( "key", vmit.key() );
2847
value.setAttribute( "value", vmit.value().toString() );
2848
editTypeElement.appendChild( value );
2852
else if ( it.value() == EditRange || it.value() == SliderRange )
2854
if ( mRanges.contains( it.key() ) )
2856
editTypeElement.setAttribute( "min", mRanges[ it.key()].mMin.toString() );
2857
editTypeElement.setAttribute( "max", mRanges[ it.key()].mMax.toString() );
2858
editTypeElement.setAttribute( "step", mRanges[ it.key()].mStep.toString() );
2861
else if ( it.value() == CheckBox )
2863
if ( mCheckedStates.contains( it.key() ) )
2865
editTypeElement.setAttribute( "checked", mCheckedStates[ it.key()].first );
2866
editTypeElement.setAttribute( "unchecked", mCheckedStates[ it.key()].second );
3187
switch (( EditType ) it.value() )
3190
if ( mValueMaps.contains( it.key() ) )
3192
const QMap<QString, QVariant> &map = mValueMaps[ it.key()];
3194
for ( QMap<QString, QVariant>::const_iterator vmit = map.begin(); vmit != map.end(); vmit++ )
3196
QDomElement value = doc.createElement( "valuepair" );
3197
value.setAttribute( "key", vmit.key() );
3198
value.setAttribute( "value", vmit.value().toString() );
3199
editTypeElement.appendChild( value );
3207
if ( mRanges.contains( it.key() ) )
3209
editTypeElement.setAttribute( "min", mRanges[ it.key()].mMin.toString() );
3210
editTypeElement.setAttribute( "max", mRanges[ it.key()].mMax.toString() );
3211
editTypeElement.setAttribute( "step", mRanges[ it.key()].mStep.toString() );
3216
if ( mCheckedStates.contains( it.key() ) )
3218
editTypeElement.setAttribute( "checked", mCheckedStates[ it.key()].first );
3219
editTypeElement.setAttribute( "unchecked", mCheckedStates[ it.key()].second );
3225
case UniqueValuesEditable:
3226
case Classification:
2870
3236
editTypesElement.appendChild( editTypeElement );
2883
3249
efiField.appendChild( efiText );
2884
3250
node.appendChild( efiField );
3252
QDomElement afField = doc.createElement( "annotationform" );
3253
QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
3254
afField.appendChild( afText );
3255
node.appendChild( afField );
2886
3257
//attribute aliases
2887
3258
if ( mAttributeAliasMap.size() > 0 )
2889
3260
QDomElement aliasElem = doc.createElement( "aliases" );
2890
QMap<int, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
3261
QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
2891
3262
for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
3264
int idx = fieldNameIndex( a_it.key() );
2893
3268
QDomElement aliasEntryElem = doc.createElement( "alias" );
2894
aliasEntryElem.setAttribute( "index", QString::number( a_it.key() ) );
3269
aliasEntryElem.setAttribute( "field", a_it.key() );
3270
aliasEntryElem.setAttribute( "index", idx );
2895
3271
aliasEntryElem.setAttribute( "name", a_it.value() );
2896
3272
aliasElem.appendChild( aliasEntryElem );
2898
3274
node.appendChild( aliasElem );
2901
// add the display field
2902
QDomElement dField = doc.createElement( "displayfield" );
2903
QDomText dFieldText = doc.createTextNode( displayField() );
2904
dField.appendChild( dFieldText );
2905
node.appendChild( dField );
2908
QDomElement label = doc.createElement( "label" );
2909
QDomText labelText = doc.createTextNode( "" );
2911
if ( hasLabelsEnabled() )
2913
labelText.setData( "1" );
2917
labelText.setData( "0" );
2919
label.appendChild( labelText );
2921
node.appendChild( label );
2923
3277
// add attribute actions
2924
3278
mActions->writeXML( node, doc );
2926
// Now we get to do all that all over again for QgsLabel
2928
// XXX Since this is largely a cut-n-paste from the previous, this
2929
// XXX therefore becomes a candidate to be generalized into a separate
2930
// XXX function. I think.
2932
const QgsLabel *myLabel = this->label();
2936
QString fieldname = myLabel->labelField( QgsLabel::Text );
2937
if ( fieldname != "" )
2939
dField = doc.createElement( "labelfield" );
2940
dFieldText = doc.createTextNode( fieldname );
2941
dField.appendChild( dFieldText );
2942
node.appendChild( dField );
2945
myLabel->writeXML( node, doc );
2948
3280
//save vector overlays (e.g. diagrams)
2949
3281
QList<QgsVectorOverlay*>::const_iterator overlay_it = mOverlays.constBegin();
2950
3282
for ( ; overlay_it != mOverlays.constEnd(); ++overlay_it )
4518
4910
for ( QgsFieldMap::const_iterator it = theFields.constBegin(); it != theFields.constEnd(); ++it )
4520
if ( it->name() == fieldName )
4912
if ( QString::compare( it->name(), fieldName, Qt::CaseInsensitive ) == 0 )
4522
4914
return it.key();
4920
void QgsVectorLayer::addJoin( QgsVectorJoinInfo joinInfo )
4922
mJoinBuffer->addJoin( joinInfo );
4926
void QgsVectorLayer::checkJoinLayerRemove( QString theLayerId )
4928
removeJoin( theLayerId );
4931
void QgsVectorLayer::removeJoin( const QString& joinLayerId )
4933
mJoinBuffer->removeJoin( joinLayerId );
4937
const QList< QgsVectorJoinInfo >& QgsVectorLayer::vectorJoins() const
4939
return mJoinBuffer->vectorJoins();
4942
void QgsVectorLayer::updateFieldMap()
4944
//first backup mAddedAttributes
4945
QgsFieldMap bkAddedAttributes;
4946
QgsAttributeIds::const_iterator attIdIt = mAddedAttributeIds.constBegin();
4947
for ( ; attIdIt != mAddedAttributeIds.constEnd(); ++attIdIt )
4949
bkAddedAttributes.insert( *attIdIt, mUpdatedFields.value( *attIdIt ) );
4952
mUpdatedFields = QgsFieldMap();
4953
if ( mDataProvider )
4955
mUpdatedFields = mDataProvider->fields();
4958
int currentMaxIndex = 0; //maximum index of current layer
4959
if ( !QgsVectorLayerJoinBuffer::maximumIndex( mUpdatedFields, currentMaxIndex ) )
4964
mMaxUpdatedIndex = currentMaxIndex;
4967
if ( mJoinBuffer->containsJoins() )
4969
mJoinBuffer->updateFieldMap( mUpdatedFields, mMaxUpdatedIndex );
4972
//insert added attributes after provider fields and joined fields
4973
mAddedAttributeIds.clear();
4974
QgsFieldMap::const_iterator fieldIt = bkAddedAttributes.constBegin();
4975
for ( ; fieldIt != bkAddedAttributes.constEnd(); ++fieldIt )
4978
mUpdatedFields.insert( mMaxUpdatedIndex, fieldIt.value() );
4979
mAddedAttributeIds.insert( mMaxUpdatedIndex );
4981
//go through the changed attributes map and adapt indices of added attributes
4982
for ( int i = 0; i < mChangedAttributeValues.size(); ++i )
4984
updateAttributeMapIndex( mChangedAttributeValues[i], fieldIt.key(), mMaxUpdatedIndex );
4987
//go through added features and adapt attribute maps
4988
QgsFeatureList::iterator featureIt = mAddedFeatures.begin();
4989
for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
4991
QgsAttributeMap attMap = featureIt->attributeMap();
4992
updateAttributeMapIndex( attMap, fieldIt.key(), mMaxUpdatedIndex );
4993
featureIt->setAttributeMap( attMap );
4997
//remove deleted attributes
4998
QgsAttributeIds::const_iterator deletedIt = mDeletedAttributeIds.constBegin();
4999
for ( ; deletedIt != mDeletedAttributeIds.constEnd(); ++deletedIt )
5001
mUpdatedFields.remove( *deletedIt );
5005
void QgsVectorLayer::createJoinCaches()
5007
if ( mJoinBuffer->containsJoins() )
5009
mJoinBuffer->createJoinCaches();
5013
void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
5015
uniqueValues.clear();
5016
if ( !mDataProvider )
5021
int maxProviderIndex;
5022
QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
5024
if ( index <= maxProviderIndex && !mEditable ) //a provider field
5026
return mDataProvider->uniqueValues( index, uniqueValues, limit );
5028
else // a joined field?
5032
int indexOffset; //offset between layer index and joined provider index
5033
const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
5036
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
5037
if ( vl && vl->dataProvider() )
5039
return vl->dataProvider()->uniqueValues( index - indexOffset, uniqueValues, limit );
5046
//the layer is editable, but in certain cases it can still be avoided going through all features
5047
if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
5049
return mDataProvider->uniqueValues( index, uniqueValues, limit );
5052
//we need to go through each feature
5053
QgsAttributeList attList;
5056
select( attList, QgsRectangle(), false, false );
5059
QVariant currentValue;
5060
QHash<QString, QVariant> val;
5061
while ( nextFeature( f ) )
5063
currentValue = f.attributeMap()[index];
5064
val.insert( currentValue.toString(), currentValue );
5065
if ( limit >= 0 && val.size() >= limit )
5071
uniqueValues = val.values();
5074
QVariant QgsVectorLayer::minimumValue( int index )
5076
if ( !mDataProvider )
5081
int maxProviderIndex;
5082
QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
5084
if ( index <= maxProviderIndex && !mEditable ) //a provider field
5086
return mDataProvider->minimumValue( index );
5088
else // a joined field?
5090
int indexOffset; //offset between layer index and joined provider index
5091
const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
5094
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
5097
return vl->minimumValue( index );
5102
//the layer is editable, but in certain cases it can still be avoided going through all features
5103
if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
5105
return mDataProvider->minimumValue( index );
5108
//we need to go through each feature
5109
QgsAttributeList attList;
5112
select( attList, QgsRectangle(), false, false );
5115
double minimumValue = std::numeric_limits<double>::max();
5116
double currentValue = 0;
5117
while ( nextFeature( f ) )
5119
currentValue = f.attributeMap()[index].toDouble();
5120
if ( currentValue < minimumValue )
5122
minimumValue = currentValue;
5125
return QVariant( minimumValue );
5128
QVariant QgsVectorLayer::maximumValue( int index )
5130
if ( !mDataProvider )
5135
int maxProviderIndex;
5136
QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
5138
if ( index <= maxProviderIndex && !mEditable ) //a provider field
5140
return mDataProvider->maximumValue( index );
5142
else // a joined field?
5144
int indexOffset; //offset between layer index and joined provider index
5145
const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
5148
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
5151
return vl->maximumValue( index );
5156
//the layer is editable, but in certain cases it can still be avoided going through all features
5157
if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
5159
return mDataProvider->maximumValue( index );
5162
//we need to go through each feature
5163
QgsAttributeList attList;
5166
select( attList, QgsRectangle(), false, false );
5169
double maximumValue = -std::numeric_limits<double>::max();
5170
double currentValue = 0;
5171
while ( nextFeature( f ) )
5173
currentValue = f.attributeMap()[index].toDouble();
5174
if ( currentValue > maximumValue )
5176
maximumValue = currentValue;
5179
return QVariant( maximumValue );
5182
void QgsVectorLayer::stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer )
5184
mRendererV2->stopRender( rendererContext );
5187
selRenderer->stopRender( rendererContext );
5192
void QgsVectorLayer::updateAttributeMapIndex( QgsAttributeMap& map, int oldIndex, int newIndex ) const
5194
QgsAttributeMap::const_iterator it = map.find( oldIndex );
5195
if ( it == map.constEnd() )
5200
map.insert( newIndex, it.value() );
5201
map.remove( oldIndex );
5204
void QgsVectorLayer::prepareLabelingAndDiagrams( QgsRenderContext& rendererContext, QgsAttributeList& attributes, bool& labeling )
5206
if ( !rendererContext.labelingEngine() )
5209
QSet<int> attrIndex;
5210
if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex, rendererContext ) )
5212
QSet<int>::const_iterator attIt = attrIndex.constBegin();
5213
for ( ; attIt != attrIndex.constEnd(); ++attIt )
5215
if ( !attributes.contains( *attIt ) )
5217
attributes << *attIt;
5223
//register diagram layers
5224
if ( mDiagramRenderer && mDiagramLayerSettings )
5226
mDiagramLayerSettings->renderer = mDiagramRenderer;
5227
rendererContext.labelingEngine()->addDiagramLayer( this, mDiagramLayerSettings );
5228
//add attributes needed by the diagram renderer
5229
QList<int> att = mDiagramRenderer->diagramAttributes();
5230
QList<int>::const_iterator attIt = att.constBegin();
5231
for ( ; attIt != att.constEnd(); ++attIt )
5233
if ( !attributes.contains( *attIt ) )
5235
attributes << *attIt;
5238
//and the ones needed for data defined diagram positions
5239
if ( mDiagramLayerSettings->xPosColumn >= 0 && !attributes.contains( mDiagramLayerSettings->xPosColumn ) )
5241
attributes << mDiagramLayerSettings->xPosColumn;
5243
if ( mDiagramLayerSettings->yPosColumn >= 0 && !attributes.contains( mDiagramLayerSettings->yPosColumn ) )
5245
attributes << mDiagramLayerSettings->yPosColumn;
5250
void QgsVectorLayer::setDiagramLayerSettings( const QgsDiagramLayerSettings& s )
5252
if ( !mDiagramLayerSettings )
5253
mDiagramLayerSettings = new QgsDiagramLayerSettings();
5254
*mDiagramLayerSettings = s;