PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ TWKBFromLWGEOMArray()

Datum TWKBFromLWGEOMArray ( PG_FUNCTION_ARGS  )

Definition at line 479 of file lwgeom_inout.c.

480{
481 ArrayType *arr_geoms = NULL;
482 ArrayType *arr_ids = NULL;
483 int num_geoms, num_ids, i = 0;
484
485 ArrayIterator iter_geoms, iter_ids;
486 bool null_geom, null_id;
487 Datum val_geom, val_id;
488
489 int is_homogeneous = true;
490 uint32_t subtype = 0;
491 int has_z = 0;
492 int has_m = 0;
493 LWCOLLECTION *col = NULL;
494 int64_t *idlist = NULL;
495 uint8_t variant = 0;
496
497 srs_precision sp;
498
499 /* The first two arguments are required */
500 if ( PG_NARGS() < 2 || PG_ARGISNULL(0) || PG_ARGISNULL(1) )
501 PG_RETURN_NULL();
502
503 arr_geoms = PG_GETARG_ARRAYTYPE_P(0);
504 arr_ids = PG_GETARG_ARRAYTYPE_P(1);
505
506 num_geoms = ArrayGetNItems(ARR_NDIM(arr_geoms), ARR_DIMS(arr_geoms));
507 num_ids = ArrayGetNItems(ARR_NDIM(arr_ids), ARR_DIMS(arr_ids));
508
509 if ( num_geoms != num_ids )
510 {
511 elog(ERROR, "size of geometry[] and integer[] arrays must match");
512 PG_RETURN_NULL();
513 }
514
515 /* Loop through array and build a collection of geometry and */
516 /* a simple array of ids. If either side is NULL, skip it */
517
518 iter_geoms = array_create_iterator(arr_geoms, 0, NULL);
519 iter_ids = array_create_iterator(arr_ids, 0, NULL);
520
521 while( array_iterate(iter_geoms, &val_geom, &null_geom) &&
522 array_iterate(iter_ids, &val_id, &null_id) )
523 {
524 LWGEOM *geom;
525 int32_t uid;
526
527 if ( null_geom || null_id )
528 {
529 elog(NOTICE, "ST_AsTWKB skipping NULL entry at position %d", i);
530 continue;
531 }
532
533 geom = lwgeom_from_gserialized((GSERIALIZED*)DatumGetPointer(val_geom));
534 uid = DatumGetInt64(val_id);
535
536 /* Construct collection/idlist first time through */
537 if ( ! col )
538 {
539 has_z = lwgeom_has_z(geom);
540 has_m = lwgeom_has_m(geom);
542 }
543 if ( ! idlist )
544 idlist = palloc0(num_geoms * sizeof(int64_t));
545
546
547 /* Check if there is differences in dimensionality*/
548 if( lwgeom_has_z(geom)!=has_z || lwgeom_has_m(geom)!=has_m)
549 {
550 elog(ERROR, "Geometries have different dimensionality");
551 PG_FREE_IF_COPY(arr_geoms, 0);
552 PG_FREE_IF_COPY(arr_ids, 1);
553 PG_RETURN_NULL();
554 }
555 /* Store the values */
556 lwcollection_add_lwgeom(col, geom);
557 idlist[i++] = uid;
558
559 /* Grab the geometry type and note if all geometries share it */
560 /* If so, we can make this a homogeneous collection and save some space */
561 if ( lwgeom_get_type(geom) != subtype && subtype )
562 {
563 is_homogeneous = false;
564 }
565 else
566 {
567 subtype = lwgeom_get_type(geom);
568 }
569
570 }
571 array_free_iterator(iter_geoms);
572 array_free_iterator(iter_ids);
573
574 if(i==0)
575 {
576 elog(NOTICE, "No valid geometry - id pairs found");
577 PG_FREE_IF_COPY(arr_geoms, 0);
578 PG_FREE_IF_COPY(arr_ids, 1);
579 PG_RETURN_NULL();
580 }
581 if ( is_homogeneous )
582 {
583 col->type = lwtype_get_collectiontype(subtype);
584 }
585
586 /* Read sensible precision defaults (about one meter) given the srs */
587 sp = srid_axis_precision(lwgeom_get_srid(lwcollection_as_lwgeom(col)), TWKB_DEFAULT_PRECISION);
588
589 /* If user specified XY precision, use it */
590 if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
591 sp.precision_xy = PG_GETARG_INT32(2);
592
593 /* If user specified Z precision, use it */
594 if ( PG_NARGS() > 3 && ! PG_ARGISNULL(3) )
595 sp.precision_z = PG_GETARG_INT32(3);
596
597 /* If user specified M precision, use it */
598 if ( PG_NARGS() > 4 && ! PG_ARGISNULL(4) )
599 sp.precision_m = PG_GETARG_INT32(4);
600
601 /* We are building an ID'ed output */
603
604 /* If user wants registered twkb sizes */
605 if ( PG_NARGS() > 5 && ! PG_ARGISNULL(5) && PG_GETARG_BOOL(5) )
607
608 /* If user wants bounding boxes */
609 if ( PG_NARGS() > 6 && ! PG_ARGISNULL(6) && PG_GETARG_BOOL(6) )
611
612 /* Write out the TWKB */
613 PG_RETURN_BYTEA_P(lwgeom_to_twkb_with_idlist(
614 lwcollection_as_lwgeom(col), idlist, variant, sp.precision_xy, sp.precision_z, sp.precision_m));
615}
static uint8_t variant
Definition cu_in_twkb.c:26
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint32_t lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
Definition lwgeom.c:1222
#define COLLECTIONTYPE
Definition liblwgeom.h:108
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
Definition lwgeom.c:955
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:962
lwvarlena_t * lwgeom_to_twkb_with_idlist(const LWGEOM *geom, int64_t *idlist, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m)
Convert LWGEOM to a char* in TWKB format.
Definition lwout_twkb.c:589
#define TWKB_ID
Definition liblwgeom.h:2229
#define TWKB_DEFAULT_PRECISION
Definition liblwgeom.h:2232
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
#define TWKB_SIZE
Definition liblwgeom.h:2228
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition lwgeom.c:969
#define TWKB_BBOX
Definition liblwgeom.h:2227
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition lwgeom.c:337
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition lwinline.h:141
uint8_t type
Definition liblwgeom.h:578

References COLLECTIONTYPE, lwcollection_add_lwgeom(), lwcollection_as_lwgeom(), lwcollection_construct_empty(), lwgeom_from_gserialized(), lwgeom_get_srid(), lwgeom_get_type(), lwgeom_has_m(), lwgeom_has_z(), lwgeom_to_twkb_with_idlist(), lwtype_get_collectiontype(), TWKB_BBOX, TWKB_DEFAULT_PRECISION, TWKB_ID, TWKB_SIZE, LWCOLLECTION::type, and variant.

Here is the call graph for this function: