PostGIS  2.3.6-r@@SVN_REVISION@@
static SHPObject * create_multipolygon ( SHPDUMPERSTATE state,
LWMPOLY lwmultipolygon 
)
static

Definition at line 234 of file pgsql2shp-core.c.

References free(), LWMPOLY::geoms, getPoint4d(), is_clockwise(), LWDEBUG, LWDEBUGF, POINT4D::m, malloc(), LWMPOLY::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, shp_dumper_state::outshptype, reverse_points(), LWPOLY::rings, SHPCreateObject(), POINT4D::x, POINT4D::y, and POINT4D::z.

Referenced by ShpLoaderGenerateShapeRow().

235 {
236  SHPObject *obj;
237  POINT4D p4d;
238  int i, j, k;
239 
240  double *xpts, *ypts, *zpts, *mpts;
241 
242  int *shpparts, shppointtotal = 0, shppoint = 0, shpringtotal = 0, shpring = 0;
243 
244  /* NOTE: Multipolygons are stored in shapefiles as Polygon* shapes with multiple outer rings */
245 
246  /* First count through each ring of each polygon so we now know much memory is required */
247  for (i = 0; i < lwmultipolygon->ngeoms; i++)
248  {
249  for (j = 0; j < lwmultipolygon->geoms[i]->nrings; j++)
250  {
251  shpringtotal++;
252  shppointtotal += lwmultipolygon->geoms[i]->rings[j]->npoints;
253  }
254  }
255 
256  /* Allocate storage for ring pointers */
257  shpparts = malloc(sizeof(int) * shpringtotal);
258 
259  /* Allocate storage for points */
260  xpts = malloc(sizeof(double) * shppointtotal);
261  ypts = malloc(sizeof(double) * shppointtotal);
262  zpts = malloc(sizeof(double) * shppointtotal);
263  mpts = malloc(sizeof(double) * shppointtotal);
264 
265  LWDEBUGF(4, "Total number of rings: %d Total number of points: %d", shpringtotal, shppointtotal);
266 
267  /* Iterate through each ring of each polygon in turn */
268  for (i = 0; i < lwmultipolygon->ngeoms; i++)
269  {
270  for (j = 0; j < lwmultipolygon->geoms[i]->nrings; j++)
271  {
272  /* For each ring, store the integer coordinate offset for the start of each ring */
273  shpparts[shpring] = shppoint;
274 
275  LWDEBUGF(4, "Ring offset: %d", shpring);
276 
277  for (k = 0; k < lwmultipolygon->geoms[i]->rings[j]->npoints; k++)
278  {
279  p4d = getPoint4d(lwmultipolygon->geoms[i]->rings[j], k);
280 
281  xpts[shppoint] = p4d.x;
282  ypts[shppoint] = p4d.y;
283  zpts[shppoint] = p4d.z;
284  mpts[shppoint] = p4d.m;
285 
286  LWDEBUGF(4, "MultiPolygon %d Polygon Ring %d - Point: %g %g %g %g", i, j, xpts[shppoint], ypts[shppoint], zpts[shppoint], mpts[shppoint]);
287 
288  /* Increment the point counter */
289  shppoint++;
290  }
291 
292  /*
293  * First ring should be clockwise,
294  * other rings should be counter-clockwise
295  */
296  if ( j == 0 )
297  {
298  if ( ! is_clockwise(lwmultipolygon->geoms[i]->rings[j]->npoints,
299  &xpts[shpparts[shpring]], &ypts[shpparts[shpring]], NULL) )
300  {
301  LWDEBUG(4, "Outer ring not clockwise, forcing clockwise\n");
302 
303  reverse_points(lwmultipolygon->geoms[i]->rings[j]->npoints,
304  &xpts[shpparts[shpring]], &ypts[shpparts[shpring]],
305  &zpts[shpparts[shpring]], &mpts[shpparts[shpring]]);
306  }
307  }
308  else
309  {
310  if ( is_clockwise(lwmultipolygon->geoms[i]->rings[j]->npoints,
311  &xpts[shpparts[shpring]], &ypts[shpparts[shpring]], NULL) )
312  {
313  LWDEBUGF(4, "Inner ring %d not counter-clockwise, forcing counter-clockwise\n", i);
314 
315  reverse_points(lwmultipolygon->geoms[i]->rings[j]->npoints,
316  &xpts[shpparts[shpring]], &ypts[shpparts[shpring]],
317  &zpts[shpparts[shpring]], &mpts[shpparts[shpring]]);
318  }
319  }
320 
321  /* Increment the ring counter */
322  shpring++;
323  }
324  }
325 
326  obj = SHPCreateObject(state->outshptype, -1, shpringtotal, shpparts, NULL, shppointtotal, xpts, ypts, zpts, mpts);
327 
328  free(xpts);
329  free(ypts);
330  free(zpts);
331  free(mpts);
332  free(shpparts);
333 
334  return obj;
335 }
double x
Definition: liblwgeom.h:351
SHPObject SHPAPI_CALL1 * SHPCreateObject(int nSHPType, int nShapeId, int nParts, const int *panPartStart, const int *panPartType, int nVertices, const double *padfX, const double *padfY, const double *padfZ, const double *padfM);SHPObject SHPAPI_CALL1(*) SHPCreateSimpleObject(int nSHPType, int nVertices, const double *padfX, const double *padfY, const double *padfZ
double m
Definition: liblwgeom.h:351
int npoints
Definition: liblwgeom.h:370
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
static int reverse_points(int num_points, double *x, double *y, double *z, double *m)
POINT4D getPoint4d(const POINTARRAY *pa, int n)
Definition: lwgeom_api.c:229
LWPOLY ** geoms
Definition: liblwgeom.h:495
static int is_clockwise(int num_points, double *x, double *y, double *z)
POINTARRAY ** rings
Definition: liblwgeom.h:456
int nrings
Definition: liblwgeom.h:454
double z
Definition: liblwgeom.h:351
int ngeoms
Definition: liblwgeom.h:493
void free(void *)
void * malloc(YYSIZE_T)
double y
Definition: liblwgeom.h:351
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88

Here is the call graph for this function:

Here is the caller graph for this function: