[postgis-tickets] r16954 - ST_LocateBetween[Elevations]: support TIN and TRIANGLE clipping.
Darafei
komzpa at gmail.com
Sat Oct 27 03:23:04 PDT 2018
Author: komzpa
Date: 2018-10-27 03:23:03 -0700 (Sat, 27 Oct 2018)
New Revision: 16954
Modified:
trunk/NEWS
trunk/doc/reference_lrs.xml
trunk/liblwgeom/cunit/cu_algorithm.c
trunk/liblwgeom/lwlinearreferencing.c
Log:
ST_LocateBetween[Elevations]: support TIN and TRIANGLE clipping.
Triangle is converted into a TIN that has several triangles with same orientation.
Committed in Paris Airport.
Closes #4155
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2018-10-27 10:21:00 UTC (rev 16953)
+++ trunk/NEWS 2018-10-27 10:23:03 UTC (rev 16954)
@@ -27,8 +27,8 @@
Praliaskouski)
- #3457, Fix raster envelope shortcut in ST_Clip (Sai-bot)
- #4215, Use floating point compare in ST_DumpAsPolygons (Darafei Praliaskouski)
- - #4155, Support for GEOMETRYCOLLECTION and POLYGON in ST_LocateBetween (Darafei
- Praliaskouski)
+ - #4155, Support for GEOMETRYCOLLECTION, POLYGON, TIN, TRIANGLE in
+ ST_LocateBetween and ST_LocateBetweenElevations (Darafei Praliaskouski)
PostGIS 2.5.0
2018/09/23
Modified: trunk/doc/reference_lrs.xml
===================================================================
--- trunk/doc/reference_lrs.xml 2018-10-27 10:21:00 UTC (rev 16953)
+++ trunk/doc/reference_lrs.xml 2018-10-27 10:23:03 UTC (rev 16954)
@@ -426,8 +426,7 @@
<refname>ST_LocateBetween</refname>
<refpurpose>Return a derived geometry collection value with elements
- that match the specified range of measures inclusively. Polygonal
- elements are not supported.</refpurpose>
+ that match the specified range of measures inclusively.</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -434,7 +433,7 @@
<funcsynopsis>
<funcprototype>
<funcdef>geometry <function>ST_LocateBetween</function></funcdef>
- <paramdef><type>geometry </type> <parameter>geomA</parameter></paramdef>
+ <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
<paramdef><type>float8 </type> <parameter>measure_start</parameter></paramdef>
<paramdef><type>float8 </type> <parameter>measure_end</parameter></paramdef>
<paramdef choice="opt"><type>float8 </type> <parameter>offset</parameter></paramdef>
@@ -447,8 +446,10 @@
<title>Description</title>
<para>Return a derived geometry collection with elements that match the specified range of
- measures inclusively. Polygonal elements are not supported.</para>
+ measures inclusively.</para>
+ <para>Clipping a non-convex POLYGON may produce invalid geometry.</para>
+
<para>If an offset is provided, the resultant will be offset to the left or right of the
input line by the specified number of units. A positive offset will be to the left, and
a negative one to the right.</para>
@@ -458,6 +459,7 @@
<para>Availability: 1.1.0 by old name ST_Locate_Between_Measures. </para>
<para>Changed: 2.0.0 - in prior versions this used to be called ST_Locate_Between_Measures. The old name has been deprecated and will be removed in the future but is still available for backward compatibility.</para>
+ <para>Enhanced: 3.0.0 - added support for POLYGON, TIN, TRIANGLE.</para>
<para>&M_support;</para>
</refsection>
@@ -465,11 +467,15 @@
<refsection>
<title>Examples</title>
- <programlisting>SELECT ST_AsText(the_geom)
- FROM
- (SELECT ST_LocateBetween(
- ST_GeomFromText('MULTILINESTRING M ((1 2 3, 3 4 2, 9 4 3),
- (1 2 3, 5 4 5))'),1.5, 3) As the_geom) As foo;
+ <programlisting>
+SELECT ST_AsText(the_geom)
+FROM (
+ SELECT ST_LocateBetween(
+ 'MULTILINESTRING M ((1 2 3, 3 4 2, 9 4 3),(1 2 3, 5 4 5))'),
+ 1.5,
+ 3
+ ) as the_geom
+) As foo;
st_asewkt
------------------------------------------------------------------------
@@ -478,10 +484,13 @@
--Geometry collections are difficult animals so dump them
--to make them more digestable
SELECT ST_AsText((ST_Dump(the_geom)).geom)
- FROM
- (SELECT ST_LocateBetween(
- ST_GeomFromText('MULTILINESTRING M ((1 2 3, 3 4 2, 9 4 3),
- (1 2 3, 5 4 5))'),1.5, 3) As the_geom) As foo;
+FROM (
+ SELECT ST_LocateBetween(
+ 'MULTILINESTRING M ((1 2 3, 3 4 2, 9 4 3),(1 2 3, 5 4 5))'),
+ 1.5,
+ 3
+ ) As the_geom
+) As foo;
st_asewkt
--------------------------------
@@ -502,8 +511,7 @@
<refname>ST_LocateBetweenElevations</refname>
<refpurpose>Return a derived geometry (collection) value with elements
- that intersect the specified range of elevations inclusively. Only 3D, 4D LINESTRINGS and MULTILINESTRINGS
- are supported.</refpurpose>
+ that intersect the specified range of elevations inclusively.</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -510,7 +518,7 @@
<funcsynopsis>
<funcprototype>
<funcdef>geometry <function>ST_LocateBetweenElevations</function></funcdef>
- <paramdef><type>geometry </type> <parameter>geom_mline</parameter></paramdef>
+ <paramdef><type>geometry </type> <parameter>geom</parameter></paramdef>
<paramdef><type>float8 </type> <parameter>elevation_start</parameter></paramdef>
<paramdef><type>float8 </type> <parameter>elevation_end</parameter></paramdef>
</funcprototype>
@@ -521,12 +529,14 @@
<refsection>
<title>Description</title>
- <para>Return a derived geometry (collection) value with elements
- that intersect the specified range of elevations inclusively. Only 3D, 3DM LINESTRINGS and MULTILINESTRINGS
- are supported.</para>
+ <para>Return a derived geometry (collection) value with elements
+ that intersect the specified range of elevations inclusively.</para>
- <para>Availability: 1.4.0</para>
+ <para>Clipping a non-convex POLYGON may produce invalid geometry.</para>
+ <para>Availability: 1.4.0</para>
+ <para>Enhanced: 3.0.0 - added support for POLYGON, TIN, TRIANGLE.</para>
+
<para>&Z_support;</para>
</refsection>
@@ -534,24 +544,22 @@
<title>Examples</title>
<programlisting>SELECT ST_AsEWKT(ST_LocateBetweenElevations(
- ST_GeomFromEWKT('LINESTRING(1 2 3, 4 5 6)'),2,4)) As ewelev;
+ ST_GeomFromEWKT('LINESTRING(1 2 3, 4 5 6)'), 2, 4)) As ewelev;
ewelev
----------------------------------------------------------------
MULTILINESTRING((1 2 3,2 3 4))
-SELECT ST_AsEWKT(ST_LocateBetweenElevations(
- ST_GeomFromEWKT('LINESTRING(1 2 6, 4 5 -1, 7 8 9)'),6,9)) As ewelev;
+SELECT ST_AsEWKT(ST_LocateBetweenElevations('LINESTRING(1 2 6, 4 5 -1, 7 8 9)', 6, 9)) As ewelev;
ewelev
----------------------------------------------------------------
GEOMETRYCOLLECTION(POINT(1 2 6),LINESTRING(6.1 7.1 6,7 8 9))
---Geometry collections are difficult animals so dump them
---to make them more digestable
+-- Geometry collections are difficult animals so dump them
+-- to make them more digestable
SELECT ST_AsEWKT((ST_Dump(the_geom)).geom)
- FROM
- (SELECT ST_LocateBetweenElevations(
- ST_GeomFromEWKT('LINESTRING(1 2 6, 4 5 -1, 7 8 9)'),6,9) As the_geom) As foo;
+ FROM
+ (SELECT ST_LocateBetweenElevations('LINESTRING(1 2 6, 4 5 -1, 7 8 9)', 6, 9) as the_geom) As foo;
st_asewkt
--------------------------------
@@ -564,7 +572,7 @@
<refsection>
<title>See Also</title>
- <para><xref linkend="ST_Dump" /></para>
+ <para><xref linkend="ST_Dump" />, <xref linkend="ST_LocateBetween" /></para>
</refsection>
</refentry>
Modified: trunk/liblwgeom/cunit/cu_algorithm.c
===================================================================
--- trunk/liblwgeom/cunit/cu_algorithm.c 2018-10-27 10:21:00 UTC (rev 16953)
+++ trunk/liblwgeom/cunit/cu_algorithm.c 2018-10-27 10:23:03 UTC (rev 16954)
@@ -557,7 +557,7 @@
c = lwgeom_clip_to_ordinate_range(l51, 'Y', 1.5, 2.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))");
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))");
lwfree(ewkt);
lwcollection_free(c);
@@ -565,7 +565,7 @@
c = lwgeom_clip_to_ordinate_range(l51, 'Y', 3.5, 5.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 3.5,0 4))");
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 3.5,0 4))");
lwfree(ewkt);
lwcollection_free(c);
@@ -573,7 +573,7 @@
c = lwgeom_clip_to_ordinate_range(l51, 'Y', -1.5, 2.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 2.5))" );
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 2.5))");
lwfree(ewkt);
lwcollection_free(c);
@@ -581,7 +581,7 @@
c = lwgeom_clip_to_ordinate_range(l51, 'Y', -1.5, 5.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 3,0 4))" );
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2,0 3,0 4))");
lwfree(ewkt);
lwcollection_free(c);
@@ -589,7 +589,7 @@
c = lwgeom_clip_to_ordinate_range(l51, 'Y', 1.0, 2.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1,0 2))" );
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1,0 2))");
lwfree(ewkt);
lwcollection_free(c);
@@ -597,7 +597,7 @@
c = lwgeom_clip_to_ordinate_range(l51, 'Y', -1.0, 2.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2))" );
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 0,0 1,0 2))");
lwfree(ewkt);
lwcollection_free(c);
@@ -605,7 +605,7 @@
c = lwgeom_clip_to_ordinate_range(l51, 'Y', -1.0, 0.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(0 0))" );
+ ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(0 0))");
lwfree(ewkt);
lwcollection_free(c);
@@ -613,7 +613,7 @@
line = lwgeom_from_wkt("LINESTRING(1 2 3, 4 5 6, 6 6 6, 1 1 1)", LW_PARSER_CHECK_NONE);
c = lwgeom_clip_to_ordinate_range(line, 'Z', 1.0, 2.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" );
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))");
lwfree(ewkt);
lwcollection_free(c);
lwgeom_free(line);
@@ -623,7 +623,7 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 1.0, 2.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("a = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))" );
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2,1 1 1))");
lwfree(ewkt);
lwcollection_free(c);
lwgeom_free(line);
@@ -633,7 +633,7 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 1.0, 1.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("b = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" );
+ ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))");
lwfree(ewkt);
lwcollection_free(c);
lwgeom_free(line);
@@ -643,7 +643,7 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 1.0, 1.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))" );
+ ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 1 1))");
lwfree(ewkt);
lwcollection_free(c);
lwgeom_free(line);
@@ -665,7 +665,7 @@
ewkt = lwgeom_to_ewkt((LWGEOM *)c);
// printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(
+ ASSERT_STRING_EQUAL(
ewkt,
"MULTIPOLYGON(((0.51 -0.25,1 -0.179078947368,1 0.270149253731,0.6 0.3,0.7 0.7,1 0.7,1 0.6,0.8 0.5,1 0.46,1 1.2,0.5 1.2,0.5 -0.1,0.3 -0.1,0.3 1.3,0 1.26875,0 -0.25,0.51 -0.25)))");
lwfree(ewkt);
@@ -679,7 +679,7 @@
ewkt = lwgeom_to_ewkt((LWGEOM *)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(
+ ASSERT_STRING_EQUAL(
ewkt,
"MULTIPOLYGON(((1 0,1 0.270149253731,0.6 0.3,0.7 0.7,1 0.7,1 0.6,0.8 0.5,1 0.46,1 1,0.5 1,0.5 0,0.3 0,0.3 1,0 1,0 0,1 0)))");
lwfree(ewkt);
@@ -687,6 +687,46 @@
lwgeom_free(g);
}
+static void
+test_lwtriangle_clip(void)
+{
+ LWCOLLECTION *c;
+ LWGEOM *g = NULL;
+ char *ewkt;
+
+ g = lwgeom_from_wkt("TRIANGLE((0 0 0, 1 1 1, 3 2 2, 0 0 0))", LW_PARSER_CHECK_NONE);
+ c = lwgeom_clip_to_ordinate_range(g, 'Z', -10.0, 4.0, 0);
+
+ ewkt = lwgeom_to_ewkt((LWGEOM *)c);
+ // printf("c = %s\n", ewkt);
+ ASSERT_STRING_EQUAL(ewkt, "TIN(((0 0 0,1 1 1,3 2 2,0 0 0)))");
+ lwfree(ewkt);
+ lwcollection_free(c);
+ lwgeom_free(g);
+
+ g = lwgeom_from_wkt("TRIANGLE((0 0 0, 1 1 1, 3 2 2, 0 0 0))", LW_PARSER_CHECK_NONE);
+ c = lwgeom_clip_to_ordinate_range(g, 'Z', 0.0, 1.0, 0);
+
+ ewkt = lwgeom_to_ewkt((LWGEOM *)c);
+ // printf("c = %s\n", ewkt);
+ ASSERT_STRING_EQUAL(ewkt, "TIN(((0 0 0,1 1 1,1.5 1 1,0 0 0)))");
+ lwfree(ewkt);
+ lwcollection_free(c);
+ lwgeom_free(g);
+
+ g = lwgeom_from_wkt("TRIANGLE((0 0 0, 1 1 1, 3 2 3, 0 0 0))", LW_PARSER_CHECK_NONE);
+ c = lwgeom_clip_to_ordinate_range(g, 'Z', 1.0, 2.0, 0);
+
+ ewkt = lwgeom_to_ewkt((LWGEOM *)c);
+ // printf("c = %s\n", ewkt);
+ ASSERT_STRING_EQUAL(
+ ewkt,
+ "TIN(((1 1 1,2 1.5 2,2 1.333333333333 2,1 1 1)),((1 1 1,2 1.333333333333 2,1 0.666666666667 1,1 1 1)))");
+ lwfree(ewkt);
+ lwcollection_free(c);
+ lwgeom_free(g);
+}
+
static void test_lwmline_clip(void)
{
LWCOLLECTION *c;
@@ -703,7 +743,7 @@
c = lwgeom_clip_to_ordinate_range(mline, 'Y', 1.5, 2.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))");
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0 1.5,0 2,0 2.5))");
lwfree(ewkt);
lwcollection_free(c);
@@ -718,7 +758,7 @@
c = lwgeom_clip_to_ordinate_range(mline, 'Y', 3.5, 5.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((1 3.5,1 4),(0 3.5,0 4))");
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((1 3.5,1 4),(0 3.5,0 4))");
lwfree(ewkt);
lwcollection_free(c);
@@ -734,7 +774,7 @@
c = lwgeom_clip_to_ordinate_range(mline, 'Y', 0.0, 2.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 0),LINESTRING(0 0,0 1,0 2,0 2.5))");
+ ASSERT_STRING_EQUAL(ewkt, "GEOMETRYCOLLECTION(POINT(1 0),LINESTRING(0 0,0 1,0 2,0 2.5))");
lwfree(ewkt);
lwcollection_free(c);
@@ -750,7 +790,7 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 3.0, 3.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5))");
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5))");
lwfree(ewkt);
lwcollection_free(c);
@@ -758,7 +798,8 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 2.0, 3.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2 2,3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5,2 2 2 6))");
+ ASSERT_STRING_EQUAL(ewkt,
+ "MULTILINESTRING((2 2 2 2,3 3 3 3,3.5 3.5 3.5 3.5),(3.5 3.5 3.5 4.5,3 3 3 5,2 2 2 6))");
lwfree(ewkt);
lwcollection_free(c);
@@ -766,7 +807,7 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 3.0, 4.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,4 4 4 4,3 3 3 5))");
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((3 3 3 3,4 4 4 4,3 3 3 5))");
lwfree(ewkt);
lwcollection_free(c);
@@ -774,7 +815,7 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 2.0, 3.0, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2 2,3 3 3 3),(3 3 3 5,2 2 2 6))");
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((2 2 2 2,3 3 3 3),(3 3 3 5,2 2 2 6))");
lwfree(ewkt);
lwcollection_free(c);
@@ -807,7 +848,7 @@
c = lwgeom_clip_to_ordinate_range(line, 'Z', 0.5, 1.5, 0);
ewkt = lwgeom_to_ewkt((LWGEOM*)c);
//printf("c = %s\n", ewkt);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0.5 0.5 0.5,1 1 1,1.5 1.5 1.5))" );
+ ASSERT_STRING_EQUAL(ewkt, "MULTILINESTRING((0.5 0.5 0.5,1 1 1,1.5 1.5 1.5))");
lwfree(ewkt);
lwcollection_free(c);
@@ -854,17 +895,17 @@
geohash = geohash_point(0, 0, 16);
//printf("\ngeohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "s000000000000000");
+ ASSERT_STRING_EQUAL(geohash, "s000000000000000");
lwfree(geohash);
geohash = geohash_point(90, 0, 16);
//printf("\ngeohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "w000000000000000");
+ ASSERT_STRING_EQUAL(geohash, "w000000000000000");
lwfree(geohash);
geohash = geohash_point(20.012345, -20.012345, 15);
//printf("\ngeohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "kkqnpkue9ktbpe5");
+ ASSERT_STRING_EQUAL(geohash, "kkqnpkue9ktbpe5");
lwfree(geohash);
}
@@ -879,7 +920,7 @@
lwpoint = (LWPOINT*)lwgeom_from_wkt("POINT(23.0 25.2)", LW_PARSER_CHECK_NONE);
geohash = lwgeom_geohash((LWGEOM*)lwpoint,0);
//printf("\ngeohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx");
+ ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx");
lwpoint_free(lwpoint);
lwfree(geohash);
@@ -886,7 +927,7 @@
lwpoint = (LWPOINT*)lwgeom_from_wkt("POINT(23.0 25.2 2.0)", LW_PARSER_CHECK_NONE);
geohash = lwgeom_geohash((LWGEOM*)lwpoint,0);
//printf("geohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx");
+ ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx");
lwpoint_free(lwpoint);
lwfree(geohash);
@@ -893,7 +934,7 @@
lwline = (LWLINE*)lwgeom_from_wkt("LINESTRING(23.0 23.0,23.1 23.1)", LW_PARSER_CHECK_NONE);
geohash = lwgeom_geohash((LWGEOM*)lwline,0);
//printf("geohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "ss0");
+ ASSERT_STRING_EQUAL(geohash, "ss0");
lwline_free(lwline);
lwfree(geohash);
@@ -900,7 +941,7 @@
lwline = (LWLINE*)lwgeom_from_wkt("LINESTRING(23.0 23.0,23.001 23.001)", LW_PARSER_CHECK_NONE);
geohash = lwgeom_geohash((LWGEOM*)lwline,0);
//printf("geohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "ss06g7h");
+ ASSERT_STRING_EQUAL(geohash, "ss06g7h");
lwline_free(lwline);
lwfree(geohash);
@@ -907,7 +948,7 @@
lwmline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((23.0 23.0,23.1 23.1),(23.0 23.0,23.1 23.1))", LW_PARSER_CHECK_NONE);
geohash = lwgeom_geohash((LWGEOM*)lwmline,0);
//printf("geohash %s\n",geohash);
- CU_ASSERT_STRING_EQUAL(geohash, "ss0");
+ ASSERT_STRING_EQUAL(geohash, "ss0");
lwmline_free(lwmline);
lwfree(geohash);
}
@@ -1045,7 +1086,7 @@
g = lwgeom_from_wkt("MULTIPOINT(0 0, 10 0, 10 10, 10 10, 0 10, 0 10, 0 10, 0 0, 0 0, 0 0, 5 5, 0 0, 5 5)", LW_PARSER_CHECK_NONE);
lwgeom_remove_repeated_points_in_place(g, 1);
ewkt = lwgeom_to_ewkt(g);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTIPOINT(0 0,10 0,10 10,0 10,5 5)");
+ ASSERT_STRING_EQUAL(ewkt, "MULTIPOINT(0 0,10 0,10 10,0 10,5 5)");
lwgeom_free(g);
lwfree(ewkt);
@@ -1052,7 +1093,7 @@
g = lwgeom_from_wkt("LINESTRING(1612830.15445 4841287.12672,1612830.15824 4841287.12674,1612829.98813 4841274.56198)", LW_PARSER_CHECK_NONE);
lwgeom_remove_repeated_points_in_place(g, 0.01);
ewkt = lwgeom_to_ewkt(g);
- CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(1612830.15445 4841287.12672,1612829.98813 4841274.56198)");
+ ASSERT_STRING_EQUAL(ewkt, "LINESTRING(1612830.15445 4841287.12672,1612829.98813 4841274.56198)");
lwgeom_free(g);
lwfree(ewkt);
@@ -1059,7 +1100,8 @@
g = lwgeom_from_wkt("MULTIPOINT(0 0,10 0,10 10,10 10,0 10,0 10,0 10,0 0,0 0,0 0,5 5,5 5,5 8,8 8,8 8,8 8,8 5,8 5,5 5,5 5,5 5,5 5,5 5,50 50,50 50,50 50,50 60,50 60,50 60,60 60,60 50,60 50,50 50,55 55,55 58,58 58,58 55,58 55,55 55)", LW_PARSER_CHECK_NONE);
lwgeom_remove_repeated_points_in_place(g, 1);
ewkt = lwgeom_to_ewkt(g);
- CU_ASSERT_STRING_EQUAL(ewkt, "MULTIPOINT(0 0,10 0,10 10,0 10,5 5,5 8,8 8,8 5,50 50,50 60,60 60,60 50,55 55,55 58,58 58,58 55)");
+ ASSERT_STRING_EQUAL(
+ ewkt, "MULTIPOINT(0 0,10 0,10 10,0 10,5 5,5 8,8 8,8 5,50 50,50 60,60 60,60 50,55 55,55 58,58 58,58 55)");
lwgeom_free(g);
lwfree(ewkt);
@@ -1066,7 +1108,7 @@
g = lwgeom_from_wkt("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))", LW_PARSER_CHECK_NONE);
lwgeom_remove_repeated_points_in_place(g, 10000);
ewkt = lwgeom_to_ewkt(g);
- CU_ASSERT_STRING_EQUAL(ewkt, "POLYGON((0 0,1 1,1 0,0 0))");
+ ASSERT_STRING_EQUAL(ewkt, "POLYGON((0 0,1 1,1 0,0 0))");
lwgeom_free(g);
lwfree(ewkt);
}
@@ -1081,7 +1123,7 @@
g = lwgeom_from_wkt("LINESTRING(0 0, 1 0, 1 1, 0 1, 0 0)", LW_PARSER_CHECK_NONE);
l = lwgeom_simplify(g, 10, LW_TRUE);
ewkt = lwgeom_to_ewkt(l);
- CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,0 0)");
+ ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,0 0)");
lwgeom_free(g);
lwgeom_free(l);
lwfree(ewkt);
@@ -1090,7 +1132,7 @@
g = lwgeom_from_wkt("POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))", LW_PARSER_CHECK_NONE);
l = lwgeom_simplify(g, 10, LW_TRUE);
ewkt = lwgeom_to_ewkt(l);
- CU_ASSERT_STRING_EQUAL(ewkt, "POLYGON((0 0,1 0,1 1,0 0))");
+ ASSERT_STRING_EQUAL(ewkt, "POLYGON((0 0,1 0,1 1,0 0))");
lwgeom_free(g);
lwgeom_free(l);
lwfree(ewkt);
@@ -1113,7 +1155,7 @@
g = lwgeom_from_wkt("LINESTRING(0 0, 50 1.00001, 100 0)", LW_PARSER_CHECK_NONE);
l = lwgeom_simplify(g, 1.0, LW_FALSE);
ewkt = lwgeom_to_ewkt(l);
- CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,50 1.00001,100 0)");
+ ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,50 1.00001,100 0)");
lwgeom_free(g);
lwgeom_free(l);
lwfree(ewkt);
@@ -1122,7 +1164,7 @@
g = lwgeom_from_wkt("LINESTRING(0 0,50 0.99999,100 0)", LW_PARSER_CHECK_NONE);
l = lwgeom_simplify(g, 1.0, LW_FALSE);
ewkt = lwgeom_to_ewkt(l);
- CU_ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,100 0)");
+ ASSERT_STRING_EQUAL(ewkt, "LINESTRING(0 0,100 0)");
lwgeom_free(g);
lwgeom_free(l);
lwfree(ewkt);
@@ -1531,6 +1573,7 @@
PG_ADD_TEST(suite,test_lwline_interpolate_points);
PG_ADD_TEST(suite,test_lwline_clip);
PG_ADD_TEST(suite, test_lwpoly_clip);
+ PG_ADD_TEST(suite, test_lwtriangle_clip);
PG_ADD_TEST(suite,test_lwline_clip_big);
PG_ADD_TEST(suite,test_lwmline_clip);
PG_ADD_TEST(suite,test_geohash_point);
Modified: trunk/liblwgeom/lwlinearreferencing.c
===================================================================
--- trunk/liblwgeom/lwlinearreferencing.c 2018-10-27 10:21:00 UTC (rev 16953)
+++ trunk/liblwgeom/lwlinearreferencing.c 2018-10-27 10:23:03 UTC (rev 16954)
@@ -440,7 +440,7 @@
}
static inline POINTARRAY *
-ptarray_clamp_to_ordinate_range(const POINTARRAY *ipa, char ordinate, double from, double to)
+ptarray_clamp_to_ordinate_range(const POINTARRAY *ipa, char ordinate, double from, double to, uint8_t is_closed)
{
POINT4D p1, p2;
POINTARRAY *opa;
@@ -524,7 +524,7 @@
LW_ON_INTERRUPT(ptarray_free(opa); return NULL);
}
- if (ptarray_is_closed(ipa) && opa->npoints > 0)
+ if (is_closed && opa->npoints > 2)
{
getPoint4d_p(opa, 0, &p1);
ptarray_append_point(opa, &p1, LW_FALSE);
@@ -769,7 +769,7 @@
for (i = 0; i < nrings; i++)
{
/* Ret number of points */
- POINTARRAY *pa = ptarray_clamp_to_ordinate_range(poly->rings[i], ordinate, from, to);
+ POINTARRAY *pa = ptarray_clamp_to_ordinate_range(poly->rings[i], ordinate, from, to, LW_TRUE);
if (pa->npoints >= 4)
lwpoly_add_ring(poly_res, pa);
@@ -786,6 +786,41 @@
}
/**
+ * Clip an input LWTRIANGLE between two values, on any ordinate input.
+ */
+static inline LWCOLLECTION *
+lwtriangle_clip_to_ordinate_range(const LWTRIANGLE *tri, char ordinate, double from, double to)
+{
+ LWCOLLECTION *lwgeom_out = NULL;
+ char hasz = FLAGS_GET_Z(tri->flags), hasm = FLAGS_GET_M(tri->flags);
+
+ assert(tri);
+ lwgeom_out = lwcollection_construct_empty(TINTYPE, tri->srid, hasz, hasm);
+
+ POINTARRAY *pa = ptarray_clamp_to_ordinate_range(tri->points, ordinate, from, to, LW_TRUE);
+
+ if (pa->npoints >= 4)
+ {
+ POINT4D first = getPoint4d(pa, 0);
+ for (uint32_t i = 1; i < pa->npoints - 2; i++)
+ {
+ POINT4D p;
+ POINTARRAY *tpa = ptarray_construct_empty(hasz, hasm, 4);
+ ptarray_append_point(tpa, &first, LW_TRUE);
+ getPoint4d_p(pa, i, &p);
+ ptarray_append_point(tpa, &p, LW_TRUE);
+ getPoint4d_p(pa, i + 1, &p);
+ ptarray_append_point(tpa, &p, LW_TRUE);
+ ptarray_append_point(tpa, &first, LW_TRUE);
+ LWTRIANGLE *otri = lwtriangle_construct(tri->srid, NULL, tpa);
+ lwgeom_out = lwcollection_add_lwgeom(lwgeom_out, (LWGEOM *)otri);
+ }
+ }
+ ptarray_free(pa);
+ return lwgeom_out;
+}
+
+/**
* Clip an input COLLECTION between two values, on any ordinate input.
*/
static inline LWCOLLECTION *
@@ -859,9 +894,9 @@
case POLYGONTYPE:
out_col = lwpoly_clip_to_ordinate_range((LWPOLY *)lwin, ordinate, from, to);
break;
- // case TRIANGLETYPE:
- // out_col = lwtriangle_clip_to_ordinate_range((LWTRIANGLE*)lwin, ordinate, from, to);
- // break;
+ case TRIANGLETYPE:
+ out_col = lwtriangle_clip_to_ordinate_range((LWTRIANGLE *)lwin, ordinate, from, to);
+ break;
case TINTYPE:
case MULTILINETYPE:
case MULTIPOLYGONTYPE:
More information about the postgis-tickets
mailing list