📄 ogrocitablelayer.cpp
字号:
FALSE, (dvoid **)&hOrdVARRAY), "OCIObjectNew(hOrdVARRAY)") ) return OGRERR_FAILURE; } else { sb4 nOldCount; OCICollSize( poSession->hEnv, poSession->hError, hOrdVARRAY, &nOldCount ); OCICollTrim( poSession->hEnv, poSession->hError, nOldCount, hOrdVARRAY ); } // Prepare the VARRAY of ordinate values. for (i = 0; i < nOrdinalCount; i++) { if( poSession->Failed( OCINumberFromReal( poSession->hError, (dvoid *) (padfOrdinals + i), (uword)sizeof(double), &oci_number), "OCINumberFromReal") ) return OGRERR_FAILURE; if( poSession->Failed( OCICollAppend( poSession->hEnv, poSession->hError, (dvoid *) &oci_number, (dvoid *)0, hOrdVARRAY), "OCICollAppend") ) return OGRERR_FAILURE; } // Do the binding. if( poSession->Failed( OCIBindByName( oInsert.GetStatement(), &hBindOrd, poSession->hError, (text *) ":ordinates", (sb4) -1, (dvoid *) 0, (sb4) 0, SQLT_NTY, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT), "OCIBindByName(:ordinates)") ) return OGRERR_FAILURE; if( poSession->Failed( OCIBindObject( hBindOrd, poSession->hError, poSession->hOrdinatesTDO, (dvoid **)&hOrdVARRAY, (ub4 *)0, (dvoid **)0, (ub4 *)0), "OCIBindObject(:ordinates)" ) ) return OGRERR_FAILURE; }/* -------------------------------------------------------------------- *//* Execute the insert. *//* -------------------------------------------------------------------- */ if( oInsert.Execute( NULL ) != CE_None ) return OGRERR_FAILURE; else return OGRERR_NONE;}/************************************************************************//* TestCapability() *//************************************************************************/int OGROCITableLayer::TestCapability( const char * pszCap ){ if( EQUAL(pszCap,OLCSequentialWrite) || EQUAL(pszCap,OLCRandomWrite) ) return bUpdateAccess; else if( EQUAL(pszCap,OLCCreateField) ) return bUpdateAccess; else return OGROCILayer::TestCapability( pszCap );}/************************************************************************//* GetFeatureCount() *//* *//* If a spatial filter is in effect, we turn control over to *//* the generic counter. Otherwise we return the total count. *//* Eventually we should consider implementing a more efficient *//* way of counting features matching a spatial query. *//************************************************************************/int OGROCITableLayer::GetFeatureCount( int bForce ){/* -------------------------------------------------------------------- *//* Use a more brute force mechanism if we have a spatial query *//* in play. *//* -------------------------------------------------------------------- */ if( m_poFilterGeom != NULL ) return OGROCILayer::GetFeatureCount( bForce );/* -------------------------------------------------------------------- *//* In theory it might be wise to cache this result, but it *//* won't be trivial to work out the lifetime of the value. *//* After all someone else could be adding records from another *//* application when working against a database. *//* -------------------------------------------------------------------- */ OGROCISession *poSession = poDS->GetSession(); OGROCIStatement oGetCount( poSession ); char szCommand[1024]; char **papszResult; sprintf( szCommand, "SELECT COUNT(*) FROM %s %s", poFeatureDefn->GetName(), pszWHERE ); oGetCount.Execute( szCommand ); papszResult = oGetCount.SimpleFetchRow(); if( CSLCount(papszResult) < 1 ) { CPLDebug( "OCI", "Fast get count failed, doing hard way." ); return OGROCILayer::GetFeatureCount( bForce ); } return atoi(papszResult[0]);}/************************************************************************//* FinalizeNewLayer() *//* *//* Our main job here is to update the USER_SDO_GEOM_METADATA *//* table to include the correct array of dimension object with *//* the appropriate extents for this layer. We may also do *//* spatial indexing at this point. *//************************************************************************/void OGROCITableLayer::FinalizeNewLayer(){ OGROCIStringBuf sDimUpdate; FlushPendingFeatures();/* -------------------------------------------------------------------- *//* 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( "INSERT INTO USER_SDO_GEOM_METADATA VALUES " ); sDimUpdate.Appendf( strlen(poFeatureDefn->GetName()) + 100, "('%s', '%s', ", poFeatureDefn->GetName(), pszGeomName ); 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 ); } if( nSRID == -1 ) sDimUpdate.Append( "), NULL)" ); else sDimUpdate.Appendf( 100, "), %d)", nSRID );/* -------------------------------------------------------------------- *//* Execute the metadata update. *//* -------------------------------------------------------------------- */ OGROCIStatement oExecStatement( poDS->GetSession() ); if( oExecStatement.Execute( sDimUpdate.GetString() ) != CE_None ) return;/* -------------------------------------------------------------------- *//* If the user has disabled INDEX support then don't create the *//* index. *//* -------------------------------------------------------------------- */ if( !CSLFetchBoolean( papszOptions, "INDEX", TRUE ) ) return;/* -------------------------------------------------------------------- *//* Establish an index name. For some reason Oracle 8.1.7 does *//* not support spatial index names longer than 18 characters so *//* we magic up an index name if it would be too long. *//* -------------------------------------------------------------------- */ char szIndexName[20]; if( strlen(poFeatureDefn->GetName()) < 15 ) sprintf( szIndexName, "%s_idx", poFeatureDefn->GetName() ); else if( strlen(poFeatureDefn->GetName()) < 17 ) sprintf( szIndexName, "%si", poFeatureDefn->GetName() ); else { int i, nHash = 0; const char *pszSrcName = poFeatureDefn->GetName(); for( i = 0; pszSrcName[i] != '\0'; i++ ) nHash = (nHash + i * pszSrcName[i]) % 987651; sprintf( szIndexName, "OSI_%d", nHash ); } poDS->GetSession()->CleanName( szIndexName );/* -------------------------------------------------------------------- *//* Try creating an index on the table now. Use a simple 5 *//* level quadtree based index. Would R-tree be a better default? *//* -------------------------------------------------------------------- */// Disable for now, spatial index creation always seems to cause me to // lose my connection to the database! OGROCIStringBuf sIndexCmd; sIndexCmd.Appendf( 10000, "CREATE INDEX \"%s\" ON %s(\"%s\") " "INDEXTYPE IS MDSYS.SPATIAL_INDEX ", szIndexName, poFeatureDefn->GetName(), pszGeomName ); if( CSLFetchNameValue( papszOptions, "INDEX_PARAMETERS" ) != NULL ) { sIndexCmd.Append( " PARAMETERS( '" ); sIndexCmd.Append( CSLFetchNameValue(papszOptions,"INDEX_PARAMETERS") ); sIndexCmd.Append( "' )" ); } if( oExecStatement.Execute( sIndexCmd.GetString() ) != CE_None ) { char szDropCommand[2000]; sprintf( szDropCommand, "DROP INDEX \"%s\"", szIndexName ); oExecStatement.Execute( szDropCommand ); }}/************************************************************************//* AllocAndBindForWrite() *//************************************************************************/int OGROCITableLayer::AllocAndBindForWrite(){ OGROCISession *poSession = poDS->GetSession(); int i; CPLAssert( nWriteCacheMax == 0 );/* -------------------------------------------------------------------- *//* Decide on the number of rows we want to be able to cache at *//* a time. *//* -------------------------------------------------------------------- */ nWriteCacheMax = 100;/* -------------------------------------------------------------------- *//* Collect the INSERT statement. *//* -------------------------------------------------------------------- */ OGROCIStringBuf oCmdBuf; oCmdBuf.Append( "INSERT INTO " ); oCmdBuf.Append( poFeatureDefn->GetName() ); for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ ) { if( i == 0 ) oCmdBuf.Append( " VALUES ( :fid, :geometry, " ); else oCmdBuf.Append( ", " ); oCmdBuf.Appendf( 20, " :field_%d", i ); } oCmdBuf.Append( ") " );/* -------------------------------------------------------------------- *//* Bind and Prepare it. *//* -------------------------------------------------------------------- */ poBoundStatement = new OGROCIStatement( poSession ); poBoundStatement->Prepare( oCmdBuf.GetString() );/* -------------------------------------------------------------------- *//* Setup geometry indicator information. *//* -------------------------------------------------------------------- */ pasWriteGeomInd = (SDO_GEOMETRY_ind *) CPLCalloc(sizeof(SDO_GEOMETRY_ind),nWriteCacheMax); papsWriteGeomIndMap = (SDO_GEOMETRY_ind **) CPLCalloc(sizeof(SDO_GEOMETRY_ind *),nWriteCacheMax); for( i = 0; i < nWriteCacheMax; i++ ) papsWriteGeomIndMap[i] = pasWriteGeomInd + i;/* -------------------------------------------------------------------- *//* Setup all the required geometry objects, and the *//* corresponding indicator map. *//* -------------------------------------------------------------------- */ pasWriteGeoms = (SDO_GEOMETRY_TYPE *) CPLCalloc( sizeof(SDO_GEOMETRY_TYPE), nWriteCacheMax); papsWriteGeomMap = (SDO_GEOMETRY_TYPE **) CPLCalloc( sizeof(SDO_GEOMETRY_TYPE *), nWriteCacheMax ); for( i = 0; i < nWriteCacheMax; i++ ) papsWriteGeomMap[i] = pasWriteGeoms + i;/* -------------------------------------------------------------------- *//* Allocate VARRAYs for the elem_info and ordinates. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -