PostGIS  2.1.10dev-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 627 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, 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().

628 {
629  Ring **Outer;
630  int polygon_total, ring_total;
631  int pi, vi; /* part index and vertex index */
632 
633  LWGEOM **lwpolygons;
634  LWGEOM *lwgeom;
635 
636  POINT4D point4d;
637 
638  int dims = 0;
639 
640  char *mem;
641  size_t mem_length;
642 
643  FLAGS_SET_Z(dims, state->has_z);
644  FLAGS_SET_M(dims, state->has_m);
645 
646  polygon_total = FindPolygons(obj, &Outer);
647 
648  if (state->config->simple_geometries == 1 && polygon_total != 1) /* We write Non-MULTI geometries, but have several parts: */
649  {
650  snprintf(state->message, SHPLOADERMSGLEN, _("We have a Multipolygon with %d parts, can't use -S switch!"), polygon_total);
651 
652  return SHPLOADERERR;
653  }
654 
655  /* Allocate memory for our array of LWPOLYs */
656  lwpolygons = malloc(sizeof(LWPOLY *) * polygon_total);
657 
658  /* Cycle through each individual polygon */
659  for (pi = 0; pi < polygon_total; pi++)
660  {
661  LWPOLY *lwpoly = lwpoly_construct_empty(state->from_srid, state->has_z, state->has_m);
662 
663  Ring *polyring;
664  int ring_index = 0;
665 
666  /* Firstly count through the total number of rings in this polygon */
667  ring_total = 0;
668  polyring = Outer[pi];
669  while (polyring)
670  {
671  ring_total++;
672  polyring = polyring->next;
673  }
674 
675  /* Cycle through each ring within the polygon, starting with the outer */
676  polyring = Outer[pi];
677 
678  while (polyring)
679  {
680  /* Create a POINTARRAY containing the points making up the ring */
681  POINTARRAY *pa = ptarray_construct_empty(state->has_z, state->has_m, polyring->n);
682 
683  for (vi = 0; vi < polyring->n; vi++)
684  {
685  /* Build up a point array of all the points in this ring */
686  point4d.x = polyring->list[vi].x;
687  point4d.y = polyring->list[vi].y;
688 
689  if (state->has_z)
690  point4d.z = polyring->list[vi].z;
691  if (state->has_m)
692  point4d.m = polyring->list[vi].m;
693 
694  ptarray_append_point(pa, &point4d, LW_TRUE);
695  }
696 
697  /* Copy the POINTARRAY pointer so we can use the LWPOLY constructor */
698  lwpoly_add_ring(lwpoly, pa);
699 
700  polyring = polyring->next;
701  ring_index++;
702  }
703 
704  /* Generate the LWGEOM */
705  lwpolygons[pi] = lwpoly_as_lwgeom(lwpoly);
706  }
707 
708  /* If using MULTIPOLYGONS then generate the serialized collection, otherwise just a single POLYGON */
709  if (state->config->simple_geometries == 0)
710  {
711  lwgeom = lwcollection_as_lwgeom(lwcollection_construct(MULTIPOLYGONTYPE, state->from_srid, NULL, polygon_total, lwpolygons));
712  }
713  else
714  {
715  lwgeom = lwpolygons[0];
716  lwfree(lwpolygons);
717  }
718 
719  if (!state->config->use_wkt)
720  mem = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &mem_length);
721  else
722  mem = lwgeom_to_wkt(lwgeom, WKT_EXTENDED, WKT_PRECISION, &mem_length);
723 
724  if ( !mem )
725  {
726  /* Free the linked list of rings */
727  ReleasePolygons(Outer, polygon_total);
728 
729  snprintf(state->message, SHPLOADERMSGLEN, "unable to write geometry");
730  return SHPLOADERERR;
731  }
732 
733  /* Free all of the allocated items */
734  lwgeom_free(lwgeom);
735 
736  /* Free the linked list of rings */
737  ReleasePolygons(Outer, polygon_total);
738 
739  /* Return the string - everything ok */
740  *geometry = mem;
741 
742  return SHPLOADEROK;
743 }
double x
Definition: liblwgeom.h:308
char * lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out)
Definition: lwout_wkb.c:776
SHPLOADERCONFIG * config
double m
Definition: liblwgeom.h:308
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:190
#define _(String)
Definition: shpcommon.h:23
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:57
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1006
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:239
#define FLAGS_SET_Z(flags, value)
Definition: liblwgeom.h:112
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:141
int FindPolygons(SHPObject *obj, Ring ***Out)
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:51
struct struct_ring * next
#define SHPLOADEROK
double z
Definition: liblwgeom.h:308
#define WKB_EXTENDED
Definition: liblwgeom.h:1769
#define WKT_PRECISION
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:65
Point * list
#define WKT_EXTENDED
Definition: liblwgeom.h:1778
char message[SHPLOADERMSGLEN]
void ReleasePolygons(Ring **polys, int npolys)
LWPOLY * lwpoly_construct_empty(int srid, char hasz, char hasm)
Definition: lwpoly.c:66
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:308
#define SHPLOADERMSGLEN
#define FLAGS_SET_M(flags, value)
Definition: liblwgeom.h:113
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: