Changeset 14765

Show
Ignore:
Timestamp:
06/24/08 17:59:05 (2 months ago)
Author:
rouault
Message:

Add possibility of defining OGR_ORGANIZE_POLYGONS=SKIP/ONLY_CCW to speed up (or skip) organizePolygons() in case the number of polygons is huge (#2428)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.5/gdal/ogr/ogrgeometryfactory.cpp

    r14734 r14765  
    733733 * In that case, a slower algorithm that tests exact topological relationships  
    734734 * is used if GEOS is available.) 
    735  *  
     735 * 
     736 * In cases where a big number of polygons is passed to this function, the processing 
     737 * may be really slow. You can skip the processing by setting OGR_ORGANIZE_POLYGONS=SKIP 
     738 * (the result of the function will be a multi-polygon with all polygons as toplevel polygons) 
     739 * or only make it analyze counter-clock wise polygons by setting OGR_ORGANIZE_POLYGONS=ONLY_CCW 
     740 * if you can assume that the outline of holes is counter-clock wise defined. 
     741 * 
    736742 * @param papoPolygons array of geometry pointers - should all be OGRPolygons. 
    737743 * Ownership of the geometries is passed, but not of the array itself. 
     
    755761    OGRPolygon*     poEnclosingPolygon; 
    756762    double          dfArea; 
     763    int             bIsCW; 
    757764}; 
    758765 
     
    781788} 
    782789 
     790#define N_CRITICAL_PART_NUMBER   100 
    783791 
    784792OGRGeometry* OGRGeometryFactory::organizePolygons( OGRGeometry **papoPolygons, 
     
    832840    int bMixedUpGeometries = FALSE; 
    833841    int bNonPolygon = FALSE; 
     842    int bFoundCCW = FALSE; 
     843    int bOrganisePolygonSkip = FALSE; 
     844    int bOrganisePolygonOnlyCCW = FALSE; 
     845 
     846    if (nPolygonCount > N_CRITICAL_PART_NUMBER) 
     847    { 
     848        bOrganisePolygonSkip = EQUAL(CPLGetConfigOption("OGR_ORGANIZE_POLYGONS", "DEFAULT"), "SKIP"); 
     849        bOrganisePolygonOnlyCCW = EQUAL(CPLGetConfigOption("OGR_ORGANIZE_POLYGONS", "DEFAULT"), "ONLY_CCW"); 
     850        if (bOrganisePolygonSkip) 
     851        { 
     852            bMixedUpGeometries = TRUE; 
     853        } 
     854    } 
     855 
    834856 
    835857    for(i=0;i<nPolygonCount;i++) 
     
    846868            asPolyEx[i].poExteriorRing = asPolyEx[i].poPolygon->getExteriorRing(); 
    847869            asPolyEx[i].poExteriorRing->getPoint(0, &asPolyEx[i].poAPoint); 
     870            asPolyEx[i].bIsCW = asPolyEx[i].poExteriorRing->isClockwise(); 
     871            if (!bFoundCCW) 
     872                bFoundCCW = ! (asPolyEx[i].bIsCW); 
    848873        } 
    849874        else 
     
    863888    } 
    864889 
     890    /* Emits a warning if the number of parts is sufficiently big to anticipate for */ 
     891    /* very long computation time */ 
     892    if (nPolygonCount > N_CRITICAL_PART_NUMBER && 
     893        !bOrganisePolygonSkip && !bOrganisePolygonOnlyCCW) 
     894    { 
     895        static int firstTime = 1; 
     896        if (firstTime) 
     897        { 
     898            if (bFoundCCW) 
     899            { 
     900                CPLError( CE_Warning, CPLE_AppDefined,  
     901                     "organizePolygons() received a polygon with more than %d parts. " 
     902                     "The processing may be really slow.\n" 
     903                     "You can skip the processing by setting OGR_ORGANIZE_POLYGONS=SKIP, " 
     904                     "or only make it analyze counter-clock wise parts by setting " 
     905                     "OGR_ORGANIZE_POLYGONS=ONLY_CCW if you can assume that the " 
     906                     "outline of holes is counter-clock wise defined", N_CRITICAL_PART_NUMBER); 
     907            } 
     908            else 
     909            { 
     910                CPLError( CE_Warning, CPLE_AppDefined,  
     911                        "organizePolygons() received a polygon with more than %d parts. " 
     912                        "The processing may be really slow.\n" 
     913                        "You can skip the processing by setting OGR_ORGANIZE_POLYGONS=SKIP.", 
     914                        N_CRITICAL_PART_NUMBER); 
     915            } 
     916            firstTime = 0; 
     917        } 
     918    } 
     919 
    865920 
    866921    /* This a several steps algorithm : 
     
    913968    for(i=1; !bMixedUpGeometries && go_on && i<nPolygonCount; i++) 
    914969    { 
     970        if (bOrganisePolygonOnlyCCW && asPolyEx[i].bIsCW) 
     971        { 
     972            nCountTopLevel ++; 
     973            asPolyEx[i].bIsTopLevel = TRUE; 
     974            asPolyEx[i].poEnclosingPolygon = NULL; 
     975            continue; 
     976        } 
     977 
    915978        for(j=i-1; go_on && j>=0;j--) 
    916979        {