OGRErr OGR_G_AddGeometryDirectly( OGRGeometryH hGeom, OGRGeometryH hNewSubGeom ) { VALIDATE_POINTER1( hGeom, "OGR_G_AddGeometryDirectly", OGRERR_UNSUPPORTED_OPERATION ); VALIDATE_POINTER1( hNewSubGeom, "OGR_G_AddGeometryDirectly", OGRERR_UNSUPPORTED_OPERATION ); OGRErr eErr = OGRERR_UNSUPPORTED_GEOMETRY_TYPE; OGRwkbGeometryType eType = wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()); if( OGR_GT_IsSubClassOf(eType, wkbCurvePolygon) ) { if( OGR_GT_IsCurve( wkbFlatten(((OGRGeometry *) hNewSubGeom)->getGeometryType()) ) ) eErr = ((OGRCurvePolygon *)hGeom)->addRingDirectly( (OGRCurve *) hNewSubGeom ); } else if( OGR_GT_IsSubClassOf(eType, wkbCompoundCurve) ) { if( OGR_GT_IsCurve( wkbFlatten(((OGRGeometry *) hNewSubGeom)->getGeometryType()) ) ) eErr = ((OGRCompoundCurve *)hGeom)->addCurveDirectly( (OGRCurve *) hNewSubGeom ); } else if( OGR_GT_IsSubClassOf(eType, wkbGeometryCollection) ) { eErr = ((OGRGeometryCollection *)hGeom)->addGeometryDirectly( (OGRGeometry *) hNewSubGeom ); } if( eErr != OGRERR_NONE ) delete (OGRGeometry*)hNewSubGeom; return eErr; }
OGRGeometryH OGR_G_GetGeometryRef( OGRGeometryH hGeom, int iSubGeom ) { VALIDATE_POINTER1( hGeom, "OGR_G_GetGeometryRef", NULL ); OGRwkbGeometryType eType = wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()); if( OGR_GT_IsSubClassOf(eType, wkbCurvePolygon) ) { if( iSubGeom == 0 ) return (OGRGeometryH) ((OGRCurvePolygon *)hGeom)->getExteriorRingCurve(); else return (OGRGeometryH) ((OGRCurvePolygon *)hGeom)->getInteriorRingCurve(iSubGeom-1); } else if( OGR_GT_IsSubClassOf(eType, wkbCompoundCurve) ) return (OGRGeometryH) ((OGRCompoundCurve *)hGeom)->getCurve(iSubGeom); else if( OGR_GT_IsSubClassOf(eType, wkbGeometryCollection) ) return (OGRGeometryH) ((OGRGeometryCollection *)hGeom)->getGeometryRef( iSubGeom ); else { CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation"); return 0; } }
double OGRGeometryCollection::get_Area() const { double dfArea = 0.0; for( auto&& poSubGeom: *this ) { OGRwkbGeometryType eType = wkbFlatten(poSubGeom->getGeometryType()); if( OGR_GT_IsSurface(eType) ) { const OGRSurface *poSurface = poSubGeom->toSurface(); dfArea += poSurface->get_Area(); } else if( OGR_GT_IsCurve(eType) ) { const OGRCurve *poCurve = poSubGeom->toCurve(); dfArea += poCurve->get_Area(); } else if( OGR_GT_IsSubClassOf(eType, wkbMultiSurface) || eType == wkbGeometryCollection ) { dfArea += poSubGeom->toGeometryCollection()->get_Area(); } } return dfArea; }
double OGR_G_Area( OGRGeometryH hGeom ) { VALIDATE_POINTER1( hGeom, "OGR_G_Area", 0 ); double dfArea; OGRwkbGeometryType eType = wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()); if( OGR_GT_IsSurface(eType) ) { dfArea = ((OGRSurface *) hGeom)->get_Area(); } else if( OGR_GT_IsCurve(eType) ) { dfArea = ((OGRCurve *) hGeom)->get_Area(); } else if( OGR_GT_IsSubClassOf(eType, wkbMultiSurface) || eType == wkbGeometryCollection ) { dfArea = ((OGRGeometryCollection *) hGeom)->get_Area(); } else { CPLError( CE_Warning, CPLE_AppDefined, "OGR_G_Area() called against non-surface geometry type." ); dfArea = 0.0; } return dfArea; }
double OGR_G_Length( OGRGeometryH hGeom ) { VALIDATE_POINTER1( hGeom, "OGR_G_GetLength", 0 ); double dfLength; OGRwkbGeometryType eType = wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()); if( OGR_GT_IsCurve(eType) ) { dfLength = ((OGRCurve *) hGeom)->get_Length(); } else if( OGR_GT_IsSubClassOf(eType, wkbMultiCurve) || eType == wkbGeometryCollection ) { dfLength = ((OGRGeometryCollection *) hGeom)->get_Length(); } else { CPLError( CE_Warning, CPLE_AppDefined, "OGR_G_Length() called against a non-curve geometry type." ); dfLength = 0.0; } return dfLength; }
OGRErr OGR_G_RemoveGeometry( OGRGeometryH hGeom, int iGeom, int bDelete ) { VALIDATE_POINTER1( hGeom, "OGR_G_RemoveGeometry", 0 ); OGRwkbGeometryType eType = wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()); if( OGR_GT_IsSubClassOf(eType, wkbCurvePolygon) ) { CPLError( CE_Failure, CPLE_AppDefined, "OGR_G_RemoveGeometry() not supported on polygons yet." ); return OGRERR_UNSUPPORTED_OPERATION; } else if( OGR_GT_IsSubClassOf(eType, wkbGeometryCollection) ) { return ((OGRGeometryCollection *)hGeom)->removeGeometry( iGeom,bDelete); } else { return OGRERR_UNSUPPORTED_OPERATION; } }
void OGRGeometryCollection::closeRings() { for( auto&& poSubGeom: *this ) { if( OGR_GT_IsSubClassOf( wkbFlatten(poSubGeom->getGeometryType()), wkbCurvePolygon ) ) { OGRCurvePolygon *poPoly = poSubGeom->toCurvePolygon(); poPoly->closeRings(); } } }
int OGR_G_GetGeometryCount( OGRGeometryH hGeom ) { VALIDATE_POINTER1( hGeom, "OGR_G_GetGeometryCount", 0 ); OGRwkbGeometryType eType = wkbFlatten(((OGRGeometry *) hGeom)->getGeometryType()); if( OGR_GT_IsSubClassOf(eType, wkbCurvePolygon) ) { if( ((OGRCurvePolygon *)hGeom)->getExteriorRingCurve() == NULL ) return 0; else return ((OGRCurvePolygon *)hGeom)->getNumInteriorRings() + 1; } else if( OGR_GT_IsSubClassOf(eType, wkbCompoundCurve) ) return ((OGRCompoundCurve *)hGeom)->getNumCurves(); else if( OGR_GT_IsSubClassOf(eType, wkbGeometryCollection) ) return ((OGRGeometryCollection *)hGeom)->getNumGeometries(); else { // autotest/pymod/ogrtest.py calls this method on any geometry. So keep silent //CPLError(CE_Failure, CPLE_NotSupported, "Incompatible geometry for operation"); return 0; } }
double OGRGeometryCollection::get_Length() const { double dfLength = 0.0; for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { OGRGeometry* geom = papoGeoms[iGeom]; OGRwkbGeometryType eType = wkbFlatten(geom->getGeometryType()); if( OGR_GT_IsCurve(eType) ) { dfLength += ((OGRCurve *) geom)->get_Length(); } else if( OGR_GT_IsSubClassOf(eType, wkbMultiCurve) || eType == wkbGeometryCollection ) { dfLength += ((OGRGeometryCollection *) geom)->get_Length(); } } return dfLength; }
double OGRGeometryCollection::get_Length() const { double dfLength = 0.0; for( auto&& poSubGeom: *this ) { const OGRwkbGeometryType eType = wkbFlatten(poSubGeom->getGeometryType()); if( OGR_GT_IsCurve(eType) ) { const OGRCurve *poCurve = poSubGeom->toCurve(); dfLength += poCurve->get_Length(); } else if( OGR_GT_IsSubClassOf(eType, wkbMultiCurve) || eType == wkbGeometryCollection ) { const OGRGeometryCollection *poColl = poSubGeom->toGeometryCollection(); dfLength += poColl->get_Length(); } } return dfLength; }
OGRErr OGRGeometryCollection::importFromWkbInternal( const unsigned char * pabyData, int nSize, int nRecLevel, OGRwkbVariant eWkbVariant, int& nBytesConsumedOut ) { nBytesConsumedOut = -1; // Arbitrary value, but certainly large enough for reasonable use cases. if( nRecLevel == 32 ) { CPLError( CE_Failure, CPLE_AppDefined, "Too many recursion levels (%d) while parsing WKB geometry.", nRecLevel ); return OGRERR_CORRUPT_DATA; } nGeomCount = 0; OGRwkbByteOrder eByteOrder = wkbXDR; int nDataOffset = 0; OGRErr eErr = importPreambleOfCollectionFromWkb( pabyData, nSize, nDataOffset, eByteOrder, 9, nGeomCount, eWkbVariant ); if( eErr != OGRERR_NONE ) return eErr; // coverity[tainted_data] papoGeoms = static_cast<OGRGeometry **>( VSI_CALLOC_VERBOSE(sizeof(void*), nGeomCount)); if( nGeomCount != 0 && papoGeoms == nullptr ) { nGeomCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { // Parses sub-geometry. const unsigned char* pabySubData = pabyData + nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; OGRwkbGeometryType eSubGeomType = wkbUnknown; eErr = OGRReadWKBGeometryType( pabySubData, eWkbVariant, &eSubGeomType ); if( eErr != OGRERR_NONE ) return eErr; if( !isCompatibleSubType(eSubGeomType) ) { nGeomCount = iGeom; CPLDebug( "OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, getGeometryType()); return OGRERR_CORRUPT_DATA; } OGRGeometry* poSubGeom = nullptr; int nSubGeomBytesConsumed = -1; if( OGR_GT_IsSubClassOf(eSubGeomType, wkbGeometryCollection) ) { poSubGeom = OGRGeometryFactory::createGeometry( eSubGeomType ); if( poSubGeom == nullptr ) eErr = OGRERR_FAILURE; else eErr = poSubGeom->toGeometryCollection()-> importFromWkbInternal( pabySubData, nSize, nRecLevel + 1, eWkbVariant, nSubGeomBytesConsumed ); } else { eErr = OGRGeometryFactory:: createFromWkb( pabySubData, nullptr, &poSubGeom, nSize, eWkbVariant, nSubGeomBytesConsumed ); } if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; delete poSubGeom; return eErr; } papoGeoms[iGeom] = poSubGeom; if( papoGeoms[iGeom]->Is3D() ) flags |= OGR_G_3D; if( papoGeoms[iGeom]->IsMeasured() ) flags |= OGR_G_MEASURED; CPLAssert( nSubGeomBytesConsumed > 0 ); if( nSize != -1 ) { CPLAssert( nSize >= nSubGeomBytesConsumed ); nSize -= nSubGeomBytesConsumed; } nDataOffset += nSubGeomBytesConsumed; } nBytesConsumedOut = nDataOffset; return OGRERR_NONE; }