PostGIS  2.2.7dev-r@@SVN_REVISION@@
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 607 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().

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

Here is the call graph for this function:

Here is the caller graph for this function: