Changeset 4847
- Timestamp:
- 11/17/09 12:03:50 (2 years ago)
- Location:
- trunk
- Files:
-
- 10 modified
-
doc/reference_editor.xml (modified) (1 diff)
-
liblwgeom/cunit/cu_libgeom.c (modified) (2 diffs)
-
liblwgeom/cunit/cu_libgeom.h (modified) (1 diff)
-
liblwgeom/liblwgeom.h (modified) (1 diff)
-
liblwgeom/lwcollection.c (modified) (1 diff)
-
liblwgeom/lwutil.c (modified) (1 diff)
-
postgis/lwgeom_functions_basic.c (modified) (2 diffs)
-
postgis/postgis.sql.in.c (modified) (1 diff)
-
regress/regress_expected (modified) (1 diff)
-
regress/regress.sql (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/reference_editor.xml
r4817 r4847 606 606 </refentry> 607 607 608 <refentry id="ST_CollectionExtract"> 609 <refnamediv> 610 <refname>ST_CollectionExtract</refname> 611 612 <refpurpose>Given a GEOMETRYCOLLECTION, returns the a MULTI* geometry consisting only the specified type. Sub-geometries that are not 613 the specified type are ignored.</refpurpose> 614 </refnamediv> 615 616 <refsynopsisdiv> 617 <funcsynopsis> 618 <funcprototype> 619 <funcdef>geometry <function>ST_CollectionExtract</function></funcdef> 620 <paramdef><type>geometry </type> <parameter>collection</parameter></paramdef> 621 <paramdef><type>integer </type> <parameter>type</parameter></paramdef> 622 </funcprototype> 623 </funcsynopsis> 624 </refsynopsisdiv> 625 626 <refsection> 627 <title>Description</title> 628 629 <para>Given a GEOMETRYCOLLECTION, returns the a MULTI* geometry consisting only the specified type. Sub-geometries that are not 630 the specified type are ignored. If there are no sub-geometries of the right type, an EMPTY collection will be returned. Only 631 points, lines and polygons are supported.</para> 632 633 </refsection> 634 635 <refsection> 636 <title>Examples</title> 637 638 <programlisting>SELECT ST_AsText(ST_CollectionExtract(ST_GeomFromText('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(0 0)))'),1)); 639 st_astext 640 --------------- 641 MULTIPOINT(0 0) 642 (1 row) 643 </programlisting> 644 </refsection> 645 <refsection> 646 <title>See Also</title> 647 <para><xref linkend="ST_Multi" /></para> 648 </refsection> 649 </refentry> 650 608 651 <refentry id="ST_Multi"> 609 652 <refnamediv> -
trunk/liblwgeom/cunit/cu_libgeom.c
r4654 r4847 38 38 (NULL == CU_add_test(pSuite, "test_lwgeom_count_vertices()", test_lwgeom_count_vertices)) || 39 39 (NULL == CU_add_test(pSuite, "test_on_gser_lwgeom_count_vertices()", test_on_gser_lwgeom_count_vertices)) || 40 (NULL == CU_add_test(pSuite, "test_gbox_calculation()", test_gbox_calculation)) 40 (NULL == CU_add_test(pSuite, "test_gbox_calculation()", test_gbox_calculation)) || 41 (NULL == CU_add_test(pSuite, "test_lwcollection_extract()", test_lwcollection_extract)) 41 42 42 43 ) … … 458 459 lwfree(gbox); 459 460 } 461 462 void test_lwcollection_extract(void) 463 { 464 465 LWGEOM *geom; 466 LWCOLLECTION *col; 467 468 geom = lwgeom_from_ewkt("GEOMETRYCOLLECTION(POINT(0 0))", PARSER_CHECK_NONE); 469 col = lwcollection_extract((LWCOLLECTION*)geom, 1); 470 CU_ASSERT_EQUAL(TYPE_GETTYPE(col->type), MULTIPOINTTYPE); 471 472 lwcollection_release(col); 473 lwgeom_free(geom); 474 475 } -
trunk/liblwgeom/cunit/cu_libgeom.h
r4537 r4847 38 38 void test_gbox_serialized_size(void); 39 39 void test_gbox_calculation(void); 40 void test_lwcollection_extract(void); -
trunk/liblwgeom/liblwgeom.h
r4710 r4847 917 917 LWGEOM *lwcollection_getsubgeom(LWCOLLECTION *col, int gnum); 918 918 BOX3D *lwcollection_compute_box3d(LWCOLLECTION *col); 919 919 LWCOLLECTION* lwcollection_extract(LWCOLLECTION *col, int type); 920 920 921 921 /****************************************************************** -
trunk/liblwgeom/lwcollection.c
r4789 r4847 558 558 return boxfinal; 559 559 } 560 561 /** 562 * Takes a potentially heterogeneous collection and returns a homogeneous 563 * collection consisting only of the specified type. 564 */ 565 LWCOLLECTION* lwcollection_extract(LWCOLLECTION *col, int type) 566 { 567 int i = 0; 568 LWGEOM **geomlist; 569 BOX3D *b3d; 570 LWCOLLECTION *outcol; 571 int geomlistsize = 16; 572 int geomlistlen = 0; 573 uchar outtype; 574 575 if( ! col ) return NULL; 576 577 switch (type) 578 { 579 case POINTTYPE: 580 outtype = MULTIPOINTTYPE; 581 break; 582 case LINETYPE: 583 outtype = MULTILINETYPE; 584 break; 585 case POLYGONTYPE: 586 outtype = MULTIPOLYGONTYPE; 587 break; 588 default: 589 lwerror("Only POLYGON, LINESTRING and POINT are supported by lwcollection_extract. %s requested.", lwgeom_typename(type)); 590 return NULL; 591 } 592 593 geomlist = lwalloc(sizeof(LWGEOM*) * geomlistsize); 594 595 /* Process each sub-geometry */ 596 for( i = 0; i < col->ngeoms; i++ ) 597 { 598 int subtype = TYPE_GETTYPE(col->geoms[i]->type); 599 /* Copy our sub-types into the output list */ 600 if( subtype == type ) 601 { 602 /* We've over-run our buffer, double the memory segment */ 603 if( geomlistlen == geomlistsize ) 604 { 605 geomlistsize *= 2; 606 geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize); 607 } 608 geomlist[geomlistlen] = col->geoms[i]; 609 geomlistlen++; 610 } 611 if( lwgeom_is_collection( subtype ) ) 612 { 613 int j = 0; 614 LWCOLLECTION *tmpcol = lwcollection_extract((LWCOLLECTION*)col->geoms[i], type); 615 for( j = 0; j < tmpcol->ngeoms; j++ ) 616 { 617 /* We've over-run our buffer, double the memory segment */ 618 if( geomlistlen == geomlistsize ) 619 { 620 geomlistsize *= 2; 621 geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize); 622 } 623 geomlist[geomlistlen] = tmpcol->geoms[j]; 624 geomlistlen++; 625 } 626 lwfree(tmpcol); 627 } 628 } 629 630 if( geomlistlen > 0 ) 631 { 632 outcol = lwcollection_construct(outtype, col->SRID, NULL, geomlistlen, geomlist); 633 b3d = lwcollection_compute_box3d(outcol); 634 outcol->bbox = box3d_to_box2df(b3d); 635 } 636 else 637 { 638 outcol = lwcollection_construct_empty(col->SRID, TYPE_HASZ(col->type), TYPE_HASM(col->type)); 639 } 640 641 return outcol; 642 } 643 -
trunk/liblwgeom/lwutil.c
r4494 r4847 208 208 209 209 210 const char * 211 lwgeom_typename(int type) 210 const char* lwgeom_typename(int type) 212 211 { 213 212 /* something went wrong somewhere */ -
trunk/postgis/lwgeom_functions_basic.c
r4831 r4847 79 79 Datum ST_GeoHash(PG_FUNCTION_ARGS); 80 80 Datum ST_MakeEnvelope(PG_FUNCTION_ARGS); 81 Datum ST_CollectionExtract(PG_FUNCTION_ARGS); 81 82 82 83 void lwgeom_affine_ptarray(POINTARRAY *pa, double afac, double bfac, double cfac, … … 3436 3437 3437 3438 } 3439 3440 PG_FUNCTION_INFO_V1(ST_CollectionExtract); 3441 Datum ST_CollectionExtract(PG_FUNCTION_ARGS) 3442 { 3443 PG_LWGEOM *input = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); 3444 PG_LWGEOM *output; 3445 LWGEOM *lwgeom = pglwgeom_deserialize(input); 3446 LWCOLLECTION *lwcol = NULL; 3447 int type = PG_GETARG_INT32(1); 3448 int lwgeom_type = TYPE_GETTYPE(lwgeom->type); 3449 3450 /* Ensure the right type was input */ 3451 if ( ! ( type == POINTTYPE || type == LINETYPE || type == POLYGONTYPE ) ) 3452 { 3453 lwgeom_free(lwgeom); 3454 elog(ERROR, "ST_CollectionExtract: only point, linestring and polygon may be extracted"); 3455 PG_RETURN_NULL(); 3456 } 3457 3458 /* Mirror non-collections right back */ 3459 if ( ! lwgeom_is_collection(lwgeom_type) ) 3460 { 3461 output = palloc(VARSIZE(input)); 3462 memcpy(VARDATA(output), VARDATA(input), VARSIZE(input) - VARHDRSZ); 3463 SET_VARSIZE(output, VARSIZE(input)); 3464 lwgeom_free(lwgeom); 3465 PG_RETURN_POINTER(output); 3466 } 3467 3468 lwcol = lwcollection_extract((LWCOLLECTION*)lwgeom, type); 3469 output = pglwgeom_serialize((LWGEOM*)lwcol); 3470 lwgeom_free(lwgeom); 3471 3472 PG_RETURN_POINTER(output); 3473 } -
trunk/postgis/postgis.sql.in.c
r4836 r4847 1437 1437 RETURNS geometry 1438 1438 AS 'MODULE_PATHNAME', 'LWGEOM_force_collection' 1439 LANGUAGE 'C' IMMUTABLE STRICT; 1440 1441 -- Availability: 1.5.0 1442 CREATE OR REPLACE FUNCTION ST_CollectionExtract(geometry, integer) 1443 RETURNS geometry 1444 AS 'MODULE_PATHNAME', 'ST_CollectionExtract' 1439 1445 LANGUAGE 'C' IMMUTABLE STRICT; 1440 1446 -
trunk/regress/regress_expected
r4832 r4847 198 198 151|0103000020E61000000100000005000000000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000000000000000000000000000000000000000 199 199 152|4326 200 153|MULTIPOINT(0 0) 201 154|MULTIPOINT(0 0) 202 155|MULTIPOINT(0 0,1 1) 203 156|MULTIPOINT(1 1) 204 157|MULTILINESTRING((0 0,1 1)) 205 158|MULTILINESTRING((0 0,1 1),(2 2,3 3)) 206 159|GEOMETRYCOLLECTION EMPTY 207 160|MULTIPOINT(1 1) 208 161|MULTILINESTRING((0 0,1 1),(2 2,3 3)) -
trunk/regress/regress.sql
r4832 r4847 278 278 select '152', ST_SRID(ST_MakeEnvelope(0, 0, 1, 1, 4326)); 279 279 280 select '153', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(POINT(0 0))',1)); 281 select '154', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(0 0)))',1)); 282 select '155', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(0 0), POINT(1 1)))',1)); 283 select '156', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1), POINT(1 1)))',1)); 284 select '157', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1), POINT(1 1)))',2)); 285 select '158', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1), POINT(1 1)),LINESTRING(2 2, 3 3))',2)); 286 select '159', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1), POINT(1 1)),LINESTRING(2 2, 3 3))',3)); 287 select '160', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1), POINT(1 1)),LINESTRING(2 2, 3 3))',1)); 288 select '161', ST_AsText(ST_CollectionExtract('GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1), GEOMETRYCOLLECTION(POINT(1 1))),LINESTRING(2 2, 3 3))',2)); 289 280 290 281 291 -- Drop test table
