int OGRCircularString::IsFullCircle( double& cx, double& cy, double& square_R ) const { if( getNumPoints() == 3 && get_IsClosed() ) { const double x0 = getX(0); const double y0 = getY(0); const double x1 = getX(1); const double y1 = getY(1); cx = (x0 + x1) / 2; cy = (y0 + y1) / 2; square_R = (x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy); return TRUE; } // Full circle defined by 2 arcs? else if( getNumPoints() == 5 && get_IsClosed() ) { double R_1 = 0.0; double cx_1 = 0.0; double cy_1 = 0.0; double alpha0_1 = 0.0; double alpha1_1 = 0.0; double alpha2_1 = 0.0; double R_2 = 0.0; double cx_2 = 0.0; double cy_2 = 0.0; double alpha0_2 = 0.0; double alpha1_2 = 0.0; double alpha2_2 = 0.0; if( OGRGeometryFactory::GetCurveParmeters( getX(0), getY(0), getX(1), getY(1), getX(2), getY(2), R_1, cx_1, cy_1, alpha0_1, alpha1_1, alpha2_1) && OGRGeometryFactory::GetCurveParmeters( getX(2), getY(2), getX(3), getY(3), getX(4), getY(4), R_2, cx_2, cy_2, alpha0_2, alpha1_2, alpha2_2) && fabs(R_1-R_2) < 1e-10 && fabs(cx_1-cx_2) < 1e-10 && fabs(cy_1-cy_2) < 1e-10 && (alpha2_1 - alpha0_1) * (alpha2_2 - alpha0_2) > 0 ) { cx = cx_1; cy = cy_1; square_R = R_1 * R_1; return TRUE; } } return FALSE; }
double OGRCircularString::get_Area() const { if( IsEmpty() || !get_IsClosed() ) return 0; double cx = 0.0; double cy = 0.0; double square_R = 0.0; if( IsFullCircle(cx, cy, square_R) ) { return M_PI * square_R; } // Optimization for convex rings. if( IsConvex() ) { // Compute area of shape without the circular segments. double dfArea = get_LinearArea(); // Add the area of the spherical segments. dfArea += get_AreaOfCurveSegments(); return dfArea; } OGRLineString* poLS = CurveToLine(); const double dfArea = poLS->get_Area(); delete poLS; return dfArea; }
double OGRCompoundCurve::get_Area() const { if( IsEmpty() || !get_IsClosed() ) return 0; // Optimization for convex rings. if( IsConvex() ) { // Compute area of shape without the circular segments. OGRPointIterator* poIter = getPointIterator(); OGRLineString oLS; oLS.setNumPoints( getNumPoints() ); OGRPoint p; for( int i = 0; poIter->getNextPoint(&p); i++ ) { oLS.setPoint( i, p.getX(), p.getY() ); } double dfArea = oLS.get_Area(); delete poIter; // Add the area of the spherical segments. dfArea += get_AreaOfCurveSegments(); return dfArea; } OGRLineString* poLS = CurveToLine(); double dfArea = poLS->get_Area(); delete poLS; return dfArea; }
OGRErr OGRLinearRing::transform( OGRCoordinateTransformation *poCT ) { const bool bIsClosed = getNumPoints() > 2 && CPL_TO_BOOL(get_IsClosed()); OGRErr eErr = OGRLineString::transform(poCT); if( bIsClosed && eErr == OGRERR_NONE && !get_IsClosed() ) { CPLDebug("OGR", "Linearring is not closed after coordinate " "transformation. Forcing last point to be identical to " "first one"); // Force last point to be identical to first point. // This is a safety belt in case the reprojection of the same coordinate // isn't perfectly stable. This can for example happen in very rare cases // when reprojecting a cutline with a RPC transform with a DEM that // is a VRT whose sources are resampled... OGRPoint oStartPoint; StartPoint( &oStartPoint ); setPoint( getNumPoints()-1, &oStartPoint); } return eErr; }