]> granicus.if.org Git - postgis/commitdiff
#2717, support startpoint, endpoint, pointn, numpoints for compoundcurve
authorPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 11 Jun 2015 21:09:13 +0000 (21:09 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 11 Jun 2015 21:09:13 +0000 (21:09 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@13664 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/liblwgeom.h.in
liblwgeom/lwcircstring.c
liblwgeom/lwcompound.c
liblwgeom/lwline.c
postgis/lwgeom_ogc.c
regress/sql-mm-compoundcurve.sql
regress/sql-mm-compoundcurve_expected
regress/tickets.sql
regress/tickets_expected

index ef0b7cbc0350822fd5b50dcb9b16cc8855625311..9bac3af5ebf30cc6ef3ff06311bbf9436fa4f10f 100644 (file)
@@ -1147,8 +1147,13 @@ extern void lwgeom_affine(LWGEOM *geom, const AFFINE *affine);
 extern void lwgeom_scale(LWGEOM *geom, const POINT4D *factors);
 extern int lwgeom_dimension(const LWGEOM *geom);
 
-extern LWPOINT* lwline_get_lwpoint(LWLINE *line, int where);
-extern LWPOINT* lwcircstring_get_lwpoint(LWCIRCSTRING *circ, int where);
+extern LWPOINT* lwline_get_lwpoint(const LWLINE *line, int where);
+extern LWPOINT* lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, int where);
+
+extern LWPOINT* lwcompound_get_startpoint(const LWCOMPOUND *lwcmp);
+extern LWPOINT* lwcompound_get_endpoint(const LWCOMPOUND *lwcmp);
+extern LWPOINT* lwcompound_get_lwpoint(const LWCOMPOUND *lwcmp, int where);
+
 
 extern double ptarray_length_2d(const POINTARRAY *pts);
 extern double ptarray_length(const POINTARRAY *pts);
index 3361cd603f0ba213537105cab389378d0e70d50a..573bc391f3a5cd7d5423b7aff522ad39ca7cf158 100644 (file)
@@ -284,7 +284,7 @@ double lwcircstring_length_2d(const LWCIRCSTRING *circ)
  * Returns freshly allocated #LWPOINT that corresponds to the index where.
  * Returns NULL if the geometry is empty or the index invalid.
  */
-LWPOINT* lwcircstring_get_lwpoint(LWCIRCSTRING *circ, int where) {
+LWPOINT* lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, int where) {
        POINT4D pt;
        LWPOINT *lwpoint;
        POINTARRAY *pa;
index 5478c44c3b951052816588a513114512c3f57bd0..8c28400e23ddc1a799247a82e44cef5c5100ef35 100644 (file)
@@ -200,3 +200,65 @@ lwcompound_construct_from_lwline(const LWLINE *lwline)
        /* ogeom->bbox = lwline->bbox; */
   return ogeom;
 }
+
+LWPOINT* 
+lwcompound_get_lwpoint(const LWCOMPOUND *lwcmp, int where)
+{
+       int i;
+       int count = 0;
+       int npoints = 0;
+       if ( lwgeom_is_empty((LWGEOM*)lwcmp) )
+               return NULL;
+       
+       npoints = lwgeom_count_vertices((LWGEOM*)lwcmp);
+       if ( where < 0 || where >= npoints )
+       {
+               lwerror("%s: index %d is not in range of number of vertices (%d) in input", __func__, where, npoints);
+               return NULL;
+       }
+       
+       for ( i = 0; i < lwcmp->ngeoms; i++ )
+       {
+               LWGEOM* part = lwcmp->geoms[i];
+               int npoints_part = lwgeom_count_vertices(part);
+               if ( where >= count && where < count + npoints_part )
+               {
+                       return lwline_get_lwpoint((LWLINE*)part, where - count);
+               }
+               else
+               {
+                       count += npoints_part;
+               }
+       }
+
+       return NULL;    
+}
+
+
+
+LWPOINT *
+lwcompound_get_startpoint(const LWCOMPOUND *lwcmp)
+{
+       return lwcompound_get_lwpoint(lwcmp, 0);
+}
+
+LWPOINT *
+lwcompound_get_endpoint(const LWCOMPOUND *lwcmp)
+{
+       LWLINE *lwline;
+       if ( lwcmp->ngeoms < 1 )
+       {
+               return NULL;
+       }
+       
+       lwline = (LWLINE*)(lwcmp->geoms[lwcmp->ngeoms-1]);
+
+       if ( (!lwline) || (!lwline->points) || (lwline->points->npoints < 1) )
+       {
+               return NULL;
+       }
+       
+       return lwline_get_lwpoint(lwline, lwline->points->npoints-1);
+}
+
+       
\ No newline at end of file
index b787eedca3c393b5573b7e6f03338568879639b3..f28a0498663d222bba31f218351249f07d7aff7d 100644 (file)
@@ -292,7 +292,7 @@ lwline_from_lwmpoint(int srid, const LWMPOINT *mpoint)
 * Returns NULL if the geometry is empty or the index invalid.
 */
 LWPOINT*
-lwline_get_lwpoint(LWLINE *line, int where)
+lwline_get_lwpoint(const LWLINE *line, int where)
 {
        POINT4D pt;
        LWPOINT *lwpoint;
index 4d9b748eb7c4483d54aed8d8090858275c546b4e..a4d82cca3317180d2b5fe2eb8237fb1455f26d35 100644 (file)
@@ -200,8 +200,9 @@ Datum LWGEOM_numpoints_linestring(PG_FUNCTION_ARGS)
        GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
        LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
        int count = -1;
+       int type = lwgeom->type;
        
-       if ( lwgeom->type == LINETYPE || lwgeom->type == CIRCSTRINGTYPE )
+       if ( type == LINETYPE || type == CIRCSTRINGTYPE || type == COMPOUNDTYPE )
                count = lwgeom_count_vertices(lwgeom);
 
        lwgeom_free(lwgeom);
@@ -545,6 +546,10 @@ Datum LWGEOM_pointn_linestring(PG_FUNCTION_ARGS)
                /* OGC index starts at one, so we substract first. */
                lwpoint = lwline_get_lwpoint((LWLINE*)lwgeom, where - 1);
        }
+       else if ( type == COMPOUNDTYPE )
+       {
+               lwpoint = lwcompound_get_lwpoint((LWCOMPOUND*)lwgeom, where - 1);
+       }       
 
        lwgeom_free(lwgeom);
        PG_FREE_IF_COPY(geom, 0);
@@ -698,6 +703,10 @@ Datum LWGEOM_startpoint_linestring(PG_FUNCTION_ARGS)
        {
                lwpoint = lwline_get_lwpoint((LWLINE*)lwgeom, 0);
        }
+       else if ( type == COMPOUNDTYPE )
+       {
+               lwpoint = lwcompound_get_startpoint((LWCOMPOUND*)lwgeom);
+       }
 
        lwgeom_free(lwgeom);
        PG_FREE_IF_COPY(geom, 0);
@@ -726,6 +735,10 @@ Datum LWGEOM_endpoint_linestring(PG_FUNCTION_ARGS)
                if ( line->points )
                        lwpoint = lwline_get_lwpoint((LWLINE*)lwgeom, line->points->npoints - 1);
        }
+       else if ( type == COMPOUNDTYPE )
+       {
+               lwpoint = lwcompound_get_endpoint((LWCOMPOUND*)lwgeom);
+       }
 
        lwgeom_free(lwgeom);
        PG_FREE_IF_COPY(geom, 0);
index 53c964242ecfa677448552336d7ea3cd6c912132..feed3b47db85c264f39dbead55454f9f88d86abe 100644 (file)
@@ -316,7 +316,7 @@ SELECT 'valid wkb compound curve 2', ST_asEWKT(ST_GeomFromEWKB(decode('010900000
 SELECT 'valid wkb compound curve 3', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000010000000102000000030000000CE586D73CF36240BBC46888F0523BC0102E91C951E76240DF90A1BEC0F841C0F970C100FFD7624074ADE6CE86CD3BC0', 'hex')));
 SELECT 'valid wkb compound curve 4', ST_asEWKT(ST_GeomFromEWKB(decode('0109000000020000000102000000030000009FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010800000005000000DB6286DFB057634082D8A1B32F843EC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex')));
 SELECT 'valid wkb compound curve 5', ST_asEWKT(ST_GeomFromEWKB(decode('010900000003000000010800000003000000468280E724BC6340BF4B46210B973BC0F890AEA18D8063402D9664151D483CC0EED64BB6EE726340903CA5BDA0863AC0010200000004000000EED64BB6EE726340903CA5BDA0863AC09FE5797057376340E09398B1B2373BC05AAE0A165F0963409F6760A2493D3DC0DB6286DFB057634082D8A1B32F843EC0010800000005000000DB6286DFB057634082D8A1B32F843EC0DB6286DFB057634082D8A1B32F843EC075B4E4D0C60C634031FA5D1A371540C0D7197CED9B636340A3CB59A7630A41C050F4A72AC0FB6240974769FCE3CF41C0', 'hex')));
-SELECT 'null response', ST_NumPoints(ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0))'));
+SELECT 'st_numpoints', ST_NumPoints(ST_GeomFromEWKT('COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0))'));
 SELECT 'minpoints issues - pass', encode(ST_AsBinary(ST_GeomFromText('COMPOUNDCURVE((0 0,1 1))'),'ndr'),'hex');
 SELECT 'minpoints issues - pass', encode(ST_AsBinary(ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0,0 1,1 1))'),'ndr'),'hex');
 SELECT 'minpoints issues - fail', ST_GeomFromText('COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1))');
index 6d535db06a6586991ac13ae1a2a8bbfa4123eb0d..07e3d09d3bd23b82a22578130ba0121f543757a1 100644 (file)
@@ -79,7 +79,7 @@ valid wkb compound curve 2|COMPOUNDCURVE((153.72942375 -27.2175704,152.29285719
 valid wkb compound curve 3|COMPOUNDCURVE((151.60117699 -27.32398274,151.22873381 -35.9433821,150.74987829 -27.80283826))
 valid wkb compound curve 4|COMPOUNDCURVE((153.72942375 -27.2175704,152.29285719 -29.23940482,154.74034096 -30.51635287),CIRCULARSTRING(154.74034096 -30.51635287,154.74034096 -30.51635287,152.39926953 -32.16574411,155.11278414 -34.08116619,151.86720784 -35.62414508))
 valid wkb compound curve 5|COMPOUNDCURVE(CIRCULARSTRING(157.87950492 -27.59001358,156.01728901 -28.28169378,155.59163966 -26.52589021),(155.59163966 -26.52589021,153.72942375 -27.2175704,152.29285719 -29.23940482,154.74034096 -30.51635287),CIRCULARSTRING(154.74034096 -30.51635287,154.74034096 -30.51635287,152.39926953 -32.16574411,155.11278414 -34.08116619,151.86720784 -35.62414508))
-null response|
+st_numpoints|9
 minpoints issues - pass|01090000000100000001020000000200000000000000000000000000000000000000000000000000f03f000000000000f03f
 minpoints issues - pass|010900000001000000010800000003000000000000000000000000000000000000000000000000000000000000000000f03f000000000000f03f000000000000f03f
 ERROR:  geometry requires more points
index 444ff87f1632873ac1115fc8e032525220f6e2a0..8373721beae405aa7ab90f1c232f0117cbb3f2fa 100644 (file)
@@ -879,6 +879,18 @@ SELECT '#2704', ST_AsText(ST_GeomFromGML('<?xml version="1.0"?>
 
 SELECT '#2712', ST_AsText(ST_Segmentize('LINESTRING EMPTY'::geometry, 0.5));
 
+SELECT '#2717', 
+   ST_AsText(ST_StartPoint(g)), 
+   ST_AsText(ST_EndPoint(g)), 
+   ST_AsText(ST_PointN(g, 1)), 
+   ST_AsText(ST_PointN(g, 2)), 
+   ST_AsText(ST_PointN(g, 3)), 
+   ST_AsText(ST_PointN(g, 4)), 
+   ST_AsText(ST_PointN(g, 5))
+   FROM ( 
+     SELECT 'COMPOUNDCURVE((-1 -1, 1 1), CIRCULARSTRING(1 1, 2 2, 3 1))'::geometry AS g
+   ) AS foo;
+
 SELECT '#2788', valid, reason, ST_AsText(location) from ST_IsValidDetail('POLYGON((0 0, 0 1, 2 1, 2 2, 1 2, 1 0, 0 0))'::geometry);
 
 SELECT '#2870', ST_Summary('Point(151.215289 -33.856885)'::geometry::bytea::geography) ;
index aa6ef40d79260c1e9fdaa613b559908ce5fb6019..a7863fee808dab7f52f069cfd67cbd74aade9afb 100644 (file)
@@ -258,6 +258,7 @@ ERROR:  invalid GML representation
 #2556|1|0
 #2704|POLYGON((0 0,0 1,1 1,1 0,0 0))
 #2712|LINESTRING EMPTY
+#2717|POINT(-1 -1)|POINT(3 1)|POINT(-1 -1)|POINT(1 1)|POINT(1 1)|POINT(2 2)|POINT(3 1)
 #2788|f|Self-intersection|POINT(1 1)
 #2870|Point[GS]
 #2956|t