PostGIS 3.7.0dev-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 622 of file shp2pgsql-core.c.

623{
624 Ring **Outer;
625 int polygon_total, ring_total;
626 int pi, vi; /* part index and vertex index */
627
628 LWGEOM **lwpolygons;
629 LWGEOM *lwgeom;
630
631 POINT4D point4d;
632
633 int dims = 0;
634
635 char *mem;
636 size_t mem_length;
637
638 FLAGS_SET_Z(dims, state->has_z);
639 FLAGS_SET_M(dims, state->has_m);
640
641 polygon_total = FindPolygons(obj, &Outer);
642
643 if (state->config->simple_geometries == 1 && polygon_total != 1) /* We write Non-MULTI geometries, but have several parts: */
644 {
645 snprintf(state->message, SHPLOADERMSGLEN, _("We have a Multipolygon with %d parts, can't use -S switch!"), polygon_total);
646
647 return SHPLOADERERR;
648 }
649
650 /* Allocate memory for our array of LWPOLYs */
651 lwpolygons = malloc(sizeof(LWPOLY *) * polygon_total);
652
653 /* Cycle through each individual polygon */
654 for (pi = 0; pi < polygon_total; pi++)
655 {
656 LWPOLY *lwpoly = lwpoly_construct_empty(state->from_srid, state->has_z, state->has_m);
657
658 Ring *polyring;
659 int ring_index = 0;
660
661 /* Firstly count through the total number of rings in this polygon */
662 ring_total = 0;
663 polyring = Outer[pi];
664 while (polyring)
665 {
666 ring_total = ring_total + 1;
667 polyring = polyring->next;
668 }
669
670 /* Cycle through each ring within the polygon, starting with the outer */
671 polyring = Outer[pi];
672
673 while (polyring)
674 {
675 /* Create a POINTARRAY containing the points making up the ring */
676 POINTARRAY *pa = ptarray_construct_empty(state->has_z, state->has_m, polyring->n);
677
678 for (vi = 0; vi < polyring->n; vi++)
679 {
680 /* Build up a point array of all the points in this ring */
681 point4d.x = polyring->list[vi].x;
682 point4d.y = polyring->list[vi].y;
683
684 if (state->has_z)
685 point4d.z = polyring->list[vi].z;
686 if (state->has_m)
687 point4d.m = polyring->list[vi].m;
688
689 ptarray_append_point(pa, &point4d, LW_TRUE);
690 }
691
692 /* Copy the POINTARRAY pointer so we can use the LWPOLY constructor */
693 lwpoly_add_ring(lwpoly, pa);
694
695 polyring = polyring->next;
696 ring_index = ring_index + 1;
697 }
698
699 /* Generate the LWGEOM */
700 lwpolygons[pi] = lwpoly_as_lwgeom(lwpoly);
701 }
702
703 /* If using MULTIPOLYGONS then generate the serialized collection, otherwise just a single POLYGON */
704 if (state->config->simple_geometries == 0)
705 {
706 lwgeom = lwcollection_as_lwgeom(lwcollection_construct(MULTIPOLYGONTYPE, state->from_srid, NULL, polygon_total, lwpolygons));
707 }
708 else
709 {
710 lwgeom = lwpolygons[0];
711 lwfree(lwpolygons);
712 }
713
714 if (!state->config->use_wkt)
716 else
717 mem = lwgeom_to_wkt(lwgeom, WKT_EXTENDED, WKT_PRECISION, &mem_length);
718
719 if ( !mem )
720 {
721 /* Free the linked list of rings */
722 ReleasePolygons(Outer, polygon_total);
723
724 snprintf(state->message, SHPLOADERMSGLEN, "unable to write geometry");
725 return SHPLOADERERR;
726 }
727
728 /* Free all of the allocated items */
729 lwgeom_free(lwgeom);
730
731 /* Free the linked list of rings */
732 ReleasePolygons(Outer, polygon_total);
733
734 /* Return the string - everything ok */
735 *geometry = mem;
736
737 return SHPLOADEROK;
738}
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:1246
#define WKT_EXTENDED
Definition liblwgeom.h:2221
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:2212
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:357
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition lwgeom.c:337
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: