Exemplo n.º 1
0
void OGROSMLayer::SetFieldsFromTags(OGRFeature* poFeature,
                                    GIntBig nID,
                                    int bIsWayID,
                                    unsigned int nTags, OSMTag* pasTags,
                                    OSMInfo* psInfo)
{
    if( !bIsWayID )
    {
        poFeature->SetFID( nID );

        if( bHasOSMId )
        {
            char szID[32];
            sprintf(szID, CPL_FRMT_GIB, nID );
            poFeature->SetField(nIndexOSMId, szID);
        }
    }
    else
    {
        poFeature->SetFID( nID );

        if( nIndexOSMWayId >= 0 )
        {
            char szID[32];
            sprintf(szID, CPL_FRMT_GIB, nID );
            poFeature->SetField(nIndexOSMWayId, szID );
        }
    }

    if( bHasVersion )
    {
        poFeature->SetField("osm_version", psInfo->nVersion);
    }
    if( bHasTimestamp )
    {
        if( psInfo->bTimeStampIsStr )
        {
            OGRField sField;
            if (OGRParseXMLDateTime(psInfo->ts.pszTimeStamp, &sField))
            {
                poFeature->SetField("osm_timestamp", &sField);
            }
        }
        else
        {
            struct tm brokendown;
            CPLUnixTimeToYMDHMS(psInfo->ts.nTimeStamp, &brokendown);
            poFeature->SetField("osm_timestamp",
                                brokendown.tm_year + 1900,
                                brokendown.tm_mon + 1,
                                brokendown.tm_mday,
                                brokendown.tm_hour,
                                brokendown.tm_min,
                                brokendown.tm_sec,
                                0);
        }

    }
    if( bHasUID )
    {
        poFeature->SetField("osm_uid", psInfo->nUID);
    }
    if( bHasUser )
    {
        poFeature->SetField("osm_user", psInfo->pszUserSID);
    }
    if( bHasChangeset )
    {
        poFeature->SetField("osm_changeset", (int) psInfo->nChangeset);
    }

    int nAllTagsOff = 0;
    for(unsigned int j = 0; j < nTags; j++)
    {
        const char* pszK = pasTags[j].pszK;
        const char* pszV = pasTags[j].pszV;
        int nIndex = GetFieldIndex(pszK);
        if( nIndex >= 0 )
        {
            poFeature->SetField(nIndex, pszV);
            if( nIndexAllTags < 0 )
                continue;
        }
        if ( nIndexAllTags >= 0 || nIndexOtherTags >= 0 )
        {
            if ( AddInOtherOrAllTags(pszK) )
            {
                int nLenK = (int)strlen(pszK);
                int nLenV = (int)strlen(pszV);
                if( nAllTagsOff +
                    1 + 2 * nLenK + 1 +
                    2 +
                    1 + 2 * nLenV + 1 +
                    1 >= ALLTAGS_LENGTH - 1 )
                {
                    if( !bHasWarnedAllTagsTruncated )
                        CPLDebug("OSM", "all_tags/other_tags field truncated for feature " CPL_FRMT_GIB, nID);
                    bHasWarnedAllTagsTruncated = TRUE;
                    continue;
                }

                if( nAllTagsOff )
                    pszAllTags[nAllTagsOff++] = ',';
                
                nAllTagsOff += OGROSMFormatForHSTORE(pszK,
                                                     pszAllTags + nAllTagsOff);

                pszAllTags[nAllTagsOff++] = '=';
                pszAllTags[nAllTagsOff++] = '>';
                
                nAllTagsOff += OGROSMFormatForHSTORE(pszV,
                                                     pszAllTags + nAllTagsOff);
            }

#ifdef notdef
            if ( aoSetWarnKeys.find(pszK) ==
                 aoSetWarnKeys.end() )
            {
                aoSetWarnKeys.insert(pszK);
                CPLDebug("OSM_KEY", "Ignored key : %s", pszK);
            }
#endif
        }
    }

    if( nAllTagsOff )
    {
        pszAllTags[nAllTagsOff] = '\0';
        if( nIndexAllTags >= 0 )
            poFeature->SetField(nIndexAllTags, pszAllTags);
        else
            poFeature->SetField(nIndexOtherTags, pszAllTags);
    }

    for(size_t i=0; i<oComputedAttributes.size();i++)
    {
        const OGROSMComputedAttribute& oAttr = oComputedAttributes[i];
        for(size_t j=0;j<oAttr.anIndexToBind.size();j++)
        {
            if( oAttr.anIndexToBind[j] >= 0 )
            {
                if( !poFeature->IsFieldSet(oAttr.anIndexToBind[j]) )
                {
                    sqlite3_bind_null( oAttr.hStmt, j + 1 );
                }
                else
                {
                    OGRFieldType eType = poFeatureDefn->GetFieldDefn(oAttr.anIndexToBind[j])->GetType();
                    if( eType == OFTInteger )
                        sqlite3_bind_int( oAttr.hStmt, j + 1,
                                          poFeature->GetFieldAsInteger(oAttr.anIndexToBind[j]) );
                    else if( eType == OFTInteger64 )
                        sqlite3_bind_int64( oAttr.hStmt, j + 1,
                                          poFeature->GetFieldAsInteger64(oAttr.anIndexToBind[j]) );
                    else if( eType == OFTReal )
                        sqlite3_bind_double( oAttr.hStmt, j + 1,
                                             poFeature->GetFieldAsDouble(oAttr.anIndexToBind[j]) );
                    else
                        sqlite3_bind_text( oAttr.hStmt, j + 1,
                                        poFeature->GetFieldAsString(oAttr.anIndexToBind[j]),
                                        -1, SQLITE_TRANSIENT);
                }
            }
            else
            {
                int bTagFound = FALSE;
                for(unsigned int k = 0; k < nTags; k++)
                {
                    const char* pszK = pasTags[k].pszK;
                    const char* pszV = pasTags[k].pszV;
                    if( strcmp(pszK, oAttr.aosAttrToBind[j]) == 0 )
                    {
                        sqlite3_bind_text( oAttr.hStmt, j + 1, pszV, -1, SQLITE_TRANSIENT);
                        bTagFound = TRUE;
                        break;
                    }
                }
                if( !bTagFound )
                    sqlite3_bind_null( oAttr.hStmt, j + 1 );
            }
        }

        if( sqlite3_step( oAttr.hStmt ) == SQLITE_ROW &&
            sqlite3_column_count( oAttr.hStmt ) == 1 )
        {
            switch( sqlite3_column_type( oAttr.hStmt, 0 ) )
            {
                case SQLITE_INTEGER:
                    poFeature->SetField( oAttr.nIndex,
                            (GIntBig)sqlite3_column_int64(oAttr.hStmt, 0) );
                    break;
                case SQLITE_FLOAT:
                    poFeature->SetField( oAttr.nIndex,
                            sqlite3_column_double(oAttr.hStmt, 0) );
                    break;
                case SQLITE_TEXT:
                    poFeature->SetField( oAttr.nIndex,
                            (const char*)sqlite3_column_text(oAttr.hStmt, 0) );
                    break;
                default:
                    break;
            }
        }

        sqlite3_reset( oAttr.hStmt );
    }
}
Exemplo n.º 2
0
OGRFeature *OGRGeoPackageLayer::TranslateFeature( sqlite3_stmt* hStmt )

{

/* -------------------------------------------------------------------- */
/*      Create a feature from the current result.                       */
/* -------------------------------------------------------------------- */
    int         iField;
    OGRFeature *poFeature = new OGRFeature( m_poFeatureDefn );

/* -------------------------------------------------------------------- */
/*      Set FID if we have a column to set it from.                     */
/* -------------------------------------------------------------------- */
    if( iFIDCol >= 0 )
        poFeature->SetFID( sqlite3_column_int64( hStmt, iFIDCol ) );
    else
        poFeature->SetFID( iNextShapeId );

    iNextShapeId++;

    m_nFeaturesRead++;

/* -------------------------------------------------------------------- */
/*      Process Geometry if we have a column.                           */
/* -------------------------------------------------------------------- */
    if( iGeomCol >= 0 )
    {
        OGRGeomFieldDefn* poGeomFieldDefn = m_poFeatureDefn->GetGeomFieldDefn(0);
        if ( sqlite3_column_type(hStmt, iGeomCol) != SQLITE_NULL &&
            !poGeomFieldDefn->IsIgnored() )
        {
            OGRSpatialReference* poSrs = poGeomFieldDefn->GetSpatialRef();
            int iGpkgSize = sqlite3_column_bytes(hStmt, iGeomCol);
            GByte *pabyGpkg = (GByte *)sqlite3_column_blob(hStmt, iGeomCol);
            OGRGeometry *poGeom = GPkgGeometryToOGR(pabyGpkg, iGpkgSize, poSrs);
            if ( ! poGeom )
            {
                // Try also spatialite geometry blobs
                if( OGRSQLiteLayer::ImportSpatiaLiteGeometry( pabyGpkg, iGpkgSize,
                                                              &poGeom ) != OGRERR_NONE )
                {
                    CPLError( CE_Failure, CPLE_AppDefined, "Unable to read geometry");
                }
            }
            poFeature->SetGeometryDirectly( poGeom );
        }
    }
    
/* -------------------------------------------------------------------- */
/*      set the fields.                                                 */
/* -------------------------------------------------------------------- */
    for( iField = 0; iField < m_poFeatureDefn->GetFieldCount(); iField++ )
    {
        OGRFieldDefn *poFieldDefn = m_poFeatureDefn->GetFieldDefn( iField );
        if ( poFieldDefn->IsIgnored() )
            continue;

        int iRawField = panFieldOrdinals[iField];

        if( sqlite3_column_type( hStmt, iRawField ) == SQLITE_NULL )
            continue;

        switch( poFieldDefn->GetType() )
        {
            case OFTInteger:
                poFeature->SetField( iField, 
                    sqlite3_column_int( hStmt, iRawField ) );
                break;

            case OFTInteger64:
                poFeature->SetField( iField, 
                    sqlite3_column_int64( hStmt, iRawField ) );
                break;

            case OFTReal:
                poFeature->SetField( iField, 
                    sqlite3_column_double( hStmt, iRawField ) );
                break;

            case OFTBinary:
            {
                const int nBytes = sqlite3_column_bytes( hStmt, iRawField );

                poFeature->SetField( iField, nBytes,
                    (GByte*)sqlite3_column_blob( hStmt, iRawField ) );
                break;
            }

            case OFTDate:
            {
                const char* pszTxt = (const char*)sqlite3_column_text( hStmt, iRawField );
                int nYear, nMonth, nDay;
                if( sscanf(pszTxt, "%d-%d-%d", &nYear, &nMonth, &nDay) == 3 )
                    poFeature->SetField(iField, nYear, nMonth, nDay, 0, 0, 0, 0);
                break;
            }

            case OFTDateTime:
            {
                const char* pszTxt = (const char*)sqlite3_column_text( hStmt, iRawField );
                OGRField sField;
                if( OGRParseXMLDateTime(pszTxt, &sField) )
                    poFeature->SetField(iField, &sField);
                break;
            }

            case OFTString:
                poFeature->SetField( iField, 
                        (const char *) sqlite3_column_text( hStmt, iRawField ) );
                break;

            default:
                break;
        }
    }

    return poFeature;
}