コード例 #1
0
OGRSQLiteSelectLayer::OGRSQLiteSelectLayer( OGRSQLiteDataSource *poDSIn,
                                            CPLString osSQLIn,
                                            sqlite3_stmt *hStmtIn,
                                            int bUseStatementForGetNextFeature,
                                            int bEmptyLayer )

{
    poDS = poDSIn;

    iNextShapeId = 0;
    poFeatureDefn = NULL;
    bAllowResetReadingEvenIfIndexAtZero = FALSE;

    std::set<CPLString> aosEmpty;
    BuildFeatureDefn( "SELECT", hStmtIn, aosEmpty );

    if( bUseStatementForGetNextFeature )
    {
        hStmt = hStmtIn;
        bDoStep = FALSE;

        // Try to extract SRS from first geometry
        if( !bEmptyLayer && osGeomColumn.size() != 0 )
        {
            int    nRawColumns = sqlite3_column_count( hStmt );
            for( int iCol = 0; iCol < nRawColumns; iCol++ )
            {
                int nBytes;
                if( sqlite3_column_type( hStmt, iCol ) == SQLITE_BLOB &&
                    strcmp(OGRSQLiteParamsUnquote(sqlite3_column_name( hStmt, iCol )).c_str(), osGeomColumn.c_str()) == 0 &&
                    (nBytes = sqlite3_column_bytes( hStmt, iCol )) > 39 )
                {
                    const GByte* pabyBlob = (const GByte*)sqlite3_column_blob( hStmt, iCol );
                    int eByteOrder = pabyBlob[1];
                    if( pabyBlob[0] == 0x00 &&
                        (eByteOrder == wkbNDR || eByteOrder == wkbXDR) &&
                        pabyBlob[38] == 0x7C )
                    {
                        memcpy(&nSRSId, pabyBlob + 2, 4);
#ifdef CPL_LSB
                        if( eByteOrder != wkbNDR)
                            CPL_SWAP32PTR(&nSRSId);
#else
                        if( eByteOrder == wkbNDR)
                            CPL_SWAP32PTR(&nSRSId);
#endif
                        CPLPushErrorHandler(CPLQuietErrorHandler);
                        poSRS = poDS->FetchSRS( nSRSId );
                        CPLPopErrorHandler();
                        if( poSRS != NULL )
                            poSRS->Reference();
                        else
                            CPLErrorReset();
                    }
#ifdef SQLITE_HAS_COLUMN_METADATA
                    else
                    {
                        const char* pszTableName = sqlite3_column_table_name( hStmt, iCol );
                        if( pszTableName != NULL )
                        {
                            OGRLayer* poLayer = poDS->GetLayerByName(pszTableName);
                            if( poLayer != NULL )
                            {
                                poSRS = poLayer->GetSpatialRef();
                                if( poSRS != NULL )
                                    poSRS->Reference();
                            }
                        }
                    }
#endif
                    break;
                }
            }
        }
    }
    else
        sqlite3_finalize( hStmtIn );

    osSQLBase = osSQLIn;
    osSQLCurrent = osSQLIn;
    this->bEmptyLayer = bEmptyLayer;
    bSpatialFilterInSQL = TRUE;
}
コード例 #2
0
void OGRGeoPackageLayer::BuildFeatureDefn( const char *pszLayerName,
                                           sqlite3_stmt *hStmt )

{
    m_poFeatureDefn = new OGRSQLiteFeatureDefn( pszLayerName );
    SetDescription( m_poFeatureDefn->GetName() );
    m_poFeatureDefn->SetGeomType(wkbNone);
    m_poFeatureDefn->Reference();

    int    nRawColumns = sqlite3_column_count( hStmt );

    panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );

    int iCol;
    for( iCol = 0; iCol < nRawColumns; iCol++ )
    {
        OGRFieldDefn    oField( OGRSQLiteParamsUnquote(sqlite3_column_name( hStmt, iCol )),
                                OFTString );

        // In some cases, particularly when there is a real name for
        // the primary key/_rowid_ column we will end up getting the
        // primary key column appearing twice.  Ignore any repeated names.
        if( m_poFeatureDefn->GetFieldIndex( oField.GetNameRef() ) != -1 )
            continue;

        if( EQUAL(oField.GetNameRef(), "FID") )
        {
            CPLFree(m_pszFidColumn);
            m_pszFidColumn = CPLStrdup(oField.GetNameRef());
            iFIDCol = iCol;
        }

        if( m_pszFidColumn != NULL && EQUAL(m_pszFidColumn, oField.GetNameRef()))
            continue;

        // The rowid is for internal use, not a real column.
        if( EQUAL(oField.GetNameRef(),"_rowid_") )
            continue;

        // this will avoid the old geom field to appear when running something
        // like "select st_buffer(geom,5) as geom, * from my_layer"
        if( m_poFeatureDefn->GetGeomFieldCount() &&
            EQUAL(oField.GetNameRef(), m_poFeatureDefn->GetGeomFieldDefn(0)->GetNameRef()) )
            continue;

        int nColType = sqlite3_column_type( hStmt, iCol );
        const char * pszDeclType = sqlite3_column_decltype(hStmt, iCol);

        // Recognize a geometry column from trying to build the geometry
        // Useful for OGRSQLiteSelectLayer
        if( nColType == SQLITE_BLOB && m_poFeatureDefn->GetGeomFieldCount() == 0 )
        {
            const int nBytes = sqlite3_column_bytes( hStmt, iCol );
            if( nBytes > 4 )
            {
                int iGpkgSize = sqlite3_column_bytes(hStmt, iCol);
                const GByte* pabyGpkg = (const GByte*)sqlite3_column_blob( hStmt, iCol  );
                GPkgHeader oHeader;
                OGRGeometry* poGeom = NULL;
                int nSRID;
                if( GPkgHeaderFromWKB(pabyGpkg, &oHeader) == OGRERR_NONE )
                {
                    OGRGeomFieldDefn oGeomField(oField.GetNameRef(), wkbUnknown);

                    /* Read the SRS */
                    OGRSpatialReference *poSRS = m_poDS->GetSpatialRef(oHeader.iSrsId);
                    if ( poSRS )
                    {
                        oGeomField.SetSpatialRef(poSRS);
                        poSRS->Dereference();
                    }

                    OGRwkbGeometryType eGeomType = wkbUnknown;
                    if( pszDeclType != NULL )
                    {
                        eGeomType = GPkgGeometryTypeToWKB(pszDeclType, (oHeader.iDims == 3));
                        if( eGeomType != wkbNone )
                            oGeomField.SetType( eGeomType );
                    }

#ifdef SQLITE_HAS_COLUMN_METADATA
                    const char* pszTableName = sqlite3_column_table_name( hStmt, iCol );
                    if( oGeomField.GetType() == wkbUnknown && pszTableName != NULL )
                    {
                        OGRGeoPackageLayer* poLayer = (OGRGeoPackageLayer*)
                                        m_poDS->GetLayerByName(pszTableName);
                        if( poLayer != NULL && poLayer->GetLayerDefn()->GetGeomFieldCount() > 0)
                        {
                            oGeomField.SetType( poLayer->GetLayerDefn()->GetGeomFieldDefn(0)->GetType() );
                        }
                    }
#endif

                    m_poFeatureDefn->AddGeomFieldDefn(&oGeomField);
                    iGeomCol = iCol;
                    continue;
                }

                // Try also spatialite geometry blobs
                else if( OGRSQLiteLayer::ImportSpatiaLiteGeometry( pabyGpkg, iGpkgSize,
                                                                   &poGeom, &nSRID ) == OGRERR_NONE )
                {
                    OGRGeomFieldDefn oGeomField(oField.GetNameRef(), wkbUnknown);

                    /* Read the SRS */
                    OGRSpatialReference *poSRS = m_poDS->GetSpatialRef(nSRID);
                    if ( poSRS )
                    {
                        oGeomField.SetSpatialRef(poSRS);
                        poSRS->Dereference();
                    }
                    delete poGeom;

                    m_poFeatureDefn->AddGeomFieldDefn(&oGeomField);
                    iGeomCol = iCol;
                    continue;
                }
            }
        }

        switch( nColType )
        {
          case SQLITE_INTEGER:
            if( CSLTestBoolean(CPLGetConfigOption("OGR_PROMOTE_TO_INTEGER64", "FALSE")) )
                oField.SetType( OFTInteger64 );
            else
            {
                GIntBig nVal = sqlite3_column_int64(hStmt, iCol);
                if( (GIntBig)(int)nVal == nVal )
                    oField.SetType( OFTInteger );
                else
                    oField.SetType( OFTInteger64 );
            }
            break;

          case SQLITE_FLOAT:
            oField.SetType( OFTReal );
            break;

          case SQLITE_BLOB:
            oField.SetType( OFTBinary );
            break;

          default:
            /* leave it as OFTString */;
        }

        if (pszDeclType != NULL)
        {
            OGRFieldSubType eSubType;
            int nMaxWidth;
            OGRFieldType eFieldType = GPkgFieldToOGR(pszDeclType, eSubType, nMaxWidth);
            if( (int)eFieldType <= OFTMaxType )
            {
                oField.SetType(eFieldType);
                oField.SetSubType(eSubType);
                oField.SetWidth(nMaxWidth);
            }
        }

        m_poFeatureDefn->AddFieldDefn( &oField );
        panFieldOrdinals[m_poFeatureDefn->GetFieldCount() - 1] = iCol;
    }

}
コード例 #3
0
void OGRGeoPackageLayer::BuildFeatureDefn( const char *pszLayerName,
                                           sqlite3_stmt *hStmt )

{
    m_poFeatureDefn = new OGRSQLiteFeatureDefn( pszLayerName );
    SetDescription( m_poFeatureDefn->GetName() );
    m_poFeatureDefn->SetGeomType(wkbNone);
    m_poFeatureDefn->Reference();

    int    nRawColumns = sqlite3_column_count( hStmt );

    panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );

    int iCol;
    for( iCol = 0; iCol < nRawColumns; iCol++ )
    {
        OGRFieldDefn    oField( OGRSQLiteParamsUnquote(sqlite3_column_name( hStmt, iCol )),
                                OFTString );

        // In some cases, particularly when there is a real name for
        // the primary key/_rowid_ column we will end up getting the
        // primary key column appearing twice.  Ignore any repeated names.
        if( m_poFeatureDefn->GetFieldIndex( oField.GetNameRef() ) != -1 )
            continue;

        if( EQUAL(oField.GetNameRef(), "FID") )
        {
            CPLFree(m_pszFidColumn);
            m_pszFidColumn = CPLStrdup(oField.GetNameRef());
            iFIDCol = iCol;
        }

        if( m_pszFidColumn != NULL && EQUAL(m_pszFidColumn, oField.GetNameRef()))
            continue;

        // The rowid is for internal use, not a real column.
        if( EQUAL(oField.GetNameRef(),"_rowid_") )
            continue;

        int nColType = sqlite3_column_type( hStmt, iCol );
        const char * pszDeclType = sqlite3_column_decltype(hStmt, iCol);

        // Recognize a geometry column from trying to build the geometry
        // Usefull for OGRSQLiteSelectLayer
        if( nColType == SQLITE_BLOB && m_poFeatureDefn->GetGeomFieldCount() == 0 )
        {
            const int nBytes = sqlite3_column_bytes( hStmt, iCol );
            if( nBytes > 4 )
            {
                const GByte* pabyGpkg = (const GByte*)sqlite3_column_blob( hStmt, iCol  );
                GPkgHeader oHeader;
                if( GPkgHeaderFromWKB(pabyGpkg, &oHeader) == OGRERR_NONE )
                {
                    OGRGeomFieldDefn oGeomField(oField.GetNameRef(), wkbUnknown);

                    /* Read the SRS */
                    OGRSpatialReference *poSRS = m_poDS->GetSpatialRef(oHeader.iSrsId);
                    if ( poSRS )
                    {
                        oGeomField.SetSpatialRef(poSRS);
                        poSRS->Dereference();
                    }

                    OGRwkbGeometryType eGeomType = wkbUnknown;
                    if( pszDeclType != NULL )
                    {
                        eGeomType = GPkgGeometryTypeToWKB(pszDeclType, (oHeader.iDims == 3));
                        if( eGeomType != wkbNone )
                            oGeomField.SetType( eGeomType );
                    }

#ifdef SQLITE_HAS_COLUMN_METADATA
                    const char* pszTableName = sqlite3_column_table_name( hStmt, iCol );
                    if( oGeomField.GetType() == wkbUnknown && pszTableName != NULL )
                    {
                        OGRGeoPackageLayer* poLayer = (OGRGeoPackageLayer*)
                                        m_poDS->GetLayerByName(pszTableName);
                        if( poLayer != NULL && poLayer->GetLayerDefn()->GetGeomFieldCount() > 0)
                        {
                            oGeomField.SetType( poLayer->GetLayerDefn()->GetGeomFieldDefn(0)->GetType() );
                        }
                    }
#endif

                    m_poFeatureDefn->AddGeomFieldDefn(&oGeomField);
                    iGeomCol = iCol;
                    continue;
                }
            }
        }

        switch( nColType )
        {
          case SQLITE_INTEGER:
            oField.SetType( OFTInteger );
            break;

          case SQLITE_FLOAT:
            oField.SetType( OFTReal );
            break;

          case SQLITE_BLOB:
            oField.SetType( OFTBinary );
            break;

          default:
            /* leave it as OFTString */;
        }

        if (pszDeclType != NULL)
        {
            OGRFieldType eFieldType = GPkgFieldToOGR(pszDeclType);
            if( (int)eFieldType <= OFTMaxType )
                oField.SetType(eFieldType);
        }

        m_poFeatureDefn->AddFieldDefn( &oField );
        panFieldOrdinals[m_poFeatureDefn->GetFieldCount() - 1] = iCol;
    }

}