mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
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.
This commit is contained in:
parent
83770dfd9e
commit
e05de3f9c6
@ -426,6 +426,49 @@ class EdgeNNComparator : public INearestNeighborComparator
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
#include <QStack>
|
||||
|
||||
/** Helper class to dump the R-index nodes and their content */
|
||||
class QgsPointLocator_DumpTree : public SpatialIndex::IQueryStrategy
|
||||
{
|
||||
private:
|
||||
QStack<id_type> ids;
|
||||
|
||||
public:
|
||||
|
||||
void getNextEntry( const IEntry& entry, id_type& nextEntry, bool& hasNext )
|
||||
{
|
||||
const INode* n = dynamic_cast<const INode*>( &entry );
|
||||
qDebug( "NODE: %ld", n->getIdentifier() );
|
||||
if ( n->getLevel() > 0 )
|
||||
{
|
||||
// inner nodes
|
||||
for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
|
||||
{
|
||||
qDebug( "- CH: %ld", n->getChildIdentifier( cChild ) );
|
||||
ids.push( n->getChildIdentifier( cChild ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// leaves
|
||||
for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
|
||||
{
|
||||
qDebug( "- L: %ld", n->getChildIdentifier( cChild ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! ids.empty() )
|
||||
{
|
||||
nextEntry = ids.back(); ids.pop();
|
||||
hasNext = true;
|
||||
}
|
||||
else
|
||||
hasNext = false;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -585,57 +628,21 @@ void QgsPointLocator::destroyIndex( int types )
|
||||
|
||||
void QgsPointLocator::onFeatureAdded( QgsFeatureId fid )
|
||||
{
|
||||
QgsFeature f;
|
||||
QgsFeatureRequest request;
|
||||
request.setFilterFid( fid );
|
||||
request.setSubsetOfAttributes( QgsAttributeList() );
|
||||
QgsFeatureIterator fi = mLayer->getFeatures( request );
|
||||
if ( fi.nextFeature( f ) && f.geometry() )
|
||||
{
|
||||
QGis::GeometryType geomType = f.geometry()->type();
|
||||
|
||||
if ( mTransform )
|
||||
f.geometry()->transform( *mTransform );
|
||||
|
||||
if ( mRTreeVertex && ( geomType == QGis::Polygon || geomType == QGis::Line || geomType == QGis::Point ) )
|
||||
{
|
||||
QLinkedList<RTree::Data*> vertexDataList;
|
||||
addVertexData( vertexDataList, f );
|
||||
foreach ( RTree::Data* d, vertexDataList )
|
||||
{
|
||||
mRTreeVertex->insertData( d->m_dataLength, d->m_pData, d->m_region, d->m_id );
|
||||
delete d;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: edge, area
|
||||
}
|
||||
Q_UNUSED( fid );
|
||||
destroyIndex( All );
|
||||
}
|
||||
|
||||
void QgsPointLocator::onFeatureDeleted( QgsFeatureId fid )
|
||||
{
|
||||
#if 0
|
||||
if ( mRTreeVertex )
|
||||
{
|
||||
MyQueryStrategy qq( fid );
|
||||
mRTreeVertex->queryStrategy( qq );
|
||||
foreach ( const SpatialIndex::Region& r, qq.regions )
|
||||
{
|
||||
bool res = mRTreeVertex->deleteData( r, fid );
|
||||
qDebug( "del: %d %f,%f - %f,%f", res, r.m_pLow[0], r.m_pLow[1], r.m_pHigh[0], r.m_pHigh[1] );
|
||||
}
|
||||
qDebug( "isvalid %d", mRTreeVertex->isIndexValid() );
|
||||
}
|
||||
|
||||
// TODO: edge, area
|
||||
#endif
|
||||
Q_UNUSED( fid );
|
||||
destroyIndex( All );
|
||||
}
|
||||
|
||||
void QgsPointLocator::onGeometryChanged( QgsFeatureId fid, QgsGeometry& geom )
|
||||
{
|
||||
Q_UNUSED( fid );
|
||||
Q_UNUSED( geom );
|
||||
onFeatureDeleted( fid );
|
||||
onFeatureAdded( fid );
|
||||
destroyIndex( All );
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,21 +116,20 @@ class TestQgsPointLocator : public QObject
|
||||
|
||||
void testLayerUpdates()
|
||||
{
|
||||
QgsPointLocator loc( mVL );
|
||||
|
||||
mVL->startEditing();
|
||||
QgsPointLocator loc( mVL );
|
||||
|
||||
QgsPointLocator::Match mAddV0 = loc.nearestVertex( QgsPoint( 12, 12 ) );
|
||||
QVERIFY( mAddV0.isValid() );
|
||||
QCOMPARE( mAddV0.point(), QgsPoint( 1, 1 ) );
|
||||
|
||||
mVL->startEditing();
|
||||
|
||||
// add a new feature
|
||||
QgsFeature ff( 0 );
|
||||
QgsPolygon polygon;
|
||||
QgsPolyline polyline;
|
||||
polyline << QgsPoint( 10, 11 ) << QgsPoint( 11, 10 ) << QgsPoint( 11, 11 ) << QgsPoint( 10, 11 );
|
||||
polyline << QgsPoint( 101, 11 ) << QgsPoint( 111, 10 ) << QgsPoint( 111, 11 ) << QgsPoint( 110, 11 );
|
||||
polyline << QgsPoint( 10, 111 ) << QgsPoint( 11, 110 ) << QgsPoint( 11, 111 ) << QgsPoint( 10, 111 );
|
||||
polygon << polyline;
|
||||
ff.setGeometry( QgsGeometry::fromPolygon( polygon ) );
|
||||
QgsFeatureList flist;
|
||||
@ -141,7 +140,6 @@ class TestQgsPointLocator : public QObject
|
||||
// verify it is added in the point locator
|
||||
QgsPointLocator::Match mAddV = loc.nearestVertex( QgsPoint( 12, 12 ) );
|
||||
QVERIFY( mAddV.isValid() );
|
||||
qDebug( "%f,%f", mAddV.point().x(), mAddV.point().y() );
|
||||
QCOMPARE( mAddV.point(), QgsPoint( 11, 11 ) );
|
||||
QgsPointLocator::Match mAddE = loc.nearestEdge( QgsPoint( 11.1, 10.5 ) );
|
||||
QVERIFY( mAddE.isValid() );
|
||||
@ -149,7 +147,20 @@ class TestQgsPointLocator : public QObject
|
||||
QgsPointLocator::MatchList mAddA = loc.pointInPolygon( QgsPoint( 10.8, 10.8 ) );
|
||||
QVERIFY( mAddA.count() == 1 );
|
||||
|
||||
#if 0
|
||||
// change geometry
|
||||
QgsGeometry* newGeom = new QgsGeometry( *ff.geometry() );
|
||||
newGeom->moveVertex( 10, 10, 2 ); // change 11,11 to 10,10
|
||||
mVL->changeGeometry( ff.id(), newGeom );
|
||||
delete newGeom;
|
||||
|
||||
// verify it is changed in the point locator
|
||||
QgsPointLocator::Match mChV = loc.nearestVertex( QgsPoint( 12, 12 ) );
|
||||
QVERIFY( mChV.isValid() );
|
||||
QVERIFY( mChV.point() != QgsPoint( 11, 11 ) ); // that point does not exist anymore
|
||||
mChV = loc.nearestVertex( QgsPoint( 9, 9 ) );
|
||||
QVERIFY( mChV.isValid() );
|
||||
QVERIFY( mChV.point() == QgsPoint( 10, 10 ) ); // updated point
|
||||
|
||||
// delete feature
|
||||
bool resD = mVL->deleteFeature( ff.id() );
|
||||
QVERIFY( resD );
|
||||
@ -157,9 +168,7 @@ class TestQgsPointLocator : public QObject
|
||||
// verify it is deleted from the point locator
|
||||
QgsPointLocator::Match mDelV = loc.nearestVertex( QgsPoint( 12, 12 ) );
|
||||
QVERIFY( mDelV.isValid() );
|
||||
qDebug( "%f,%f", mDelV.point().x(), mDelV.point().y() );
|
||||
QCOMPARE( mDelV.point(), QgsPoint( 1, 1 ) );
|
||||
#endif
|
||||
|
||||
mVL->rollBack();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user