OGRSpatialReference *OGRIDBTableLayer::GetSpatialRef() { if( nSRSId == -2 ) { nSRSId = -1; if ( ! pszGeomColumn ) return NULL; CPLString osCmd; osCmd.Printf( " SELECT FIRST 1 srid, trim(srtext)" " FROM spatial_ref_sys, %s" " WHERE srid = ST_Srid(%s) ", poFeatureDefn->GetName(), pszGeomColumn ); ITCursor oSridCur( *poDS->GetConnection() ); if( oSridCur.Prepare( osCmd.c_str() )&& oSridCur.Open( ITCursor::ReadOnly ) ) { ITRow * row = static_cast<ITRow *>( oSridCur.NextRow() ); if ( row && ! row->IsNull() ) { nSRSId = atoi(row->Column(0)->Printable()); const char * wkt = row->Column(1)->Printable(); if ( poSRS ) { // Hmm ... it should be null delete poSRS; } poSRS = new OGRSpatialReference(); if ( poSRS->importFromWkt( (char **)&wkt ) != OGRERR_NONE ) { CPLError( CE_Warning, CPLE_AppDefined, "Error parse srs wkt: %s", wkt ); delete poSRS; poSRS = NULL; } } } } return OGRIDBLayer::GetSpatialRef(); }
OGRErr OGRIDBTableLayer::ICreateFeature( OGRFeature *poFeature ) { OGRErr eErr(OGRERR_FAILURE); if ( ! bUpdateAccess ) { CPLError( CE_Failure, CPLE_AppDefined, "Error create feature. Layer is read only." ); return eErr; } if( NULL == poFeature ) { CPLError( CE_Failure, CPLE_AppDefined, "NULL pointer to OGRFeature passed to CreateFeature()." ); return eErr; } if( poFeature->GetFID() != OGRNullFID && pszFIDColumn == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "FID ignored on feature given to CreateFeature(). Unknown FID column." ); return eErr; } int bUpdateGeom = TRUE; CPLString osGeomFunc; if ( poFeature->GetGeometryRef() ) { OGRwkbGeometryType nGeomType = poFeature->GetGeometryRef()->getGeometryType(); switch (nGeomType) { case wkbPoint: osGeomFunc = "ST_PointFromText"; break; case wkbLineString: osGeomFunc = "ST_LineFromText"; break; case wkbPolygon: osGeomFunc = "ST_PolyFromText"; break; case wkbMultiPoint: osGeomFunc = "ST_MPointFromText"; break; case wkbMultiLineString: osGeomFunc = "ST_MLineFromText"; break; case wkbMultiPolygon: osGeomFunc = "ST_MPolyFromText"; break; default: bUpdateGeom = FALSE; CPLDebug("OGR_IDB", "SetFeature(): Unknown geometry type. Geometry will not be updated."); } } else bUpdateGeom = FALSE; // Create query CPLString osSql; CPLString osFields; CPLString osValues; if ( pszGeomColumn && bUpdateGeom ) { OGRGeometry * poGeom = poFeature->GetGeometryRef(); char * wkt; poGeom->exportToWkt( &wkt ); osFields += pszGeomColumn; osValues.Printf( "%s( '%s', %d )", osGeomFunc.c_str(), wkt, nSRSId ); CPLFree( wkt ); } for( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ ) { const char * pszFieldName = poFeatureDefn->GetFieldDefn(i)->GetNameRef(); // Skip NULL fields if ( ! poFeature->IsFieldSet( i ) ) { continue; } if ( ! osFields.empty() ) { osFields += ","; osValues += ","; } osFields += pszFieldName; CPLString osVal; switch ( poFeatureDefn->GetFieldDefn( i )->GetType() ) { case OFTInteger: osVal.Printf( "%d", poFeature->GetFieldAsInteger( i ) ); break; case OFTReal: if ( poFeatureDefn->GetFieldDefn( i )->GetPrecision() ) { // have a decimal format width.precision CPLString osFormatString; osFormatString.Printf( "%%%d.%df", poFeatureDefn->GetFieldDefn( i )->GetWidth(), poFeatureDefn->GetFieldDefn( i )->GetPrecision() ); osVal.Printf( osFormatString.c_str(), poFeature->GetFieldAsDouble( i ) ); } else osVal.Printf( "%f", poFeature->GetFieldAsDouble( i ) ); break; case OFTIntegerList: case OFTRealList: case OFTStringList: // FIXME Prepare array of values field //cv->ConvertFrom( poFeature->GetFieldAsStringList( i ) ); //break; case OFTBinary: // FIXME Prepare binary field case OFTString: case OFTDate: case OFTTime: case OFTDateTime: default: osVal.Printf( "'%s'", poFeature->GetFieldAsString( i ) ); break; } osValues += osVal; } osSql.Printf( "INSERT INTO %s (%s) VALUES (%s)", poFeatureDefn->GetName(), osFields.c_str(), osValues.c_str() ); ITStatement oQuery( *poDS->GetConnection() ); if ( ! oQuery.Prepare( osSql.c_str() ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Error prepare SQL.\n%s",osSql.c_str() ); return eErr; } CPLDebug( "OGR_IDB", "Exec(%s)", oQuery.QueryText().Data() ); if( !oQuery.Exec() ) { CPLError( CE_Failure, CPLE_AppDefined, "Error create Feature."); return eErr; } ITQuery oFidQuery( *poDS->GetConnection() ); osSql.Printf( "SELECT MAX(%s) from %s", pszFIDColumn, poFeatureDefn->GetName() ); CPLDebug( "OGR_IDB", "Exec(%s)", osSql.c_str() ); ITRow * row = oFidQuery.ExecOneRow( osSql.c_str() ); if( ! row || row->NumColumns() < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Error create Feature."); return eErr; } int fid = atoi( row->Column(0)->Printable() ); if ( fid > 0 ) poFeature->SetFID( fid ); else { CPLError( CE_Failure, CPLE_AppDefined, "Error create Feature. Unable to get new fid" ); return eErr; } return OGRERR_NONE; }
OGRFeature *OGRIDBLayer::GetNextRawFeature() { if( GetQuery() == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* If we are marked to restart then do so, and fetch a record. */ /* -------------------------------------------------------------------- */ ITRow * row = poCurr->NextRow(); if ( ! row ) { delete poCurr; poCurr = NULL; return NULL; } iNextShapeId++; m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Create a feature from the current result. */ /* -------------------------------------------------------------------- */ int iField; OGRFeature *poFeature = new OGRFeature( poFeatureDefn ); const ITTypeInfo * poRowType = poCurr->RowType(); int nFieldCount = poRowType->ColumnCount(); for ( iField = 0; iField < nFieldCount; iField++ ) { /* -------------------------------------------------------------------- */ /* Handle FID column */ /* -------------------------------------------------------------------- */ if ( pszFIDColumn != NULL && EQUAL( poRowType->ColumnName( iField ), pszFIDColumn ) ) poFeature->SetFID( atoi( row->Column( iField )->Printable() ) ); /* -------------------------------------------------------------------- */ /* Handle geometry */ /* -------------------------------------------------------------------- */ if( pszGeomColumn != NULL && EQUAL( poRowType->ColumnName( iField ), pszGeomColumn ) ) { OGRGeometry *poGeom = NULL; OGRErr eErr = OGRERR_NONE; ITValue * v = row->Column( iField ); if( ! v->IsNull() && ! bGeomColumnWKB ) { const char *pszGeomText = v->Printable(); if ( pszGeomText != NULL ) eErr = OGRGeometryFactory::createFromWkt((char **) &pszGeomText, poSRS, &poGeom); } else if( ! v->IsNull() && bGeomColumnWKB ) { ITDatum *rv = 0; if ( v->QueryInterface( ITDatumIID, (void **) &rv ) == IT_QUERYINTERFACE_SUCCESS ) { int nLength = rv->DataLength(); unsigned char * wkb = (unsigned char *)rv->Data(); eErr = OGRGeometryFactory::createFromWkb( wkb, poSRS, &poGeom, nLength); rv->Release(); } } v->Release(); if ( eErr != OGRERR_NONE ) { const char *pszMessage; switch ( eErr ) { case OGRERR_NOT_ENOUGH_DATA: pszMessage = "Not enough data to deserialize"; break; case OGRERR_UNSUPPORTED_GEOMETRY_TYPE: pszMessage = "Unsupported geometry type"; break; case OGRERR_CORRUPT_DATA: pszMessage = "Corrupt data"; default: pszMessage = "Unrecognized error"; } CPLError(CE_Failure, CPLE_AppDefined, "GetNextRawFeature(): %s", pszMessage); } if( poGeom != NULL ) { poFeature->SetGeometryDirectly( poGeom ); } continue; } /* -------------------------------------------------------------------- */ /* Transfer regular data fields. */ /* -------------------------------------------------------------------- */ int iOGRField = poFeatureDefn->GetFieldIndex( poRowType->ColumnName( iField ) ); if( iOGRField < 0 ) continue; const char * pszColData = row->Column( iField )->Printable(); if( ! pszColData ) continue; if( poFeatureDefn->GetFieldDefn(iOGRField)->GetType() == OFTBinary ) poFeature->SetField( iOGRField, poRowType->ColumnType( iField )->Size(), (GByte *) pszColData ); else poFeature->SetField( iOGRField, pszColData ); } row->Release(); return poFeature; }