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 ); } }
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; }