00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <cassert>
00025 #include <cfloat>
00026 #include <cstring>
00027 #include <climits>
00028 #include <cmath>
00029 #include <iosfwd>
00030 #include <limits>
00031 #include <memory>
00032 #include <set>
00033 #include <sstream>
00034 #include <utility>
00035
00036 #include <QImage>
00037 #include <QPainter>
00038 #include <QPainterPath>
00039 #include <QPolygonF>
00040 #include <QSettings>
00041 #include <QString>
00042
00043 #include "qgsvectorlayer.h"
00044
00045
00046 #include "qgscontinuouscolorrenderer.h"
00047 #include "qgsgraduatedsymbolrenderer.h"
00048 #include "qgsrenderer.h"
00049 #include "qgssinglesymbolrenderer.h"
00050 #include "qgsuniquevaluerenderer.h"
00051
00052 #include "qgsattributeaction.h"
00053
00054 #include "qgis.h"
00055 #include "qgsapplication.h"
00056 #include "qgscoordinatetransform.h"
00057 #include "qgsfeature.h"
00058 #include "qgsfield.h"
00059 #include "qgsgeometry.h"
00060 #include "qgslabel.h"
00061 #include "qgslogger.h"
00062 #include "qgsmaptopixel.h"
00063 #include "qgspoint.h"
00064 #include "qgsproviderregistry.h"
00065 #include "qgsrectangle.h"
00066 #include "qgsrendercontext.h"
00067 #include "qgssinglesymbolrenderer.h"
00068 #include "qgscoordinatereferencesystem.h"
00069 #include "qgsvectordataprovider.h"
00070 #include "qgslogger.h"
00071
00072 #ifdef Q_WS_X11
00073 #include "qgsclipper.h"
00074 #endif
00075
00076 #ifdef TESTPROVIDERLIB
00077 #include <dlfcn.h>
00078 #endif
00079
00080
00081 static const char * const ident_ = "$Id: qgsvectorlayer.cpp 9897 2008-12-26 21:07:03Z jef $";
00082
00083
00084 typedef QgsDataProvider * create_it( const QString* uri );
00085
00086
00087
00088 QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
00089 QString baseName,
00090 QString providerKey,
00091 bool loadDefaultStyleFlag )
00092 : QgsMapLayer( VectorLayer, baseName, vectorLayerPath ),
00093 mUpdateThreshold( 0 ),
00094 mDataProvider( NULL ),
00095 mProviderKey( providerKey ),
00096 mEditable( false ),
00097 mModified( false ),
00098 mMaxUpdatedIndex( -1 ),
00099 mRenderer( 0 ),
00100 mLabel( 0 ),
00101 mLabelOn( false ),
00102 mFetching( false )
00103 {
00104 mActions = new QgsAttributeAction;
00105
00106
00107 if ( ! mProviderKey.isEmpty() )
00108 {
00109 setDataProvider( mProviderKey );
00110 }
00111 if ( mValid )
00112 {
00113
00114
00115
00116 if ( loadDefaultStyleFlag )
00117 {
00118 bool defaultLoadedFlag = false;
00119 loadDefaultStyle( defaultLoadedFlag );
00120 if ( !defaultLoadedFlag )
00121 {
00122 setCoordinateSystem();
00123
00124 QgsSingleSymbolRenderer *renderer = new QgsSingleSymbolRenderer( geometryType() );
00125 setRenderer( renderer );
00126 }
00127 }
00128 else
00129 {
00130 setCoordinateSystem();
00131
00132 QgsSingleSymbolRenderer *renderer = new QgsSingleSymbolRenderer( geometryType() );
00133 setRenderer( renderer );
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143 }
00144 }
00145
00146
00147
00148 QgsVectorLayer::~QgsVectorLayer()
00149 {
00150 QgsDebugMsg( "In QgsVectorLayer destructor" );
00151
00152 emit layerDeleted();
00153
00154 mValid = false;
00155
00156 if ( mRenderer )
00157 {
00158 delete mRenderer;
00159 }
00160
00161 delete mDataProvider;
00162
00163 delete mLabel;
00164
00165
00166 deleteCachedGeometries();
00167
00168 delete mActions;
00169 }
00170
00171 QString QgsVectorLayer::storageType() const
00172 {
00173 if ( mDataProvider )
00174 {
00175 return mDataProvider->storageType();
00176 }
00177 return 0;
00178 }
00179
00180
00181 QString QgsVectorLayer::capabilitiesString() const
00182 {
00183 if ( mDataProvider )
00184 {
00185 return mDataProvider->capabilitiesString();
00186 }
00187 return 0;
00188 }
00189
00190 QString QgsVectorLayer::dataComment() const
00191 {
00192 if ( mDataProvider )
00193 {
00194 return mDataProvider->dataComment();
00195 }
00196 return QString();
00197 }
00198
00199
00200 QString QgsVectorLayer::providerType() const
00201 {
00202 return mProviderKey;
00203 }
00204
00208 void QgsVectorLayer::setDisplayField( QString fldName )
00209 {
00210
00211
00212
00213
00214
00215 QString idxName = "";
00216 QString idxId = "";
00217
00218 if ( !fldName.isEmpty() )
00219 {
00220 mDisplayField = fldName;
00221 }
00222 else
00223 {
00224 const QgsFieldMap &fields = pendingFields();
00225 int fieldsSize = fields.size();
00226
00227 for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it )
00228 {
00229 QString fldName = it.value().name();
00230 QgsDebugMsg( "Checking field " + fldName + " of " + QString::number( fieldsSize ) + " total" );
00231
00232
00233
00234
00235
00236 if ( fldName.indexOf( "name", false ) > -1 )
00237 {
00238 if ( idxName.isEmpty() )
00239 {
00240 idxName = fldName;
00241 }
00242 }
00243 if ( fldName.indexOf( "descrip", false ) > -1 )
00244 {
00245 if ( idxName.isEmpty() )
00246 {
00247 idxName = fldName;
00248 }
00249 }
00250 if ( fldName.indexOf( "id", false ) > -1 )
00251 {
00252 if ( idxId.isEmpty() )
00253 {
00254 idxId = fldName;
00255 }
00256 }
00257 }
00258
00259
00260 if ( fieldsSize == 0 )
00261 return;
00262
00263 if ( idxName.length() > 0 )
00264 {
00265 mDisplayField = idxName;
00266 }
00267 else
00268 {
00269 if ( idxId.length() > 0 )
00270 {
00271 mDisplayField = idxId;
00272 }
00273 else
00274 {
00275 mDisplayField = fields[0].name();
00276 }
00277 }
00278
00279 }
00280 }
00281
00282
00283
00284
00285 void QgsVectorLayer::drawLabels( QgsRenderContext& rendererContext )
00286 {
00287 QgsDebugMsg( "Starting draw of labels" );
00288
00289 if ( mRenderer && mLabelOn &&
00290 ( !label()->scaleBasedVisibility() ||
00291 ( label()->minScale() <= rendererContext.rendererScale() &&
00292 rendererContext.rendererScale() <= label()->maxScale() ) ) )
00293 {
00294 QgsAttributeList attributes = mRenderer->classificationAttributes();
00295
00296
00297 mLabel->addRequiredFields( attributes );
00298
00299 QgsDebugMsg( "Selecting features based on view extent" );
00300
00301 int featureCount = 0;
00302
00303 try
00304 {
00305
00306
00307 select( attributes, rendererContext.extent() );
00308
00309 QgsFeature fet;
00310 while ( nextFeature( fet ) )
00311 {
00312 if ( mRenderer->willRenderFeature( &fet ) )
00313 {
00314 bool sel = mSelectedFeatureIds.contains( fet.id() );
00315 mLabel->renderLabel( rendererContext.painter(), rendererContext.extent(), rendererContext.coordinateTransform(), &( rendererContext.mapToPixel() ), fet, sel, 0, rendererContext.scaleFactor(), rendererContext.rasterScaleFactor() );
00316 }
00317 featureCount++;
00318 }
00319 }
00320 catch ( QgsCsException &e )
00321 {
00322 Q_UNUSED( e );
00323 QgsLogger::critical( "Error projecting label locations, caught in " + QString( __FILE__ ) + ", line " + QString( __LINE__ ) );
00324 }
00325
00326 #ifdef QGISDEBUG
00327 QgsLogger::debug( "Total features processed", featureCount, 1, __FILE__, __FUNCTION__, __LINE__ );
00328 #endif
00329
00330
00331
00332
00333
00334 }
00335 }
00336
00337
00338 unsigned char* QgsVectorLayer::drawLineString(
00339 unsigned char *feature,
00340 QPainter* p,
00341 const QgsMapToPixel* mtp,
00342 const QgsCoordinateTransform* ct,
00343 bool drawingToEditingCanvas )
00344 {
00345 unsigned char *ptr = feature + 5;
00346 unsigned int wkbType = *(( int* )( feature + 1 ) );
00347 unsigned int nPoints = *(( int* )ptr );
00348 ptr = feature + 9;
00349
00350 bool hasZValue = ( wkbType == QGis::WKBLineString25D );
00351
00352 std::vector<double> x( nPoints );
00353 std::vector<double> y( nPoints );
00354 std::vector<double> z( nPoints, 0.0 );
00355
00356
00357 for ( register unsigned int i = 0; i < nPoints; ++i )
00358 {
00359 x[i] = *(( double * ) ptr );
00360 ptr += sizeof( double );
00361 y[i] = *(( double * ) ptr );
00362 ptr += sizeof( double );
00363
00364 if ( hasZValue )
00365 ptr += sizeof( double );
00366 }
00367
00368
00369
00370
00371 transformPoints( x, y, z, mtp, ct );
00372
00373 #if defined(Q_WS_X11)
00374
00375
00376
00377
00378
00379 for ( register unsigned int i = 0; i < nPoints; ++i )
00380 {
00381 if ( std::abs( x[i] ) > QgsClipper::MAX_X ||
00382 std::abs( y[i] ) > QgsClipper::MAX_Y )
00383 {
00384 QgsClipper::trimFeature( x, y, true );
00385 nPoints = x.size();
00386 break;
00387 }
00388 }
00389 #endif
00390
00391
00392 QPolygonF pa( nPoints );
00393 for ( register unsigned int i = 0; i < nPoints; ++i )
00394 {
00395 pa[i].setX( x[i] );
00396 pa[i].setY( y[i] );
00397 }
00398
00399 #ifdef QGISDEBUGVERBOSE
00400
00401 for ( int i = 0; i < pa.size(); ++i )
00402 {
00403 QgsDebugMsgLevel( "pa" + QString::number( pa.point( i ).x() ), 2 );
00404 QgsDebugMsgLevel( "pa" + QString::number( pa.point( i ).y() ), 2 );
00405 }
00406 #endif
00407
00408
00409
00410
00411 QPen pen = p->pen();
00412
00413
00414
00415
00416
00417 QPen myTransparentPen = p->pen();
00418 QColor myColor = myTransparentPen.color();
00419
00420
00421 if ( !mRenderer->usesTransparency() )
00422 {
00423 myColor.setAlpha( mTransparencyLevel );
00424 }
00425 myTransparentPen.setColor( myColor );
00426 p->setPen( myTransparentPen );
00427 p->drawPolyline( pa );
00428
00429
00430 if ( mEditable && drawingToEditingCanvas )
00431 {
00432 QgsVectorLayer::VertexMarkerType markerType = currentVertexMarkerType();
00433
00434 std::vector<double>::const_iterator xIt;
00435 std::vector<double>::const_iterator yIt;
00436 for ( xIt = x.begin(), yIt = y.begin(); xIt != x.end(); ++xIt, ++yIt )
00437 {
00438 drawVertexMarker(( int )( *xIt ), ( int )( *yIt ), *p, markerType );
00439 }
00440 }
00441
00442
00443 p->setPen( pen );
00444
00445 return ptr;
00446 }
00447
00448 unsigned char *QgsVectorLayer::drawPolygon(
00449 unsigned char *feature,
00450 QPainter *p,
00451 const QgsMapToPixel *mtp,
00452 const QgsCoordinateTransform *ct,
00453 bool drawingToEditingCanvas )
00454 {
00455 typedef std::pair<std::vector<double>, std::vector<double> > ringType;
00456 typedef ringType* ringTypePtr;
00457 typedef std::vector<ringTypePtr> ringsType;
00458
00459
00460 unsigned int numRings = *(( int* )( feature + 1 + sizeof( int ) ) );
00461
00462 if ( numRings == 0 )
00463 return feature + 9;
00464
00465 unsigned int wkbType = *(( int* )( feature + 1 ) );
00466
00467 bool hasZValue = ( wkbType == QGis::WKBPolygon25D );
00468
00469 int total_points = 0;
00470
00471
00472
00473
00474 ringsType rings;
00475
00476
00477 unsigned char* ptr = feature + 1 + 2 * sizeof( int );
00478
00479 for ( register unsigned int idx = 0; idx < numRings; idx++ )
00480 {
00481 unsigned int nPoints = *(( int* )ptr );
00482
00483 ringTypePtr ring = new ringType( std::vector<double>( nPoints ), std::vector<double>( nPoints ) );
00484 ptr += 4;
00485
00486
00487 std::vector<double> zVector( nPoints, 0.0 );
00488
00489
00490 for ( register unsigned int jdx = 0; jdx < nPoints; jdx++ )
00491 {
00492 ring->first[jdx] = *(( double * ) ptr );
00493 ptr += sizeof( double );
00494 ring->second[jdx] = *(( double * ) ptr );
00495 ptr += sizeof( double );
00496
00497 if ( hasZValue )
00498 ptr += sizeof( double );
00499 }
00500
00501
00502 if ( nPoints < 1 )
00503 {
00504 QgsDebugMsg( "Ring has only " + QString::number( nPoints ) + " points! Skipping this ring." );
00505 continue;
00506 }
00507
00508 transformPoints( ring->first, ring->second, zVector, mtp, ct );
00509
00510 #if defined(Q_WS_X11)
00511
00512
00513
00514
00515
00516 for ( register unsigned int i = 0; i < nPoints; ++i )
00517 {
00518 if ( std::abs( ring->first[i] ) > QgsClipper::MAX_X ||
00519 std::abs( ring->second[i] ) > QgsClipper::MAX_Y )
00520 {
00521 QgsClipper::trimFeature( ring->first, ring->second, false );
00522 break;
00523 }
00524 }
00525 #endif
00526
00527
00528
00529 if ( ring->first.size() == 0 )
00530 delete ring;
00531 else
00532 {
00533 rings.push_back( ring );
00534 total_points += ring->first.size();
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543
00544 QPainterPath path;
00545
00546
00547 if ( total_points > 0 )
00548 {
00549
00550
00551 int numRings = rings.size();
00552 for ( register int i = 0; i < numRings; ++i )
00553 {
00554
00555
00556 ringTypePtr r = rings[i];
00557
00558 unsigned ringSize = r->first.size();
00559
00560
00561 QPolygonF pa( ringSize );
00562 for ( register unsigned int j = 0; j != ringSize; ++j )
00563 {
00564 pa[j].setX( r->first[j] );
00565 pa[j].setY( r->second[j] );
00566 }
00567
00568 path.addPolygon( pa );
00569
00570
00571 delete rings[i];
00572 }
00573
00574 #ifdef QGISDEBUGVERBOSE
00575
00576
00577 QgsDebugMsg( "Pixel points are:" );
00578 for ( int i = 0; i < pa.size(); ++i )
00579 {
00580 QgsDebugMsgLevel( "i" + QString::number( i ), 2 );
00581 QgsDebugMsgLevel( "pa[i].x()" + QString::number( pa[i].x() ), 2 );
00582 QgsDebugMsgLevel( "pa[i].y()" + QString::number( pa[i].y() ), 2 );
00583 }
00584 QgsDebugMsg( "Ring positions are:" );
00585 QgsDebugMsg( "Ring positions are:" );
00586 for ( int i = 0; i < ringDetails.size(); ++i )
00587 {
00588 QgsDebugMsgLevel( "ringDetails[i].first" + QString::number( ringDetails[i].first ), 2 );
00589 QgsDebugMsgLevel( "ringDetails[i].second" + QString::number( ringDetails[i].second ), 2 );
00590 }
00591 QgsDebugMsg( "Outer ring point is " + QString::number( outerRingPt.x() ) + ", " + QString::number( outerRingPt.y() ) );
00592 #endif
00593
00594 #if 0
00595
00596
00597 int largestX = -std::numeric_limits<int>::max();
00598 int smallestX = std::numeric_limits<int>::max();
00599 int largestY = -std::numeric_limits<int>::max();
00600 int smallestY = std::numeric_limits<int>::max();
00601
00602 for ( int i = 0; i < pa.size(); ++i )
00603 {
00604 largestX = std::max( largestX, pa.point( i ).x() );
00605 smallestX = std::min( smallestX, pa.point( i ).x() );
00606 largestY = std::max( largestY, pa.point( i ).y() );
00607 smallestY = std::min( smallestY, pa.point( i ).y() );
00608 }
00609 QgsDebugMsg( QString( "Largest X coordinate was %1" ).arg( largestX ) );
00610 QgsDebugMsg( QString( "Smallest X coordinate was %1" ).arg( smallestX ) );
00611 QgsDebugMsg( QString( "Largest Y coordinate was %1" ).arg( largestY ) );
00612 QgsDebugMsg( QString( "Smallest Y coordinate was %1" ).arg( smallestY ) );
00613 #endif
00614
00615
00616 QBrush brush = p->brush();
00617 QPen pen = p->pen();
00618
00619
00620
00621
00622 QBrush myTransparentBrush = p->brush();
00623 QColor myColor = brush.color();
00624
00625
00626
00627 if ( !mRenderer->usesTransparency() )
00628 {
00629 myColor.setAlpha( mTransparencyLevel );
00630 }
00631 myTransparentBrush.setColor( myColor );
00632 QPen myTransparentPen = p->pen();
00633 myColor = myTransparentPen.color();
00634
00635
00636
00637 if ( !mRenderer->usesTransparency() )
00638 {
00639 myColor.setAlpha( mTransparencyLevel );
00640 }
00641 myTransparentPen.setColor( myColor );
00642
00643 p->setBrush( myTransparentBrush );
00644 p->setPen( myTransparentPen );
00645
00646
00647
00648
00649 p->drawPath( path );
00650
00651
00652
00653 if ( mEditable && drawingToEditingCanvas )
00654 {
00655 QgsVectorLayer::VertexMarkerType markerType = currentVertexMarkerType();
00656
00657 for ( int i = 0; i < path.elementCount(); ++i )
00658 {
00659 const QPainterPath::Element & e = path.elementAt( i );
00660 drawVertexMarker(( int )e.x, ( int )e.y, *p, markerType );
00661 }
00662 }
00663
00664
00665
00666
00667 p->setBrush( brush );
00668 p->setPen( pen );
00669
00670 }
00671
00672 return ptr;
00673 }
00674
00675 bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
00676 {
00677
00678 QSettings settings;
00679 mUpdateThreshold = settings.value( "Map/updateThreshold", 0 ).toInt();
00680
00681
00682 if ( mRenderer )
00683 {
00684
00685
00686
00687
00688
00689
00690
00691
00692 QPen pen;
00693
00694 QImage marker;
00695
00696 if ( mEditable )
00697 {
00698
00699 deleteCachedGeometries();
00700 }
00701
00702 updateFeatureCount();
00703 int totalFeatures = pendingFeatureCount();
00704 int featureCount = 0;
00705 QgsFeature fet;
00706 QgsAttributeList attributes = mRenderer->classificationAttributes();
00707 select( attributes, rendererContext.extent() );
00708
00709 try
00710 {
00711 while ( nextFeature( fet ) )
00712 {
00713
00714 if ( rendererContext.renderingStopped() )
00715 {
00716 break;
00717 }
00718
00719 #ifndef Q_WS_MAC //MH: disable this on Mac for now to avoid problems with resizing
00720 if ( mUpdateThreshold > 0 && 0 == featureCount % mUpdateThreshold )
00721 {
00722 emit screenUpdateRequested();
00723 emit drawingProgress( featureCount, totalFeatures );
00724 qApp->processEvents();
00725 }
00726 else if ( featureCount % 1000 == 0 )
00727 {
00728 emit drawingProgress( featureCount, totalFeatures );
00729 qApp->processEvents();
00730 }
00731 #else
00732 Q_UNUSED( totalFeatures );
00733 #endif //Q_WS_MAC
00734
00735 if ( mEditable )
00736 {
00737
00738 mCachedGeometries[fet.id()] = *fet.geometry();
00739 }
00740
00741
00742
00743
00744 bool sel = mSelectedFeatureIds.contains( fet.id() );
00745
00746
00747
00748 mRenderer->renderFeature(
00749 rendererContext.painter(),
00750 fet,
00751 &marker,
00752 sel,
00753 rendererContext.scaleFactor(),
00754 rendererContext.rasterScaleFactor() );
00755
00756
00757
00758
00759 drawFeature(
00760 rendererContext.painter(),
00761 fet,
00762 &rendererContext.mapToPixel(),
00763 rendererContext.coordinateTransform(),
00764 &marker,
00765 rendererContext.scaleFactor(),
00766 rendererContext.rasterScaleFactor(),
00767 rendererContext.drawEditingInformation() );
00768
00769 ++featureCount;
00770 }
00771 }
00772 catch ( QgsCsException &cse )
00773 {
00774 QString msg( "Failed to transform a point while drawing a feature of type '"
00775 + fet.typeName() + "'. Ignoring this feature." );
00776 msg += cse.what();
00777 QgsLogger::warning( msg );
00778 }
00779
00780 }
00781 else
00782 {
00783 QgsLogger::warning( "QgsRenderer is null in QgsVectorLayer::draw()" );
00784 }
00785
00786 return TRUE;
00787 }
00788
00789 void QgsVectorLayer::deleteCachedGeometries()
00790 {
00791
00792 mCachedGeometries.clear();
00793 }
00794
00795 void QgsVectorLayer::drawVertexMarker( int x, int y, QPainter& p, QgsVectorLayer::VertexMarkerType type )
00796 {
00797 if ( type == QgsVectorLayer::SemiTransparentCircle )
00798 {
00799 p.setPen( QColor( 50, 100, 120, 200 ) );
00800 p.setBrush( QColor( 200, 200, 210, 120 ) );
00801 p.drawEllipse( QRectF( x - 7, y - 7, 14, 14 ) );
00802 }
00803 else
00804 {
00805 int size = 15;
00806 int m = ( size - 1 ) / 2;
00807 p.setPen( QColor( 255, 0, 0 ) );
00808 p.drawLine( x - m, y + m, x + m, y - m );
00809 p.drawLine( x - m, y - m, x + m, y + m );
00810 }
00811 }
00812
00813 void QgsVectorLayer::select( int number, bool emitSignal )
00814 {
00815 mSelectedFeatureIds.insert( number );
00816
00817 if ( emitSignal )
00818 {
00819 emit selectionChanged();
00820 }
00821 }
00822
00823 void QgsVectorLayer::deselect( int number, bool emitSignal )
00824 {
00825 mSelectedFeatureIds.remove( number );
00826
00827 if ( emitSignal )
00828 {
00829 emit selectionChanged();
00830 }
00831 }
00832
00833 void QgsVectorLayer::select( QgsRectangle & rect, bool lock )
00834 {
00835
00836 rect.normalize();
00837
00838 if ( lock == false )
00839 {
00840 removeSelection( FALSE );
00841 }
00842
00843
00844 select( QgsAttributeList(), rect, false, true );
00845
00846 QgsFeature f;
00847 while ( nextFeature( f ) )
00848 {
00849 select( f.id(), false );
00850 }
00851
00852 emit selectionChanged();
00853 }
00854
00855 void QgsVectorLayer::invertSelection()
00856 {
00857
00858 QgsFeatureIds tmp = mSelectedFeatureIds;
00859
00860 removeSelection( FALSE );
00861
00862 select( QgsAttributeList(), QgsRectangle(), false );
00863
00864 QgsFeature fet;
00865 while ( nextFeature( fet ) )
00866 {
00867 select( fet.id(), false );
00868 }
00869
00870 for ( QgsFeatureIds::iterator iter = tmp.begin(); iter != tmp.end(); ++iter )
00871 {
00872 mSelectedFeatureIds.remove( *iter );
00873 }
00874
00875 emit selectionChanged();
00876 }
00877
00878 void QgsVectorLayer::invertSelectionInRectangle( QgsRectangle & rect )
00879 {
00880
00881 rect.normalize();
00882
00883 select( QgsAttributeList(), rect, false, true );
00884
00885 QgsFeature fet;
00886 while ( nextFeature( fet ) )
00887 {
00888 if ( mSelectedFeatureIds.contains( fet.id() ) )
00889 {
00890 deselect( fet.id(), false );
00891 }
00892 else
00893 {
00894 select( fet.id(), false );
00895 }
00896 }
00897
00898 emit selectionChanged();
00899 }
00900
00901 void QgsVectorLayer::removeSelection( bool emitSignal )
00902 {
00903 mSelectedFeatureIds.clear();
00904
00905 if ( emitSignal )
00906 emit selectionChanged();
00907 }
00908
00909 void QgsVectorLayer::triggerRepaint()
00910 {
00911 emit repaintRequested();
00912 }
00913
00914 QgsVectorDataProvider* QgsVectorLayer::dataProvider()
00915 {
00916 return mDataProvider;
00917 }
00918
00919 const QgsVectorDataProvider* QgsVectorLayer::dataProvider() const
00920 {
00921 return mDataProvider;
00922 }
00923
00924 void QgsVectorLayer::setProviderEncoding( const QString& encoding )
00925 {
00926 if ( mDataProvider )
00927 {
00928 mDataProvider->setEncoding( encoding );
00929 }
00930 }
00931
00932
00933 const QgsRenderer* QgsVectorLayer::renderer() const
00934 {
00935 return mRenderer;
00936 }
00937
00938 void QgsVectorLayer::setRenderer( QgsRenderer * r )
00939 {
00940 if ( r != mRenderer )
00941 {
00942 delete mRenderer;
00943 mRenderer = r;
00944 }
00945 }
00946
00947 QGis::GeometryType QgsVectorLayer::geometryType() const
00948 {
00949 if ( mDataProvider )
00950 {
00951 int type = mDataProvider->geometryType();
00952 switch ( type )
00953 {
00954 case QGis::WKBPoint:
00955 case QGis::WKBPoint25D:
00956 return QGis::Point;
00957
00958 case QGis::WKBLineString:
00959 case QGis::WKBLineString25D:
00960 return QGis::Line;
00961
00962 case QGis::WKBPolygon:
00963 case QGis::WKBPolygon25D:
00964 return QGis::Polygon;
00965
00966 case QGis::WKBMultiPoint:
00967 case QGis::WKBMultiPoint25D:
00968 return QGis::Point;
00969
00970 case QGis::WKBMultiLineString:
00971 case QGis::WKBMultiLineString25D:
00972 return QGis::Line;
00973
00974 case QGis::WKBMultiPolygon:
00975 case QGis::WKBMultiPolygon25D:
00976 return QGis::Polygon;
00977 }
00978 #ifdef QGISDEBUG
00979 QgsLogger::debug( "Warning: Data Provider Geometry type is not recognised, is", type, 1, __FILE__, __FUNCTION__, __LINE__ );
00980 #endif
00981
00982 }
00983 else
00984 {
00985 #ifdef QGISDEBUG
00986 qWarning( "warning, pointer to mDataProvider is null in QgsVectorLayer::type()" );
00987 #endif
00988
00989 }
00990
00991
00992
00993
00994
00995
00996 QgsDebugMsg( "WARNING: This code should never be reached. Problems may occur..." );
00997
00998 return QGis::UnknownGeometry;
00999 }
01000
01001 QGis::WkbType QgsVectorLayer::wkbType() const
01002 {
01003 return ( QGis::WkbType )( mWkbType );
01004 }
01005
01006 QgsRectangle QgsVectorLayer::boundingBoxOfSelected()
01007 {
01008 if ( mSelectedFeatureIds.size() == 0 )
01009 {
01010 return QgsRectangle( 0, 0, 0, 0 );
01011 }
01012
01013 QgsRectangle r, retval;
01014
01015
01016 select( QgsAttributeList(), QgsRectangle(), true );
01017
01018 retval.setMinimal();
01019
01020 QgsFeature fet;
01021 while ( nextFeature( fet ) )
01022 {
01023 if ( mSelectedFeatureIds.contains( fet.id() ) )
01024 {
01025 if ( fet.geometry() )
01026 {
01027 r = fet.geometry()->boundingBox();
01028 retval.combineExtentWith( &r );
01029 }
01030 }
01031 }
01032
01033 if ( retval.width() == 0.0 || retval.height() == 0.0 )
01034 {
01035
01036
01037
01038
01039 if ( retval.xMinimum() == 0.0 && retval.xMaximum() == 0.0 &&
01040 retval.yMinimum() == 0.0 && retval.yMaximum() == 0.0 )
01041 {
01042 retval.set( -1.0, -1.0, 1.0, 1.0 );
01043 }
01044 else
01045 {
01046 const double padFactor = 1e-8;
01047 double widthPad = retval.xMinimum() * padFactor;
01048 double heightPad = retval.yMinimum() * padFactor;
01049 double xmin = retval.xMinimum() - widthPad;
01050 double xmax = retval.xMaximum() + widthPad;
01051 double ymin = retval.yMinimum() - heightPad;
01052 double ymax = retval.yMaximum() + heightPad;
01053 retval.set( xmin, ymin, xmax, ymax );
01054 }
01055 }
01056
01057 return retval;
01058 }
01059
01060
01061
01062 long QgsVectorLayer::featureCount() const
01063 {
01064 if ( !mDataProvider )
01065 {
01066 QgsLogger::warning( " QgsVectorLayer::featureCount() invoked with null mDataProvider" );
01067 return 0;
01068 }
01069
01070 return mDataProvider->featureCount();
01071 }
01072
01073 long QgsVectorLayer::updateFeatureCount() const
01074 {
01075 if ( !mDataProvider )
01076 {
01077 QgsLogger::warning( " QgsVectorLayer::updateFeatureCount() invoked with null mDataProvider" );
01078 return 0;
01079 }
01080 return mDataProvider->updateFeatureCount();
01081 }
01082
01083 void QgsVectorLayer::updateExtents()
01084 {
01085 mLayerExtent.setMinimal();
01086
01087 if ( !mDataProvider )
01088 QgsLogger::warning( " QgsVectorLayer::updateExtents() invoked with null mDataProvider" );
01089
01090 if ( mDeletedFeatureIds.isEmpty() && mChangedGeometries.isEmpty() )
01091 {
01092
01093
01094 if ( mDataProvider->featureCount() != 0 )
01095 {
01096 QgsRectangle r = mDataProvider->extent();
01097 mLayerExtent.combineExtentWith( &r );
01098 }
01099
01100 for ( QgsFeatureList::iterator it = mAddedFeatures.begin(); it != mAddedFeatures.end(); it++ )
01101 {
01102 QgsRectangle r = it->geometry()->boundingBox();
01103 mLayerExtent.combineExtentWith( &r );
01104 }
01105 }
01106 else
01107 {
01108 select( QgsAttributeList(), QgsRectangle(), true );
01109
01110 QgsFeature fet;
01111 while ( nextFeature( fet ) )
01112 {
01113 if ( fet.geometry() )
01114 {
01115 QgsRectangle bb = fet.geometry()->boundingBox();
01116 mLayerExtent.combineExtentWith( &bb );
01117 }
01118 }
01119 }
01120
01121 if ( mLayerExtent.xMinimum() > mLayerExtent.xMaximum() && mLayerExtent.yMinimum() > mLayerExtent.yMaximum() )
01122 {
01123
01124 mLayerExtent = QgsRectangle();
01125 }
01126
01127
01128 emit recalculateExtents();
01129 }
01130
01131 QString QgsVectorLayer::subsetString()
01132 {
01133 if ( ! mDataProvider )
01134 {
01135 QgsLogger::warning( " QgsVectorLayer::subsetString() invoked with null mDataProvider" );
01136 return 0;
01137 }
01138 return mDataProvider->subsetString();
01139 }
01140
01141 void QgsVectorLayer::setSubsetString( QString subset )
01142 {
01143 if ( ! mDataProvider )
01144 {
01145 QgsLogger::warning( " QgsVectorLayer::setSubsetString() invoked with null mDataProvider" );
01146 return;
01147 }
01148
01149 mDataProvider->setSubsetString( subset );
01150
01151 mDataSource = mDataProvider->dataSourceUri();
01152 updateExtents();
01153 }
01154
01155 void QgsVectorLayer::updateFeatureAttributes( QgsFeature &f )
01156 {
01157
01158 if ( ! mEditable )
01159 return;
01160
01161 if ( mChangedAttributeValues.contains( f.id() ) )
01162 {
01163 const QgsAttributeMap &map = mChangedAttributeValues[f.id()];
01164 for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); it++ )
01165 f.changeAttribute( it.key(), it.value() );
01166 }
01167
01168
01169 const QgsAttributeMap &map = f.attributeMap();
01170 for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); it++ )
01171 if ( !mUpdatedFields.contains( it.key() ) )
01172 f.deleteAttribute( it.key() );
01173
01174
01175 for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
01176 if ( !map.contains( it.key() ) )
01177 f.changeAttribute( it.key(), QVariant( QString::null ) );
01178 }
01179
01180 void QgsVectorLayer::updateFeatureGeometry( QgsFeature &f )
01181 {
01182 if ( mChangedGeometries.contains( f.id() ) )
01183 f.setGeometry( mChangedGeometries[f.id()] );
01184 }
01185
01186
01187 void QgsVectorLayer::select( QgsAttributeList attributes, QgsRectangle rect, bool fetchGeometries, bool useIntersect )
01188 {
01189 if ( !mDataProvider )
01190 return;
01191
01192 mFetching = true;
01193 mFetchRect = rect;
01194 mFetchAttributes = attributes;
01195 mFetchGeometry = fetchGeometries;
01196
01197 mFetchConsidered = mDeletedFeatureIds;
01198
01199 if ( mEditable )
01200 {
01201 mFetchAddedFeaturesIt = mAddedFeatures.begin();
01202 mFetchChangedGeomIt = mChangedGeometries.begin();
01203 }
01204
01205
01206 if ( mFetchAttributes.size() > 0 )
01207 {
01208 if ( mEditable )
01209 {
01210
01211 QgsAttributeList provAttributes;
01212 for ( QgsAttributeList::iterator it = mFetchAttributes.begin(); it != mFetchAttributes.end(); it++ )
01213 {
01214 if ( !mUpdatedFields.contains( *it ) || mAddedAttributeIds.contains( *it ) )
01215 continue;
01216
01217 provAttributes << *it;
01218 }
01219
01220 mDataProvider->select(