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

◆ FindPolygons()

int FindPolygons ( SHPObject obj,
Ring ***  Out 
)

Definition at line 439 of file shp2pgsql-core.c.

440{
441 Ring **Outer; /* Pointers to Outer rings */
442 int out_index=0; /* Count of Outer rings */
443 Ring **Inner; /* Pointers to Inner rings */
444 int in_index=0; /* Count of Inner rings */
445 int pi; /* part index */
446
447#if POSTGIS_DEBUG_LEVEL > 0
448 static int call = -1;
449 call++;
450#endif
451
452 LWDEBUGF(4, "FindPolygons[%d]: allocated space for %d rings\n", call, obj->nParts);
453
454 /* Allocate initial memory */
455 Outer = (Ring **)malloc(sizeof(Ring *) * obj->nParts);
456 Inner = (Ring **)malloc(sizeof(Ring *) * obj->nParts);
457
458 /* Iterate over rings dividing in Outers and Inners */
459 for (pi=0; pi < obj->nParts; pi++)
460 {
461 int vi; /* vertex index */
462 int vs; /* start index */
463 int ve; /* end index */
464 int nv; /* number of vertex */
465 double area = 0.0;
466 Ring *ring;
467
468 /* Set start and end vertices */
469 if (pi == obj->nParts - 1)
470 ve = obj->nVertices;
471 else
472 ve = obj->panPartStart[pi + 1];
473
474 vs = obj->panPartStart[pi];
475
476 /* Compute number of vertices */
477 nv = ve - vs;
478
479 /* Allocate memory for a ring */
480 ring = (Ring *)malloc(sizeof(Ring));
481 ring->list = (Point *)malloc(sizeof(Point) * nv);
482 ring->n = nv;
483 ring->next = NULL;
484 ring->linked = 0;
485
486 /* Iterate over ring vertices */
487 for (vi = vs; vi < ve; vi++)
488 {
489 int vn = vi+1; /* next vertex for area */
490 if (vn == ve)
491 vn = vs;
492
493 ring->list[vi - vs].x = obj->padfX[vi];
494 ring->list[vi - vs].y = obj->padfY[vi];
495 ring->list[vi - vs].z = obj->padfZ[vi];
496 ring->list[vi - vs].m = obj->padfM[vi];
497
498 area += (obj->padfX[vi] * obj->padfY[vn]) -
499 (obj->padfY[vi] * obj->padfX[vn]);
500 }
501
502 /* Close the ring with first vertex */
503 /*ring->list[vi].x = obj->padfX[vs]; */
504 /*ring->list[vi].y = obj->padfY[vs]; */
505 /*ring->list[vi].z = obj->padfZ[vs]; */
506 /*ring->list[vi].m = obj->padfM[vs]; */
507
508 /* Clockwise (or single-part). It's an Outer Ring ! */
509 if (area < 0.0 || obj->nParts == 1)
510 {
511 Outer[out_index] = ring;
512 out_index++;
513 }
514 else
515 {
516 /* Counterclockwise. It's an Inner Ring ! */
517 Inner[in_index] = ring;
518 in_index++;
519 }
520 }
521
522 LWDEBUGF(4, "FindPolygons[%d]: found %d Outer, %d Inners\n", call, out_index, in_index);
523
524 /* Put the inner rings into the list of the outer rings */
525 /* of which they are within */
526 for (pi = 0; pi < in_index; pi++)
527 {
528 Point pt, pt2;
529 int i;
530 Ring *inner = Inner[pi], *outer = NULL;
531
532 pt.x = inner->list[0].x;
533 pt.y = inner->list[0].y;
534 pt.z = 0.0;
535 pt.m = 0.0;
536
537 pt2.x = inner->list[1].x;
538 pt2.y = inner->list[1].y;
539 pt2.z = 0.0;
540 pt2.m = 0.0;
541
542 /*
543 * If we assume that the case of the "big polygon w/o hole
544 * containing little polygon w/ hold" is ordered so that the
545 * big polygon comes first, then checking the list in reverse
546 * will assign the little polygon's hole to the little polygon
547 * w/o a lot of extra fancy containment logic here
548 */
549 for (i = out_index - 1; i >= 0; i--)
550 {
551 int in;
552
553 in = PIP(pt, Outer[i]->list, Outer[i]->n);
554 if ( in || PIP(pt2, Outer[i]->list, Outer[i]->n) )
555 {
556 outer = Outer[i];
557 break;
558 }
559 }
560
561 if (outer)
562 {
563 outer->linked++;
564 while (outer->next)
565 outer = outer->next;
566
567 outer->next = inner;
568 }
569 else
570 {
571 /* The ring wasn't within any outer rings, */
572 /* assume it is a new outer ring. */
573 LWDEBUGF(4, "FindPolygons[%d]: hole %d is orphan\n", call, pi);
574
575 Outer[out_index] = inner;
576 out_index++;
577 }
578 }
579
580 *Out = Outer;
581 /*
582 * Only free the containing Inner array, not the ring elements, because
583 * the rings are now owned by the linked lists in the Outer array elements.
584 */
585 free(Inner);
586
587 return out_index;
588}
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void * malloc(YYSIZE_T)
void free(void *)
int PIP(Point P, Point *V, int n)
PIP(): crossing number test for a point in a polygon input: P = a point, V[] = vertex points of a pol...
unsigned int linked
struct struct_ring * next
double * padfX
Definition shapefil.h:390
double * padfY
Definition shapefil.h:391
double * padfZ
Definition shapefil.h:392
int * panPartStart
Definition shapefil.h:386
double * padfM
Definition shapefil.h:393

References free(), struct_ring::linked, struct_ring::list, LWDEBUGF, struct_point::m, malloc(), struct_ring::n, struct_ring::next, tagSHPObject::nParts, tagSHPObject::nVertices, tagSHPObject::padfM, tagSHPObject::padfX, tagSHPObject::padfY, tagSHPObject::padfZ, tagSHPObject::panPartStart, PIP(), struct_point::x, struct_point::y, and struct_point::z.

Referenced by GeneratePolygonGeometry().

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