Skip to content

Commit

Permalink
[quick] Fix identify: give priority to points (and lines)
Browse files Browse the repository at this point in the history
Without priority for points (and lines) it is otherwise very difficult
to identify them on top of polygons or difficult to identify a point
on top of a line.

Also lowered the default radius from 8mm (which seemed excessively large) to 5mm.
  • Loading branch information
wonder-sk committed Feb 12, 2019
1 parent f95d323 commit 673d494
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 15 deletions.
52 changes: 38 additions & 14 deletions src/quickgui/qgsquickidentifykit.cpp
Expand Up @@ -93,13 +93,13 @@ QgsQuickFeatureLayerPairs QgsQuickIdentifyKit::identify( const QPointF &point, Q
return results;
}

static QgsQuickFeatureLayerPair _closestFeature( const QgsQuickFeatureLayerPairs &results, const QgsMapSettings &mapSettings, const QPointF &point )
static QgsQuickFeatureLayerPair _closestFeature( const QgsQuickFeatureLayerPairs &results, const QgsMapSettings &mapSettings, const QPointF &point, double searchRadius )
{
QgsPointXY mapPoint = mapSettings.mapToPixel().toMapCoordinates( point.toPoint() );
QgsGeometry mapPointGeom( QgsGeometry::fromPointXY( mapPoint ) );

double distMin = 1e10;
int iMin = -1;
double distMinPoint = 1e10, distMinLine = 1e10, distMinPolygon = 1e10;
int iMinPoint = -1, iMinLine = -1, iMinPolygon = -1;
for ( int i = 0; i < results.count(); ++i )
{
const QgsQuickFeatureLayerPair &res = results.at( i );
Expand All @@ -116,27 +116,51 @@ static QgsQuickFeatureLayerPair _closestFeature( const QgsQuickFeatureLayerPairs
}

double dist = geom.distance( mapPointGeom );
if ( dist < distMin )
QgsWkbTypes::GeometryType type = QgsWkbTypes::geometryType( geom.wkbType() );
if ( type == QgsWkbTypes::PointGeometry )
{
iMin = i;
distMin = dist;
if ( dist < distMinPoint )
{
iMinPoint = i;
distMinPoint = dist;
}
}
else if ( type == QgsWkbTypes::LineGeometry )
{
if ( dist < distMinLine )
{
iMinLine = i;
distMinLine = dist;
}
}
else // polygons
{
if ( dist < distMinPolygon )
{
iMinPolygon = i;
distMinPolygon = dist;
}
}
}

if ( results.empty() )
{
return QgsQuickFeatureLayerPair();
}
// we give priority to points, then lines, then polygons
// the rationale is that points in polygon (or on a line) would have nearly
// always non-zero distance while polygon surrounding it has zero distance,
// so it would be difficult to identify it
if ( iMinPoint != -1 && distMinPoint <= searchRadius )
return results.at( iMinPoint );
else if ( iMinLine != -1 && distMinLine <= searchRadius )
return results.at( iMinLine );
else if ( iMinPolygon != -1 )
return results.at( iMinPolygon );
else
{
return results.at( iMin );
}
return QgsQuickFeatureLayerPair();
}

QgsQuickFeatureLayerPair QgsQuickIdentifyKit::identifyOne( const QPointF &point, QgsVectorLayer *layer )
{
QgsQuickFeatureLayerPairs results = identify( point, layer );
return _closestFeature( results, mMapSettings->mapSettings(), point );
return _closestFeature( results, mMapSettings->mapSettings(), point, searchRadiusMU() );
}

QgsFeatureList QgsQuickIdentifyKit::identifyVectorLayer( QgsVectorLayer *layer, const QgsPointXY &point ) const
Expand Down
2 changes: 1 addition & 1 deletion src/quickgui/qgsquickidentifykit.h
Expand Up @@ -166,7 +166,7 @@ class QUICK_EXPORT QgsQuickIdentifyKit : public QObject
QgsRectangle toLayerCoordinates( QgsMapLayer *layer, const QgsRectangle &rect ) const;
QgsFeatureList identifyVectorLayer( QgsVectorLayer *layer, const QgsPointXY &point ) const;

double mSearchRadiusMm = 8;
double mSearchRadiusMm = 5;
int mFeaturesLimit = 100;
IdentifyMode mIdentifyMode = IdentifyMode::TopDownAll;
};
Expand Down

0 comments on commit 673d494

Please sign in to comment.