]> granicus.if.org Git - postgis/commitdiff
Added regression tests and docs for two of the ST_SetValues variants
authorBborie Park <bkpark at ucdavis.edu>
Tue, 31 Jul 2012 23:44:16 +0000 (23:44 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Tue, 31 Jul 2012 23:44:16 +0000 (23:44 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@10148 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
doc/reference_raster.xml
raster/rt_pg/rtpostgis.sql.in.c
raster/test/regress/Makefile.in
raster/test/regress/rt_setvalues_array.sql [new file with mode: 0644]
raster/test/regress/rt_setvalues_array_expected [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 2794db52514e4eb8feac0da28565360f7362c463..ed2ecb78ade1d9cd84c03b5ba82e94966d101528 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ PostGIS 2.1.0
     (ST_Contains, ST_ContainsProperly, ST_Covers, ST_CoveredBy, ST_Disjoint,
     ST_Overlaps, ST_Touches, ST_Within, ST_DWithin, ST_DFullyWithin)
     (Bborie Park / UC Davis)
+  - Added array variants of ST_SetValues() to set many pixel values of a band
+    in one call (Bborie Park / UC Davis)
   - #1643, Tiger Geocoder - Tiger 2011 loader (Regina Obe / Paragon Corporation) 
     Funded by Hunter Systems Group
   - GEOMETRYCOLLECTION support for ST_MakeValid (Sandro Santilli / Vizzuality)
index 47dee238e48ab539142ce5b5ddaf4e20b451fe7d..540a39019fcfd369db63fd1241006374423c9935 100644 (file)
@@ -4004,6 +4004,345 @@ GROUP BY (foo.geomval).val;
                        </refsection>
                </refentry>
 
+               <refentry id="RT_ST_SetValues">
+                       <refnamediv>
+                               <refname>ST_SetValues</refname>
+                               <refpurpose>Returns modified raster resulting from setting the values of a given band.</refpurpose>
+                       </refnamediv>
+
+                       <refsynopsisdiv>
+                               <funcsynopsis>
+                                       <funcprototype>
+                                               <funcdef>raster <function>ST_SetValues</function></funcdef>
+                                               <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
+                                               <paramdef><type>double precision[][] </type> <parameter>newvalueset</parameter></paramdef>
+                                               <paramdef><type>boolean[][] </type> <parameter>noset=NULL</parameter></paramdef>
+                                               <paramdef><type>boolean </type> <parameter>keepnodata=FALSE</parameter></paramdef>
+                                       </funcprototype>
+
+                                 <funcprototype>
+                                               <funcdef>raster <function>ST_SetValues</function></funcdef>
+                                               <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>columnx</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>rowy</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>width</parameter></paramdef>
+                                               <paramdef><type>integer </type> <parameter>height</parameter></paramdef>
+                                               <paramdef><type>double precision </type> <parameter>newvalue</parameter></paramdef>
+                                               <paramdef><type>boolean </type> <parameter>keepnodata=FALSE</parameter></paramdef>
+                                       </funcprototype>
+
+                               </funcsynopsis>
+                       </refsynopsisdiv>
+
+                       <refsection>
+                               <title>Description</title>
+                               <para>
+                                       Returns modified raster resulting from setting specified pixels to new value(s) for the designated band.
+                               </para>
+
+                               <para>
+                                       For variant 1, the specific pixels to be set are determined by the <varname>columnx</varname>, <varname>rowy</varname> pixel coordinates and the dimensions of the <varname>newvalueset</varname> array. <varname>noset</varname> can be used to prevent pixels with values present in <varname>newvalueset</varname> from being set (due to PostgreSQL not permitting ragged/jagged arrays). If <varname>keepnodata</varname> is TRUE, those pixels whose values are NODATA will not be set with the corresponding value in <varname>newvalueset</varname>.  See example Variant 1.
+                               </para>
+
+                               <para>
+                                       For variant 2, the specific pixels to be set are determined by the <varname>columnx</varname>, <varname>rowy</varname> pixel coordinates, <varname>width</varname> and <varname>height</varname>. If <varname>keepnodata</varname> is TRUE, those pixels whose values are NODATA will not be set with the corresponding value in <varname>newvalueset</varname>.  See example Variant 2.
+                               </para>
+
+                       </refsection>
+
+                       <refsection>
+                               <title>Examples: Variant 1</title>
+
+                               <programlisting>
+/*
+The ST_SetValues() does the following...
+
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 1 | 1 | 1 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |    =>    | 1 | 9 | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 1 | 9 | 9 |
++ - + - + - +          + - + - + - +
+*/
+SELECT
+       (poly).x,
+       (poly).y,
+       (poly).val
+FROM (
+SELECT
+       ST_PixelAsPolygons(
+               ST_SetValues(
+                       ST_AddBand(
+                               ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
+                               1, '8BUI', 1, 0
+                       ),
+                       1, 2, 2, ARRAY[[9, 9], [9, 9]]::double precision[][]
+               )
+       ) AS poly
+) foo
+ORDER BY 1, 2;
+
+ x | y | val 
+---+---+-----
+ 1 | 1 |   1
+ 1 | 2 |   1
+ 1 | 3 |   1
+ 2 | 1 |   1
+ 2 | 2 |   9
+ 2 | 3 |   9
+ 3 | 1 |   1
+ 3 | 2 |   9
+ 3 | 3 |   9
+                               </programlisting>
+
+                               <programlisting>
+/*
+The ST_SetValues() does the following...
+
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 9 | 9 | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |    =>    | 9 |   | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 9 | 9 | 9 |
++ - + - + - +          + - + - + - +
+*/
+SELECT
+       (poly).x,
+       (poly).y,
+       (poly).val
+FROM (
+SELECT
+       ST_PixelAsPolygons(
+               ST_SetValues(
+                       ST_AddBand(
+                               ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
+                               1, '8BUI', 1, 0
+                       ),
+                       1, 1, 1, ARRAY[[9, 9, 9], [9, NULL, 9], [9, 9, 9]]::double precision[][]
+               )
+       ) AS poly
+) foo
+ORDER BY 1, 2;
+
+ x | y | val 
+---+---+-----
+ 1 | 1 |   9
+ 1 | 2 |   9
+ 1 | 3 |   9
+ 2 | 1 |   9
+ 2 | 2 |    
+ 2 | 3 |   9
+ 3 | 1 |   9
+ 3 | 2 |   9
+ 3 | 3 |   9
+                               </programlisting>
+
+                               <programlisting>
+/*
+The ST_SetValues() does the following...
+
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 9 | 9 | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |    =>    | 1 |   | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 9 | 9 | 9 |
++ - + - + - +          + - + - + - +
+*/
+SELECT
+       (poly).x,
+       (poly).y,
+       (poly).val
+FROM (
+SELECT
+       ST_PixelAsPolygons(
+               ST_SetValues(
+                       ST_AddBand(
+                               ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
+                               1, '8BUI', 1, 0
+                       ),
+                       1, 1, 1,
+                               ARRAY[[9, 9, 9], [9, NULL, 9], [9, 9, 9]]::double precision[][],
+                               ARRAY[[false], [true]]::boolean[][]
+               )
+       ) AS poly
+) foo
+ORDER BY 1, 2;
+
+ x | y | val 
+---+---+-----
+ 1 | 1 |   9
+ 1 | 2 |   1
+ 1 | 3 |   9
+ 2 | 1 |   9
+ 2 | 2 |    
+ 2 | 3 |   9
+ 3 | 1 |   9
+ 3 | 2 |   9
+ 3 | 3 |   9
+                               </programlisting>
+
+                               <programlisting>
+/*
+The ST_SetValues() does the following...
+
++ - + - + - +          + - + - + - +
+|   | 1 | 1 |          |   | 9 | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |    =>    | 1 |   | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 9 | 9 | 9 |
++ - + - + - +          + - + - + - +
+*/
+SELECT
+       (poly).x,
+       (poly).y,
+       (poly).val
+FROM (
+SELECT
+       ST_PixelAsPolygons(
+               ST_SetValues(
+                       ST_SetValue(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
+                                       1, '8BUI', 1, 0
+                               ),
+                               1, 1, 1, NULL
+                       ),
+                       1, 1, 1,
+                               ARRAY[[9, 9, 9], [9, NULL, 9], [9, 9, 9]]::double precision[][],
+                               ARRAY[[false], [true]]::boolean[][],
+                               TRUE
+               )
+       ) AS poly
+) foo
+ORDER BY 1, 2;
+
+ x | y | val 
+---+---+-----
+ 1 | 1 |   
+ 1 | 2 |   1
+ 1 | 3 |   9
+ 2 | 1 |   9
+ 2 | 2 |    
+ 2 | 3 |   9
+ 3 | 1 |   9
+ 3 | 2 |   9
+ 3 | 3 |   9
+                               </programlisting>
+
+                       </refsection>
+
+                       <refsection>
+                               <title>Examples: Variant 2</title>
+
+                               <programlisting>
+/*
+The ST_SetValues() does the following...
+
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 1 | 1 | 1 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |    =>    | 1 | 9 | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 1 | 9 | 9 |
++ - + - + - +          + - + - + - +
+*/
+SELECT
+       (poly).x,
+       (poly).y,
+       (poly).val
+FROM (
+SELECT
+       ST_PixelAsPolygons(
+               ST_SetValues(
+                       ST_AddBand(
+                               ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
+                               1, '8BUI', 1, 0
+                       ),
+                       1, 2, 2, 2, 2, 9
+               )
+       ) AS poly
+) foo
+ORDER BY 1, 2;
+
+ x | y | val 
+---+---+-----
+ 1 | 1 |   1
+ 1 | 2 |   1
+ 1 | 3 |   1
+ 2 | 1 |   1
+ 2 | 2 |   9
+ 2 | 3 |   9
+ 3 | 1 |   1
+ 3 | 2 |   9
+ 3 | 3 |   9
+                               </programlisting>
+
+                               <programlisting>
+/*
+The ST_SetValues() does the following...
+
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 1 | 1 | 1 |
++ - + - + - +          + - + - + - +
+| 1 |   | 1 |    =>    | 1 |   | 9 |
++ - + - + - +          + - + - + - +
+| 1 | 1 | 1 |          | 1 | 9 | 9 |
++ - + - + - +          + - + - + - +
+*/
+SELECT
+       (poly).x,
+       (poly).y,
+       (poly).val
+FROM (
+SELECT
+       ST_PixelAsPolygons(
+               ST_SetValues(
+                       ST_SetValue(
+                               ST_AddBand(
+                                       ST_MakeEmptyRaster(3, 3, 0, 0, 1, -1, 0, 0, 0),
+                                       1, '8BUI', 1, 0
+                               ),
+                               1, 2, 2, NULL
+                       ),
+                       1, 2, 2, 2, 2, 9, TRUE
+               )
+       ) AS poly
+) foo
+ORDER BY 1, 2;
+
+ x | y | val 
+---+---+-----
+ 1 | 1 |   1
+ 1 | 2 |   1
+ 1 | 3 |   1
+ 2 | 1 |   1
+ 2 | 2 |    
+ 2 | 3 |   9
+ 3 | 1 |   1
+ 3 | 2 |   9
+ 3 | 3 |   9
+                               </programlisting>
+
+                       </refsection>
+
+                       <refsection>
+                               <title>See Also</title>
+                               <para>
+                                       <xref linkend="RT_ST_Value" />, 
+                                       <xref linkend="RT_ST_SetValue" />, 
+                                       <xref linkend="RT_ST_PixelAsPolygons" />
+                               </para>
+                       </refsection>
+               </refentry>
+
                <refentry id="RT_ST_PixelOfValue">
                        <refnamediv>
                                <refname>ST_PixelOfValue</refname>
index bef1cf47aa4955c2b57697cd875cd6e5bca3037e..1e9d3fb3fd961fdc91dc69324cd6546efad6ecb6 100644 (file)
@@ -2917,8 +2917,7 @@ CREATE OR REPLACE FUNCTION st_setvalue(rast raster, pt geometry, newvalue float8
 -- ST_SetValues (set one or more pixels to a one or more values)
 -----------------------------------------------------------------------
 CREATE OR REPLACE FUNCTION st_setvalues(
-       rast raster,
-       nband integer,
+       rast raster, nband integer,
        x integer, y integer,
        newvalueset double precision[][],
        noset boolean[][] DEFAULT NULL,
@@ -2930,8 +2929,7 @@ CREATE OR REPLACE FUNCTION st_setvalues(
 
 -- cannot be STRICT as newvalue can be NULL
 CREATE OR REPLACE FUNCTION st_setvalues(
-       rast raster,
-       nband integer,
+       rast raster, nband integer,
        x integer, y integer,
        width integer, height integer,
        newvalue double precision,
index 6319418722351771b468cfa2f6764331907a0cb9..083fe7ee589b48c20298859e2a4040f0aa8b6062 100644 (file)
@@ -43,11 +43,7 @@ TEST_FUNC = \
        rt_bytea \
        box3d \
        rt_addband \
-       rt_band \
-       rt_asgdalraster \
-       rt_astiff \
-       rt_asjpeg \
-       rt_aspng
+       rt_band
 
 TEST_PROPS = \
        rt_dimensions \
@@ -66,6 +62,7 @@ TEST_PROPS = \
 TEST_BANDPROPS = \
        rt_band_properties \
        rt_set_band_properties \
+       rt_setvalues_array \
        rt_summarystats \
        rt_count \
        rt_histogram \
@@ -84,6 +81,10 @@ TEST_BANDPROPS = \
 
 TEST_UTILITY = \
        rt_utility \
+       rt_asgdalraster \
+       rt_astiff \
+       rt_asjpeg \
+       rt_aspng \
        rt_mapalgebraexpr \
        rt_mapalgebrafct \
        rt_mapalgebraexpr_2raster \
@@ -135,9 +136,9 @@ TEST_LOADER = \
        loader/Tiled10x10 \
        loader/Tiled10x10Copy
 
-TESTS = $(TEST_FIRST) $(TEST_METADATA) $(TEST_IO) $(TEST_FUNC) \
-               $(TEST_PROPS) $(TEST_BANDPROPS) \
-               $(TEST_UTILITY) $(TEST_GIST) $(TEST_SREL) \
+TESTS = $(TEST_FIRST) $(TEST_METADATA) $(TEST_IO) $(TEST_BASIC_FUNC) \
+               $(TEST_PROPS) $(TEST_GIST) $(TEST_BANDPROPS) \
+               $(TEST_UTILITY) $(TEST_SREL) \
                $(TEST_BUGS) \
                $(TEST_LOADER)
 
diff --git a/raster/test/regress/rt_setvalues_array.sql b/raster/test/regress/rt_setvalues_array.sql
new file mode 100644 (file)
index 0000000..f81d1fb
--- /dev/null
@@ -0,0 +1,199 @@
+SET client_min_messages TO warning;
+
+DROP TABLE IF EXISTS raster_setvalues_rast;
+DROP TABLE IF EXISTS raster_setvalues_out;
+CREATE TABLE raster_setvalues_rast (
+       rid integer,
+       rast raster
+);
+CREATE TABLE raster_setvalues_out (
+       rid integer,
+       rast raster
+);
+CREATE OR REPLACE FUNCTION make_test_raster(rid integer, width integer DEFAULT 2, height integer DEFAULT 2, ul_x double precision DEFAULT 0, ul_y double precision DEFAULT 0, skew_x double precision DEFAULT 0, skew_y double precision DEFAULT 0)
+       RETURNS void
+       AS $$
+       DECLARE
+               x int;
+               y int;
+               rast raster;
+       BEGIN
+               rast := ST_MakeEmptyRaster(width, height, ul_x, ul_y, 1, 1, skew_x, skew_y, 0);
+               rast := ST_AddBand(rast, 1, '8BUI', 1, 0);
+
+               INSERT INTO raster_setvalues_rast VALUES (rid, rast);
+
+               RETURN;
+       END;
+       $$ LANGUAGE 'plpgsql';
+SELECT make_test_raster(0, 5, 3);
+DROP FUNCTION make_test_raster(integer, integer, integer, double precision, double precision, double precision, double precision);
+
+INSERT INTO raster_setvalues_out VALUES (
+       1, (
+       SELECT ST_SetValues(
+               rast, 1, 1, 1,
+               ARRAY[10]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       2, (
+       SELECT ST_SetValues(
+               rast, 1, 2, 1,
+               ARRAY[10]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       3, (
+       SELECT ST_SetValues(
+               rast, 1, 3, 1,
+               ARRAY[10]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       4, (
+       SELECT ST_SetValues(
+               rast, 1, 1, 1,
+               ARRAY[10, 10]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       5, (
+       SELECT ST_SetValues(
+               rast, 1, 2, 2,
+               ARRAY[10, 10]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       6, (
+       SELECT ST_SetValues(
+               rast, 1, 3, 3,
+               ARRAY[10, 10, 10]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       7, (
+       SELECT ST_SetValues(
+               rast, 1, 4, 3,
+               ARRAY[10, 10, 10]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       8, (
+       SELECT ST_SetValues(
+               rast, 1, 2, 1,
+               ARRAY[[5, 5, 5, 5], [6, 6, 6, 6]]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       9, (
+       SELECT ST_SetValues(
+               rast, 1, 2, 1,
+               ARRAY[[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, NULL]]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       10, (
+       SELECT ST_SetValues(
+               rast, 1, 2, 1,
+               ARRAY[[5, 5, 5, 5, 10], [6, 6, 6, 6, 10], [7, 7, 7, NULL, 10]]::double precision[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       11, (
+       SELECT ST_SetValues(
+               rast, 1, 1, 1,
+               ARRAY[10, 10, 10]::double precision[],
+               ARRAY[false, true]::boolean[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       12, (
+       SELECT ST_SetValues(
+               rast, 1, 1, 1,
+               ARRAY[NULL, 10, 0]::double precision[],
+               ARRAY[false, NULL, false]::boolean[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       13, (
+       SELECT ST_SetValues(
+               rast, 1, 1, 1,
+               ARRAY[NULL, 10, 0]::double precision[],
+               ARRAY[false, NULL, true]::boolean[]
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       21, (
+       SELECT ST_SetValues(
+               rast, 1,
+               1, 1,
+               5, 3, 
+               100
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       22, (
+       SELECT ST_SetValues(
+               rast, 1,
+               1, 1,
+               5, 3, 
+               NULL
+       )
+       FROM raster_setvalues_rast
+));
+
+INSERT INTO raster_setvalues_out VALUES (
+       23, (
+       SELECT ST_SetValues(
+               rast, 1,
+               1, 1,
+               5, 3, 
+               0
+       )
+       FROM raster_setvalues_rast
+));
+
+SELECT
+       rid,
+       (poly).x,
+       (poly).y,
+       (poly).val
+FROM (
+       SELECT
+               rid,
+               ST_PixelAsPolygons(rast) AS poly
+       FROM raster_setvalues_out
+) AS foo
+ORDER BY 1, 2, 3;
+
+DROP TABLE IF EXISTS raster_setvalues_rast;
+DROP TABLE IF EXISTS raster_setvalues_out;
diff --git a/raster/test/regress/rt_setvalues_array_expected b/raster/test/regress/rt_setvalues_array_expected
new file mode 100644 (file)
index 0000000..51aa700
--- /dev/null
@@ -0,0 +1,240 @@
+1|1|1|10
+1|1|2|1
+1|1|3|1
+1|2|1|1
+1|2|2|1
+1|2|3|1
+1|3|1|1
+1|3|2|1
+1|3|3|1
+1|4|1|1
+1|4|2|1
+1|4|3|1
+1|5|1|1
+1|5|2|1
+1|5|3|1
+2|1|1|1
+2|1|2|1
+2|1|3|1
+2|2|1|10
+2|2|2|1
+2|2|3|1
+2|3|1|1
+2|3|2|1
+2|3|3|1
+2|4|1|1
+2|4|2|1
+2|4|3|1
+2|5|1|1
+2|5|2|1
+2|5|3|1
+3|1|1|1
+3|1|2|1
+3|1|3|1
+3|2|1|1
+3|2|2|1
+3|2|3|1
+3|3|1|10
+3|3|2|1
+3|3|3|1
+3|4|1|1
+3|4|2|1
+3|4|3|1
+3|5|1|1
+3|5|2|1
+3|5|3|1
+4|1|1|10
+4|1|2|1
+4|1|3|1
+4|2|1|10
+4|2|2|1
+4|2|3|1
+4|3|1|1
+4|3|2|1
+4|3|3|1
+4|4|1|1
+4|4|2|1
+4|4|3|1
+4|5|1|1
+4|5|2|1
+4|5|3|1
+5|1|1|1
+5|1|2|1
+5|1|3|1
+5|2|1|1
+5|2|2|10
+5|2|3|1
+5|3|1|1
+5|3|2|10
+5|3|3|1
+5|4|1|1
+5|4|2|1
+5|4|3|1
+5|5|1|1
+5|5|2|1
+5|5|3|1
+6|1|1|1
+6|1|2|1
+6|1|3|1
+6|2|1|1
+6|2|2|1
+6|2|3|1
+6|3|1|1
+6|3|2|1
+6|3|3|10
+6|4|1|1
+6|4|2|1
+6|4|3|10
+6|5|1|1
+6|5|2|1
+6|5|3|10
+7|1|1|1
+7|1|2|1
+7|1|3|1
+7|2|1|1
+7|2|2|1
+7|2|3|1
+7|3|1|1
+7|3|2|1
+7|3|3|1
+7|4|1|1
+7|4|2|1
+7|4|3|10
+7|5|1|1
+7|5|2|1
+7|5|3|10
+8|1|1|1
+8|1|2|1
+8|1|3|1
+8|2|1|5
+8|2|2|6
+8|2|3|1
+8|3|1|5
+8|3|2|6
+8|3|3|1
+8|4|1|5
+8|4|2|6
+8|4|3|1
+8|5|1|5
+8|5|2|6
+8|5|3|1
+9|1|1|1
+9|1|2|1
+9|1|3|1
+9|2|1|5
+9|2|2|6
+9|2|3|7
+9|3|1|5
+9|3|2|6
+9|3|3|7
+9|4|1|5
+9|4|2|6
+9|4|3|7
+9|5|1|5
+9|5|2|6
+9|5|3|
+10|1|1|1
+10|1|2|1
+10|1|3|1
+10|2|1|5
+10|2|2|6
+10|2|3|7
+10|3|1|5
+10|3|2|6
+10|3|3|7
+10|4|1|5
+10|4|2|6
+10|4|3|7
+10|5|1|5
+10|5|2|6
+10|5|3|
+11|1|1|10
+11|1|2|1
+11|1|3|1
+11|2|1|1
+11|2|2|1
+11|2|3|1
+11|3|1|10
+11|3|2|1
+11|3|3|1
+11|4|1|1
+11|4|2|1
+11|4|3|1
+11|5|1|1
+11|5|2|1
+11|5|3|1
+12|1|1|
+12|1|2|1
+12|1|3|1
+12|2|1|10
+12|2|2|1
+12|2|3|1
+12|3|1|
+12|3|2|1
+12|3|3|1
+12|4|1|1
+12|4|2|1
+12|4|3|1
+12|5|1|1
+12|5|2|1
+12|5|3|1
+13|1|1|
+13|1|2|1
+13|1|3|1
+13|2|1|10
+13|2|2|1
+13|2|3|1
+13|3|1|1
+13|3|2|1
+13|3|3|1
+13|4|1|1
+13|4|2|1
+13|4|3|1
+13|5|1|1
+13|5|2|1
+13|5|3|1
+21|1|1|100
+21|1|2|100
+21|1|3|100
+21|2|1|100
+21|2|2|100
+21|2|3|100
+21|3|1|100
+21|3|2|100
+21|3|3|100
+21|4|1|100
+21|4|2|100
+21|4|3|100
+21|5|1|100
+21|5|2|100
+21|5|3|100
+22|1|1|
+22|1|2|
+22|1|3|
+22|2|1|
+22|2|2|
+22|2|3|
+22|3|1|
+22|3|2|
+22|3|3|
+22|4|1|
+22|4|2|
+22|4|3|
+22|5|1|
+22|5|2|
+22|5|3|
+23|1|1|
+23|1|2|
+23|1|3|
+23|2|1|
+23|2|2|
+23|2|3|
+23|3|1|
+23|3|2|
+23|3|3|
+23|4|1|
+23|4|2|
+23|4|3|
+23|5|1|
+23|5|2|
+23|5|3|