OGRErr OGRSpatialReference::Validate(OGR_SRSNode *poRoot) { if( !EQUAL(poRoot->GetValue(),"GEOGCS") && !EQUAL(poRoot->GetValue(),"PROJCS") && !EQUAL(poRoot->GetValue(),"LOCAL_CS") && !EQUAL(poRoot->GetValue(),"GEOCCS") && !EQUAL(poRoot->GetValue(),"VERT_CS") && !EQUAL(poRoot->GetValue(),"COMPD_CS")) { CPLDebug( "OGRSpatialReference::Validate", "Unrecognised root node `%s'\n", poRoot->GetValue() ); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* For a COMPD_CS, validate subparameters and head & tail cs */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"COMPD_CS") ) { OGR_SRSNode *poNode; int i; for( i = 1; i < poRoot->GetChildCount(); i++ ) { poNode = poRoot->GetChild(i); if( EQUAL(poNode->GetValue(),"GEOGCS") || EQUAL(poNode->GetValue(),"PROJCS") || EQUAL(poNode->GetValue(),"LOCAL_CS") || EQUAL(poNode->GetValue(),"GEOCCS") || EQUAL(poNode->GetValue(),"VERT_CS") || EQUAL(poNode->GetValue(),"COMPD_CS") ) { OGRErr eErr = Validate(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for COMPD_CS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Validate VERT_CS */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"VERT_CS") ) { OGR_SRSNode *poNode; int i; int bGotVertDatum = FALSE; int bGotUnit = FALSE; int nCountAxis = 0; for( i = 1; i < poRoot->GetChildCount(); i++ ) { poNode = poRoot->GetChild(i); if( EQUAL(poNode->GetValue(),"VERT_DATUM") ) { OGRErr eErr = ValidateVertDatum(poNode); if (eErr != OGRERR_NONE) return eErr; bGotVertDatum = TRUE; } else if( EQUAL(poNode->GetValue(),"UNIT") ) { OGRErr eErr = ValidateUnit(poNode); if (eErr != OGRERR_NONE) return eErr; bGotUnit = TRUE; } else if( EQUAL(poNode->GetValue(),"AXIS") ) { OGRErr eErr = ValidateAxis(poNode); if (eErr != OGRERR_NONE) return eErr; nCountAxis ++; } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for VERT_CS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } if (!bGotVertDatum) { CPLDebug( "OGRSpatialReference::Validate", "No VERT_DATUM child in VERT_CS.\n" ); return OGRERR_CORRUPT_DATA; } if (!bGotUnit) { CPLDebug( "OGRSpatialReference::Validate", "No UNIT child in VERT_CS.\n" ); return OGRERR_CORRUPT_DATA; } if (nCountAxis > 1) { CPLDebug( "OGRSpatialReference::Validate", "Too many AXIS children in VERT_CS.\n" ); return OGRERR_CORRUPT_DATA; } return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* For a PROJCS, validate subparameters (other than GEOGCS). */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"PROJCS") ) { OGR_SRSNode *poNode; int i; for( i = 1; i < poRoot->GetChildCount(); i++ ) { poNode = poRoot->GetChild(i); if( EQUAL(poNode->GetValue(),"GEOGCS") ) { /* validated elsewhere */ } else if( EQUAL(poNode->GetValue(),"UNIT") ) { OGRErr eErr = ValidateUnit(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"PARAMETER") ) { if( poNode->GetChildCount() != 2 ) { CPLDebug( "OGRSpatialReference::Validate", "PARAMETER has wrong number of children (%d)," "not 2 as expected.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } else if( CSLFindString( (char **)papszParameters, poNode->GetChild(0)->GetValue()) == -1) { CPLDebug( "OGRSpatialReference::Validate", "Unrecognised PARAMETER `%s'.\n", poNode->GetChild(0)->GetValue() ); return OGRERR_UNSUPPORTED_SRS; } } else if( EQUAL(poNode->GetValue(),"PROJECTION") ) { if( poNode->GetChildCount() != 1 && poNode->GetChildCount() != 2 ) { CPLDebug( "OGRSpatialReference::Validate", "PROJECTION has wrong number of children (%d)," "not 1 or 2 as expected.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } else if( CSLFindString( (char **)papszProjectionSupported, poNode->GetChild(0)->GetValue()) == -1 && CSLFindString( (char **)papszProjectionUnsupported, poNode->GetChild(0)->GetValue()) == -1) { CPLDebug( "OGRSpatialReference::Validate", "Unrecognised PROJECTION `%s'.\n", poNode->GetChild(0)->GetValue() ); return OGRERR_UNSUPPORTED_SRS; } else if( CSLFindString( (char **)papszProjectionSupported, poNode->GetChild(0)->GetValue()) == -1) { CPLDebug( "OGRSpatialReference::Validate", "Unsupported, but recognised PROJECTION `%s'.\n", poNode->GetChild(0)->GetValue() ); return OGRERR_UNSUPPORTED_SRS; } if (poNode->GetChildCount() == 2) { poNode = poNode->GetChild(1); if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for PROJECTION `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AXIS") ) { OGRErr eErr = ValidateAxis(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"EXTENSION") ) { // We do not try to control the sub-organization of // EXTENSION nodes. } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for PROJCS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } } /* -------------------------------------------------------------------- */ /* Validate GEOGCS if found. */ /* -------------------------------------------------------------------- */ OGR_SRSNode *poGEOGCS = poRoot->GetNode( "GEOGCS" ); if( poGEOGCS != NULL ) { OGR_SRSNode *poNode; int i; for( i = 1; i < poGEOGCS->GetChildCount(); i++ ) { poNode = poGEOGCS->GetChild(i); if( EQUAL(poNode->GetValue(),"DATUM") ) { /* validated elsewhere */ } else if( EQUAL(poNode->GetValue(),"PRIMEM") ) { if( poNode->GetChildCount() < 2 || poNode->GetChildCount() > 3 ) { CPLDebug( "OGRSpatialReference::Validate", "PRIMEM has wrong number of children (%d)," "not 2 or 3 as expected.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } } else if( EQUAL(poNode->GetValue(),"UNIT") ) { OGRErr eErr = ValidateUnit(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AXIS") ) { OGRErr eErr = ValidateAxis(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for GEOGCS `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } if( poGEOGCS->GetNode("DATUM") == NULL ) { CPLDebug( "OGRSpatialReference::Validate", "No DATUM child in GEOGCS.\n" ); return OGRERR_CORRUPT_DATA; } } /* -------------------------------------------------------------------- */ /* Validate DATUM/SPHEROID. */ /* -------------------------------------------------------------------- */ OGR_SRSNode *poDATUM = poRoot->GetNode( "DATUM" ); if( poDATUM != NULL ) { OGR_SRSNode *poSPHEROID; int bGotSpheroid = FALSE; int i; if( poDATUM->GetChildCount() == 0 ) { CPLDebug( "OGRSpatialReference::Validate", "DATUM has no children." ); return OGRERR_CORRUPT_DATA; } for( i = 1; i < poDATUM->GetChildCount(); i++ ) { OGR_SRSNode *poNode; poNode = poDATUM->GetChild(i); if( EQUAL(poNode->GetValue(),"SPHEROID") ) { poSPHEROID = poDATUM->GetChild(1); bGotSpheroid = TRUE; if( poSPHEROID->GetChildCount() != 3 && poSPHEROID->GetChildCount() != 4 ) { CPLDebug( "OGRSpatialReference::Validate", "SPHEROID has wrong number of children (%d)," "not 3 or 4 as expected.\n", poSPHEROID->GetChildCount() ); return OGRERR_CORRUPT_DATA; } else if( CPLAtof(poSPHEROID->GetChild(1)->GetValue()) == 0.0 ) { CPLDebug( "OGRSpatialReference::Validate", "SPHEROID semi-major axis is zero (%s)!\n", poSPHEROID->GetChild(1)->GetValue() ); return OGRERR_CORRUPT_DATA; } } else if( EQUAL(poNode->GetValue(),"AUTHORITY") ) { OGRErr eErr = ValidateAuthority(poNode); if (eErr != OGRERR_NONE) return eErr; } else if( EQUAL(poNode->GetValue(),"TOWGS84") ) { if( poNode->GetChildCount() != 3 && poNode->GetChildCount() != 7) { CPLDebug( "OGRSpatialReference::Validate", "TOWGS84 has wrong number of children (%d), not 3 or 7.\n", poNode->GetChildCount() ); return OGRERR_CORRUPT_DATA; } } else { CPLDebug( "OGRSpatialReference::Validate", "Unexpected child for DATUM `%s'.\n", poNode->GetValue() ); return OGRERR_CORRUPT_DATA; } } if( !bGotSpheroid ) { CPLDebug( "OGRSpatialReference::Validate", "No SPHEROID child in DATUM.\n" ); return OGRERR_CORRUPT_DATA; } } /* -------------------------------------------------------------------- */ /* If this is projected, try to validate the detailed set of */ /* parameters used for the projection. */ /* -------------------------------------------------------------------- */ OGRErr eErr; eErr = ValidateProjection(poRoot); if( eErr != OGRERR_NONE ) return eErr; /* -------------------------------------------------------------------- */ /* Final check. */ /* -------------------------------------------------------------------- */ if( EQUAL(poRoot->GetValue(),"GEOCCS") ) return OGRERR_UNSUPPORTED_SRS; return OGRERR_NONE; }
/** * \brief Validate the current PROJECTION's arguments. * * @return OGRERR_NONE if the PROJECTION's arguments validate, an error code * otherwise */ OGRErr OGRSpatialReference::ValidateProjection(OGR_SRSNode *poRoot) { OGR_SRSNode *poPROJCS = poRoot->GetNode( "PROJCS" ); if( poPROJCS == NULL ) return OGRERR_NONE; if( poPROJCS->GetNode( "PROJECTION" ) == NULL ) { CPLDebug( "OGRSpatialReference::Validate", "PROJCS does not have PROJECTION subnode." ); return OGRERR_CORRUPT_DATA; } /* -------------------------------------------------------------------- */ /* Find the matching group in the proj and parms table. */ /* -------------------------------------------------------------------- */ const char *pszProjection; int iOffset; pszProjection = poPROJCS->GetNode("PROJECTION")->GetChild(0)->GetValue(); for( iOffset = 0; papszProjWithParms[iOffset] != NULL && !EQUAL(papszProjWithParms[iOffset],pszProjection); ) { while( papszProjWithParms[iOffset] != NULL ) iOffset++; iOffset++; } if( papszProjWithParms[iOffset] == NULL ) return OGRERR_UNSUPPORTED_SRS; iOffset++; /* -------------------------------------------------------------------- */ /* Check all parameters, and verify they are in the permitted */ /* list. */ /* -------------------------------------------------------------------- */ int iNode; for( iNode = 0; iNode < poPROJCS->GetChildCount(); iNode++ ) { OGR_SRSNode *poParm = poPROJCS->GetChild(iNode); int i; const char *pszParmName; if( !EQUAL(poParm->GetValue(),"PARAMETER") ) continue; pszParmName = poParm->GetChild(0)->GetValue(); for( i = iOffset; papszProjWithParms[i] != NULL; i++ ) { if( EQUAL(papszProjWithParms[i],pszParmName) ) break; } /* This parameter is not an exact match, is it an alias? */ if( papszProjWithParms[i] == NULL ) { for( i = iOffset; papszProjWithParms[i] != NULL; i++ ) { if( IsAliasFor(papszProjWithParms[i],pszParmName) ) break; } if( papszProjWithParms[i] == NULL ) { CPLDebug( "OGRSpatialReference::Validate", "PARAMETER %s for PROJECTION %s is not permitted.", pszParmName, pszProjection ); return OGRERR_CORRUPT_DATA; } else { CPLDebug( "OGRSpatialReference::Validate", "PARAMETER %s for PROJECTION %s is an alias for %s.", pszParmName, pszProjection, papszProjWithParms[i] ); return OGRERR_CORRUPT_DATA; } } } return OGRERR_NONE; }