Skip to content

Commit 40223db

Browse files
authored
Merge branch 'master' into patch-2
2 parents 399bbf1 + 31fadd1 commit 40223db

35 files changed

+846
-116
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/qgsgeometryfixes.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
class QgsGeometryFixes
13+
{
14+
%Docstring
15+
16+
The QgsGeometryFixes class contains options to automatically adjust geometries to
17+
constraints on a layer.
18+
19+
.. versionadded:: 3.4
20+
%End
21+
22+
%TypeHeaderCode
23+
#include "qgsgeometryfixes.h"
24+
%End
25+
public:
26+
27+
QgsGeometryFixes();
28+
%Docstring
29+
Create a new QgsGeometryFixes object.
30+
%End
31+
32+
bool removeDuplicateNodes() const;
33+
%Docstring
34+
Automatically remove duplicate nodes on all geometries which are edited on this layer.
35+
36+
.. versionadded:: 3.4
37+
%End
38+
39+
void setRemoveDuplicateNodes( bool value );
40+
%Docstring
41+
Automatically remove duplicate nodes on all geometries which are edited on this layer.
42+
43+
.. versionadded:: 3.4
44+
%End
45+
46+
double geometryPrecision() const;
47+
%Docstring
48+
The precision in which geometries on this layer should be saved.
49+
Geometries which are edited on this layer will be rounded to multiples of this value (snap to grid).
50+
Set to 0.0 to disable.
51+
52+
.. versionadded:: 3.4
53+
%End
54+
55+
void setGeometryPrecision( double value );
56+
%Docstring
57+
The precision in which geometries on this layer should be saved.
58+
Geometries which are edited on this layer will be rounded to multiples of this value (snap to grid).
59+
Set to 0.0 to disable.
60+
61+
.. versionadded:: 3.4
62+
%End
63+
64+
bool isActive() const;
65+
%Docstring
66+
Determines if at least one fix is enabled.
67+
68+
.. versionadded:: 3.4
69+
%End
70+
71+
void apply( QgsGeometry &geometry ) const;
72+
%Docstring
73+
Apply any fixes configured on this class to ``geometry``.
74+
75+
.. versionadded:: 3.4
76+
%End
77+
78+
};
79+
80+
/************************************************************************
81+
* This file has been generated automatically from *
82+
* *
83+
* src/core/qgsgeometryfixes.h *
84+
* *
85+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
86+
************************************************************************/

python/core/auto_generated/qgsvectorlayer.sip.in

+10-3
Original file line numberDiff line numberDiff line change
@@ -1062,7 +1062,7 @@ Query the layer for the features which intersect the specified rectangle.
10621062
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = 0 );
10631063

10641064

1065-
bool updateFeature( const QgsFeature &feature, bool skipDefaultValues = false );
1065+
bool updateFeature( QgsFeature &feature, bool skipDefaultValues = false );
10661066
%Docstring
10671067
Updates an existing ``feature`` in the layer, replacing the attributes and geometry for the feature
10681068
with matching QgsFeature.id() with the attributes and geometry from ``feature``.
@@ -1498,7 +1498,7 @@ Make layer read-only (editing disabled) or not
14981498
:return: false if the layer is in editing yet
14991499
%End
15001500

1501-
bool changeGeometry( QgsFeatureId fid, const QgsGeometry &geometry, bool skipDefaultValue = false );
1501+
bool changeGeometry( QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue = false );
15021502
%Docstring
15031503
Changes a feature's ``geometry`` within the layer's edit buffer
15041504
(but does not immediately commit the changes). The ``fid`` argument
@@ -2223,6 +2223,13 @@ it.
22232223
Test if an edit command is active
22242224

22252225
.. versionadded:: 3.0
2226+
%End
2227+
2228+
QgsGeometryFixes *geometryFixes() const;
2229+
%Docstring
2230+
Configuration and logic to apply automatically on any edit happening on this layer.
2231+
2232+
.. versionadded:: 3.4
22262233
%End
22272234

22282235
public slots:
@@ -2590,7 +2597,7 @@ Emitted when the feature count for symbols on this layer has been recalculated.
25902597
Sets the extent
25912598
%End
25922599

2593-
private: // Private methods
2600+
private:
25942601
QgsVectorLayer( const QgsVectorLayer &rhs );
25952602
};
25962603

python/core/core_auto.sip

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
%Include auto_generated/qgsfields.sip
5454
%Include auto_generated/qgsfileutils.sip
5555
%Include auto_generated/qgsfontutils.sip
56+
%Include auto_generated/qgsgeometryfixes.sip
5657
%Include auto_generated/qgsgeometrysimplifier.sip
5758
%Include auto_generated/qgshistogram.sip
5859
%Include auto_generated/qgshtmlutils.sip

python/testing/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ def assertFilesEqual(self, filepath_expected, filepath_result):
196196
diff = list(diff)
197197
self.assertEqual(0, len(diff), ''.join(diff))
198198

199+
def assertGeometriesEqual(self, geom0, geom1, geom0_id='geometry 1', geom1_id='geometry 2', precision=14, topo_equal_check=False):
200+
self.checkGeometriesEqual(geom0, geom1, geom0_id, geom1_id, use_asserts=True, precision=precision, topo_equal_check=topo_equal_check)
201+
199202
def checkGeometriesEqual(self, geom0, geom1, geom0_id, geom1_id, use_asserts=False, precision=14, topo_equal_check=False):
200203
""" Checks whether two geometries are the same - using either a strict check of coordinates (up to given precision)
201204
or by using topological equality (where e.g. a polygon with clockwise is equal to a polygon with counter-clockwise

resources/function_help/json/array

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
{"arg":"value1", "syntaxOnly": true},
88
{"arg":"value2", "syntaxOnly": true},
99
{"arg":"value", "descOnly": true, "description":"a value"}],
10-
"examples": [ { "expression":"array(2,10)", "returns":"array: 2, 10"}
10+
"examples": [ { "expression":"array(2,10)", "returns":"[ 2, 10 ]"}
1111
]
1212
}

resources/function_help/json/array_append

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"description": "Returns an array with the given value added at the end.",
55
"arguments": [ {"arg":"array","description":"an array"},
66
{"arg":"value","description":"the value to add"}],
7-
"examples": [ { "expression":"array_append(array(1,2,3),4)", "returns":"array: 1,2,3,4"}]
7+
"examples": [ { "expression":"array_append(array(1,2,3),4)", "returns":"[ 1, 2, 3, 4 ]"}]
88
}

resources/function_help/json/array_cat

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
{"arg":"array1", "syntaxOnly": true},
88
{"arg":"array2", "syntaxOnly": true},
99
{"arg":"array", "descOnly": true, "description":"an array"}],
10-
"examples": [ { "expression":"array_cat(array(1,2),array(2,3))", "returns":"array: 1,2,2,3"}
10+
"examples": [ { "expression":"array_cat(array(1,2),array(2,3))", "returns":"[ 1, 2, 2, 3 ]"}
1111
]
1212
}

resources/function_help/json/array_distinct

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"description": "Returns an array containing distinct values of the given array.",
55
"arguments": [
66
{"arg":"array","description":"an array"}],
7-
"examples": [ { "expression":"array_distinct(array(1,2,3,2,1))", "returns":"array: 1,2,3"}
7+
"examples": [ { "expression":"array_distinct(array(1,2,3,2,1))", "returns":"[ 1, 2, 3 ]"}
88
]
99
}

resources/function_help/json/array_foreach

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{"arg":"expression","description":"an expression to evaluate on each item. The variable `@element` will be replaced by the current value."}
88
],
99
"examples": [
10-
{ "expression": "array_foreach(array('a','b','c'),upper(@element))", "returns":"array: 'A', 'B', 'C'"},
11-
{ "expression": "array_foreach(array(1,2,3),@element + 10)", "returns":"array: 11, 12, 13"}
10+
{ "expression": "array_foreach(array('a','b','c'),upper(@element))", "returns":"[ 'A', 'B', 'C' ]"},
11+
{ "expression": "array_foreach(array(1,2,3),@element + 10)", "returns":"[ 11, 12, 13 ]"}
1212
]
1313
}

resources/function_help/json/array_insert

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"arguments": [ {"arg":"array","description":"an array"},
66
{"arg":"pos","description":"the position where to add (0 based)"},
77
{"arg":"value","description":"the value to add"}],
8-
"examples": [ { "expression":"array_insert(array(1,2,3),1,100)", "returns":"array: 1,100,2,3"}]
8+
"examples": [ { "expression":"array_insert(array(1,2,3),1,100)", "returns":"[ 1, 100, 2, 3 ]"}]
99
}

resources/function_help/json/array_prepend

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"description": "Returns an array with the given value added at the beginning.",
55
"arguments": [ {"arg":"array","description":"an array"},
66
{"arg":"value","description":"the value to add"}],
7-
"examples": [ { "expression":"array_prepend(array(1,2,3),0)", "returns":"array: 0,1,2,3"}]
7+
"examples": [ { "expression":"array_prepend(array(1,2,3),0)", "returns":"[ 0, 1, 2, 3 ]"}]
88
}

resources/function_help/json/array_remove_all

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"description": "Returns an array with all the entries of the given value removed.",
55
"arguments": [ {"arg":"array","description":"an array"},
66
{"arg":"value","description":"the values to remove"}],
7-
"examples": [ { "expression":"array_remove_all(array('a','b','c','b'),'b')", "returns":"array: 'a','c'"}]
7+
"examples": [ { "expression":"array_remove_all(array('a','b','c','b'),'b')", "returns":"[ 'a', 'c' ]"}]
88
}

resources/function_help/json/array_remove_at

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"description": "Returns an array with the given index removed.",
55
"arguments": [ {"arg":"array","description":"an array"},
66
{"arg":"pos","description":"the position to remove (0 based)"}],
7-
"examples": [ { "expression":"array_remove_at(array(1,2,3),1)", "returns":"array: 1,3"}]
7+
"examples": [ { "expression":"array_remove_at(array(1,2,3),1)", "returns":"[ 1, 3 ]"}]
88
}

resources/function_help/json/array_reverse

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
"type": "function",
44
"description": "Returns the given array with array values in reversed order.",
55
"arguments": [ {"arg":"array","description":"an array"} ],
6-
"examples": [ { "expression":"array_reverse(array(2,4,0,10))", "returns":"array: 10,0,4,2"}]
6+
"examples": [ { "expression":"array_reverse(array(2,4,0,10))", "returns":"[ 10, 0, 4, 2 ]"}]
77
}

resources/function_help/json/array_slice

+8-8
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,35 @@
1717
],
1818
"examples": [{
1919
"expression": "array_slice(array(1,2,3,4,5),0,3)",
20-
"returns": "array: 1,2,3,4"
20+
"returns": "[ 1, 2, 3, 4 ]"
2121
},
2222
{
2323
"expression": "array_slice(array(1,2,3,4,5),0,-1)",
24-
"returns": "array: 1,2,3,4,5"
24+
"returns": "[ 1, 2, 3, 4, 5 ]"
2525
},
2626
{
2727
"expression": "array_slice(array(1,2,3,4,5),-5,-1)",
28-
"returns": "array: 1,2,3,4,5"
28+
"returns": "[ 1, 2, 3, 4, 5 ]"
2929
},
3030
{
3131
"expression": "array_slice(array(1,2,3,4,5),0,0)",
32-
"returns": "array: 1"
32+
"returns": "[ 1 ]"
3333
},
3434
{
3535
"expression": "array_slice(array(1,2,3,4,5),-2,-1)",
36-
"returns": "array: 4,5"
36+
"returns": "[ 4, 5 ]"
3737
},
3838
{
3939
"expression": "array_slice(array(1,2,3,4,5),-1,-1)",
40-
"returns": "array: 5"
40+
"returns": "[ 5 ]"
4141
},
4242
{
4343
"expression": "array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),1,2)",
44-
"returns": "array: 'Valmiera','Chugiak'"
44+
"returns": "[ 'Valmiera', 'Chugiak' ]"
4545
},
4646
{
4747
"expression": "array_slice(array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),-2,-1)",
48-
"returns": "array: 'Chugiak','Brighton'"
48+
"returns": "[ 'Chugiak', 'Brighton' ]"
4949
}
5050
]
5151
}

resources/function_help/json/generate_series

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{"arg":"stop", "description":"value that ends the sequence once reached"},
88
{"arg":"step","optional":true,"default":"1","description":"value used as the increment between values"}
99
],
10-
"examples": [ { "expression":"generate_series(1,5)", "returns":"array: 1, 2, 3, 4, 5"},
11-
{ "expression":"generate_series(5,1,-1)", "returns":"array: 5, 4, 3, 2, 1"}
10+
"examples": [ { "expression":"generate_series(1,5)", "returns":"[ 1, 2, 3, 4, 5 ]"},
11+
{ "expression":"generate_series(5,1,-1)", "returns":"[ 5, 4, 3, 2, 1 ]"}
1212
]
1313
}

resources/function_help/json/map

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
{"arg":"value2", "syntaxOnly": true},
1111
{"arg":"key", "descOnly": true, "description":"a key (string)"},
1212
{"arg":"value", "descOnly": true, "description":"a value"}],
13-
"examples": [ { "expression":"map('1','one','2', 'two')", "returns":"map: 1: 'one', 2: 'two'"}
13+
"examples": [ { "expression":"map('1','one','2', 'two')", "returns":"{ '1': 'one', '2': 'two' }"}
1414
]
1515
}

resources/function_help/json/map_akeys

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
"type": "function",
44
"description": "Returns all the keys of a map as an array.",
55
"arguments": [ {"arg":"map","description":"a map"}],
6-
"examples": [ { "expression":"map_akeys(map('1','one','2','two'))", "returns":"array: '1', '2'"}]
6+
"examples": [ { "expression":"map_akeys(map('1','one','2','two'))", "returns":"[ '1', '2' ]"}]
77
}

resources/function_help/json/map_avals

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
"type": "function",
44
"description": "Returns all the values of a map as an array.",
55
"arguments": [ {"arg":"map","description":"a map"}],
6-
"examples": [ { "expression":"map_avals(map('1','one','2','two'))", "returns":"array: 'one', 'two'"}]
6+
"examples": [ { "expression":"map_avals(map('1','one','2','two'))", "returns":"[ 'one', 'two' ]"}]
77
}

resources/function_help/json/map_concat

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
{"arg":"map1", "syntaxOnly": true},
88
{"arg":"map2", "syntaxOnly": true},
99
{"arg":"map", "descOnly": true, "description":"a map"}],
10-
"examples": [ { "expression":"map_concat(map('1','one', '2','overridden'),map('2','two', '3','three'))", "returns":"map: 1: 'one, 2: 'two', 3: 'three'"}
10+
"examples": [ { "expression":"map_concat(map('1','one', '2','overridden'),map('2','two', '3','three'))", "returns":"{ '1': 'one, '2': 'two', '3': 'three' }"}
1111
]
1212
}

resources/function_help/json/map_delete

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"description": "Returns a map with the given key and its corresponding value deleted.",
55
"arguments": [ {"arg":"map","description":"a map"},
66
{"arg":"key","description":"the key to delete"}],
7-
"examples": [ { "expression":"map_delete(map('1','one','2','two'),'2')", "returns":"map: 1: 'one'"}]
7+
"examples": [ { "expression":"map_delete(map('1','one','2','two'),'2')", "returns":"{ '1': 'one' }"}]
88
}

resources/function_help/json/map_insert

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"arguments": [ {"arg":"map","description":"a map"},
66
{"arg":"key","description":"the key to add"},
77
{"arg":"value","description":"the value to add"}],
8-
"examples": [ { "expression":"map_insert(map('1','one'),'3','three')", "returns":"map: 1: 'one', 3: 'three'"}]
8+
"examples": [ { "expression":"map_insert(map('1','one'),'3','three')", "returns":"{ '1': 'one', '3': 'three' }"}]
99
}

resources/function_help/json/regexp_matches

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
{"arg":"string", "description":"the string to capture groups from against the regular expression"},
77
{"arg":"regex","description":"the regular expression used to capture groups"},
88
{"arg":"empty_value","optional":true,"default":"''","description":"the optional string to use as replacement for empty (zero length) matches"}],
9-
"examples": [ { "expression":"regexp_matches('QGIS=>rocks','(.*)=>(.*)')", "returns":"array: 'QGIS', 'rocks'"},
10-
{ "expression":"regexp_matches('key=>','(.*)=>(.*)','empty value')", "returns":"array: 'key', 'empty value'"}
9+
"examples": [ { "expression":"regexp_matches('QGIS=>rocks','(.*)=>(.*)')", "returns":"[ 'QGIS', 'rocks' ]"},
10+
{ "expression":"regexp_matches('key=>','(.*)=>(.*)','empty value')", "returns":"[ 'key', 'empty value' ]"}
1111
]
1212
}

resources/function_help/json/string_to_array

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
{"arg":"string", "description":"the input string"},
77
{"arg":"delimiter","optional":true,"default":"','","description":"the string delimiter used to split the input string"},
88
{"arg":"empty_value","optional":true,"default":"''","description":"the optional string to use as replacement for empty (zero length) matches"}],
9-
"examples": [ { "expression":"string_to_array('1,2,3',',')", "returns":"array: '1', '2', '3'"},
10-
{ "expression":"string_to_array('1,,3',',','0')", "returns":"array: '1', '0', '3'"}
9+
"examples": [ { "expression":"string_to_array('1,2,3',',')", "returns":"[ '1', '2', '3' ]"},
10+
{ "expression":"string_to_array('1,,3',',','0')", "returns":"[ '1', '0', '3' ]"}
1111
]
1212
}

src/app/qgsvectorlayerproperties.cpp

+22-2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#include "qgsnewauxiliaryfielddialog.h"
6363
#include "qgslabelinggui.h"
6464
#include "qgssymbollayer.h"
65+
#include "qgsgeometryfixes.h"
6566

6667
#include "layertree/qgslayertreelayer.h"
6768
#include "qgslayertree.h"
@@ -289,9 +290,9 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
289290

290291
//insert existing join info
291292
const QList< QgsVectorLayerJoinInfo > &joins = mLayer->vectorJoins();
292-
for ( int i = 0; i < joins.size(); ++i )
293+
for ( const QgsVectorLayerJoinInfo &join : joins )
293294
{
294-
addJoinToTreeWidget( joins[i] );
295+
addJoinToTreeWidget( join );
295296
}
296297

297298
mOldJoins = mLayer->vectorJoins();
@@ -423,6 +424,22 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
423424

424425
updateAuxiliaryStoragePage();
425426

427+
if ( mLayer->isSpatial() )
428+
{
429+
mRemoveDuplicateNodesCheckbox->setEnabled( true );
430+
mGeometryPrecisionSpinBox->setEnabled( true );
431+
432+
mRemoveDuplicateNodesCheckbox->setChecked( mLayer->geometryFixes()->removeDuplicateNodes() );
433+
mGeometryPrecisionSpinBox->setValue( mLayer->geometryFixes()->geometryPrecision() );
434+
435+
mGeometryPrecisionSpinBox->setSuffix( QStringLiteral( " [%1]" ).arg( QgsUnitTypes::toAbbreviatedString( mLayer->crs().mapUnits() ) ) );
436+
}
437+
else
438+
{
439+
mRemoveDuplicateNodesCheckbox->setEnabled( false );
440+
mGeometryPrecisionSpinBox->setEnabled( false );
441+
}
442+
426443
optionsStackedWidget_CurrentChanged( mOptStackedWidget->currentIndex() );
427444
}
428445

@@ -761,6 +778,9 @@ void QgsVectorLayerProperties::apply()
761778
mVector3DWidget->apply();
762779
#endif
763780

781+
mLayer->geometryFixes()->setRemoveDuplicateNodes( mRemoveDuplicateNodesCheckbox->isChecked() );
782+
mLayer->geometryFixes()->setGeometryPrecision( mGeometryPrecisionSpinBox->value() );
783+
764784
// update symbology
765785
emit refreshLegend( mLayer->id() );
766786

0 commit comments

Comments
 (0)