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

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