530{
531 ArrayType *arr_geoms = NULL;
532 ArrayType *arr_ids = NULL;
533 int num_geoms, num_ids, i = 0;
534
535 ArrayIterator iter_geoms, iter_ids;
536 bool null_geom, null_id;
537 Datum val_geom, val_id;
538
539 int is_homogeneous = true;
540 uint32_t subtype = 0;
541 int has_z = 0;
542 int has_m = 0;
544 int64_t *idlist = NULL;
546
547 srs_precision sp;
548 uint8_t *twkb;
549 size_t twkb_size;
550 bytea *result;
551
552
553 if ( PG_NARGS() < 2 || PG_ARGISNULL(0) || PG_ARGISNULL(1) )
554 PG_RETURN_NULL();
555
556 arr_geoms = PG_GETARG_ARRAYTYPE_P(0);
557 arr_ids = PG_GETARG_ARRAYTYPE_P(1);
558
559 num_geoms = ArrayGetNItems(ARR_NDIM(arr_geoms), ARR_DIMS(arr_geoms));
560 num_ids = ArrayGetNItems(ARR_NDIM(arr_ids), ARR_DIMS(arr_ids));
561
562 if ( num_geoms != num_ids )
563 {
564 elog(ERROR, "size of geometry[] and integer[] arrays must match");
565 PG_RETURN_NULL();
566 }
567
568
569
570
571 iter_geoms = array_create_iterator(arr_geoms, 0, NULL);
572 iter_ids = array_create_iterator(arr_ids, 0, NULL);
573
574 while( array_iterate(iter_geoms, &val_geom, &null_geom) &&
575 array_iterate(iter_ids, &val_id, &null_id) )
576 {
578 int32_t uid;
579
580 if ( null_geom || null_id )
581 {
582 elog(NOTICE, "ST_AsTWKB skipping NULL entry at position %d", i);
583 continue;
584 }
585
587 uid = DatumGetInt64(val_id);
588
589
590 if ( ! col )
591 {
595 }
596 if ( ! idlist )
597 idlist = palloc0(num_geoms * sizeof(int64_t));
598
599
600
602 {
603 elog(ERROR, "Geometries have different dimensionality");
604 PG_FREE_IF_COPY(arr_geoms, 0);
605 PG_FREE_IF_COPY(arr_ids, 1);
606 PG_RETURN_NULL();
607 }
608
610 idlist[i++] = uid;
611
612
613
615 {
616 is_homogeneous = false;
617 }
618 else
619 {
621 }
622
623 }
624 array_free_iterator(iter_geoms);
625 array_free_iterator(iter_ids);
626
627 if(i==0)
628 {
629 elog(NOTICE, "No valid geometry - id pairs found");
630 PG_FREE_IF_COPY(arr_geoms, 0);
631 PG_FREE_IF_COPY(arr_ids, 1);
632 PG_RETURN_NULL();
633 }
634 if ( is_homogeneous )
635 {
637 }
638
639
641
642
643 if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
644 sp.precision_xy = PG_GETARG_INT32(2);
645
646
647 if ( PG_NARGS() > 3 && ! PG_ARGISNULL(3) )
648 sp.precision_z = PG_GETARG_INT32(3);
649
650
651 if ( PG_NARGS() > 4 && ! PG_ARGISNULL(4) )
652 sp.precision_m = PG_GETARG_INT32(4);
653
654
656
657
658 if ( PG_NARGS() > 5 && ! PG_ARGISNULL(5) && PG_GETARG_BOOL(5) )
660
661
662 if ( PG_NARGS() > 6 && ! PG_ARGISNULL(6) && PG_GETARG_BOOL(6) )
664
665
668 sp.precision_xy, sp.precision_z, sp.precision_m,
669 &twkb_size);
670
671
672 result = palloc(twkb_size + VARHDRSZ);
673 memcpy(VARDATA(result), twkb, twkb_size);
674 SET_VARSIZE(result, twkb_size + VARHDRSZ);
675
676
677 pfree(twkb);
678 pfree(idlist);
680 PG_FREE_IF_COPY(arr_geoms, 0);
681 PG_FREE_IF_COPY(arr_ids, 1);
682
683 PG_RETURN_BYTEA_P(result);
684}
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?
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
uint8_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, size_t *twkb_size)
Convert LWGEOM to a char* in TWKB format.
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
void lwcollection_free(LWCOLLECTION *col)
#define TWKB_DEFAULT_PRECISION
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
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.
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.