Skip to content

Commit e05de3f

Browse files
committedJan 20, 2015
Handle updates of the layer in the point locator
This currently just invalidates the whole trees. It would be more sophisticated to do just the updates to the existing trees - but I run into various issues with the spatial index library when doing that. So resorting to this for the moment.
1 parent 83770df commit e05de3f

File tree

2 files changed

+66
-50
lines changed

2 files changed

+66
-50
lines changed
 

‎src/core/qgspointlocator.cpp

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,49 @@ class EdgeNNComparator : public INearestNeighborComparator
426426
};
427427

428428

429+
////////////////////////////////////////////////////////////////////////////
430+
#include <QStack>
431+
432+
/** Helper class to dump the R-index nodes and their content */
433+
class QgsPointLocator_DumpTree : public SpatialIndex::IQueryStrategy
434+
{
435+
private:
436+
QStack<id_type> ids;
437+
438+
public:
439+
440+
void getNextEntry( const IEntry& entry, id_type& nextEntry, bool& hasNext )
441+
{
442+
const INode* n = dynamic_cast<const INode*>( &entry );
443+
qDebug( "NODE: %ld", n->getIdentifier() );
444+
if ( n->getLevel() > 0 )
445+
{
446+
// inner nodes
447+
for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
448+
{
449+
qDebug( "- CH: %ld", n->getChildIdentifier( cChild ) );
450+
ids.push( n->getChildIdentifier( cChild ) );
451+
}
452+
}
453+
else
454+
{
455+
// leaves
456+
for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
457+
{
458+
qDebug( "- L: %ld", n->getChildIdentifier( cChild ) );
459+
}
460+
}
461+
462+
if ( ! ids.empty() )
463+
{
464+
nextEntry = ids.back(); ids.pop();
465+
hasNext = true;
466+
}
467+
else
468+
hasNext = false;
469+
}
470+
};
471+
429472
////////////////////////////////////////////////////////////////////////////
430473

431474

@@ -585,57 +628,21 @@ void QgsPointLocator::destroyIndex( int types )
585628

586629
void QgsPointLocator::onFeatureAdded( QgsFeatureId fid )
587630
{
588-
QgsFeature f;
589-
QgsFeatureRequest request;
590-
request.setFilterFid( fid );
591-
request.setSubsetOfAttributes( QgsAttributeList() );
592-
QgsFeatureIterator fi = mLayer->getFeatures( request );
593-
if ( fi.nextFeature( f ) && f.geometry() )
594-
{
595-
QGis::GeometryType geomType = f.geometry()->type();
596-
597-
if ( mTransform )
598-
f.geometry()->transform( *mTransform );
599-
600-
if ( mRTreeVertex && ( geomType == QGis::Polygon || geomType == QGis::Line || geomType == QGis::Point ) )
601-
{
602-
QLinkedList<RTree::Data*> vertexDataList;
603-
addVertexData( vertexDataList, f );
604-
foreach ( RTree::Data* d, vertexDataList )
605-
{
606-
mRTreeVertex->insertData( d->m_dataLength, d->m_pData, d->m_region, d->m_id );
607-
delete d;
608-
}
609-
}
610-
611-
// TODO: edge, area
612-
}
631+
Q_UNUSED( fid );
632+
destroyIndex( All );
613633
}
614634

615635
void QgsPointLocator::onFeatureDeleted( QgsFeatureId fid )
616636
{
617-
#if 0
618-
if ( mRTreeVertex )
619-
{
620-
MyQueryStrategy qq( fid );
621-
mRTreeVertex->queryStrategy( qq );
622-
foreach ( const SpatialIndex::Region& r, qq.regions )
623-
{
624-
bool res = mRTreeVertex->deleteData( r, fid );
625-
qDebug( "del: %d %f,%f - %f,%f", res, r.m_pLow[0], r.m_pLow[1], r.m_pHigh[0], r.m_pHigh[1] );
626-
}
627-
qDebug( "isvalid %d", mRTreeVertex->isIndexValid() );
628-
}
629-
630-
// TODO: edge, area
631-
#endif
637+
Q_UNUSED( fid );
638+
destroyIndex( All );
632639
}
633640

634641
void QgsPointLocator::onGeometryChanged( QgsFeatureId fid, QgsGeometry& geom )
635642
{
643+
Q_UNUSED( fid );
636644
Q_UNUSED( geom );
637-
onFeatureDeleted( fid );
638-
onFeatureAdded( fid );
645+
destroyIndex( All );
639646
}
640647

641648

‎tests/src/core/testqgspointlocator.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,21 +116,20 @@ class TestQgsPointLocator : public QObject
116116

117117
void testLayerUpdates()
118118
{
119-
QgsPointLocator loc( mVL );
120119

121-
mVL->startEditing();
120+
QgsPointLocator loc( mVL );
122121

123122
QgsPointLocator::Match mAddV0 = loc.nearestVertex( QgsPoint( 12, 12 ) );
124123
QVERIFY( mAddV0.isValid() );
125124
QCOMPARE( mAddV0.point(), QgsPoint( 1, 1 ) );
126125

126+
mVL->startEditing();
127+
127128
// add a new feature
128129
QgsFeature ff( 0 );
129130
QgsPolygon polygon;
130131
QgsPolyline polyline;
131132
polyline << QgsPoint( 10, 11 ) << QgsPoint( 11, 10 ) << QgsPoint( 11, 11 ) << QgsPoint( 10, 11 );
132-
polyline << QgsPoint( 101, 11 ) << QgsPoint( 111, 10 ) << QgsPoint( 111, 11 ) << QgsPoint( 110, 11 );
133-
polyline << QgsPoint( 10, 111 ) << QgsPoint( 11, 110 ) << QgsPoint( 11, 111 ) << QgsPoint( 10, 111 );
134133
polygon << polyline;
135134
ff.setGeometry( QgsGeometry::fromPolygon( polygon ) );
136135
QgsFeatureList flist;
@@ -141,25 +140,35 @@ class TestQgsPointLocator : public QObject
141140
// verify it is added in the point locator
142141
QgsPointLocator::Match mAddV = loc.nearestVertex( QgsPoint( 12, 12 ) );
143142
QVERIFY( mAddV.isValid() );
144-
qDebug( "%f,%f", mAddV.point().x(), mAddV.point().y() );
145143
QCOMPARE( mAddV.point(), QgsPoint( 11, 11 ) );
146144
QgsPointLocator::Match mAddE = loc.nearestEdge( QgsPoint( 11.1, 10.5 ) );
147145
QVERIFY( mAddE.isValid() );
148146
QCOMPARE( mAddE.point(), QgsPoint( 11, 10.5 ) );
149147
QgsPointLocator::MatchList mAddA = loc.pointInPolygon( QgsPoint( 10.8, 10.8 ) );
150148
QVERIFY( mAddA.count() == 1 );
151149

152-
#if 0
150+
// change geometry
151+
QgsGeometry* newGeom = new QgsGeometry( *ff.geometry() );
152+
newGeom->moveVertex( 10, 10, 2 ); // change 11,11 to 10,10
153+
mVL->changeGeometry( ff.id(), newGeom );
154+
delete newGeom;
155+
156+
// verify it is changed in the point locator
157+
QgsPointLocator::Match mChV = loc.nearestVertex( QgsPoint( 12, 12 ) );
158+
QVERIFY( mChV.isValid() );
159+
QVERIFY( mChV.point() != QgsPoint( 11, 11 ) ); // that point does not exist anymore
160+
mChV = loc.nearestVertex( QgsPoint( 9, 9 ) );
161+
QVERIFY( mChV.isValid() );
162+
QVERIFY( mChV.point() == QgsPoint( 10, 10 ) ); // updated point
163+
153164
// delete feature
154165
bool resD = mVL->deleteFeature( ff.id() );
155166
QVERIFY( resD );
156167

157168
// verify it is deleted from the point locator
158169
QgsPointLocator::Match mDelV = loc.nearestVertex( QgsPoint( 12, 12 ) );
159170
QVERIFY( mDelV.isValid() );
160-
qDebug( "%f,%f", mDelV.point().x(), mDelV.point().y() );
161171
QCOMPARE( mDelV.point(), QgsPoint( 1, 1 ) );
162-
#endif
163172

164173
mVL->rollBack();
165174
}

0 commit comments

Comments
 (0)
Please sign in to comment.