Changeset 19398


Ignore:
Timestamp:
Apr 13, 2010 11:34:32 AM (6 years ago)
Author:
rouault
Message:

Move Centroid() method from OGRPolygon to OGRGeometry base class to be able to operate on various geometry types, and to be consistant with PostGIS ST_Centroid() capabilities and the underlying GEOS method

Location:
trunk/gdal
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/gdal/ogr/ogr_geometry.h

    r18913 r19398  
    6060/*                             OGRGeometry                              */
    6161/************************************************************************/
     62
     63class OGRPoint;
    6264
    6365/**
     
    148150    virtual OGRGeometry *Difference( const OGRGeometry * ) const;
    149151    virtual OGRGeometry *SymmetricDifference( const OGRGeometry * ) const;
     152    virtual OGRErr       Centroid( OGRPoint * poPoint ) const;
    150153
    151154    // backward compatibility methods.
     
    383386  public:
    384387    virtual double      get_Area() const = 0;
    385     virtual OGRErr      Centroid( OGRPoint * poPoint ) const = 0;
    386388    virtual OGRErr      PointOnSurface( OGRPoint * poPoint ) const = 0;
    387389};
     
    421423    // ISurface Interface
    422424    virtual double      get_Area() const;
    423     virtual int         Centroid( OGRPoint * poPoint ) const;
    424425    virtual int         PointOnSurface( OGRPoint * poPoint ) const;
    425426   
  • trunk/gdal/ogr/ogrgeometry.cpp

    r17010 r19398  
    30813081    ((OGRGeometry *) hGeom)->closeRings();
    30823082}
     3083
     3084/************************************************************************/
     3085/*                              Centroid()                              */
     3086/************************************************************************/
     3087
     3088/**
     3089 * \brief Compute the geometry centroid.
     3090 *
     3091 * The centroid location is applied to the passed in OGRPoint object.
     3092 * The centroid is not necessarily within the geometry. 
     3093 *
     3094 * This method relates to the SFCOM ISurface::get_Centroid() method
     3095 * however the current implementation based on GEOS can operate on other
     3096 * geometry types such as multipoint, linestring, geometrycollection such as
     3097 * multipolygons.
     3098 * OGC SF SQL 1.1 defines the operation for surfaces (polygons).
     3099 * SQL/MM-Part 3 defines the operation for surfaces and multisurfaces (multipolygons).
     3100 *
     3101 * This function is the same as the C function OGR_G_Centroid().
     3102 *
     3103 * This function is built on the GEOS library, check it for the definition
     3104 * of the geometry operation.
     3105 * If OGR is built without the GEOS library, this function will always fail,
     3106 * issuing a CPLE_NotSupported error.
     3107 *
     3108 * @return OGRERR_NONE on success or OGRERR_FAILURE on error.
     3109 *
     3110 * @since GDAL 1.8.0 as a OGRGeometry method (previously was restricted to OGRPolygon)
     3111 */
     3112
     3113int OGRGeometry::Centroid( OGRPoint *poPoint ) const
     3114
     3115{
     3116    if( poPoint == NULL )
     3117        return OGRERR_FAILURE;
     3118
     3119#ifndef HAVE_GEOS
     3120    // notdef ... not implemented yet.
     3121    CPLError( CE_Failure, CPLE_NotSupported,
     3122              "GEOS support not enabled." );
     3123    return OGRERR_FAILURE;
     3124
     3125#else
     3126
     3127    GEOSGeom hThisGeosGeom = NULL;
     3128    GEOSGeom hOtherGeosGeom = NULL;
     3129   
     3130    hThisGeosGeom = exportToGEOS();
     3131
     3132    if( hThisGeosGeom != NULL )
     3133    {
     3134        hOtherGeosGeom = GEOSGetCentroid( hThisGeosGeom );
     3135        GEOSGeom_destroy( hThisGeosGeom );
     3136
     3137        if( hOtherGeosGeom == NULL )
     3138            return OGRERR_FAILURE;
     3139
     3140        OGRPoint *poCentroid = (OGRPoint *)
     3141            OGRGeometryFactory::createFromGEOS( hOtherGeosGeom );
     3142
     3143        GEOSGeom_destroy( hOtherGeosGeom );
     3144
     3145        if (poCentroid == NULL)
     3146            return OGRERR_FAILURE;
     3147
     3148        poPoint->setX( poCentroid->getX() );
     3149        poPoint->setY( poCentroid->getY() );
     3150
     3151        delete poCentroid;
     3152
     3153        return OGRERR_NONE;
     3154    }
     3155    else
     3156    {
     3157        return OGRERR_FAILURE;
     3158    }
     3159
     3160#endif /* HAVE_GEOS */
     3161}
     3162
     3163/************************************************************************/
     3164/*                           OGR_G_Centroid()                           */
     3165/************************************************************************/
     3166
     3167/**
     3168 * \brief Compute the geometry centroid.
     3169 *
     3170 * The centroid location is applied to the passed in OGRPoint object.
     3171 * The centroid is not necessarily within the geometry. 
     3172 *
     3173 * This method relates to the SFCOM ISurface::get_Centroid() method
     3174 * however the current implementation based on GEOS can operate on other
     3175 * geometry types such as multipoint, linestring, geometrycollection such as
     3176 * multipolygons.
     3177 * OGC SF SQL 1.1 defines the operation for surfaces (polygons).
     3178 * SQL/MM-Part 3 defines the operation for surfaces and multisurfaces (multipolygons).
     3179 *
     3180 * This function is the same as the C++ method OGRGeometry::Centroid().
     3181 *
     3182 * This function is built on the GEOS library, check it for the definition
     3183 * of the geometry operation.
     3184 * If OGR is built without the GEOS library, this function will always fail,
     3185 * issuing a CPLE_NotSupported error.
     3186 *
     3187 * @return OGRERR_NONE on success or OGRERR_FAILURE on error.
     3188 */
     3189
     3190int OGR_G_Centroid( OGRGeometryH hGeom, OGRGeometryH hCentroidPoint )
     3191
     3192{
     3193    VALIDATE_POINTER1( hGeom, "OGR_G_Centroid", OGRERR_FAILURE );
     3194
     3195    OGRGeometry *poGeom = ((OGRGeometry *) hGeom);
     3196    OGRPoint *poCentroid = ((OGRPoint *) hCentroidPoint);
     3197   
     3198    if( poCentroid == NULL )
     3199        return OGRERR_FAILURE;
     3200
     3201    if( wkbFlatten(poCentroid->getGeometryType()) != wkbPoint )
     3202    {
     3203        CPLError( CE_Failure, CPLE_AppDefined,
     3204                  "Passed wrong geometry type as centroid argument." );
     3205        return OGRERR_FAILURE;
     3206    }
     3207
     3208    return poGeom->Centroid( poCentroid );
     3209}
  • trunk/gdal/ogr/ogrpolygon.cpp

    r19088 r19398  
    811811    return eErr;
    812812}
    813 
    814 /************************************************************************/
    815 /*                              Centroid()                              */
    816 /************************************************************************/
    817 
    818 /**
    819  * \brief Compute the polygon centroid.
    820  *
    821  * The centroid location is applied to the passed in OGRPoint object.
    822  *
    823  * @return OGRERR_NONE on success or OGRERR_FAILURE on error.
    824  */
    825 
    826 int OGRPolygon::Centroid( OGRPoint *poPoint ) const
    827 
    828 {
    829     if( poPoint == NULL )
    830         return OGRERR_FAILURE;
    831 
    832 #ifndef HAVE_GEOS
    833     // notdef ... not implemented yet.
    834    
    835     return OGRERR_FAILURE;
    836 
    837 #else
    838 
    839     GEOSGeom hThisGeosGeom = NULL;
    840     GEOSGeom hOtherGeosGeom = NULL;
    841    
    842     hThisGeosGeom = exportToGEOS();
    843 
    844     if( hThisGeosGeom != NULL )
    845     {
    846         hOtherGeosGeom = GEOSGetCentroid( hThisGeosGeom );
    847         GEOSGeom_destroy( hThisGeosGeom );
    848 
    849         if( hOtherGeosGeom == NULL )
    850             return OGRERR_FAILURE;
    851 
    852         OGRPoint *poCentroid = (OGRPoint *)
    853             OGRGeometryFactory::createFromGEOS( hOtherGeosGeom );
    854 
    855         GEOSGeom_destroy( hOtherGeosGeom );
    856 
    857         if( poPoint == NULL
    858             || wkbFlatten(poPoint->getGeometryType()) != wkbPoint )
    859             return OGRERR_FAILURE;
    860 
    861         poPoint->setX( poCentroid->getX() );
    862         poPoint->setY( poCentroid->getY() );
    863 
    864         delete poCentroid;
    865 
    866         return OGRERR_NONE;
    867     }
    868     else
    869     {
    870         return OGRERR_FAILURE;
    871     }
    872 
    873 #endif /* HAVE_GEOS */
    874 }
    875 
    876 /************************************************************************/
    877 /*                           OGR_G_Centroid()                           */
    878 /************************************************************************/
    879 
    880 int OGR_G_Centroid( OGRGeometryH hPolygon, OGRGeometryH hCentroidPoint )
    881 
    882 {
    883     OGRPolygon *poPoly = ((OGRPolygon *) hPolygon);
    884     OGRPoint *poCentroid = ((OGRPoint *) hCentroidPoint);
    885    
    886     if( poCentroid == NULL )
    887         return OGRERR_FAILURE;
    888 
    889     if( wkbFlatten(poCentroid->getGeometryType()) != wkbPoint )
    890     {
    891         CPLError( CE_Failure, CPLE_AppDefined,
    892                   "Passed wrong geometry type as centroid argument." );
    893         return OGRERR_FAILURE;
    894     }
    895 
    896     if( wkbFlatten(poPoly->getGeometryType()) != wkbPolygon )
    897     {
    898         CPLError( CE_Failure, CPLE_AppDefined,
    899                   "Invoked Centroid() on non-Polygon." );
    900         return OGRERR_FAILURE;
    901     }
    902                            
    903     return poPoly->Centroid( poCentroid );
    904 }
    905 
    906813
    907814/************************************************************************/
  • trunk/gdal/swig/java/javadoc.java

    r19391 r19398  
    75177517
    75187518/**
    7519  * Compute and return centroid of surface.  The centroid is not necessarily
    7520  * within the geometry. 
    7521  * <p>
    7522  * This method relates to the SFCOM ISurface::get_Centroid() method.
    7523  * <p>
    7524  * NOTE: Only implemented when GEOS included in build.
     7519 * Compute the geometry centroid.
     7520 *
     7521 * The centroid is not necessarily within the geometry. 
     7522 * <p>
     7523 * This method relates to the SFCOM ISurface::get_Centroid() method
     7524 * however the current implementation based on GEOS can operate on other
     7525 * geometry types such as multipoint, linestring, geometrycollection such as
     7526 * multipolygons.
     7527 * OGC SF SQL 1.1 defines the operation for surfaces (polygons).
     7528 * SQL/MM-Part 3 defines the operation for surfaces and multisurfaces (multipolygons).
     7529 * <p>
     7530 * This function is built on the GEOS library, check it for the definition
     7531 * of the geometry operation.
     7532 * If OGR is built without the GEOS library, this function will always fail,
     7533 * issuing a CPLE_NotSupported error.
    75257534 *
    75267535 * @return point with the centroid location, or null in case of failure
Note: See TracChangeset for help on using the changeset viewer.