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

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(), struct_point::m, POINT4D::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, struct_point::x, POINT4D::x, struct_point::y, POINT4D::y, struct_point::z, and POINT4D::z.

Referenced by ShpLoaderGenerateSQLRowStatement().

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 }
double x
Definition: liblwgeom.h:352
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Definition: lwout_wkb.c:848
SHPLOADERCONFIG * config
double m
Definition: liblwgeom.h:352
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:669
void lwfree(void *mem)
Definition: lwutil.c:244
#define _(String)
Definition: shpcommon.h:24
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1099
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:288
#define FLAGS_SET_Z(flags, value)
Definition: liblwgeom.h:146
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, then a duplicate point will not be added.
Definition: ptarray.c:156
int FindPolygons(SHPObject *obj, Ring ***Out)
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
struct struct_ring * next
#define SHPLOADEROK
double z
Definition: liblwgeom.h:352
#define WKB_EXTENDED
Definition: liblwgeom.h:2076
#define WKT_PRECISION
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:90
Point * list
#define WKT_EXTENDED
Definition: liblwgeom.h:2085
char message[SHPLOADERMSGLEN]
void ReleasePolygons(Ring **polys, int npolys)
LWPOLY * lwpoly_construct_empty(int srid, char hasz, char hasm)
Definition: lwpoly.c:161
void * malloc(YYSIZE_T)
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
Definition: lwpoly.c:249
#define SHPLOADERERR
double y
Definition: liblwgeom.h:352
#define SHPLOADERMSGLEN
#define FLAGS_SET_M(flags, value)
Definition: liblwgeom.h:147
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:268
Here is the call graph for this function:
Here is the caller graph for this function: