diff --git a/python/plugins/processing/tests/testdata/expected/vectorize.gml b/python/plugins/processing/tests/testdata/expected/vectorize.gml
new file mode 100644
index 00000000000..c13efb68ade
--- /dev/null
+++ b/python/plugins/processing/tests/testdata/expected/vectorize.gml
@@ -0,0 +1,734 @@
+
+
+
+
+ 270746.30402147234458929.133005036
+ 270869.14437832164459029.574521748
+
+
+
+
+
+ 270746.304021472,4459019.53037008 270756.540717876,4459019.53037008 270756.540717876,4459029.57452175 270746.304021472,4459029.57452175 270746.304021472,4459019.53037008
+ 826.00000000
+
+
+
+
+ 270756.540717876,4459019.53037008 270766.77741428,4459019.53037008 270766.77741428,4459029.57452175 270756.540717876,4459029.57452175 270756.540717876,4459019.53037008
+ 826.00000000
+
+
+
+
+ 270766.777414281,4459019.53037008 270777.014110685,4459019.53037008 270777.014110685,4459029.57452175 270766.777414281,4459029.57452175 270766.777414281,4459019.53037008
+ 837.00000000
+
+
+
+
+ 270777.014110685,4459019.53037008 270787.250807089,4459019.53037008 270787.250807089,4459029.57452175 270777.014110685,4459029.57452175 270777.014110685,4459019.53037008
+ 837.00000000
+
+
+
+
+ 270787.250807089,4459019.53037008 270797.487503493,4459019.53037008 270797.487503493,4459029.57452175 270787.250807089,4459029.57452175 270787.250807089,4459019.53037008
+ 837.00000000
+
+
+
+
+ 270797.487503493,4459019.53037008 270807.724199897,4459019.53037008 270807.724199897,4459029.57452175 270797.487503493,4459029.57452175 270797.487503493,4459019.53037008
+ 845.00000000
+
+
+
+
+ 270807.724199897,4459019.53037008 270817.960896301,4459019.53037008 270817.960896301,4459029.57452175 270807.724199897,4459029.57452175 270807.724199897,4459019.53037008
+ 845.00000000
+
+
+
+
+ 270817.960896301,4459019.53037008 270828.197592705,4459019.53037008 270828.197592705,4459029.57452175 270817.960896301,4459029.57452175 270817.960896301,4459019.53037008
+ 853.00000000
+
+
+
+
+ 270828.197592705,4459019.53037008 270838.434289109,4459019.53037008 270838.434289109,4459029.57452175 270828.197592705,4459029.57452175 270828.197592705,4459019.53037008
+ 853.00000000
+
+
+
+
+ 270838.434289109,4459019.53037008 270848.670985513,4459019.53037008 270848.670985513,4459029.57452175 270838.434289109,4459029.57452175 270838.434289109,4459019.53037008
+ 853.00000000
+
+
+
+
+ 270848.670985513,4459019.53037008 270858.907681917,4459019.53037008 270858.907681917,4459029.57452175 270848.670985513,4459029.57452175 270848.670985513,4459019.53037008
+ 861.00000000
+
+
+
+
+ 270858.907681918,4459019.53037008 270869.144378322,4459019.53037008 270869.144378322,4459029.57452175 270858.907681918,4459029.57452175 270858.907681918,4459019.53037008
+ 861.00000000
+
+
+
+
+ 270746.304021472,4459009.48621841 270756.540717876,4459009.48621841 270756.540717876,4459019.53037008 270746.304021472,4459019.53037008 270746.304021472,4459009.48621841
+ 826.00000000
+
+
+
+
+ 270756.540717876,4459009.48621841 270766.77741428,4459009.48621841 270766.77741428,4459019.53037008 270756.540717876,4459019.53037008 270756.540717876,4459009.48621841
+ 826.00000000
+
+
+
+
+ 270766.777414281,4459009.48621841 270777.014110685,4459009.48621841 270777.014110685,4459019.53037008 270766.777414281,4459019.53037008 270766.777414281,4459009.48621841
+ 837.00000000
+
+
+
+
+ 270777.014110685,4459009.48621841 270787.250807089,4459009.48621841 270787.250807089,4459019.53037008 270777.014110685,4459019.53037008 270777.014110685,4459009.48621841
+ 837.00000000
+
+
+
+
+ 270787.250807089,4459009.48621841 270797.487503493,4459009.48621841 270797.487503493,4459019.53037008 270787.250807089,4459019.53037008 270787.250807089,4459009.48621841
+ 837.00000000
+
+
+
+
+ 270797.487503493,4459009.48621841 270807.724199897,4459009.48621841 270807.724199897,4459019.53037008 270797.487503493,4459019.53037008 270797.487503493,4459009.48621841
+ 845.00000000
+
+
+
+
+ 270807.724199897,4459009.48621841 270817.960896301,4459009.48621841 270817.960896301,4459019.53037008 270807.724199897,4459019.53037008 270807.724199897,4459009.48621841
+ 845.00000000
+
+
+
+
+ 270817.960896301,4459009.48621841 270828.197592705,4459009.48621841 270828.197592705,4459019.53037008 270817.960896301,4459019.53037008 270817.960896301,4459009.48621841
+ 853.00000000
+
+
+
+
+ 270828.197592705,4459009.48621841 270838.434289109,4459009.48621841 270838.434289109,4459019.53037008 270828.197592705,4459019.53037008 270828.197592705,4459009.48621841
+ 853.00000000
+
+
+
+
+ 270838.434289109,4459009.48621841 270848.670985513,4459009.48621841 270848.670985513,4459019.53037008 270838.434289109,4459019.53037008 270838.434289109,4459009.48621841
+ 853.00000000
+
+
+
+
+ 270848.670985513,4459009.48621841 270858.907681917,4459009.48621841 270858.907681917,4459019.53037008 270848.670985513,4459019.53037008 270848.670985513,4459009.48621841
+ 861.00000000
+
+
+
+
+ 270858.907681918,4459009.48621841 270869.144378322,4459009.48621841 270869.144378322,4459019.53037008 270858.907681918,4459019.53037008 270858.907681918,4459009.48621841
+ 861.00000000
+
+
+
+
+ 270746.304021472,4458999.44206673 270756.540717876,4458999.44206673 270756.540717876,4459009.48621841 270746.304021472,4459009.48621841 270746.304021472,4458999.44206673
+ 843.00000000
+
+
+
+
+ 270756.540717876,4458999.44206673 270766.77741428,4458999.44206673 270766.77741428,4459009.48621841 270756.540717876,4459009.48621841 270756.540717876,4458999.44206673
+ 843.00000000
+
+
+
+
+ 270766.777414281,4458999.44206673 270777.014110685,4458999.44206673 270777.014110685,4459009.48621841 270766.777414281,4459009.48621841 270766.777414281,4458999.44206673
+ 851.00000000
+
+
+
+
+ 270777.014110685,4458999.44206673 270787.250807089,4458999.44206673 270787.250807089,4459009.48621841 270777.014110685,4459009.48621841 270777.014110685,4458999.44206673
+ 851.00000000
+
+
+
+
+ 270787.250807089,4458999.44206673 270797.487503493,4458999.44206673 270797.487503493,4459009.48621841 270787.250807089,4459009.48621841 270787.250807089,4458999.44206673
+ 851.00000000
+
+
+
+
+ 270797.487503493,4458999.44206673 270807.724199897,4458999.44206673 270807.724199897,4459009.48621841 270797.487503493,4459009.48621841 270797.487503493,4458999.44206673
+ 859.00000000
+
+
+
+
+ 270807.724199897,4458999.44206673 270817.960896301,4458999.44206673 270817.960896301,4459009.48621841 270807.724199897,4459009.48621841 270807.724199897,4458999.44206673
+ 859.00000000
+
+
+
+
+ 270817.960896301,4458999.44206673 270828.197592705,4458999.44206673 270828.197592705,4459009.48621841 270817.960896301,4459009.48621841 270817.960896301,4458999.44206673
+ 866.00000000
+
+
+
+
+ 270828.197592705,4458999.44206673 270838.434289109,4458999.44206673 270838.434289109,4459009.48621841 270828.197592705,4459009.48621841 270828.197592705,4458999.44206673
+ 866.00000000
+
+
+
+
+ 270838.434289109,4458999.44206673 270848.670985513,4458999.44206673 270848.670985513,4459009.48621841 270838.434289109,4459009.48621841 270838.434289109,4458999.44206673
+ 866.00000000
+
+
+
+
+ 270848.670985513,4458999.44206673 270858.907681917,4458999.44206673 270858.907681917,4459009.48621841 270848.670985513,4459009.48621841 270848.670985513,4458999.44206673
+ 878.00000000
+
+
+
+
+ 270858.907681918,4458999.44206673 270869.144378322,4458999.44206673 270869.144378322,4459009.48621841 270858.907681918,4459009.48621841 270858.907681918,4458999.44206673
+ 878.00000000
+
+
+
+
+ 270746.304021472,4458989.39791506 270756.540717876,4458989.39791506 270756.540717876,4458999.44206673 270746.304021472,4458999.44206673 270746.304021472,4458989.39791506
+ 843.00000000
+
+
+
+
+ 270756.540717876,4458989.39791506 270766.77741428,4458989.39791506 270766.77741428,4458999.44206673 270756.540717876,4458999.44206673 270756.540717876,4458989.39791506
+ 843.00000000
+
+
+
+
+ 270766.777414281,4458989.39791506 270777.014110685,4458989.39791506 270777.014110685,4458999.44206673 270766.777414281,4458999.44206673 270766.777414281,4458989.39791506
+ 851.00000000
+
+
+
+
+ 270777.014110685,4458989.39791506 270787.250807089,4458989.39791506 270787.250807089,4458999.44206673 270777.014110685,4458999.44206673 270777.014110685,4458989.39791506
+ 851.00000000
+
+
+
+
+ 270787.250807089,4458989.39791506 270797.487503493,4458989.39791506 270797.487503493,4458999.44206673 270787.250807089,4458999.44206673 270787.250807089,4458989.39791506
+ 851.00000000
+
+
+
+
+ 270797.487503493,4458989.39791506 270807.724199897,4458989.39791506 270807.724199897,4458999.44206673 270797.487503493,4458999.44206673 270797.487503493,4458989.39791506
+ 859.00000000
+
+
+
+
+ 270807.724199897,4458989.39791506 270817.960896301,4458989.39791506 270817.960896301,4458999.44206673 270807.724199897,4458999.44206673 270807.724199897,4458989.39791506
+ 859.00000000
+
+
+
+
+ 270817.960896301,4458989.39791506 270828.197592705,4458989.39791506 270828.197592705,4458999.44206673 270817.960896301,4458999.44206673 270817.960896301,4458989.39791506
+ 866.00000000
+
+
+
+
+ 270828.197592705,4458989.39791506 270838.434289109,4458989.39791506 270838.434289109,4458999.44206673 270828.197592705,4458999.44206673 270828.197592705,4458989.39791506
+ 866.00000000
+
+
+
+
+ 270838.434289109,4458989.39791506 270848.670985513,4458989.39791506 270848.670985513,4458999.44206673 270838.434289109,4458999.44206673 270838.434289109,4458989.39791506
+ 866.00000000
+
+
+
+
+ 270848.670985513,4458989.39791506 270858.907681917,4458989.39791506 270858.907681917,4458999.44206673 270848.670985513,4458999.44206673 270848.670985513,4458989.39791506
+ 878.00000000
+
+
+
+
+ 270858.907681918,4458989.39791506 270869.144378322,4458989.39791506 270869.144378322,4458999.44206673 270858.907681918,4458999.44206673 270858.907681918,4458989.39791506
+ 878.00000000
+
+
+
+
+ 270746.304021472,4458979.35376339 270756.540717876,4458979.35376339 270756.540717876,4458989.39791506 270746.304021472,4458989.39791506 270746.304021472,4458979.35376339
+ 843.00000000
+
+
+
+
+ 270756.540717876,4458979.35376339 270766.77741428,4458979.35376339 270766.77741428,4458989.39791506 270756.540717876,4458989.39791506 270756.540717876,4458979.35376339
+ 843.00000000
+
+
+
+
+ 270766.777414281,4458979.35376339 270777.014110685,4458979.35376339 270777.014110685,4458989.39791506 270766.777414281,4458989.39791506 270766.777414281,4458979.35376339
+ 851.00000000
+
+
+
+
+ 270777.014110685,4458979.35376339 270787.250807089,4458979.35376339 270787.250807089,4458989.39791506 270777.014110685,4458989.39791506 270777.014110685,4458979.35376339
+ 851.00000000
+
+
+
+
+ 270787.250807089,4458979.35376339 270797.487503493,4458979.35376339 270797.487503493,4458989.39791506 270787.250807089,4458989.39791506 270787.250807089,4458979.35376339
+ 851.00000000
+
+
+
+
+ 270797.487503493,4458979.35376339 270807.724199897,4458979.35376339 270807.724199897,4458989.39791506 270797.487503493,4458989.39791506 270797.487503493,4458979.35376339
+ 859.00000000
+
+
+
+
+ 270807.724199897,4458979.35376339 270817.960896301,4458979.35376339 270817.960896301,4458989.39791506 270807.724199897,4458989.39791506 270807.724199897,4458979.35376339
+ 859.00000000
+
+
+
+
+ 270817.960896301,4458979.35376339 270828.197592705,4458979.35376339 270828.197592705,4458989.39791506 270817.960896301,4458989.39791506 270817.960896301,4458979.35376339
+ 866.00000000
+
+
+
+
+ 270828.197592705,4458979.35376339 270838.434289109,4458979.35376339 270838.434289109,4458989.39791506 270828.197592705,4458989.39791506 270828.197592705,4458979.35376339
+ 866.00000000
+
+
+
+
+ 270838.434289109,4458979.35376339 270848.670985513,4458979.35376339 270848.670985513,4458989.39791506 270838.434289109,4458989.39791506 270838.434289109,4458979.35376339
+ 866.00000000
+
+
+
+
+ 270848.670985513,4458979.35376339 270858.907681917,4458979.35376339 270858.907681917,4458989.39791506 270848.670985513,4458989.39791506 270848.670985513,4458979.35376339
+ 878.00000000
+
+
+
+
+ 270858.907681918,4458979.35376339 270869.144378322,4458979.35376339 270869.144378322,4458989.39791506 270858.907681918,4458989.39791506 270858.907681918,4458979.35376339
+ 878.00000000
+
+
+
+
+ 270746.304021472,4458969.30961172 270756.540717876,4458969.30961172 270756.540717876,4458979.35376339 270746.304021472,4458979.35376339 270746.304021472,4458969.30961172
+ 859.00000000
+
+
+
+
+ 270756.540717876,4458969.30961172 270766.77741428,4458969.30961172 270766.77741428,4458979.35376339 270756.540717876,4458979.35376339 270756.540717876,4458969.30961172
+ 859.00000000
+
+
+
+
+ 270766.777414281,4458969.30961172 270777.014110685,4458969.30961172 270777.014110685,4458979.35376339 270766.777414281,4458979.35376339 270766.777414281,4458969.30961172
+ 864.00000000
+
+
+
+
+ 270777.014110685,4458969.30961172 270787.250807089,4458969.30961172 270787.250807089,4458979.35376339 270777.014110685,4458979.35376339 270777.014110685,4458969.30961172
+ 864.00000000
+
+
+
+
+ 270787.250807089,4458969.30961172 270797.487503493,4458969.30961172 270797.487503493,4458979.35376339 270787.250807089,4458979.35376339 270787.250807089,4458969.30961172
+ 864.00000000
+
+
+
+
+ 270797.487503493,4458969.30961172 270807.724199897,4458969.30961172 270807.724199897,4458979.35376339 270797.487503493,4458979.35376339 270797.487503493,4458969.30961172
+ 872.00000000
+
+
+
+
+ 270807.724199897,4458969.30961172 270817.960896301,4458969.30961172 270817.960896301,4458979.35376339 270807.724199897,4458979.35376339 270807.724199897,4458969.30961172
+ 872.00000000
+
+
+
+
+ 270817.960896301,4458969.30961172 270828.197592705,4458969.30961172 270828.197592705,4458979.35376339 270817.960896301,4458979.35376339 270817.960896301,4458969.30961172
+ 880.00000000
+
+
+
+
+ 270828.197592705,4458969.30961172 270838.434289109,4458969.30961172 270838.434289109,4458979.35376339 270828.197592705,4458979.35376339 270828.197592705,4458969.30961172
+ 880.00000000
+
+
+
+
+ 270838.434289109,4458969.30961172 270848.670985513,4458969.30961172 270848.670985513,4458979.35376339 270838.434289109,4458979.35376339 270838.434289109,4458969.30961172
+ 880.00000000
+
+
+
+
+ 270848.670985513,4458969.30961172 270858.907681917,4458969.30961172 270858.907681917,4458979.35376339 270848.670985513,4458979.35376339 270848.670985513,4458969.30961172
+ 890.00000000
+
+
+
+
+ 270858.907681918,4458969.30961172 270869.144378322,4458969.30961172 270869.144378322,4458979.35376339 270858.907681918,4458979.35376339 270858.907681918,4458969.30961172
+ 890.00000000
+
+
+
+
+ 270746.304021472,4458959.26546005 270756.540717876,4458959.26546005 270756.540717876,4458969.30961172 270746.304021472,4458969.30961172 270746.304021472,4458959.26546005
+ 859.00000000
+
+
+
+
+ 270756.540717876,4458959.26546005 270766.77741428,4458959.26546005 270766.77741428,4458969.30961172 270756.540717876,4458969.30961172 270756.540717876,4458959.26546005
+ 859.00000000
+
+
+
+
+ 270766.777414281,4458959.26546005 270777.014110685,4458959.26546005 270777.014110685,4458969.30961172 270766.777414281,4458969.30961172 270766.777414281,4458959.26546005
+ 864.00000000
+
+
+
+
+ 270777.014110685,4458959.26546005 270787.250807089,4458959.26546005 270787.250807089,4458969.30961172 270777.014110685,4458969.30961172 270777.014110685,4458959.26546005
+ 864.00000000
+
+
+
+
+ 270787.250807089,4458959.26546005 270797.487503493,4458959.26546005 270797.487503493,4458969.30961172 270787.250807089,4458969.30961172 270787.250807089,4458959.26546005
+ 864.00000000
+
+
+
+
+ 270797.487503493,4458959.26546005 270807.724199897,4458959.26546005 270807.724199897,4458969.30961172 270797.487503493,4458969.30961172 270797.487503493,4458959.26546005
+ 872.00000000
+
+
+
+
+ 270807.724199897,4458959.26546005 270817.960896301,4458959.26546005 270817.960896301,4458969.30961172 270807.724199897,4458969.30961172 270807.724199897,4458959.26546005
+ 872.00000000
+
+
+
+
+ 270817.960896301,4458959.26546005 270828.197592705,4458959.26546005 270828.197592705,4458969.30961172 270817.960896301,4458969.30961172 270817.960896301,4458959.26546005
+ 880.00000000
+
+
+
+
+ 270828.197592705,4458959.26546005 270838.434289109,4458959.26546005 270838.434289109,4458969.30961172 270828.197592705,4458969.30961172 270828.197592705,4458959.26546005
+ 880.00000000
+
+
+
+
+ 270838.434289109,4458959.26546005 270848.670985513,4458959.26546005 270848.670985513,4458969.30961172 270838.434289109,4458969.30961172 270838.434289109,4458959.26546005
+ 880.00000000
+
+
+
+
+ 270848.670985513,4458959.26546005 270858.907681917,4458959.26546005 270858.907681917,4458969.30961172 270848.670985513,4458969.30961172 270848.670985513,4458959.26546005
+ 890.00000000
+
+
+
+
+ 270858.907681918,4458959.26546005 270869.144378322,4458959.26546005 270869.144378322,4458969.30961172 270858.907681918,4458969.30961172 270858.907681918,4458959.26546005
+ 890.00000000
+
+
+
+
+ 270746.304021472,4458949.22130838 270756.540717876,4458949.22130838 270756.540717876,4458959.26546005 270746.304021472,4458959.26546005 270746.304021472,4458949.22130838
+ 868.00000000
+
+
+
+
+ 270756.540717876,4458949.22130838 270766.77741428,4458949.22130838 270766.77741428,4458959.26546005 270756.540717876,4458959.26546005 270756.540717876,4458949.22130838
+ 868.00000000
+
+
+
+
+ 270766.777414281,4458949.22130838 270777.014110685,4458949.22130838 270777.014110685,4458959.26546005 270766.777414281,4458959.26546005 270766.777414281,4458949.22130838
+ 873.00000000
+
+
+
+
+ 270777.014110685,4458949.22130838 270787.250807089,4458949.22130838 270787.250807089,4458959.26546005 270777.014110685,4458959.26546005 270777.014110685,4458949.22130838
+ 873.00000000
+
+
+
+
+ 270787.250807089,4458949.22130838 270797.487503493,4458949.22130838 270797.487503493,4458959.26546005 270787.250807089,4458959.26546005 270787.250807089,4458949.22130838
+ 873.00000000
+
+
+
+
+ 270797.487503493,4458949.22130838 270807.724199897,4458949.22130838 270807.724199897,4458959.26546005 270797.487503493,4458959.26546005 270797.487503493,4458949.22130838
+ 881.00000000
+
+
+
+
+ 270807.724199897,4458949.22130838 270817.960896301,4458949.22130838 270817.960896301,4458959.26546005 270807.724199897,4458959.26546005 270807.724199897,4458949.22130838
+ 881.00000000
+
+
+
+
+ 270817.960896301,4458949.22130838 270828.197592705,4458949.22130838 270828.197592705,4458959.26546005 270817.960896301,4458959.26546005 270817.960896301,4458949.22130838
+ 890.00000000
+
+
+
+
+ 270828.197592705,4458949.22130838 270838.434289109,4458949.22130838 270838.434289109,4458959.26546005 270828.197592705,4458959.26546005 270828.197592705,4458949.22130838
+ 890.00000000
+
+
+
+
+ 270838.434289109,4458949.22130838 270848.670985513,4458949.22130838 270848.670985513,4458959.26546005 270838.434289109,4458959.26546005 270838.434289109,4458949.22130838
+ 890.00000000
+
+
+
+
+ 270848.670985513,4458949.22130838 270858.907681917,4458949.22130838 270858.907681917,4458959.26546005 270848.670985513,4458959.26546005 270848.670985513,4458949.22130838
+ 899.00000000
+
+
+
+
+ 270858.907681918,4458949.22130838 270869.144378322,4458949.22130838 270869.144378322,4458959.26546005 270858.907681918,4458959.26546005 270858.907681918,4458949.22130838
+ 899.00000000
+
+
+
+
+ 270746.304021472,4458939.17715671 270756.540717876,4458939.17715671 270756.540717876,4458949.22130838 270746.304021472,4458949.22130838 270746.304021472,4458939.17715671
+ 868.00000000
+
+
+
+
+ 270756.540717876,4458939.17715671 270766.77741428,4458939.17715671 270766.77741428,4458949.22130838 270756.540717876,4458949.22130838 270756.540717876,4458939.17715671
+ 868.00000000
+
+
+
+
+ 270766.777414281,4458939.17715671 270777.014110685,4458939.17715671 270777.014110685,4458949.22130838 270766.777414281,4458949.22130838 270766.777414281,4458939.17715671
+ 873.00000000
+
+
+
+
+ 270777.014110685,4458939.17715671 270787.250807089,4458939.17715671 270787.250807089,4458949.22130838 270777.014110685,4458949.22130838 270777.014110685,4458939.17715671
+ 873.00000000
+
+
+
+
+ 270787.250807089,4458939.17715671 270797.487503493,4458939.17715671 270797.487503493,4458949.22130838 270787.250807089,4458949.22130838 270787.250807089,4458939.17715671
+ 873.00000000
+
+
+
+
+ 270797.487503493,4458939.17715671 270807.724199897,4458939.17715671 270807.724199897,4458949.22130838 270797.487503493,4458949.22130838 270797.487503493,4458939.17715671
+ 881.00000000
+
+
+
+
+ 270807.724199897,4458939.17715671 270817.960896301,4458939.17715671 270817.960896301,4458949.22130838 270807.724199897,4458949.22130838 270807.724199897,4458939.17715671
+ 881.00000000
+
+
+
+
+ 270817.960896301,4458939.17715671 270828.197592705,4458939.17715671 270828.197592705,4458949.22130838 270817.960896301,4458949.22130838 270817.960896301,4458939.17715671
+ 890.00000000
+
+
+
+
+ 270828.197592705,4458939.17715671 270838.434289109,4458939.17715671 270838.434289109,4458949.22130838 270828.197592705,4458949.22130838 270828.197592705,4458939.17715671
+ 890.00000000
+
+
+
+
+ 270838.434289109,4458939.17715671 270848.670985513,4458939.17715671 270848.670985513,4458949.22130838 270838.434289109,4458949.22130838 270838.434289109,4458939.17715671
+ 890.00000000
+
+
+
+
+ 270848.670985513,4458939.17715671 270858.907681917,4458939.17715671 270858.907681917,4458949.22130838 270848.670985513,4458949.22130838 270848.670985513,4458939.17715671
+ 899.00000000
+
+
+
+
+ 270858.907681918,4458939.17715671 270869.144378322,4458939.17715671 270869.144378322,4458949.22130838 270858.907681918,4458949.22130838 270858.907681918,4458939.17715671
+ 899.00000000
+
+
+
+
+ 270746.304021472,4458929.13300504 270756.540717876,4458929.13300504 270756.540717876,4458939.17715671 270746.304021472,4458939.17715671 270746.304021472,4458929.13300504
+ 868.00000000
+
+
+
+
+ 270756.540717876,4458929.13300504 270766.77741428,4458929.13300504 270766.77741428,4458939.17715671 270756.540717876,4458939.17715671 270756.540717876,4458929.13300504
+ 868.00000000
+
+
+
+
+ 270766.777414281,4458929.13300504 270777.014110685,4458929.13300504 270777.014110685,4458939.17715671 270766.777414281,4458939.17715671 270766.777414281,4458929.13300504
+ 873.00000000
+
+
+
+
+ 270777.014110685,4458929.13300504 270787.250807089,4458929.13300504 270787.250807089,4458939.17715671 270777.014110685,4458939.17715671 270777.014110685,4458929.13300504
+ 873.00000000
+
+
+
+
+ 270787.250807089,4458929.13300504 270797.487503493,4458929.13300504 270797.487503493,4458939.17715671 270787.250807089,4458939.17715671 270787.250807089,4458929.13300504
+ 873.00000000
+
+
+
+
+ 270797.487503493,4458929.13300504 270807.724199897,4458929.13300504 270807.724199897,4458939.17715671 270797.487503493,4458939.17715671 270797.487503493,4458929.13300504
+ 881.00000000
+
+
+
+
+ 270807.724199897,4458929.13300504 270817.960896301,4458929.13300504 270817.960896301,4458939.17715671 270807.724199897,4458939.17715671 270807.724199897,4458929.13300504
+ 881.00000000
+
+
+
+
+ 270817.960896301,4458929.13300504 270828.197592705,4458929.13300504 270828.197592705,4458939.17715671 270817.960896301,4458939.17715671 270817.960896301,4458929.13300504
+ 890.00000000
+
+
+
+
+ 270828.197592705,4458929.13300504 270838.434289109,4458929.13300504 270838.434289109,4458939.17715671 270828.197592705,4458939.17715671 270828.197592705,4458929.13300504
+ 890.00000000
+
+
+
+
+ 270838.434289109,4458929.13300504 270848.670985513,4458929.13300504 270848.670985513,4458939.17715671 270838.434289109,4458939.17715671 270838.434289109,4458929.13300504
+ 890.00000000
+
+
+
+
+ 270848.670985513,4458929.13300504 270858.907681917,4458929.13300504 270858.907681917,4458939.17715671 270848.670985513,4458939.17715671 270848.670985513,4458929.13300504
+ 899.00000000
+
+
+
+
+ 270858.907681918,4458929.13300504 270869.144378322,4458929.13300504 270869.144378322,4458939.17715671 270858.907681918,4458939.17715671 270858.907681918,4458929.13300504
+ 899.00000000
+
+
+
diff --git a/python/plugins/processing/tests/testdata/expected/vectorize.xsd b/python/plugins/processing/tests/testdata/expected/vectorize.xsd
new file mode 100644
index 00000000000..cec4763d2f2
--- /dev/null
+++ b/python/plugins/processing/tests/testdata/expected/vectorize.xsd
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
index 7d4f3138074..3bff504b854 100644
--- a/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
+++ b/python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
@@ -5647,6 +5647,17 @@ tests:
hash: c29d14f71e8686f7445d53be646fce84702644f159fd0164ac38e861
type: rasterhash
-
+ - algorithm: native:pixelstopolygons
+ name: Pixels to polygons
+ params:
+ FIELD_NAME: pix_val
+ INPUT_RASTER:
+ name: raster.tif
+ type: raster
+ RASTER_BAND: 1
+ results:
+ OUTPUT:
+ name: expected/vectorize.gml
+ type: vector
# See ../README.md for a description of the file format
diff --git a/src/analysis/CMakeLists.txt b/src/analysis/CMakeLists.txt
index 50a1ed60143..26b83289af2 100755
--- a/src/analysis/CMakeLists.txt
+++ b/src/analysis/CMakeLists.txt
@@ -82,6 +82,7 @@ SET(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmtranslate.cpp
processing/qgsalgorithmunion.cpp
processing/qgsalgorithmuniquevalueindex.cpp
+ processing/qgsalgorithmvectorize.cpp
processing/qgsalgorithmwedgebuffers.cpp
processing/qgsalgorithmzonalhistogram.cpp
diff --git a/src/analysis/processing/qgsalgorithmvectorize.cpp b/src/analysis/processing/qgsalgorithmvectorize.cpp
new file mode 100644
index 00000000000..a9b9e2a7f84
--- /dev/null
+++ b/src/analysis/processing/qgsalgorithmvectorize.cpp
@@ -0,0 +1,167 @@
+/***************************************************************************
+ qgsalgorithmvectorize.cpp
+ ---------------------
+ begin : June, 2018
+ copyright : (C) 2018 by Nyall Dawson
+ email : nyall dot dawson at gmail dot com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsalgorithmvectorize.h"
+#include "qgis.h"
+#include "qgsprocessing.h"
+
+///@cond PRIVATE
+
+QString QgsVectorizeAlgorithm::name() const
+{
+ return QStringLiteral( "pixelstopolygons" );
+}
+
+QString QgsVectorizeAlgorithm::displayName() const
+{
+ return QObject::tr( "Raster pixels to polygons" );
+}
+
+QStringList QgsVectorizeAlgorithm::tags() const
+{
+ return QObject::tr( "vectorize,polygonize,raster,convert,pixels" ).split( ',' );
+}
+
+QString QgsVectorizeAlgorithm::shortHelpString() const
+{
+ return QObject::tr( "This algorithm converts a raster layer to a vector layer, by creating polygon features for each individual pixel in the raster layer." );
+}
+
+QgsVectorizeAlgorithm *QgsVectorizeAlgorithm::createInstance() const
+{
+ return new QgsVectorizeAlgorithm();
+}
+
+QString QgsVectorizeAlgorithm::group() const
+{
+ return QObject::tr( "Vector creation" );
+}
+
+QString QgsVectorizeAlgorithm::groupId() const
+{
+ return QStringLiteral( "vectorcreation" );
+}
+
+void QgsVectorizeAlgorithm::initAlgorithm( const QVariantMap & )
+{
+ addParameter( new QgsProcessingParameterRasterLayer( QStringLiteral( "INPUT_RASTER" ),
+ QObject::tr( "Raster layer" ) ) );
+ addParameter( new QgsProcessingParameterBand( QStringLiteral( "RASTER_BAND" ),
+ QObject::tr( "Band number" ), 1, QStringLiteral( "INPUT_RASTER" ) ) );
+ addParameter( new QgsProcessingParameterString( QStringLiteral( "FIELD_NAME" ),
+ QObject::tr( "Field name" ), QStringLiteral( "VALUE" ) ) );
+
+ addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Vectorized layer" ), QgsProcessing::TypeVectorPolygon ) );
+}
+
+bool QgsVectorizeAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * )
+{
+ QgsRasterLayer *layer = parameterAsRasterLayer( parameters, QStringLiteral( "INPUT_RASTER" ), context );
+
+ if ( !layer )
+ throw QgsProcessingException( invalidRasterError( parameters, QStringLiteral( "INPUT_RASTER" ) ) );
+
+ mBand = parameterAsInt( parameters, QStringLiteral( "RASTER_BAND" ), context );
+ if ( mBand < 1 || mBand > layer->bandCount() )
+ throw QgsProcessingException( QObject::tr( "Invalid band number for RASTER_BAND (%1): Valid values for input raster are 1 to %2" ).arg( mBand )
+ .arg( layer->bandCount() ) );
+
+ mInterface.reset( layer->dataProvider()->clone() );
+ mExtent = layer->extent();
+ mCrs = layer->crs();
+ mRasterUnitsPerPixelX = std::abs( layer->rasterUnitsPerPixelX() );
+ mRasterUnitsPerPixelY = std::abs( layer->rasterUnitsPerPixelY() );
+ mNbCellsXProvider = mInterface->xSize();
+ mNbCellsYProvider = mInterface->ySize();
+ return true;
+}
+
+QVariantMap QgsVectorizeAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
+{
+ const QString fieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context );
+ QgsFields fields;
+ fields.append( QgsField( fieldName, QVariant::Double, QString(), 20, 8 ) );
+
+ QString dest;
+ std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, fields, QgsWkbTypes::Polygon, mCrs ) );
+ if ( !sink )
+ throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
+
+
+ int maxWidth = QgsRasterIterator::DEFAULT_MAXIMUM_TILE_WIDTH;
+ int maxHeight = QgsRasterIterator::DEFAULT_MAXIMUM_TILE_HEIGHT;
+
+ QgsRasterIterator iter( mInterface.get() );
+ iter.startRasterRead( mBand, mNbCellsXProvider, mNbCellsYProvider, mExtent );
+
+ int nbBlocksWidth = static_cast< int >( std::ceil( 1.0 * mNbCellsXProvider / maxWidth ) );
+ int nbBlocksHeight = static_cast< int >( std::ceil( 1.0 * mNbCellsYProvider / maxHeight ) );
+ int nbBlocks = nbBlocksWidth * nbBlocksHeight;
+
+ double hCellSizeX = mRasterUnitsPerPixelX / 2.0;
+ double hCellSizeY = mRasterUnitsPerPixelY / 2.0;
+
+ int iterLeft = 0;
+ int iterTop = 0;
+ int iterCols = 0;
+ int iterRows = 0;
+ std::unique_ptr< QgsRasterBlock > rasterBlock;
+ QgsRectangle blockExtent;
+ while ( iter.readNextRasterPart( mBand, iterCols, iterRows, rasterBlock, iterLeft, iterTop, &blockExtent ) )
+ {
+ if ( feedback )
+ feedback->setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
+ if ( feedback && feedback->isCanceled() )
+ break;
+
+ double currentY = blockExtent.yMaximum() - 0.5 * mRasterUnitsPerPixelY;
+
+ for ( int row = 0; row < iterRows; row++ )
+ {
+ if ( feedback && feedback->isCanceled() )
+ break;
+
+ double currentX = blockExtent.xMinimum() + 0.5 * mRasterUnitsPerPixelX;
+
+ for ( int column = 0; column < iterCols; column++ )
+ {
+ if ( !rasterBlock->isNoData( row, column ) )
+ {
+
+ QgsGeometry pixelRectGeometry = QgsGeometry::fromRect( QgsRectangle( currentX - hCellSizeX, currentY - hCellSizeY, currentX + hCellSizeX, currentY + hCellSizeY ) );
+
+ double value = rasterBlock->value( row, column );
+
+ QgsFeature f;
+ f.setGeometry( pixelRectGeometry );
+ f.setAttributes( QgsAttributes() << value );
+ sink->addFeature( f, QgsFeatureSink::FastInsert );
+ }
+ currentX += mRasterUnitsPerPixelX;
+ }
+ currentY -= mRasterUnitsPerPixelY;
+ }
+ }
+
+ QVariantMap outputs;
+ outputs.insert( QStringLiteral( "OUTPUT" ), dest );
+ return outputs;
+}
+
+///@endcond
+
+
diff --git a/src/analysis/processing/qgsalgorithmvectorize.h b/src/analysis/processing/qgsalgorithmvectorize.h
new file mode 100644
index 00000000000..5e942b0cda7
--- /dev/null
+++ b/src/analysis/processing/qgsalgorithmvectorize.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ qgsalgorithmvectorize.h
+ ---------------------
+ begin : June, 2018
+ copyright : (C) 2018 by Nyall Dawson
+ email : nyall dot dawson at gmail dot com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSALGORITHMVECTORIZE_H
+#define QGSALGORITHMVECTORIZE_H
+
+#define SIP_NO_FILE
+
+#include "qgis.h"
+#include "qgsprocessingalgorithm.h"
+#include "qgsreclassifyutils.h"
+
+///@cond PRIVATE
+
+/**
+ * Native vectorize algorithm
+ */
+class QgsVectorizeAlgorithm : public QgsProcessingAlgorithm
+{
+ public:
+
+ QgsVectorizeAlgorithm() = default;
+ QString name() const override;
+ QString displayName() const override;
+ QStringList tags() const override;
+ QString shortHelpString() const override;
+ QgsVectorizeAlgorithm *createInstance() const override SIP_FACTORY;
+ QString group() const override final;
+ QString groupId() const override final;
+ void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
+
+ protected:
+
+ bool prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
+
+ QVariantMap processAlgorithm( const QVariantMap ¶meters,
+ QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
+
+ std::unique_ptr< QgsRasterInterface > mInterface;
+
+ Qgis::DataType mDataType = Qgis::Float32;
+ double mNoDataValue = -9999;
+ int mBand = 1;
+ QgsRectangle mExtent;
+ QgsCoordinateReferenceSystem mCrs;
+ double mRasterUnitsPerPixelX = 0;
+ double mRasterUnitsPerPixelY = 0;
+ int mNbCellsXProvider = 0;
+ int mNbCellsYProvider = 0;
+ QgsReclassifyUtils::RasterClass::BoundsType mBoundsType = QgsReclassifyUtils::RasterClass::IncludeMax;
+ bool mUseNoDataForMissingValues = false;
+};
+
+///@endcond PRIVATE
+
+#endif // QGSALGORITHMVECTORIZE_H
+
+
diff --git a/src/analysis/processing/qgsnativealgorithms.cpp b/src/analysis/processing/qgsnativealgorithms.cpp
index 24db2a6d73b..eea2ebfe0c8 100644
--- a/src/analysis/processing/qgsnativealgorithms.cpp
+++ b/src/analysis/processing/qgsnativealgorithms.cpp
@@ -79,6 +79,7 @@
#include "qgsalgorithmtranslate.h"
#include "qgsalgorithmunion.h"
#include "qgsalgorithmuniquevalueindex.h"
+#include "qgsalgorithmvectorize.h"
#include "qgsalgorithmwedgebuffers.h"
#include "qgsalgorithmzonalhistogram.h"
@@ -189,6 +190,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsTranslateAlgorithm() );
addAlgorithm( new QgsUnionAlgorithm() );
addAlgorithm( new QgsVariableWidthBufferByMAlgorithm() );
+ addAlgorithm( new QgsVectorizeAlgorithm() );
addAlgorithm( new QgsWedgeBuffersAlgorithm() );
addAlgorithm( new QgsZonalHistogramAlgorithm() );
}