PostGIS  3.4.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 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)
711  mem = lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED);
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 }
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:309
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
#define WKT_EXTENDED
Definition: liblwgeom.h:2186
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:329
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:242
#define WKB_EXTENDED
Definition: liblwgeom.h:2177
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: