Skip to content

Commit ee47d42

Browse files
committedOct 23, 2017
[Geometry checker] Add point must be covered by line check
1 parent 7fb1c55 commit ee47d42

File tree

6 files changed

+197
-35
lines changed

6 files changed

+197
-35
lines changed
 

‎src/plugins/geometry_checker/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ SET (geometrychecker_SRCS
1818
checks/qgsgeometrymultipartcheck.cpp
1919
checks/qgsgeometrycontainedcheck.cpp
2020
checks/qgsgeometryoverlapcheck.cpp
21+
checks/qgsgeometrypointcoveredbylinecheck.cpp
2122
checks/qgsgeometrysegmentlengthcheck.cpp
2223
checks/qgsgeometryselfcontactcheck.cpp
2324
checks/qgsgeometryselfintersectioncheck.cpp
@@ -55,6 +56,7 @@ SET (geometrychecker_MOC_HDRS
5556
checks/qgsgeometrymultipartcheck.h
5657
checks/qgsgeometrycontainedcheck.h
5758
checks/qgsgeometryoverlapcheck.h
59+
checks/qgsgeometrypointcoveredbylinecheck.h
5860
checks/qgsgeometrysegmentlengthcheck.h
5961
checks/qgsgeometryselfcontactcheck.h
6062
checks/qgsgeometryselfintersectioncheck.h
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/***************************************************************************
2+
qgsgeometrypointcoveredbylinecheck.cpp
3+
---------------------
4+
begin : June 2017
5+
copyright : (C) 2017 by Sandro Mani / Sourcepole AG
6+
email : smani at sourcepole dot ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsgeometrypointcoveredbylinecheck.h"
17+
#include "qgslinestring.h"
18+
#include "../utils/qgsfeaturepool.h"
19+
20+
void QgsGeometryPointCoveredByLineCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &/*messages*/, QAtomicInt *progressCounter, const QMap<QString, QgsFeatureIds> &ids ) const
21+
{
22+
QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
23+
QgsGeometryCheckerUtils::LayerFeatures layerFeatures( mContext->featurePools, featureIds, mCompatibleGeometryTypes, progressCounter, true );
24+
for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
25+
{
26+
const QgsAbstractGeometry *geom = layerFeature.geometry();
27+
for ( int iPart = 0, nParts = geom->partCount(); iPart < nParts; ++iPart )
28+
{
29+
const QgsPoint *point = dynamic_cast<const QgsPoint *>( QgsGeometryCheckerUtils::getGeomPart( geom, iPart ) );
30+
if ( !point )
31+
{
32+
// Should not happen
33+
continue;
34+
}
35+
// Check that point lies on a line
36+
bool touches = false;
37+
QgsRectangle rect( point->x() - mContext->tolerance, point->y() - mContext->tolerance,
38+
point->x() + mContext->tolerance, point->y() + mContext->tolerance );
39+
QgsGeometryCheckerUtils::LayerFeatures checkFeatures( mContext->featurePools, featureIds.keys(), rect, {QgsWkbTypes::LineGeometry} );
40+
for ( const QgsGeometryCheckerUtils::LayerFeature &checkFeature : checkFeatures )
41+
{
42+
const QgsAbstractGeometry *testGeom = checkFeature.geometry();
43+
for ( int jPart = 0, mParts = testGeom->partCount(); jPart < mParts; ++jPart )
44+
{
45+
const QgsLineString *testLine = dynamic_cast<const QgsLineString *>( QgsGeometryCheckerUtils::getGeomPart( testGeom, jPart ) );
46+
if ( !testLine )
47+
{
48+
continue;
49+
}
50+
if ( QgsGeometryCheckerUtils::pointOnLine( *point, testLine, mContext->tolerance ) )
51+
{
52+
touches = true;
53+
break;
54+
}
55+
}
56+
if ( touches == true )
57+
{
58+
break;
59+
}
60+
}
61+
if ( touches == true )
62+
{
63+
continue;
64+
}
65+
errors.append( new QgsGeometryCheckError( this, layerFeature, *point, QgsVertexId( iPart, 0, 0 ) ) );
66+
}
67+
}
68+
}
69+
70+
void QgsGeometryPointCoveredByLineCheck::fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes & /*changes*/ ) const
71+
{
72+
if ( method == NoChange )
73+
{
74+
error->setFixed( method );
75+
}
76+
else
77+
{
78+
error->setFixFailed( tr( "Unknown method" ) );
79+
}
80+
}
81+
82+
QStringList QgsGeometryPointCoveredByLineCheck::getResolutionMethods() const
83+
{
84+
static QStringList methods = QStringList() << tr( "No action" );
85+
return methods;
86+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/***************************************************************************
2+
qgsgeometrypointcoveredbylinecheck.h
3+
---------------------
4+
begin : June 2017
5+
copyright : (C) 2017 by Sandro Mani / Sourcepole AG
6+
email : smani at sourcepole dot ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSGEOMETRYPOINTCOVEREDBYLINECHECK_H
17+
#define QGSGEOMETRYPOINTCOVEREDBYLINECHECK_H
18+
19+
#include "qgsgeometrycheck.h"
20+
21+
class QgsGeometryPointCoveredByLineCheck : public QgsGeometryCheck
22+
{
23+
Q_OBJECT
24+
25+
public:
26+
QgsGeometryPointCoveredByLineCheck( QgsGeometryCheckerContext *context )
27+
: QgsGeometryCheck( FeatureNodeCheck, {QgsWkbTypes::PointGeometry}, context )
28+
{}
29+
void collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter = nullptr, const QMap<QString, QgsFeatureIds> &ids = QMap<QString, QgsFeatureIds>() ) const override;
30+
void fixError( QgsGeometryCheckError *error, int method, const QMap<QString, int> &mergeAttributeIndices, Changes &changes ) const override;
31+
QStringList getResolutionMethods() const override;
32+
QString errorDescription() const override { return tr( "Point not covered by line" ); }
33+
QString errorName() const override { return QStringLiteral( "QgsGeometryPointCoveredByLineCheck" ); }
34+
private:
35+
enum ResolutionMethod { NoChange };
36+
};
37+
38+
#endif // QGSGEOMETRYPOINTCOVEREDBYLINECHECK_H

‎src/plugins/geometry_checker/qgsgeometrycheckfactory.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "checks/qgsgeometryholecheck.h"
2828
#include "checks/qgsgeometrymultipartcheck.h"
2929
#include "checks/qgsgeometryoverlapcheck.h"
30+
#include "checks/qgsgeometrypointcoveredbylinecheck.h"
3031
#include "checks/qgsgeometrysegmentlengthcheck.h"
3132
#include "checks/qgsgeometryselfcontactcheck.h"
3233
#include "checks/qgsgeometryselfintersectioncheck.h"
@@ -356,6 +357,34 @@ REGISTER_QGS_GEOMETRY_CHECK_FACTORY( QgsGeometryCheckFactoryT<QgsGeometryOverlap
356357

357358
///////////////////////////////////////////////////////////////////////////////
358359

360+
template<> void QgsGeometryCheckFactoryT<QgsGeometryPointCoveredByLineCheck>::restorePrevious( Ui::QgsGeometryCheckerSetupTab &ui ) const
361+
{
362+
ui.checkPointCoveredByLine->setChecked( QgsSettings().value( sSettingsGroup + "checkPointCoveredByLine" ).toBool() );
363+
}
364+
365+
template<> bool QgsGeometryCheckFactoryT<QgsGeometryPointCoveredByLineCheck>::checkApplicability( Ui::QgsGeometryCheckerSetupTab &ui, int nPoint, int /*nLineString*/, int /*nPolygon*/ ) const
366+
{
367+
ui.checkPointCoveredByLine->setEnabled( nPoint > 0 );
368+
return ui.checkPointCoveredByLine->isEnabled();
369+
}
370+
371+
template<> QgsGeometryCheck *QgsGeometryCheckFactoryT<QgsGeometryPointCoveredByLineCheck>::createInstance( QgsGeometryCheckerContext *context, const Ui::QgsGeometryCheckerSetupTab &ui ) const
372+
{
373+
QgsSettings().setValue( sSettingsGroup + "checkPointCoveredByLine", ui.checkPointCoveredByLine->isChecked() );
374+
if ( ui.checkPointCoveredByLine->isEnabled() && ui.checkPointCoveredByLine->isChecked() )
375+
{
376+
return new QgsGeometryPointCoveredByLineCheck( context );
377+
}
378+
else
379+
{
380+
return nullptr;
381+
}
382+
}
383+
384+
REGISTER_QGS_GEOMETRY_CHECK_FACTORY( QgsGeometryCheckFactoryT<QgsGeometryPointCoveredByLineCheck> )
385+
386+
///////////////////////////////////////////////////////////////////////////////
387+
359388
template<> void QgsGeometryCheckFactoryT<QgsGeometrySegmentLengthCheck>::restorePrevious( Ui::QgsGeometryCheckerSetupTab &ui ) const
360389
{
361390
ui.checkBoxSegmentLength->setChecked( QgsSettings().value( sSettingsGroup + "checkSegmentLength" ).toBool() );

‎src/plugins/geometry_checker/ui/qgsgeometrycheckersetuptab.ui

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<x>0</x>
4444
<y>0</y>
4545
<width>626</width>
46-
<height>872</height>
46+
<height>895</height>
4747
</rect>
4848
</property>
4949
<layout class="QGridLayout" name="gridLayout_4">
@@ -485,30 +485,16 @@
485485
<property name="spacing">
486486
<number>2</number>
487487
</property>
488-
<item row="0" column="0">
489-
<widget class="QCheckBox" name="checkBoxDuplicates">
490-
<property name="text">
491-
<string>Check for duplicates</string>
492-
</property>
493-
</widget>
494-
</item>
495-
<item row="2" column="1">
496-
<widget class="QDoubleSpinBox" name="doubleSpinBoxOverlapArea">
497-
<property name="decimals">
498-
<number>6</number>
499-
</property>
500-
<property name="maximum">
501-
<double>999999999.000000000000000</double>
502-
</property>
503-
</widget>
504-
</item>
505-
<item row="3" column="1">
506-
<widget class="QDoubleSpinBox" name="doubleSpinBoxGapArea">
507-
<property name="decimals">
508-
<number>6</number>
488+
<item row="3" column="0">
489+
<widget class="QCheckBox" name="checkBoxGaps">
490+
<property name="sizePolicy">
491+
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
492+
<horstretch>0</horstretch>
493+
<verstretch>0</verstretch>
494+
</sizepolicy>
509495
</property>
510-
<property name="maximum">
511-
<double>999999999.000000000000000</double>
496+
<property name="text">
497+
<string>Check for gaps smaller than (map units sqr.)</string>
512498
</property>
513499
</widget>
514500
</item>
@@ -525,16 +511,10 @@
525511
</property>
526512
</widget>
527513
</item>
528-
<item row="3" column="0">
529-
<widget class="QCheckBox" name="checkBoxGaps">
530-
<property name="sizePolicy">
531-
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
532-
<horstretch>0</horstretch>
533-
<verstretch>0</verstretch>
534-
</sizepolicy>
535-
</property>
514+
<item row="0" column="0">
515+
<widget class="QCheckBox" name="checkBoxDuplicates">
536516
<property name="text">
537-
<string>Check for gaps smaller than (map units sqr.)</string>
517+
<string>Check for duplicates</string>
538518
</property>
539519
</widget>
540520
</item>
@@ -545,13 +525,40 @@
545525
</property>
546526
</widget>
547527
</item>
548-
<item row="4" column="0" colspan="2">
528+
<item row="3" column="1">
529+
<widget class="QDoubleSpinBox" name="doubleSpinBoxGapArea">
530+
<property name="decimals">
531+
<number>6</number>
532+
</property>
533+
<property name="maximum">
534+
<double>999999999.000000000000000</double>
535+
</property>
536+
</widget>
537+
</item>
538+
<item row="5" column="0" colspan="2">
549539
<widget class="QLabel" name="label">
550540
<property name="text">
551541
<string>&lt;i&gt;Note: Topology checks are performed in the current map CRS.&lt;/i&gt;</string>
552542
</property>
553543
</widget>
554544
</item>
545+
<item row="2" column="1">
546+
<widget class="QDoubleSpinBox" name="doubleSpinBoxOverlapArea">
547+
<property name="decimals">
548+
<number>6</number>
549+
</property>
550+
<property name="maximum">
551+
<double>999999999.000000000000000</double>
552+
</property>
553+
</widget>
554+
</item>
555+
<item row="4" column="0" colspan="2">
556+
<widget class="QCheckBox" name="checkPointCoveredByLine">
557+
<property name="text">
558+
<string>Points must be covered by lines</string>
559+
</property>
560+
</widget>
561+
</item>
555562
</layout>
556563
</widget>
557564
</item>

‎src/plugins/geometry_checker/utils/qgsgeometrycheckerutils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ namespace QgsGeometryCheckerUtils
213213
{
214214
QgsPoint p1 = line->vertexAt( QgsVertexId( 0, 0, i ) );
215215
QgsPoint p2 = line->vertexAt( QgsVertexId( 0, 0, i + 1 ) );
216-
double dist = pointLineDist( p1, p2, 1 );
216+
double dist = pointLineDist( p1, p2, p );
217217
if ( dist < tol )
218218
{
219219
return true;

0 commit comments

Comments
 (0)
Please sign in to comment.