PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ 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)
715  mem = lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED);
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 }
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:337
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1246
#define WKT_EXTENDED
Definition: liblwgeom.h:2221
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:357
char * lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant)
Definition: lwout_wkb.c:845
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
Definition: lwpoly.c:247
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:107
void lwfree(void *mem)
Definition: lwutil.c:248
#define WKB_EXTENDED
Definition: liblwgeom.h:2212
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:59
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 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
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:42
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
#define FLAGS_SET_M(flags, value)
Definition: liblwgeom.h:173
#define FLAGS_SET_Z(flags, value)
Definition: liblwgeom.h:172
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwpoly.c:161
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
Point * list
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: