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

◆ GeneratePolygonGeometry()

int GeneratePolygonGeometry ( SHPLOADERSTATE state,
SHPObject obj,
char **  geometry 
)

Generate an allocated geometry string for shapefile object obj using the state parameters.

This function basically deals with the polygon case. It sorts the polys in order of outer, inner,inner, so that inners always come after outers they are within.

Definition at line 618 of file shp2pgsql-core.c.

619{
620 Ring **Outer;
621 int polygon_total, ring_total;
622 int pi, vi; /* part index and vertex index */
623
624 LWGEOM **lwpolygons;
625 LWGEOM *lwgeom;
626
627 POINT4D point4d;
628
629 int dims = 0;
630
631 char *mem;
632 size_t mem_length;
633
634 FLAGS_SET_Z(dims, state->has_z);
635 FLAGS_SET_M(dims, state->has_m);
636
637 polygon_total = FindPolygons(obj, &Outer);
638
639 if (state->config->simple_geometries == 1 && polygon_total != 1) /* We write Non-MULTI geometries, but have several parts: */
640 {
641 snprintf(state->message, SHPLOADERMSGLEN, _("We have a Multipolygon with %d parts, can't use -S switch!"), polygon_total);
642
643 return SHPLOADERERR;
644 }
645
646 /* Allocate memory for our array of LWPOLYs */
647 lwpolygons = malloc(sizeof(LWPOLY *) * polygon_total);
648
649 /* Cycle through each individual polygon */
650 for (pi = 0; pi < polygon_total; pi++)
651 {
652 LWPOLY *lwpoly = lwpoly_construct_empty(state->from_srid, state->has_z, state->has_m);
653
654 Ring *polyring;
655 int ring_index = 0;
656
657 /* Firstly count through the total number of rings in this polygon */
658 ring_total = 0;
659 polyring = Outer[pi];
660 while (polyring)
661 {
662 ring_total = ring_total + 1;
663 polyring = polyring->next;
664 }
665
666 /* Cycle through each ring within the polygon, starting with the outer */
667 polyring = Outer[pi];
668
669 while (polyring)
670 {
671 /* Create a POINTARRAY containing the points making up the ring */
672 POINTARRAY *pa = ptarray_construct_empty(state->has_z, state->has_m, polyring->n);
673
674 for (vi = 0; vi < polyring->n; vi++)
675 {
676 /* Build up a point array of all the points in this ring */
677 point4d.x = polyring->list[vi].x;
678 point4d.y = polyring->list[vi].y;
679
680 if (state->has_z)
681 point4d.z = polyring->list[vi].z;
682 if (state->has_m)
683 point4d.m = polyring->list[vi].m;
684
685 ptarray_append_point(pa, &point4d, LW_TRUE);
686 }
687
688 /* Copy the POINTARRAY pointer so we can use the LWPOLY constructor */
689 lwpoly_add_ring(lwpoly, pa);
690
691 polyring = polyring->next;
692 ring_index = ring_index + 1;
693 }
694
695 /* Generate the LWGEOM */
696 lwpolygons[pi] = lwpoly_as_lwgeom(lwpoly);
697 }
698
699 /* If using MULTIPOLYGONS then generate the serialized collection, otherwise just a single POLYGON */
700 if (state->config->simple_geometries == 0)
701 {
702 lwgeom = lwcollection_as_lwgeom(lwcollection_construct(MULTIPOLYGONTYPE, state->from_srid, NULL, polygon_total, lwpolygons));
703 }
704 else
705 {
706 lwgeom = lwpolygons[0];
707 lwfree(lwpolygons);
708 }
709
710 if (!state->config->use_wkt)
712 else
713 mem = lwgeom_to_wkt(lwgeom, WKT_EXTENDED, WKT_PRECISION, &mem_length);
714
715 if ( !mem )
716 {
717 /* Free the linked list of rings */
718 ReleasePolygons(Outer, polygon_total);
719
720 snprintf(state->message, SHPLOADERMSGLEN, "unable to write geometry");
721 return SHPLOADERERR;
722 }
723
724 /* Free all of the allocated items */
725 lwgeom_free(lwgeom);
726
727 /* Free the linked list of rings */
728 ReleasePolygons(Outer, polygon_total);
729
730 /* Return the string - everything ok */
731 *geometry = mem;
732
733 return SHPLOADEROK;
734}
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
char * lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant)
Definition lwout_wkb.c:845
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1218
#define WKT_EXTENDED
Definition liblwgeom.h:2218
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition lwout_wkt.c:708
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
Definition lwpoly.c:247
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition ptarray.c:59
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
void lwfree(void *mem)
Definition lwutil.c:248
#define WKB_EXTENDED
Definition liblwgeom.h:2209
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE,...
Definition ptarray.c:147
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
#define FLAGS_SET_M(flags, value)
Definition liblwgeom.h:173
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoly.c:161
#define FLAGS_SET_Z(flags, value)
Definition liblwgeom.h:172
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition lwgeom.c:329
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition lwgeom.c:309
void * malloc(YYSIZE_T)
int FindPolygons(SHPObject *obj, Ring ***Out)
void ReleasePolygons(Ring **polys, int npolys)
#define WKT_PRECISION
#define SHPLOADERMSGLEN
#define SHPLOADERERR
#define SHPLOADEROK
#define _(String)
Definition shpcommon.h:24
double m
Definition liblwgeom.h:414
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
char message[SHPLOADERMSGLEN]
SHPLOADERCONFIG * config
struct struct_ring * next

References _, shp_loader_state::config, FindPolygons(), FLAGS_SET_M, FLAGS_SET_Z, shp_loader_state::from_srid, shp_loader_state::has_m, shp_loader_state::has_z, struct_ring::list, LW_TRUE, lwcollection_as_lwgeom(), lwcollection_construct(), lwfree(), lwgeom_free(), lwgeom_to_hexwkb_buffer(), lwgeom_to_wkt(), lwpoly_add_ring(), lwpoly_as_lwgeom(), lwpoly_construct_empty(), POINT4D::m, struct_point::m, malloc(), shp_loader_state::message, MULTIPOLYGONTYPE, struct_ring::n, struct_ring::next, ptarray_append_point(), ptarray_construct_empty(), ReleasePolygons(), SHPLOADERERR, SHPLOADERMSGLEN, SHPLOADEROK, shp_loader_config::simple_geometries, shp_loader_config::use_wkt, WKB_EXTENDED, WKT_EXTENDED, WKT_PRECISION, POINT4D::x, struct_point::x, POINT4D::y, struct_point::y, POINT4D::z, and struct_point::z.

Referenced by ShpLoaderGenerateSQLRowStatement().

Here is the call graph for this function:
Here is the caller graph for this function: