PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ create_multipolygon()

static SHPObject * create_multipolygon ( SHPDUMPERSTATE state,
LWMPOLY lwmultipolygon 
)
static

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

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

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().

Here is the call graph for this function:
Here is the caller graph for this function: