int OGROCIDataSource::Open( const char * pszNewName, char** papszOpenOptionsIn, int bUpdate, int bTestOpen ) { CPLAssert( nLayers == 0 && poSession == NULL ); /* -------------------------------------------------------------------- */ /* Verify Oracle prefix. */ /* -------------------------------------------------------------------- */ if( !STARTS_WITH_CI(pszNewName,"OCI:") ) { if( !bTestOpen ) { CPLError( CE_Failure, CPLE_AppDefined, "%s does not conform to Oracle OCI driver naming convention," " OCI:*\n", pszNewName ); } return FALSE; } /* -------------------------------------------------------------------- */ /* Try to parse out name, password and database name. */ /* -------------------------------------------------------------------- */ char *pszUserid; const char *pszPassword = ""; const char *pszDatabase = ""; char **papszTableList = NULL; const char *pszWorkspace = ""; int i; if( pszNewName[4] == '\0' ) { pszUserid = CPLStrdup(CSLFetchNameValueDef(papszOpenOptionsIn, "USER", "")); pszPassword = CSLFetchNameValueDef(papszOpenOptionsIn, "PASSWORD", ""); pszDatabase = CSLFetchNameValueDef(papszOpenOptionsIn, "DBNAME", ""); const char* pszTables = CSLFetchNameValue(papszOpenOptionsIn, "TABLES"); if( pszTables ) papszTableList = CSLTokenizeStringComplex(pszTables, ",", TRUE, FALSE ); pszWorkspace = CSLFetchNameValueDef(papszOpenOptions, "WORKSPACE", ""); } else { pszUserid = CPLStrdup( pszNewName + 4 ); // Is there a table list? for( i = static_cast<int>(strlen(pszUserid))-1; i > 1; i-- ) { if( pszUserid[i] == ':' ) { papszTableList = CSLTokenizeStringComplex( pszUserid+i+1, ",", TRUE, FALSE ); pszUserid[i] = '\0'; break; } if( pszUserid[i] == '/' || pszUserid[i] == '@' ) break; } for( i = 0; pszUserid[i] != '\0' && pszUserid[i] != '/' && pszUserid[i] != '@'; i++ ) {} if( pszUserid[i] == '/' ) { pszUserid[i++] = '\0'; pszPassword = pszUserid + i; for( ; pszUserid[i] != '\0' && pszUserid[i] != '@'; i++ ) {} } if( pszUserid[i] == '@' ) { pszUserid[i++] = '\0'; pszDatabase = pszUserid + i; } } /* -------------------------------------------------------------------- */ /* Try to establish connection. */ /* -------------------------------------------------------------------- */ CPLDebug( "OCI", "Userid=%s, Password=%s, Database=%s", pszUserid, pszPassword, pszDatabase ); if( EQUAL(pszDatabase, "") && EQUAL(pszPassword, "") && EQUAL(pszUserid, "") ) { /* Use username/password OS Authentication and ORACLE_SID database */ poSession = OGRGetOCISession( "/", "", "" ); } else { poSession = OGRGetOCISession( pszUserid, pszPassword, pszDatabase ); } if( poSession == NULL ) { CPLFree(pszUserid); CSLDestroy(papszTableList); return FALSE; } if( ! EQUAL(pszWorkspace, "") ) { OGROCIStringBuf oValidateCmd; OGROCIStatement oValidateStmt( GetSession() ); oValidateCmd.Append( "call DBMS_WM.GotoWorkspace('" ); oValidateCmd.Append( pszWorkspace ); oValidateCmd.Append( "')" ); oValidateStmt.Execute( oValidateCmd.GetString() ); } pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate; /* -------------------------------------------------------------------- */ /* If no list of target tables was provided, collect a list of */ /* spatial tables now. */ /* -------------------------------------------------------------------- */ if( papszTableList == NULL ) { OGROCIStatement oGetTables( poSession ); if( oGetTables.Execute( "SELECT TABLE_NAME, OWNER FROM ALL_SDO_GEOM_METADATA" ) == CE_None ) { char **papszRow; while( (papszRow = oGetTables.SimpleFetchRow()) != NULL ) { char szFullTableName[100]; if( EQUAL(papszRow[1],pszUserid) ) strcpy( szFullTableName, papszRow[0] ); else snprintf( szFullTableName, sizeof(szFullTableName), "%s.%s", papszRow[1], papszRow[0] ); if( CSLFindString( papszTableList, szFullTableName ) == -1 ) papszTableList = CSLAddString( papszTableList, szFullTableName ); } } } CPLFree( pszUserid ); /* -------------------------------------------------------------------- */ /* Open all the selected tables or views. */ /* -------------------------------------------------------------------- */ for( i = 0; papszTableList != NULL && papszTableList[i] != NULL; i++ ) { OpenTable( papszTableList[i], -1, bUpdate, FALSE, papszOpenOptionsIn ); } CSLDestroy( papszTableList ); return TRUE; }
int OGROCIDataSource::FetchSRSId( OGRSpatialReference * poSRS ) { char *pszWKT = NULL; int nSRSId; if( poSRS == NULL ) return -1; if( !poSRS->IsProjected() && !poSRS->IsGeographic() ) return -1; /* ==================================================================== */ /* The first strategy is to see if we can identify it by */ /* authority information within the SRS. Either using ORACLE */ /* authority values directly, or check if there is a known */ /* translation for an EPSG authority code. */ /* ==================================================================== */ const char *pszAuthName = NULL, *pszAuthCode = NULL; if( poSRS->IsGeographic() ) { pszAuthName = poSRS->GetAuthorityName( "GEOGCS" ); pszAuthCode = poSRS->GetAuthorityCode( "GEOGCS" ); } else if( poSRS->IsProjected() ) { pszAuthName = poSRS->GetAuthorityName( "PROJCS" ); pszAuthCode = poSRS->GetAuthorityCode( "PROJCS" ); } if( pszAuthName != NULL && pszAuthCode != NULL ) { if( EQUAL(pszAuthName,"Oracle") && atoi(pszAuthCode) != 0 ) return atoi(pszAuthCode); if( EQUAL(pszAuthName,"EPSG") ) { int i, nEPSGCode = atoi(pszAuthCode); for( i = 0; anEPSGOracleMapping[i] != 0; i += 2 ) { if( nEPSGCode == anEPSGOracleMapping[i+1] ) return anEPSGOracleMapping[i]; } } } /* ==================================================================== */ /* We need to lookup the SRS in the existing Oracle CS_SRS */ /* table. */ /* ==================================================================== */ /* -------------------------------------------------------------------- */ /* Convert SRS into old style format (SF-SQL 1.0). */ /* -------------------------------------------------------------------- */ OGRSpatialReference *poSRS2 = poSRS->Clone(); poSRS2->StripCTParms(); /* -------------------------------------------------------------------- */ /* Convert any degree type unit names to "Decimal Degree". */ /* -------------------------------------------------------------------- */ double dfAngularUnits = poSRS2->GetAngularUnits( NULL ); if( fabs(dfAngularUnits - 0.0174532925199433) < 0.0000000000000010 ) poSRS2->SetAngularUnits( "Decimal Degree", 0.0174532925199433 ); /* -------------------------------------------------------------------- */ /* Translate SRS to WKT. */ /* -------------------------------------------------------------------- */ if( poSRS2->exportToWkt( &pszWKT ) != OGRERR_NONE ) { delete poSRS2; return -1; } delete poSRS2; /* -------------------------------------------------------------------- */ /* Try to find in the existing table. */ /* -------------------------------------------------------------------- */ OGROCIStringBuf oCmdText; OGROCIStatement oCmdStatement( GetSession() ); char **papszResult = NULL; oCmdText.Append( "SELECT SRID FROM MDSYS.CS_SRS WHERE WKTEXT = '" ); oCmdText.Append( pszWKT ); oCmdText.Append( "'" ); if( oCmdStatement.Execute( oCmdText.GetString() ) == CE_None ) papszResult = oCmdStatement.SimpleFetchRow() ; /* -------------------------------------------------------------------- */ /* We got it! Return it. */ /* -------------------------------------------------------------------- */ if( CSLCount(papszResult) == 1 ) { CPLFree( pszWKT ); return atoi( papszResult[0] ); } /* ==================================================================== */ /* We didn't find it, so we need to define it as a new SRID at */ /* the end of the list of known values. */ /* ==================================================================== */ /* -------------------------------------------------------------------- */ /* Get the current maximum srid in the srs table. */ /* -------------------------------------------------------------------- */ if( oCmdStatement.Execute("SELECT MAX(SRID) FROM MDSYS.CS_SRS") == CE_None ) papszResult = oCmdStatement.SimpleFetchRow(); else papszResult = NULL; if( CSLCount(papszResult) == 1 ) nSRSId = atoi(papszResult[0]) + 1; else nSRSId = 1; /* -------------------------------------------------------------------- */ /* Try adding the SRS to the SRS table. */ /* -------------------------------------------------------------------- */ oCmdText.Clear(); oCmdText.Append( "INSERT INTO MDSYS.CS_SRS (SRID, WKTEXT, CS_NAME) " ); oCmdText.Appendf( 100, " VALUES (%d,'", nSRSId ); oCmdText.Append( pszWKT ); oCmdText.Append( "', '" ); oCmdText.Append( poSRS->GetRoot()->GetChild(0)->GetValue() ); oCmdText.Append( "' )" ); CPLFree( pszWKT ); if( oCmdStatement.Execute( oCmdText.GetString() ) != CE_None ) return -1; else return nSRSId; }
void OGROCILoaderLayer::FinalizeNewLayer() { OGROCIStringBuf sDimUpdate; /* -------------------------------------------------------------------- */ /* If the dimensions are degenerate (all zeros) then we assume */ /* there were no geometries, and we don't bother setting the */ /* dimensions. */ /* -------------------------------------------------------------------- */ if( sExtent.MaxX == 0 && sExtent.MinX == 0 && sExtent.MaxY == 0 && sExtent.MinY == 0 ) { CPLError( CE_Warning, CPLE_AppDefined, "Layer %s appears to have no geometry ... not setting SDO DIMINFO metadata.", poFeatureDefn->GetName() ); return; } /* -------------------------------------------------------------------- */ /* Establish the extents and resolution to use. */ /* -------------------------------------------------------------------- */ double dfResSize; double dfXMin, dfXMax, dfXRes; double dfYMin, dfYMax, dfYRes; double dfZMin, dfZMax, dfZRes; if( sExtent.MaxX - sExtent.MinX > 400 ) dfResSize = 0.001; else dfResSize = 0.0000001; dfXMin = sExtent.MinX - dfResSize * 3; dfXMax = sExtent.MaxX + dfResSize * 3; dfXRes = dfResSize; ParseDIMINFO( "DIMINFO_X", &dfXMin, &dfXMax, &dfXRes ); dfYMin = sExtent.MinY - dfResSize * 3; dfYMax = sExtent.MaxY + dfResSize * 3; dfYRes = dfResSize; ParseDIMINFO( "DIMINFO_Y", &dfYMin, &dfYMax, &dfYRes ); dfZMin = -100000.0; dfZMax = 100000.0; dfZRes = 0.002; ParseDIMINFO( "DIMINFO_Z", &dfZMin, &dfZMax, &dfZRes ); /* -------------------------------------------------------------------- */ /* Prepare dimension update statement. */ /* -------------------------------------------------------------------- */ sDimUpdate.Append( "UPDATE USER_SDO_GEOM_METADATA SET DIMINFO = " ); sDimUpdate.Append( "MDSYS.SDO_DIM_ARRAY(" ); sDimUpdate.Appendf(200, "MDSYS.SDO_DIM_ELEMENT('X',%.16g,%.16g,%.12g)", dfXMin, dfXMax, dfXRes ); sDimUpdate.Appendf(200, ",MDSYS.SDO_DIM_ELEMENT('Y',%.16g,%.16g,%.12g)", dfYMin, dfYMax, dfYRes ); if( nDimension == 3 ) { sDimUpdate.Appendf(200, ",MDSYS.SDO_DIM_ELEMENT('Z',%.16g,%.16g,%.12g)", dfZMin, dfZMax, dfZRes ); } sDimUpdate.Append( ")" ); sDimUpdate.Appendf( strlen(poFeatureDefn->GetName()) + 100, " WHERE table_name = UPPER('%s')", poFeatureDefn->GetName() ); /* -------------------------------------------------------------------- */ /* Execute the metadata update. */ /* -------------------------------------------------------------------- */ OGROCIStatement oExecStatement( poDS->GetSession() ); if( oExecStatement.Execute( sDimUpdate.GetString() ) != CE_None ) return; }
void OGROCIDataSource::ValidateLayer( const char *pszLayerName ) { int iLayer; /* -------------------------------------------------------------------- */ /* Try to find layer. */ /* -------------------------------------------------------------------- */ for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) ) break; } if( iLayer == nLayers ) { CPLError( CE_Failure, CPLE_AppDefined, "ValidateLayer(): %s is not a recognised layer.", pszLayerName ); return; } /* -------------------------------------------------------------------- */ /* Verify we have an FID and geometry column for this table. */ /* -------------------------------------------------------------------- */ OGROCITableLayer *poLayer = (OGROCITableLayer *) papoLayers[iLayer]; if( strlen(poLayer->GetFIDColumn()) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "ValidateLayer(): %s lacks a fid column.", pszLayerName ); return; } /* -------------------------------------------------------------------- */ /* Prepare and execute the geometry validation. */ /* -------------------------------------------------------------------- */ if( strlen(poLayer->GetGeometryColumn()) != 0 ) { OGROCIStringBuf oValidateCmd; OGROCIStatement oValidateStmt( GetSession() ); oValidateCmd.Append( "SELECT c." ); oValidateCmd.Append( poLayer->GetFIDColumn() ); oValidateCmd.Append( ", SDO_GEOM.VALIDATE_GEOMETRY(c." ); oValidateCmd.Append( poLayer->GetGeometryColumn() ); oValidateCmd.Append( ", m.diminfo) from " ); oValidateCmd.Append( poLayer->GetLayerDefn()->GetName() ); oValidateCmd.Append( " c, user_sdo_geom_metadata m WHERE m.table_name= '"); oValidateCmd.Append( poLayer->GetLayerDefn()->GetName() ); oValidateCmd.Append( "' AND m.column_name = '" ); oValidateCmd.Append( poLayer->GetGeometryColumn() ); oValidateCmd.Append( "' AND SDO_GEOM.VALIDATE_GEOMETRY(c." ); oValidateCmd.Append( poLayer->GetGeometryColumn() ); oValidateCmd.Append( ", m.diminfo ) <> 'TRUE'" ); oValidateStmt.Execute( oValidateCmd.GetString() ); /* -------------------------------------------------------------------- */ /* Report results to debug stream. */ /* -------------------------------------------------------------------- */ char **papszRow; while( (papszRow = oValidateStmt.SimpleFetchRow()) != NULL ) { const char *pszReason = papszRow[1]; if( EQUAL(pszReason,"13011") ) pszReason = "13011: value is out of range"; else if( EQUAL(pszReason,"13050") ) pszReason = "13050: unable to construct spatial object"; else if( EQUAL(pszReason,"13349") ) pszReason = "13349: polygon boundary crosses itself"; CPLDebug( "OCI", "Validation failure for FID=%s: %s", papszRow[0], pszReason ); } } }
OGRErr OGROCILoaderLayer::WriteFeatureVariableMode( OGRFeature *poFeature ) { OGROCIStringBuf oLine; if( fpData == NULL ) return OGRERR_FAILURE; /* -------------------------------------------------------------------- */ /* Write the FID. */ /* -------------------------------------------------------------------- */ oLine.Append( "00000000" ); oLine.Appendf( 32, " %d|", poFeature->GetFID() ); /* -------------------------------------------------------------------- */ /* Set the geometry */ /* -------------------------------------------------------------------- */ if( poFeature->GetGeometryRef() != NULL) { char szSRID[128]; int nGType; int i; if( nSRID == -1 ) strcpy( szSRID, "NULL" ); else sprintf( szSRID, "%d", nSRID ); if( TranslateToSDOGeometry( poFeature->GetGeometryRef(), &nGType ) == OGRERR_NONE ) { oLine.Appendf( 32, "%d|", nGType ); for( i = 0; i < nElemInfoCount; i++ ) { oLine.Appendf( 32, "%d|", panElemInfo[i] ); } oLine.Append( "/" ); for( i = 0; i < nOrdinalCount; i++ ) { oLine.Appendf( 32, "%.16g|", padfOrdinals[i] ); } oLine.Append( "/" ); } else { oLine.Append( "0|/|/" ); } } else { oLine.Append( "0|/|/" ); } /* -------------------------------------------------------------------- */ /* Set the other fields. */ /* -------------------------------------------------------------------- */ int i; for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ ) { OGRFieldDefn *poFldDefn = poFeatureDefn->GetFieldDefn(i); if( !poFeature->IsFieldSet( i ) ) { if( poFldDefn->GetType() != OFTInteger && poFldDefn->GetType() != OFTReal ) oLine.Append( "0000" ); else oLine.Append( "|" ); continue; } const char *pszStrValue = poFeature->GetFieldAsString(i); if( poFldDefn->GetType() == OFTInteger || poFldDefn->GetType() == OFTReal ) { if( poFldDefn->GetWidth() > 0 && bPreservePrecision && (int) strlen(pszStrValue) > poFldDefn->GetWidth() ) { ReportTruncation( poFldDefn ); oLine.Append( "|" ); } else { oLine.Append( pszStrValue ); oLine.Append( "|" ); } } else { int nLength = strlen(pszStrValue); if( poFldDefn->GetWidth() > 0 && nLength > poFldDefn->GetWidth() ) { ReportTruncation( poFldDefn ); nLength = poFldDefn->GetWidth(); ((char *) pszStrValue)[nLength] = '\0'; } oLine.Appendf( 5, "%04d", nLength ); oLine.Append( pszStrValue ); } } oLine.Appendf( 3, "\n" ); /* -------------------------------------------------------------------- */ /* Update the line's length, and write to disk. */ /* -------------------------------------------------------------------- */ char szLength[9]; size_t nStringLen = strlen(oLine.GetString()); sprintf( szLength, "%08d", (int) (nStringLen-8) ); strncpy( oLine.GetString(), szLength, 8 ); if( VSIFWrite( oLine.GetString(), 1, nStringLen, fpData ) != nStringLen ) { CPLError( CE_Failure, CPLE_FileIO, "Write to loader file failed, likely out of disk space." ); return OGRERR_FAILURE; } else return OGRERR_NONE; }