diff -r f727727520eb -r aa5a574040a4 locationmanager/locationtrail/src/clocationrecord.cpp --- a/locationmanager/locationtrail/src/clocationrecord.cpp Wed Jun 23 18:41:19 2010 +0300 +++ b/locationmanager/locationtrail/src/clocationrecord.cpp Tue Jul 06 14:44:37 2010 +0300 @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include #include "rlocationtrail.h" #include "clocationrecord.h" @@ -26,30 +29,50 @@ #include "locationtraildefs.h" #include "locationtrailpskeys.h" #include "mdeconstants.h" -#include -#include +#ifdef LOC_REVERSEGEOCODE +#include "reversegeocoderplugin.h" +const TUid KReverseGeoCodeUid = {0x2002DD12}; +#endif using namespace MdeConstants; +const TUint KNetQueryBit = 1; // 1 bit +const TUint KDownloadMediaFile = 2; // 2 bit +const TUint KSnapMediaFile = 4; // 3 bit +const TUint KLocationQueryInProgress = 1; // 1 bit +#ifdef LOC_REVERSEGEOCODE +const TUint KReverseGeoCodingInProgress = 2; // 2 bit +_LIT ( KCountry, "country:"); // country:india +_LIT ( KCity, "city:"); // city:bangalore|country:india +#endif +const TUint KSnapGeoConvertInProgress = 4; // 3 bit +#ifdef LOC_GEOTAGGING_CELLID +const TUint KSnapGeoConvertInPendingState = 8; // 4 bit +#endif + + + // -------------------------------------------------------------------------- // CLocationRecord::NewL // -------------------------------------------------------------------------- // -EXPORT_C CLocationRecord* CLocationRecord::NewL() +EXPORT_C CLocationRecord* CLocationRecord::NewL(MGeoTaggerObserver& aGeoTaggerObserver, + RMobilePhone& aPhone) { - CLocationRecord* self = new (ELeave) CLocationRecord(); + CLocationRecord* self = new (ELeave) CLocationRecord(aGeoTaggerObserver, aPhone); CleanupStack::PushL( self ); self->ConstructL(); CleanupStack::Pop( self ); return self; } - + // -------------------------------------------------------------------------- // CLocationRecord::CLocationRecord // -------------------------------------------------------------------------- // -CLocationRecord::CLocationRecord() +CLocationRecord::CLocationRecord(MGeoTaggerObserver& aGeoTaggerObserver, + RMobilePhone& aPhone) : iNetworkInfoTimer( NULL ), iState( RLocationTrail::ETrailStopped ), iTrailCaptureSetting( RLocationTrail::ECaptureAll ), @@ -57,7 +80,29 @@ iRequestCurrentLoc( EFalse ), iTrailStarted( EFalse ), iLastGPSFixState( EFalse ), - iLastLocationId( 0 ) + iLocationQuery(NULL), + iNetLocationQuery(NULL), + iRemapState( ERemapProgressNone), + iNamespaceDef(NULL), + iLocationObjectDef(NULL), + iLatitudeDef(NULL), + iLongitudeDef(NULL), + iAltitudeDef(NULL), + iMediaHandlingFlag(0), + iPhone(aPhone), + iGpsDataAvailableFlag(EFalse), + iGeoTaggerObserver(aGeoTaggerObserver) +#ifdef LOC_GEOTAGGING_CELLID + ,iGeoConverter(NULL) + , iConvertRetry(ETrue) +#endif +#ifdef LOC_REVERSEGEOCODE + ,iConnectionOption(ESilent) + ,iImageQuery(NULL) + ,iTagQuery(NULL) + ,iTagCreator( NULL ) + ,iRevGeocoderPlugin( NULL ) +#endif { iMaxTrailSize = KMaxTrailLength / KUpdateInterval; } @@ -68,6 +113,7 @@ // void CLocationRecord::ConstructL() { + LOG( "CLocationRecord::ConstructL(), begin" ); const TInt KMillion = 1000000; TInt err = iProperty.Define( KPSUidLocationTrail, KLocationTrailState, RProperty::EInt ); if ( err != KErrNone && err != KErrAlreadyExists ) @@ -77,18 +123,36 @@ User::LeaveIfError( iProperty.Set( KPSUidLocationTrail, KLocationTrailState, (TInt) RLocationTrail::ETrailStopped ) ); - iNetworkInfo = CNetworkInfo::NewL( this ); + + iNetworkInfoChangeListener = CNetworkInfo::NewL( this ); iPositionInfo = CPositionInfo::NewL( this ); iRemapper = CLocationRemappingAO::NewL(); iNetworkInfoTimer = CPeriodic::NewL( CActive::EPriorityStandard ); - + +#ifdef LOC_REVERSEGEOCODE + iTagCreator = CTagCreator::NewL(); + + + if (!iRevGeocoderPlugin) + { + iRevGeocoderPlugin = reinterpret_cast( + REComSession::CreateImplementationL(KReverseGeoCodeUid,iDtorKey)); + if(iRevGeocoderPlugin) + { + iRevGeocoderPlugin->AddObserverL(*this); + } + } + + #endif + + TInt interval( 0 ); TRAP(err, ReadCenRepValueL(KIntervalKey, interval)); - LOG1("CLocationManagerServer::ConstructL, cenrep interval value:%d", interval); + LOG1("Cenrep interval value:%d", interval); if (interval == 0 || err != KErrNone ) { - LOG1("CLocationManagerServer::ConstructL, cenrep interval err:%d", err); + LOG1("Cenrep interval err:%d", err); iInterval = KUpdateInterval; } else @@ -97,14 +161,25 @@ } TRAP(err, ReadCenRepValueL(KLocationDeltaKey, iLocationDelta)); - LOG1("CLocationManagerServer::ConstructL, location delta value:%d", iLocationDelta); + LOG1("Location delta value:%d", iLocationDelta); if (iLocationDelta == 0) { - LOG1("CLocationManagerServer::ConstructL, location delta err:%d", err); + LOG1("Location delta err:%d", err); iLocationDelta = KLocationDelta; } + iLastMediaItem.iFlag = 0; + iLastMediaItem.iLocationId = 0; +#ifdef LOC_REVERSEGEOCODE + iLastMediaItem.iCityTagId= 0; + iLastMediaItem.iCountryTagId = 0; + iLastLocationItem.iFlag = 0; + iLastLocationItem.iCityTagId= 0; + iLastLocationItem.iCountryTagId = 0; + iLastLocationItem.iLocationId = 0; +#endif + LOG( "CLocationRecord::ConstructL(), end" ); } // -------------------------------------------------------------------------- @@ -113,19 +188,72 @@ // EXPORT_C CLocationRecord::~CLocationRecord() { + LOG( "CLocationRecord::~CLocationRecord(), begin" ); Stop(); iProperty.Delete( KPSUidLocationTrail, KLocationTrailState ); iProperty.Close(); + iTrail.ResetAndDestroy(); iTrail.Close(); - - delete iNetworkInfo; + iMediaItems.ResetAndDestroy(); + iMediaItems.Close(); +#ifdef LOC_REVERSEGEOCODE + iLocationItems.ResetAndDestroy(); + iLocationItems.Close(); +#endif + delete iNetworkInfoChangeListener; delete iPositionInfo; delete iNetworkInfoTimer; - if (iRemapper) +#ifdef LOC_GEOTAGGING_CELLID + if(iGeoConverter) + { + delete iGeoConverter; + iGeoConverter = NULL; + } +#endif + if (iRemapper) { iRemapper->StopRemapping(); delete iRemapper; } + if(iLocationQuery) + { + iLocationQuery->RemoveObserver(*this); + iLocationQuery->Cancel(); + delete iLocationQuery; + iLocationQuery = NULL; + } + +if(iNetLocationQuery) + { + iNetLocationQuery->RemoveObserver(*this); + iNetLocationQuery->Cancel(); + delete iNetLocationQuery; + iNetLocationQuery = NULL; + } + + +#ifdef LOC_REVERSEGEOCODE + if(iImageQuery) + { + iImageQuery->RemoveObserver(*this); + iImageQuery->Cancel(); + delete iImageQuery; + iImageQuery = NULL; + } + if(iTagQuery) + { + iTagQuery->RemoveObserver(*this); + iTagQuery->Cancel(); + delete iTagQuery; + iTagQuery = NULL; + } + delete iTagCreator; + // set the pointer to NULL, ECOM will destroy object. + delete iRevGeocoderPlugin; + iRevGeocoderPlugin = NULL; + REComSession::DestroyedImplementation(iDtorKey); +#endif + LOG( "CLocationRecord::~CLocationRecord(), end" ); } // -------------------------------------------------------------------------- @@ -145,12 +273,17 @@ { LOG( "CLocationRecord::StartL(), begin" ); iTrailCaptureSetting = aCaptureSetting; + iGpsDataAvailableFlag = EFalse; if ( aCaptureSetting == RLocationTrail::ECaptureAll && !iPositionInfo->IsActive() ) { if( iState == RLocationTrail::ETrailStopped ) { - iTrail.Reset(); + iTrail.ResetAndDestroy(); } + // Capture at least one location with n/w info else we wouldn't be able to tag the immediate taken photograph + // incase LBS didn't provide any valid position data. Without this there may be a leave from GetLocationByTimeL + // method while calling this from LocationSnapshotL method + UpdateNetworkInfo( this ); iPositionInfo->StartL( aCaptureSetting, iInterval ); } else if ( aCaptureSetting == RLocationTrail::ECaptureNetworkInfo ) @@ -167,11 +300,9 @@ StartTimerL(); } - iLastLocationId = 0; - + iTrailStarted = ETrue; SetCurrentState( RLocationTrail::ETrailStarting ); - iTrailStarted = ETrue; LOG( "CLocationRecord::StartL(), end" ); } @@ -183,8 +314,8 @@ { LOG( "CLocationRecord::StopL(), begin" ); iPositionInfo->Stop(); + iGpsDataAvailableFlag = EFalse; iTrailStarted = EFalse; - if ( iNetworkInfoTimer && iNetworkInfoTimer->IsActive() ) { iNetworkInfoTimer->Cancel(); @@ -224,22 +355,22 @@ LOG1( "CLocationRecord::GetLocationByTimeL - aTime: %Ld", aTime.Int64() ); TBuf str1; aTime.FormatL( str1, KDateTimeFormat ); - LOG1( "CLocationRecord::GetLocationByTimeL - aTime: %S", &str1 ); + // LOG1( "CLocationRecord::GetLocationByTimeL - aTime: %S", &str1 ); #endif TTimeIntervalSeconds interval; TTimeIntervalSeconds nextInterval; for ( TInt i(iTrail.Count()-1) ; i >= 0 && !posFound ; i-- ) { - TInt err = iTrail[i].iTimeStamp.SecondsFrom( aTime, interval ); + TInt err = iTrail[i]->iTimeStamp.SecondsFrom( aTime, interval ); TInt timeDiff = Abs( interval.Int() ); #ifdef _DEBUG - LOG1( "CLocationRecord::GetLocationByTimeL - Trail timestamp: %Ld", iTrail[i].iTimeStamp.Int64() ); + LOG1( "CLocationRecord::GetLocationByTimeL - Trail timestamp: %Ld", iTrail[i]->iTimeStamp.Int64() ); TBuf str; - iTrail[i].iTimeStamp.FormatL( str, KDateTimeFormat ); - LOG1( "CLocationRecord::GetLocationByTimeL - Trail timestamp: %S", &str ); + iTrail[i]->iTimeStamp.FormatL( str, KDateTimeFormat ); + //LOG1( "CLocationRecord::GetLocationByTimeL - Trail timestamp: %S", &str ); LOG1( "CLocationRecord::GetLocationByTimeL - timeDiff: %d", timeDiff ); #endif @@ -248,25 +379,25 @@ // The nearest time is in iTrail[i] or in iTrail[i-1]. if ( i > 0 ) { - iTrail[i-1].iTimeStamp.SecondsFrom( aTime, nextInterval ); + iTrail[i-1]->iTimeStamp.SecondsFrom( aTime, nextInterval ); TInt nextDiff = Abs( nextInterval.Int() ); if ( nextDiff < timeDiff ) { - aLocationData = iTrail[i-1].iLocationData; - aState = iTrail[i-1].iTrailState; + aLocationData = iTrail[i-1]->iLocationData; + aState = iTrail[i-1]->iTrailState; } else { - aLocationData = iTrail[i].iLocationData; - aState = iTrail[i].iTrailState; + aLocationData = iTrail[i]->iLocationData; + aState = iTrail[i]->iTrailState; } } else { - aLocationData = iTrail[i].iLocationData; - aState = iTrail[i].iTrailState; + aLocationData = iTrail[i]->iLocationData; + aState = iTrail[i]->iTrailState; } posFound = ETrue; } @@ -284,11 +415,15 @@ // EXPORT_C void CLocationRecord::RequestLocationL() { + LOG( "CLocationRecord::RequestLocationL(), begin" ); iRequestCurrentLoc = ETrue; if ( iTrailCaptureSetting != RLocationTrail::ECaptureNetworkInfo && !iPositionInfo->IsActive() ) { iPositionInfo->StartL( iTrailCaptureSetting, iInterval ); + SetCurrentState( RLocationTrail::ETrailStarting ); + + iTrailStarted = ETrue; } else if ( iTrailCaptureSetting == RLocationTrail::ECaptureNetworkInfo ) { @@ -298,6 +433,7 @@ iObserver->CurrentLocation( posInfo, network, KErrNone ); iRequestCurrentLoc = EFalse; } + LOG( "CLocationRecord::RequestLocationL(), end" ); } // -------------------------------------------------------------------------- @@ -306,11 +442,14 @@ // EXPORT_C void CLocationRecord::CancelLocationRequest() { + LOG( "CLocationRecord::CancelLocationRequest(), begin" ); iRequestCurrentLoc = EFalse; if ( !iTrailStarted ) { + iGpsDataAvailableFlag = EFalse; iPositionInfo->Stop(); } + LOG( "CLocationRecord::CancelLocationRequest(), end" ); } @@ -351,6 +490,7 @@ void CLocationRecord::Position( const TPositionInfo& aPositionInfo, const TInt aError ) { + LOG( "CLocationRecord::Position(), begin" ); const TPositionSatelliteInfo& positionSatelliteInfo = static_cast(aPositionInfo); @@ -358,56 +498,59 @@ { HandleLocationRequest( positionSatelliteInfo, aError ); } - if( iState == RLocationTrail::ETrailStopped ) - { - LOG("CLocationRecord::Position - trail stopped"); - return; - } + + iGpsDataAvailableFlag = EFalse; - if ( !iTrailStarted ) + if ( !iTrailStarted || iState == RLocationTrail::ETrailStopped) { - iPositionInfo->NextPosition(); + LOG("trail not started/stopped"); + iPositionInfo->Stop(); return; } + // all cases store the location.. + StoreLocation( positionSatelliteInfo ); + + if ( RemappingNeeded() ) + { + //either network or gps signal is available + if ( ( iNetwork.iCellId != 0 && + iNetwork.iCountryCode.Length() != 0 && + iNetwork.iNetworkId.Length() != 0 ) || ( aError == KErrNone ) ) + { + //no error means gps info available + TRAP_IGNORE( RemapObjectsL( aError == KErrNone ) ); + } + } switch ( aError ) { case KPositionPartialUpdate: // fall through case KPositionQualityLoss: { // Location is stored, even if it may not be valid. - StoreLocation( positionSatelliteInfo ); - LOG("CLocationRecord::Position - partial update"); + LOG("Partial update"); if ( iState != RLocationTrail::EWaitingGPSData && iState != RLocationTrail::ETrailStopping ) { SetCurrentState( RLocationTrail::EWaitingGPSData ); - LOG("CLocationRecord::Position trail waiting for gps"); + LOG("Trail waiting for gps"); } break; } case KErrNone: { - StoreLocation( positionSatelliteInfo ); - LOG("CLocationRecord::Position - good GPS coordinates"); + LOG("Good GPS coordinates"); + iGpsDataAvailableFlag = ETrue; if ( iState != RLocationTrail::ETrailStarted ) { if ( iRemapper ) { - LOG("CLocationRecord::Position start remapping"); - iLastLocationId = 0; - TBool createLocation = iRemapper->CheckQueue(); - if( createLocation ) - { - TRAP_IGNORE( - TItemId locationId = DoCreateLocationL( iNewItem.iLocationData ); - iRemapper->UpdateRelationsL( locationId ); - ) - } + LOG("Start remapping"); iRemapper->StartRemappingObjects( iNewItem.iLocationData ); if( iObserver->WaitForPositioningStopTimeout() && !RemappingNeeded() ) { iObserver->RemapedCompleted(); + iPositionInfo->HandleRemapComplete(); return; } @@ -415,47 +558,135 @@ if ( iState != RLocationTrail::ETrailStopping ) { SetCurrentState( RLocationTrail::ETrailStarted ); - LOG("CLocationRecord::Position trail started"); + LOG("Trail started"); } } break; } default: { - StoreLocation( positionSatelliteInfo ); - LOG1("CLocationRecord::Position - searching GPS, aError %d", aError ); + LOG1("Searching GPS, aError %d", aError ); if ( iState != RLocationTrail::ESearchingGPS && iState != RLocationTrail::ETrailStopping ) { SetCurrentState( RLocationTrail::ESearchingGPS ); - LOG("CLocationRecord::Position trail searching gps"); + LOG("Trail searching gps"); } break; } } TBool fixState = CheckGPSFix( positionSatelliteInfo ); - LOG1( "CLocationRecord::Position fixState %d", fixState ); - LOG1( "CLocationRecord::Position iLastGPSFixState %d", iLastGPSFixState ); + LOG1( "fixState %d", fixState ); + LOG1( "iLastGPSFixState %d", iLastGPSFixState ); if ( iObserver && iLastGPSFixState != fixState ) { - LOG("CLocationRecord::Position quality changed"); + LOG("Quality changed"); iObserver->GPSSignalQualityChanged( positionSatelliteInfo ); } iLastGPSFixState = fixState; - iPositionInfo->NextPosition(); + LOG( "CLocationRecord::Position(), end" ); + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::RemapObjectsL +// Remaps the location objects when GPS is available +// -------------------------------------------------------------------------- +// +void CLocationRecord::RemapObjectsL( TBool aGPSInfoAvailable ) + { + LOG( "CLocationRecord::RemapObjectsL(), begin" ); + TBool createLocation = EFalse; + + if (iRemapper) + { + createLocation = iRemapper->CheckQueue(); + } + + if ( !createLocation || iRemapper == NULL) + { + return; + } + + + if ( aGPSInfoAvailable ) + { + TItemId locationId = DoCreateLocationL( iNewItem.iLocationData ); + iRemapper->UpdateRelationsL( locationId ); +#ifdef LOC_REVERSEGEOCODE + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress)) + { + iRemapState = ERemapRevGeoCodeInProgress; + //Find the address by coordinate, results a call to ReverseGeocodeComplete() + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + + if(iRevGeocoderPlugin) + { + iRevGeocoderPlugin->GetAddressByCoordinateL( iNewItem.iLocationData.iPosition, iConnectionOption ); + } + } + else + { + // make this as pending state so that on rev geo code complete + // it will take the priority over the next item within the location + // item in location queue. + iRemapState = ERemapRevGeoCodePending; + } +#endif //LOC_REVERSEGEOCODE + } + else + { + //call location m/w API to convert cell ID to lat, long +#ifdef LOC_GEOTAGGING_CELLID + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0) + { + iRemapState = ERemapNwGeoConverterPending; + } + else + { + // go for cell id based geo coding. + iRemapState = ERemapNwGeoConverterInProgress; + if(iGeoConverter == NULL) + { + iGeoConverter = CGeoConverter::NewL(*this); + } + iGeoConverter->ConvertL(iNewItem.iLocationData.iNetworkInfo); + iMediaHandlingFlag |= KSnapGeoConvertInProgress; + } +#endif + } +#ifdef LOC_REVERSEGEOCODE + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0 || + (iMediaHandlingFlag & KReverseGeoCodingInProgress) > 0) +#else + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0 ) +#endif //LOC_REVERSEGEOCODE + { + // stop n/w info change listener, since device may connect to n/w + // and local trail will receive so many call backs on current n/w info change. + iNetworkInfoChangeListener->StopNwInfoChangeNotifier(); + } + else + { + iNetworkInfoChangeListener->StartNwInfoChangeNotifier(); + } + LOG( "CLocationRecord::RemapObjectsL(), end" ); + } TBool CLocationRecord::CheckGPSFix( const TPositionSatelliteInfo& aSatelliteInfo ) { + LOG("CLocationRecord::CheckGPSFix, begin"); TPosition position; aSatelliteInfo.GetPosition( position ); - LOG1( "CLocationRecord::CheckGPSFix latitude %f", position.Latitude() ); - LOG1( "CLocationRecord::CheckGPSFix longitude %f", position.Longitude() ); + LOG1( "latitude %f", position.Latitude() ); + LOG1( "longitude %f", position.Longitude() ); TBool ret = ( Math::IsNaN(position.Latitude()) || Math::IsNaN(position.Longitude()) ) ? EFalse : ETrue; + LOG1("CLocationRecord::CheckGPSFix, end. Ret - %d", ret); return ret; } @@ -467,7 +698,7 @@ void CLocationRecord::NetworkInfo( const CTelephony::TNetworkInfoV1 &aNetworkInfo, const TInt aError ) { - LOG("CLocationRecord::NetworkInfo"); + LOG("CLocationRecord::NetworkInfo, begin"); if ( aError == KErrNone ) { LOG("CLocationRecord::NetworkInfo - KErrNone"); @@ -492,6 +723,17 @@ iNetwork.iCountryCode.Zero(); iNetwork.iNetworkId.Zero(); } + LOG( "CLocationRecord::NetworkInfo(), end" ); + } + +// -------------------------------------------------------------------------- +// CLocationRecord::GetMobilePhone4NwInfo +// -------------------------------------------------------------------------- +// +RMobilePhone& CLocationRecord::GetMobilePhone4NwInfo() + { + LOG( "CLocationRecord::GetMobilePhone4NwInfo()" ); + return iPhone; } // -------------------------------------------------------------------------- @@ -500,6 +742,7 @@ // void CLocationRecord::StoreLocation( const TPositionSatelliteInfo& aSatelliteInfo ) { + LOG( "CLocationRecord::StoreLocation(), begin" ); aSatelliteInfo.GetPosition( iNewItem.iLocationData.iPosition ); aSatelliteInfo.GetCourse( iNewItem.iLocationData.iCourse ); iNewItem.iLocationData.iSatellites = aSatelliteInfo.NumSatellitesUsed(); @@ -511,7 +754,13 @@ iNewItem.iTimeStamp.UniversalTime(); iNewItem.iTrailState = iState; - TInt error = iTrail.Append( iNewItem ); + TLocationTrailItem *item = new TLocationTrailItem(); + TInt error = KErrNone; + if(item != NULL) + { + *item = iNewItem; + error = iTrail.Append( item ); + } // If appending an item to the trail fails because of OOM, remove oldest trail items // until the new item fits or there's only one item left in the trail. @@ -519,18 +768,22 @@ { LOG("CLocationRecord::StoreLocation - Out of memory! Shortening trail!"); iTrail.Remove( 0 ); - error = iTrail.Append( iNewItem ); + error = iTrail.Append( item ); } if ( iTrail.Count() > iMaxTrailSize ) { + item = iTrail[0]; iTrail.Remove( 0 ); + iTrail.Compress(); + delete item; } if( iAddObserver ) { iAddObserver->LocationAdded( iNewItem, aSatelliteInfo ); } + LOG( "CLocationRecord::StoreLocation(), end" ); } // -------------------------------------------------------------------------- @@ -541,7 +794,33 @@ { LOG1( "CLocationRecord::SetCurrentState(), begin, state:%d", aState ); iState = aState; - iProperty.Set( KPSUidLocationTrail, KLocationTrailState, (TInt) aState ); + if( iTrailStarted ) + { + // Set the property only when trail is started to avoid icon flickering and wrong icon update in UI + if( iGpsDataAvailableFlag || + iNetwork.iCellId > 0 && + ((iNetwork.iLocationAreaCode == 0 && iNetwork.iAccess == CTelephony::ENetworkAccessUtran) || // 3G + (iNetwork.iLocationAreaCode > 0 && (iNetwork.iAccess == CTelephony::ENetworkAccessGsm || // 2G + iNetwork.iAccess == CTelephony::ENetworkAccessGsmCompact))) && + iNetwork.iCountryCode.Length() > 0 && + iNetwork.iNetworkId.Length() > 0 ) + { + // set the value 3 to have Geo tag available icon else not available. + iProperty.Set( KPSUidLocationTrail, KLocationTrailState, + (TInt) RLocationTrail::ETrailStarted ); + } + else + { + iProperty.Set( KPSUidLocationTrail, KLocationTrailState, + (TInt) RLocationTrail::ETrailStopped ); + } + } + else + { + iProperty.Set( KPSUidLocationTrail, KLocationTrailState, + (TInt) RLocationTrail::ETrailStopped ); + } + if ( iObserver ) { iObserver->LocationTrailStateChange(); @@ -556,6 +835,7 @@ void CLocationRecord::HandleLocationRequest( const TPositionSatelliteInfo& aSatelliteInfo, const TInt aError ) { + LOG( "CLocationRecord::HandleLocationRequest(), begin" ); CTelephony::TNetworkInfoV1 network = CTelephony::TNetworkInfoV1(); if ( aError == KErrNone ) { @@ -564,6 +844,7 @@ iRequestCurrentLoc = EFalse; if ( !iTrailStarted ) { + iGpsDataAvailableFlag = EFalse; iPositionInfo->Stop(); } } @@ -577,12 +858,19 @@ iLocationCounter = 0; if ( !iTrailStarted ) { + iGpsDataAvailableFlag = EFalse; iPositionInfo->Stop(); } } - } + } + LOG( "CLocationRecord::HandleLocationRequest(), end" ); } + +// -------------------------------------------------------------------------- +// CLocationRecord::UpdateNetworkInfo +// -------------------------------------------------------------------------- +// TInt CLocationRecord::UpdateNetworkInfo( TAny* aAny ) { TPositionSatelliteInfo nullPositionInfo; @@ -595,124 +883,167 @@ EXPORT_C void CLocationRecord::CreateLocationObjectL( const TLocationData& aLocationData, const TUint& aObjectId ) { - TItemId locationId = DoCreateLocationL( aLocationData ); - CreateRelationL( aObjectId, locationId ); + LOG( "CLocationRecord::CreateLocationObjectL(), begin" ); + TLocationSnapshotItem* newItem = new (ELeave) TLocationSnapshotItem; + newItem->iObjectId = aObjectId; + newItem->iLocationData = aLocationData; + + // for downloaded files, network informations are not valid. + // Do location handling only based on lat/lon + // all all n/w information to invalid value. + newItem->iLocationData.iNetworkInfo.iCellId = 0; + newItem->iLocationData.iNetworkInfo.iAccess = CTelephony::ENetworkAccessUnknown; + newItem->iLocationData.iNetworkInfo.iLocationAreaCode = 0; + newItem->iLocationData.iNetworkInfo.iCountryCode.Zero(); + newItem->iLocationData.iNetworkInfo.iNetworkId.Zero(); + newItem->iFlag = KDownloadMediaFile; + + iMediaItems.Append( newItem ); + FindLocationFromDBL(); + GeoTaggingCompleted(); + LOG( "CLocationRecord::CreateLocationObjectL(), end" ); + } - +// -------------------------------------------------------------------------- +// CLocationRecord::LocationSnapshotL +// -------------------------------------------------------------------------- +// EXPORT_C void CLocationRecord::LocationSnapshotL( const TUint& aObjectId ) { - LOG("CLocationRecord::LocationSnapshotL"); - + LOG( "CLocationRecord::LocationSnapshotL(), begin" ); TBool previousMatch = EFalse; - CMdENamespaceDef& namespaceDef = iMdeSession->GetDefaultNamespaceDefL(); // get locationdata from trail with object time TTime timestamp = GetMdeObjectTimeL( aObjectId ); TLocationData locationData; TLocTrailState state; - GetLocationByTimeL( timestamp, locationData, state ); - - iObjectId = aObjectId; - iLocationData = locationData; + TRAPD(err, GetLocationByTimeL( timestamp, locationData, state )); + if(err != KErrNone && iTrailStarted) + { + // Execution shouldn't come over here. + // Handling error case in worst sceenario.. + StartL(iTrailCaptureSetting); + // this case may apprear, when cache data is not within the delta limit because someone call stop trail. + // sceenario, take photograph, then stop taking for sometime, again take photograph. + // during this time, if there is no change in position (because someone stop trail) and n/w, then cache has old value. + // go with the n/w based. + LOG( "Old trail cache. go for n/w based." ); + UpdateNetworkInfo( this ); + // again read the location. + GetLocationByTimeL( timestamp, locationData, state ); + } + TLocationSnapshotItem* newItem = new (ELeave) TLocationSnapshotItem; + newItem->iObjectId = aObjectId; + newItem->iLocationData = locationData; + newItem->iFlag = KSnapMediaFile; + + iMediaItems.Append( newItem ); + TItemId lastLocationId = 0; + if ( (iLastMediaItem.iFlag & KSnapMediaFile) > 0) + { + lastLocationId = iLastMediaItem.iLocationId; + } + + CTelephony::TNetworkInfoV1* net = &locationData.iNetworkInfo; // capture only network data if ( iTrailCaptureSetting == RLocationTrail::ECaptureNetworkInfo ) { - CTelephony::TNetworkInfoV1* net = &locationData.iNetworkInfo; + if ( net->iCellId == 0 && + net->iLocationAreaCode == 0 && + net->iCountryCode.Length() == 0 && + net->iNetworkId.Length() == 0 ) + { + // no n/w info... put it into remap. + // remove the last appended element. + LOG("No network info (offline mode + no GPS fix), keep for remapping"); + TRemapItem remapItem; + remapItem.iObjectId = aObjectId; + remapItem.iTime = timestamp; + iRemapper->Append( remapItem ); + TLocationSnapshotItem* firstPtr = iMediaItems[iMediaItems.Count() - 1]; + iMediaItems.Remove(iMediaItems.Count() - 1); + iMediaItems.Compress(); + delete firstPtr; + } + else + { + // n/w info available + NetworkInfoSnapshotL(); + } + } + else if ( Math::IsNaN( locationData.iPosition.Latitude() ) && + Math::IsNaN( locationData.iPosition.Longitude() )) + { + // coordinates empty, with or without cellular info + if ( net->iCellId == 0 && net->iLocationAreaCode == 0 && net->iCountryCode.Length() == 0 && net->iNetworkId.Length() == 0 ) { - // nothing to do - LOG("CLocationRecord::LocationSnapshotL - no network info available"); - } - else if ( iLastLocationId != 0 ) - { - CTelephony::TNetworkInfoV1* lastnet = &iLastLocation.iNetworkInfo; - - // compare to previous network info - TItemId locationId = iLastLocationId; - if ( lastnet->iCellId != net->iCellId || - lastnet->iLocationAreaCode != net->iLocationAreaCode || - lastnet->iCountryCode != net->iCountryCode || - lastnet->iNetworkId != net->iNetworkId ) - { - LOG("CLocationRecord::LocationSnapshotL - network info changed"); - locationId = DoCreateLocationL( locationData ); - } - CreateRelationL( aObjectId, locationId ); - } - else - { - // new location - TItemId locationId = DoCreateLocationL( locationData ); - CreateRelationL( aObjectId, locationId ); - } - return; - } - - // coordinates empty (will be remapped) - if ( Math::IsNaN( locationData.iPosition.Latitude() ) && - Math::IsNaN( locationData.iPosition.Longitude() )) - { - TRemapItem remapItem; - remapItem.iObjectId = aObjectId; - remapItem.iTime = timestamp; + LOG("No network info (offline mode + no GPS fix), keep for remapping"); + TRemapItem remapItem; + remapItem.iObjectId = aObjectId; + remapItem.iTime = timestamp; + iRemapper->Append( remapItem ); - CTelephony::TNetworkInfoV1* net = &locationData.iNetworkInfo; - - // no network info (offline mode + no GPS fix) - if ( net->iCellId == 0 && - net->iLocationAreaCode == 0 && - net->iCountryCode.Length() == 0 && - net->iNetworkId.Length() == 0 ) - { - LOG("CLocationRecord::LocationSnapshotL - empty remap item created"); + TLocationSnapshotItem* firstPtr = iMediaItems[iMediaItems.Count() - 1]; + iMediaItems.Remove(iMediaItems.Count() - 1); + iMediaItems.Compress(); + delete firstPtr; } // check match for last created locationobject - else if ( iLastLocationId != 0 ) +#ifdef LOC_REVERSEGEOCODE + else if ( (iLastMediaItem.iFlag & KSnapMediaFile) > 0 && + iLastMediaItem.iCountryTagId > 0) +#else + else if ( (iLastMediaItem.iFlag & KSnapMediaFile) > 0) +#endif //LOC_REVERSEGEOCODE { - TItemId locationId; - CTelephony::TNetworkInfoV1* lastnet = &iLastLocation.iNetworkInfo; + TLocationData lastLocationData = iLastMediaItem.iLocationData; + CTelephony::TNetworkInfoV1* lastnet = &lastLocationData.iNetworkInfo; // networkinfo changed from last location - if ( lastnet->iCellId != net->iCellId || - lastnet->iLocationAreaCode != net->iLocationAreaCode || - lastnet->iCountryCode != net->iCountryCode || - lastnet->iNetworkId != net->iNetworkId ) + if ( lastnet->iCellId == net->iCellId && + lastnet->iLocationAreaCode == net->iLocationAreaCode && + lastnet->iCountryCode == net->iCountryCode && + lastnet->iNetworkId == net->iNetworkId ) { - LOG("CLocationRecord::LocationSnapshotL - remap with new network info"); - locationId = DoCreateLocationL( locationData ); - } - else - { - LOG("CLocationRecord::LocationSnapshotL - remap with previous network info"); - locationId = iLastLocationId; + // same network. + previousMatch = ETrue; + CreateRelationL( aObjectId, lastLocationId ); + // attach same tags associated to last location +#ifdef LOC_REVERSEGEOCODE + if ( iLastMediaItem.iCountryTagId ) //found from DB last time + { + iTagCreator->AttachTagsL( aObjectId, + iLastMediaItem.iCountryTagId, iLastMediaItem.iCityTagId ); + } +#endif //LOC_REVERSEGEOCODE + // remove the current item. + TLocationSnapshotItem* firstPtr = iMediaItems[iMediaItems.Count() - 1]; + iMediaItems.Remove(iMediaItems.Count() - 1); + iMediaItems.Compress(); + delete firstPtr; } - TItemId relationId = CreateRelationL( aObjectId, locationId ); - remapItem.iLocationId = locationId; - remapItem.iRelationId = relationId; } - else - { - // new location with only network data - TItemId locationId = DoCreateLocationL( locationData ); - TItemId relationId = CreateRelationL( aObjectId, locationId ); - remapItem.iLocationId = locationId; - remapItem.iRelationId = relationId; - } - iRemapper->Append( remapItem ); - return; + + if ( !previousMatch ) + { + // go for n/w based + newItem->iFlag |= KNetQueryBit; + } } - + // valid coordinates found - if ( iLastLocationId != 0 ) + else if ( lastLocationId != 0 && + ((iLastMediaItem.iFlag & KSnapMediaFile) > 0)) { - CTelephony::TNetworkInfoV1* net = &locationData.iNetworkInfo; - CTelephony::TNetworkInfoV1* lastnet = &iLastLocation.iNetworkInfo; + TLocationData lastLocationData = iLastMediaItem.iLocationData; + CTelephony::TNetworkInfoV1* lastnet = &lastLocationData.iNetworkInfo; // first check if networkinfo matches last created location if ( lastnet->iCellId == net->iCellId && @@ -720,23 +1051,60 @@ lastnet->iCountryCode == net->iCountryCode && lastnet->iNetworkId == net->iNetworkId ) { - LOG("CLocationRecord::LocationSnapshotL - network info matches"); // if both locations have valid coordinates, calculate distance between points - if ( !Math::IsNaN( iLastLocation.iPosition.Latitude() ) && - !Math::IsNaN( iLastLocation.iPosition.Longitude() ) && + if ( !Math::IsNaN( lastLocationData.iPosition.Latitude() ) && + !Math::IsNaN( lastLocationData.iPosition.Longitude() ) && !Math::IsNaN( locationData.iPosition.Latitude() ) && !Math::IsNaN( locationData.iPosition.Longitude() )) { TReal32 distance; - TInt err = locationData.iPosition.Distance(iLastLocation.iPosition, distance); + TInt err = locationData.iPosition.Distance(lastLocationData.iPosition, distance); if ( distance < iLocationDelta ) { - LOG("CLocationRecord::LocationSnapshotL - location close to the previous one"); + LOG("location close to the previous one"); previousMatch = ETrue; - CreateRelationL( aObjectId, iLastLocationId ); - LOG("CLocationRecord::CreateLocationObjectL - last location matched"); + CreateRelationL( aObjectId, lastLocationId ); + +#ifdef LOC_REVERSEGEOCODE + // attach same tags associated to last location + if ( iLastMediaItem.iCountryTagId ) + { + iTagCreator->AttachTagsL( + aObjectId, iLastMediaItem.iCountryTagId, iLastMediaItem.iCityTagId ); + TLocationSnapshotItem* firstPtr = iMediaItems[iMediaItems.Count() - 1]; + iMediaItems.Remove(iMediaItems.Count() - 1); + iMediaItems.Compress(); + delete firstPtr; + } + else + { + // country tag not found.. go for reverse geocoding.. + newItem->iLocationId = lastLocationId; + iLocationItems.Append( newItem ); + iMediaItems.Remove(iMediaItems.Count() - 1); + iMediaItems.Compress(); + + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress)) + { + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + if(iRevGeocoderPlugin) + { + iRevGeocoderPlugin->GetAddressByCoordinateL + ( iLocationItems[0]->iLocationData.iPosition, + iConnectionOption); + } + } + } +#else + // remove from the queue + TLocationSnapshotItem* firstPtr = iMediaItems[iMediaItems.Count() - 1]; + iMediaItems.Remove(iMediaItems.Count() - 1); + iMediaItems.Compress(); + delete firstPtr; + +#endif //LOC_REVERSEGEOCODE } } } @@ -745,109 +1113,194 @@ // last location did not match, find existing one from DB if( !previousMatch ) { - LOG("CLocationRecord::LocationSnapshotL - query location"); - const TReal64 KMeterInDegrees = 0.000009; - const TReal64 KPi = 3.14159265358979; - const TReal32 K180Degrees = 180.0; - - TReal64 latitude = locationData.iPosition.Latitude(); - TReal64 longitude = locationData.iPosition.Longitude(); - // calculate distance in degrees - TReal64 cosine; - Math::Cos(cosine, locationData.iPosition.Latitude() * KPi / K180Degrees ); - TReal64 latDelta = iLocationDelta * KMeterInDegrees; - TReal64 lonDelta = latDelta * cosine; - - CMdEObjectDef& locationObjectDef = namespaceDef.GetObjectDefL( Location::KLocationObject ); - - CMdEPropertyDef& latitudeDef = locationObjectDef.GetPropertyDefL( - Location::KLatitudeProperty ); - CMdEPropertyDef& longitudeDef = locationObjectDef.GetPropertyDefL( - Location::KLongitudeProperty ); - CMdEPropertyDef& cellIdDef = locationObjectDef.GetPropertyDefL( - Location::KCellIdProperty ); - CMdEPropertyDef& locationCodeDef = locationObjectDef.GetPropertyDefL( - Location::KLocationAreaCodeProperty ); - CMdEPropertyDef& countryCodeDef = locationObjectDef.GetPropertyDefL( - Location::KCountryCodeProperty ); - CMdEPropertyDef& networkCodeDef = locationObjectDef.GetPropertyDefL( - Location::KNetworkCodeProperty ); - - iLocationQuery = iMdeSession->NewObjectQueryL( namespaceDef, locationObjectDef, this ); - CMdELogicCondition& cond = iLocationQuery->Conditions(); - cond.SetOperator( ELogicConditionOperatorAnd ); - - LOG1( "CLocationRecord::LocationSnapshotL latitude: %f", latitude); - LOG1( "CLocationRecord::LocationSnapshotL latdelta: %f", latDelta); - LOG1( "CLocationRecord::LocationSnapshotL longitude: %f", longitude); - LOG1( "CLocationRecord::LocationSnapshotL londelta: %f", lonDelta); - - cond.AddPropertyConditionL( latitudeDef, - TMdERealBetween( latitude - latDelta, latitude + latDelta )); - cond.AddPropertyConditionL( longitudeDef, - TMdERealBetween( longitude - lonDelta, longitude + lonDelta )); - cond.AddPropertyConditionL( cellIdDef, - TMdEUintEqual( locationData.iNetworkInfo.iCellId) ); - cond.AddPropertyConditionL( locationCodeDef, - TMdEUintEqual( locationData.iNetworkInfo.iLocationAreaCode) ); - cond.AddPropertyConditionL( countryCodeDef, ETextPropertyConditionCompareEquals, - locationData.iNetworkInfo.iCountryCode ); - cond.AddPropertyConditionL( networkCodeDef, ETextPropertyConditionCompareEquals, - locationData.iNetworkInfo.iNetworkId ); - - iLocationQuery->FindL(); + FindLocationFromDBL(); } + LOG( "CLocationRecord::LocationSnapshotL(), end" ); } - -TItemId CLocationRecord::DoCreateLocationL( const TLocationData& aLocationData ) + +// -------------------------------------------------------------------------- +// CLocationRecord::NetworkInfoSnapshotL +// -------------------------------------------------------------------------- +// +void CLocationRecord::NetworkInfoSnapshotL() + { + LOG( "CLocationRecord::NetworkInfoSnapshotL(), begin" ); + // n/w info available.. always act on last element within the queue + TInt lastItemIndex = iMediaItems.Count() - 1; + if ( lastItemIndex >= 0 && + (iMediaItems[lastItemIndex]->iFlag & KSnapMediaFile) > 0 ) + { + CTelephony::TNetworkInfoV1* net = &iMediaItems[lastItemIndex]->iLocationData.iNetworkInfo; + //only for snap item. + if ( (iLastMediaItem.iFlag & KSnapMediaFile) > 0 ) + { + CTelephony::TNetworkInfoV1* lastnet = &iLastMediaItem.iLocationData.iNetworkInfo; + + // compare to previous network info + TItemId locationId = iLastMediaItem.iLocationId; + if ( lastnet->iCellId != net->iCellId || + lastnet->iLocationAreaCode != net->iLocationAreaCode || + lastnet->iCountryCode != net->iCountryCode || + lastnet->iNetworkId != net->iNetworkId ) + { + // last one is not matching. + // let's check the database of any existing etry. + iMediaItems[lastItemIndex]->iFlag |= KNetQueryBit; + } + else + { + // matching with the last entry. Just create a relation. + CreateRelationL( iMediaItems[lastItemIndex]->iObjectId, locationId ); + TLocationSnapshotItem* firstPtr = iMediaItems[lastItemIndex]; + iMediaItems.Remove(lastItemIndex); + delete firstPtr; + } + } + else + { + // let's check the database of any existing etry. + iMediaItems[lastItemIndex]->iFlag |= KNetQueryBit; + } + } + LOG( "CLocationRecord::NetworkInfoSnapshotL(), end" ); + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::FindLocationFromDBL +// -------------------------------------------------------------------------- +// +void CLocationRecord::FindLocationFromDBL() + { + LOG( "CLocationRecord::FindLocationFromDBL(), begin" ); + if(((iMediaHandlingFlag & KLocationQueryInProgress)> 0) + || (iMediaItems.Count() <= 0)) + { + // query is in progress or queue is empty + LOG1( "query is in progress or queue is empty. Count - %d", iMediaItems.Count() ); + return; + } + if ( (iMediaItems[0]->iFlag & KNetQueryBit) > 0 ) + { + // n/w based. + FindLocationWithSameNetInfoL(); + return; + } + + const TReal64 KMeterInDegrees = 0.000009; + const TReal64 KPi = 3.14159265358979; + const TReal32 K180Degrees = 180.0; + + //TLocationData locationData = iMediaItems[0].iLocationData; + + TReal64 latitude = iMediaItems[0]->iLocationData.iPosition.Latitude(); + TReal64 longitude = iMediaItems[0]->iLocationData.iPosition.Longitude(); + // calculate distance in degrees + TReal64 cosine; + Math::Cos(cosine, latitude * KPi / K180Degrees ); + TReal64 latDelta = iLocationDelta * KMeterInDegrees; + TReal64 lonDelta = latDelta * cosine; + + //get network related defs + CMdEPropertyDef& cellIdDef = iLocationObjectDef->GetPropertyDefL( + Location::KCellIdProperty ); + CMdEPropertyDef& locationCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KLocationAreaCodeProperty ); + CMdEPropertyDef& countryCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KCountryCodeProperty ); + CMdEPropertyDef& networkCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KNetworkCodeProperty ); + if(iLocationQuery) + { + iLocationQuery->RemoveObserver(*this); + iLocationQuery->Cancel(); + delete iLocationQuery; + iLocationQuery = NULL; + } + iLocationQuery = iMdeSession->NewObjectQueryL( *iNamespaceDef, *iLocationObjectDef, this ); + + CMdELogicCondition& cond = iLocationQuery->Conditions(); + cond.SetOperator( ELogicConditionOperatorAnd ); + + LOG1( "latitude: %f", latitude); + LOG1( "latdelta: %f", latDelta); + LOG1( "longitude: %f", longitude); + LOG1( "londelta: %f", lonDelta); + + cond.AddPropertyConditionL( *iLatitudeDef, + TMdERealBetween( latitude - latDelta, latitude + latDelta )); + cond.AddPropertyConditionL( *iLongitudeDef, + TMdERealBetween( longitude - lonDelta, longitude + lonDelta )); + + if ( iMediaItems[0]->iLocationData.iNetworkInfo.iCellId > 0 ) + { + cond.AddPropertyConditionL( cellIdDef, + TMdEUintEqual( iMediaItems[0]->iLocationData.iNetworkInfo.iCellId) ); + } + if ( iMediaItems[0]->iLocationData.iNetworkInfo.iLocationAreaCode > 0 ) + { + cond.AddPropertyConditionL( locationCodeDef, + TMdEUintEqual( iMediaItems[0]->iLocationData.iNetworkInfo.iLocationAreaCode) ); + } + if ( iMediaItems[0]->iLocationData.iNetworkInfo.iCountryCode.Length() > 0 ) + { + cond.AddPropertyConditionL( countryCodeDef, ETextPropertyConditionCompareEquals, + iMediaItems[0]->iLocationData.iNetworkInfo.iCountryCode ); + } + if ( iMediaItems[0]->iLocationData.iNetworkInfo.iNetworkId.Length() > 0 ) + { + cond.AddPropertyConditionL( networkCodeDef, ETextPropertyConditionCompareEquals, + iMediaItems[0]->iLocationData.iNetworkInfo.iNetworkId ); + } + iMediaHandlingFlag |= KLocationQueryInProgress; + iLocationQuery->FindL(); + + LOG( "CLocationRecord::FindLocationFromDBL(), end" ); + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::DoCreateLocationL +// -------------------------------------------------------------------------- +// +TItemId CLocationRecord::DoCreateLocationL( const TLocationData& aLocationData ) { - LOG("CLocationRecord::DoCreateLocationL - start"); + LOG( "CLocationRecord::DoCreateLocationL(), begin" ); TItemId locationObjectId; - CMdENamespaceDef& namespaceDef = iMdeSession->GetDefaultNamespaceDefL(); - - CMdEObjectDef& locationObjectDef = namespaceDef.GetObjectDefL( Location::KLocationObject ); - // required object properties - CMdEPropertyDef& creationDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& creationDef = iLocationObjectDef->GetPropertyDefL( Object::KCreationDateProperty ); - CMdEPropertyDef& modifiedDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& modifiedDef = iLocationObjectDef->GetPropertyDefL( Object::KLastModifiedDateProperty ); - CMdEPropertyDef& sizeDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& sizeDef = iLocationObjectDef->GetPropertyDefL( Object::KSizeProperty ); - CMdEPropertyDef& itemTypeDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& itemTypeDef = iLocationObjectDef->GetPropertyDefL( Object::KItemTypeProperty ); - CMdEPropertyDef& offSetDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& offSetDef = iLocationObjectDef->GetPropertyDefL( Object::KTimeOffsetProperty ); // location related properties - CMdEPropertyDef& cellIdDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& cellIdDef = iLocationObjectDef->GetPropertyDefL( Location::KCellIdProperty ); - CMdEPropertyDef& latitudeDef = locationObjectDef.GetPropertyDefL( - Location::KLatitudeProperty ); - CMdEPropertyDef& longitudeDef = locationObjectDef.GetPropertyDefL( - Location::KLongitudeProperty ); - CMdEPropertyDef& altitudeDef = locationObjectDef.GetPropertyDefL( - Location::KAltitudeProperty ); - - CMdEPropertyDef& directionDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& directionDef = iLocationObjectDef->GetPropertyDefL( Location::KDirectionProperty ); - CMdEPropertyDef& speedDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& speedDef = iLocationObjectDef->GetPropertyDefL( Location::KSpeedProperty ); - CMdEPropertyDef& locationCodeDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& locationCodeDef = iLocationObjectDef->GetPropertyDefL( Location::KLocationAreaCodeProperty ); - CMdEPropertyDef& countryCodeDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& countryCodeDef = iLocationObjectDef->GetPropertyDefL( Location::KCountryCodeProperty ); - CMdEPropertyDef& networkCodeDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& networkCodeDef = iLocationObjectDef->GetPropertyDefL( Location::KNetworkCodeProperty ); - CMdEPropertyDef& qualityDef = locationObjectDef.GetPropertyDefL( + CMdEPropertyDef& qualityDef = iLocationObjectDef->GetPropertyDefL( Location::KQualityProperty ); // location object CMdEObject* locationObject = NULL; - locationObject = iMdeSession->NewObjectL( locationObjectDef, Object::KAutomaticUri ); + locationObject = iMdeSession->NewObjectL( *iLocationObjectDef, Object::KAutomaticUri ); CleanupStack::PushL( locationObject ); TTime timestamp( 0 ); @@ -863,18 +1316,19 @@ locationObject->AddTextPropertyL( itemTypeDef, Location::KLocationItemType ); locationObject->AddInt16PropertyL( offSetDef, timeOffset.Int() / 60 ); - LOG1( "CLocationRecord::DoCreateLocationL - location created with stamp: %Ld", timestamp.Int64() ); + LOG1( "Location created with stamp: %Ld", timestamp.Int64() ); // location related properties if ( !Math::IsNaN( aLocationData.iPosition.Latitude() ) && !Math::IsNaN( aLocationData.iPosition.Longitude() )) { - locationObject->AddReal64PropertyL( latitudeDef, aLocationData.iPosition.Latitude() ); - locationObject->AddReal64PropertyL( longitudeDef, aLocationData.iPosition.Longitude() ); + locationObject->AddReal64PropertyL( *iLatitudeDef, aLocationData.iPosition.Latitude() ); + locationObject->AddReal64PropertyL( *iLongitudeDef, aLocationData.iPosition.Longitude() ); + } if ( !Math::IsNaN( aLocationData.iPosition.Altitude() ) ) { - locationObject->AddReal64PropertyL( altitudeDef, aLocationData.iPosition.Altitude() ); + locationObject->AddReal64PropertyL( *iAltitudeDef, aLocationData.iPosition.Altitude() ); } if ( !Math::IsNaN( aLocationData.iCourse.Course() ) ) { @@ -916,21 +1370,20 @@ } } - + // Add the location object to the database. locationObjectId = iMdeSession->AddObjectL( *locationObject ); - iLastLocationId = locationObjectId; - iLastLocation = aLocationData; + CleanupStack::PopAndDestroy( locationObject ); + LOG( "CLocationRecord::DoCreateLocationL(), end" ); - CleanupStack::PopAndDestroy( locationObject ); - - LOG("CLocationRecord::DoCreateLocationL - end"); - return locationObjectId; } - +// -------------------------------------------------------------------------- +// CLocationRecord::CreateRelationL +// -------------------------------------------------------------------------- +// TItemId CLocationRecord::CreateRelationL( const TUint& aObjectId, const TUint& aLocationId ) { LOG("CLocationRecord::CreateRelationL - start"); @@ -968,131 +1421,715 @@ LOG( "CLocationRecord::::ReadCenRepValueL(), end" ); } + +// -------------------------------------------------------------------------- +// CLocationRecord::HandleQueryNewResults +// -------------------------------------------------------------------------- +// void CLocationRecord::HandleQueryNewResults(CMdEQuery& /*aQuery*/, TInt /*aFirstNewItemIndex*/, TInt /*aNewItemCount*/) { } + +// -------------------------------------------------------------------------- +// CLocationRecord::HandleQueryCompleted +// -------------------------------------------------------------------------- +// void CLocationRecord::HandleQueryCompleted(CMdEQuery& aQuery, TInt aError) { LOG("CLocationRecord::HandleQueryCompleted - start"); const TInt count = aQuery.Count(); LOG1("CLocationRecord::HandleQueryCompleted count: %d", count); - - CMdENamespaceDef* namespaceDef = NULL; + + if ( aError != KErrNone ) + { + HandleQueryFailure(); + } + + else if ( &aQuery == iLocationQuery ) + { + + TRAPD(err,HandleLocationQueryL( aQuery )); + if(err != KErrNone) + { + // unable to process the first node.. + // remove this and process the next. - TRAP_IGNORE( namespaceDef = &iMdeSession->GetDefaultNamespaceDefL() ); - if ( namespaceDef ) + // reset the flag + HandleQueryFailure(); + } + + } + else if ( &aQuery == iNetLocationQuery ) { - CMdEObjectDef* locationObjectDef = NULL; + TRAPD(err,HandleNetLocationQueryL( aQuery )); + if(err != KErrNone) + { + // unable to process the first node.. + // remove this and process the next. + HandleQueryFailure(); + } + + } - TRAP_IGNORE( locationObjectDef = &namespaceDef->GetObjectDefL( Location::KLocationObject ) ); - if ( locationObjectDef ) - { - CMdEPropertyDef* latitudeDef = NULL; - CMdEPropertyDef* longitudeDef = NULL; - CMdEPropertyDef* altitudeDef = NULL; - - TRAP_IGNORE( - latitudeDef = &locationObjectDef->GetPropertyDefL( - Location::KLatitudeProperty ); - longitudeDef = &locationObjectDef->GetPropertyDefL( - Location::KLongitudeProperty ); - altitudeDef = &locationObjectDef->GetPropertyDefL( - Location::KAltitudeProperty ); - ); +#ifdef LOC_REVERSEGEOCODE + else if ( &aQuery == iImageQuery ) + { + if(aQuery.Count() > 0) + { + + CMdERelation& relation = static_cast( aQuery.ResultItem( 0 ) ); + + TItemId imageId = relation.LeftObjectId(); + + TRAPD(err, GetTagsL( imageId ) ); + if(err != KErrNone) + { + // unable to process the first node.. + // remove this and process the next. + + // reset the flag + HandleQueryFailure(); + } + } + else + { + HandleQueryFailure(); + } + } + + else if ( &aQuery == iTagQuery ) + { + TRAPD(err, HandleTagQueryL( aQuery ) ); + + GeoTaggingCompleted(); + if(err != KErrNone) + { + // unable to process the first node.. + // remove this and process the next. + + // reset the flag + HandleQueryFailure(); + } + } +#endif //LOC_REVERSEGEOCODE + else + { + // execution should not come over here...still take recovery action. + HandleQueryFailure(); + } + GeoTaggingCompleted(); + LOG( "CLocationRecord::HandleQueryCompleted(), end" ); + } - if( latitudeDef && longitudeDef && altitudeDef ) - { - TBool created = EFalse; - for ( TInt i = 0; i < count; i++ ) - { - LOG1("CLocationRecord::HandleQueryCompleted check item: %d", i); - CMdEItem& item = aQuery.ResultItem(i); - CMdEObject& locationObject = static_cast(item); - - CMdEProperty* latProp = NULL; - CMdEProperty* lonProp = NULL; - CMdEProperty* altProp = NULL; - - locationObject.Property( *latitudeDef, latProp, 0 ); - locationObject.Property( *longitudeDef, lonProp, 0 ); - locationObject.Property( *altitudeDef, altProp, 0 ); - - if ( latProp && lonProp ) - { - TReal32 distance; - TCoordinate newCoords; - if ( altProp ) - { - TRAP_IGNORE( newCoords = TCoordinate( latProp->Real64ValueL(), lonProp->Real64ValueL(), (TReal32)altProp->Real64ValueL() ) ); - } - else - { - TRAP_IGNORE( newCoords = TCoordinate( latProp->Real64ValueL(), lonProp->Real64ValueL() ) ); - } - - const TInt err = iLocationData.iPosition.Distance(newCoords, distance); - - if ( distance < iLocationDelta ) - { - LOG("CLocationRecord::HandleQueryCompleted - match found in db"); - TRAPD( err, CreateRelationL( iObjectId, locationObject.Id() ) ); - if( err == KErrNone) - { - created = ETrue; - i = count; - } - else - { - aError = err; - } - } - } - } +// -------------------------------------------------------------------------- +// CLocationRecord::HandleQueryFailure() +// handle MDS query sceenario +// -------------------------------------------------------------------------- +// +void CLocationRecord::HandleQueryFailure() + { + LOG( "CLocationRecord::HandleQueryFailure(), begin" ); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + if ( iMediaItems.Count() > 0 ) + { + TLocationSnapshotItem* firstPtr = iMediaItems[0]; + iMediaItems.Remove(0); + delete firstPtr; + iMediaItems.Compress(); + HandleFindLocationFromDB(); + } + LOG( "CLocationRecord::HandleQueryFailure(), end" ); + } - if ( !created && aError == KErrNone ) - { - LOG("CLocationRecord::HandleQueryCompleted - no match found in db, create new"); - TInt locationId( 0 ); - TRAPD( err, locationId = DoCreateLocationL( iLocationData ) ); - LOG1("CLocationRecord::HandleQueryCompleted - DoCreateLocationL err: %d", err); - if( err == KErrNone ) - { - TRAP( err, CreateRelationL( iObjectId, locationId )); - LOG1("CLocationRecord::HandleQueryCompleted - CreateRelationL err: %d", err); - } - } - } +// -------------------------------------------------------------------------- +// CLocationRecord::HandleFindLocationFromDB() +// handle find location from DB within the non leaving method +// -------------------------------------------------------------------------- +// +void CLocationRecord::HandleFindLocationFromDB() + { + LOG( "CLocationRecord::HandleFindLocationFromDB(), begin" ); + if ( iMediaItems.Count() > 0 ) + { + //TODO: by module owner + TInt trapErr = KErrNone; + TRAP(trapErr,FindLocationFromDBL()); + // no memory, don't proceed further + // other error sceenario, we can move the node to the end and process the next + if(trapErr != KErrNoMemory && trapErr != KErrNone) + { + // other than no memory + TInt numberOfNodes = iMediaItems.Count(); + LOG1("media count - %d\n", numberOfNodes); + while(--numberOfNodes >= 0 && + trapErr != KErrNoMemory && + trapErr != KErrNone) + { + // first remove the node + TLocationSnapshotItem* firstPtr = iMediaItems[0]; + iMediaItems.Remove(0); + // move this to last + iMediaItems.Append(firstPtr); + iMediaItems.Compress(); + trapErr = KErrNone; + // process for the next till we reached the last node. + TRAP(trapErr,FindLocationFromDBL()); + } + } + } + LOG( "CLocationRecord::HandleFindLocationFromDB(), end" ); + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::HandleLocationQuery() +// handle if only gps info available +// -------------------------------------------------------------------------- +// +void CLocationRecord::HandleLocationQueryL( CMdEQuery& aQuery ) + { + LOG( "CLocationRecord::HandleLocationQueryL(), begin" ); + TInt error = KErrNone; + TUint locationId( 0 ); + if ( iMediaItems.Count() <= 0 ) + { + LOG("CLocationRecord::HandleLocationQueryL. No media items to process"); + return; + } + + TLocationData locationData = iMediaItems[0]->iLocationData; + + const TInt count = aQuery.Count(); + //find any location matches + for ( TInt i = 0; i < count; i++ ) + { + LOG1("CLocationRecord::HandleLocationQueryL check item: %d", i); + CMdEItem& item = aQuery.ResultItem(i); + CMdEObject& locationObject = static_cast(item); + + CMdEProperty* latProp = NULL; + CMdEProperty* lonProp = NULL; + CMdEProperty* altProp = NULL; + + locationObject.Property( *iLatitudeDef, latProp, 0 ); + locationObject.Property( *iLongitudeDef, lonProp, 0 ); + locationObject.Property( *iAltitudeDef, altProp, 0 ); + + if ( latProp && lonProp ) + { + TReal32 distance; + TCoordinate newCoords; + + TReal64 lat = latProp->Real64ValueL(); + TReal64 lon = lonProp->Real64ValueL(); + if ( altProp ) + { + TReal32 alt = (TReal32)altProp->Real64ValueL(); + newCoords = TCoordinate( lat, lon, alt ); + } + else + { + newCoords = TCoordinate( lat, lon ); + } + + locationData.iPosition.Distance(newCoords, distance); + + if ( distance < iLocationDelta ) + { + i = count; + locationId = locationObject.Id(); + iMediaItems[0]->iLocationId = locationId; + break; + } } } + + + if ( locationId ) + { + TRAP( error, CreateRelationL( iMediaItems[0]->iObjectId, locationId ) ); + +#ifdef LOC_REVERSEGEOCODE + if( error == KErrNone) + { + //find out if image for this location is tagged already + GetRelatedImageL( locationId ); + } +#else + TLocationSnapshotItem* firstPtr = iMediaItems[0]; + iMediaItems.Remove(0); + delete firstPtr; + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + if ( iMediaItems.Count() > 0 ) + { + FindLocationFromDBL(); + } +#endif //LOC_REVERSEGEOCODE + } + else + { + + if((iMediaItems[0]->iFlag & KDownloadMediaFile) > 0) + { + locationData.iNetworkInfo.iCellId = 0; + locationData.iNetworkInfo.iAccess = CTelephony::ENetworkAccessUnknown; + locationData.iNetworkInfo.iLocationAreaCode = 0; + locationData.iNetworkInfo.iCountryCode.Zero(); + locationData.iNetworkInfo.iNetworkId.Zero(); + } + TRAP( error, locationId = DoCreateLocationL( locationData ) ); - LOG("CLocationRecord::HandleQueryCompleted - end"); + if ( error == KErrNone ) + { + iMediaItems[0]->iLocationId = locationId; + TRAP( error, CreateRelationL( iMediaItems[0]->iObjectId, locationId )); + } + + TLocationSnapshotItem* item = iMediaItems[0]; + if((iMediaItems[0]->iFlag & KSnapMediaFile) > 0) + { + iLastMediaItem = *(iMediaItems[0]); + } + iMediaItems.Remove(0); + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + if ( error == KErrNone ) + { + //Find the address by coordinate, results a call to ReverseGeocodeComplete() +#ifdef LOC_REVERSEGEOCODE + iLocationItems.Append( item ); + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress)) + { + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + + if(iRevGeocoderPlugin) + { + iRevGeocoderPlugin->GetAddressByCoordinateL + ( iLocationItems[0]->iLocationData.iPosition, + iConnectionOption); + } + } +#else + // free resources + delete item; +#endif //LOC_REVERSEGEOCODE + } + else + { + // free resources + delete item; + } + + if ( iMediaItems.Count() > 0 ) + { + FindLocationFromDBL(); + } + } + LOG( "CLocationRecord::HandleLocationQueryL(), end" ); + } +// -------------------------------------------------------------------------- +// CLocationRecord::HandleNetLocationQuery() +// handle if only network info available +// -------------------------------------------------------------------------- +// +void CLocationRecord::HandleNetLocationQueryL( CMdEQuery& aQuery ) + { + LOG( "CLocationRecord::HandleNetLocationQueryL(), begin" ); + TInt error = KErrNone; + TUint locationId( 0 ); + if ( iMediaItems.Count() <= 0 ) + { + LOG("CLocationRecord::HandleNetLocationQueryL(), End. No media items to process\n"); + return; + } + if( aQuery.Count() ) + { + CMdEItem& item = aQuery.ResultItem(0); + CMdEObject& locationObject = static_cast(item); + locationId = locationObject.Id(); + + TRAP( error, CreateRelationL( iMediaItems[0]->iObjectId, locationId ) ); +#ifdef LOC_REVERSEGEOCODE + //check if found location object has lat, long + CMdEProperty* latProp = NULL; + CMdEProperty* lonProp = NULL; + CMdEProperty* cellIdProp = NULL; + CMdEProperty* areadCodeProp = NULL; + CMdEProperty* countryProp = NULL; + CMdEProperty* networkCodeProp = NULL; + if ( error == KErrNone ) + { + + CMdEPropertyDef& cellIdDef = iLocationObjectDef->GetPropertyDefL( + Location::KCellIdProperty ); + CMdEPropertyDef& locationAreadCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KLocationAreaCodeProperty ); + CMdEPropertyDef& countryCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KCountryCodeProperty ); + CMdEPropertyDef& networkCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KNetworkCodeProperty ); + + locationObject.Property( *iLatitudeDef, latProp, 0 ); + locationObject.Property( *iLongitudeDef, lonProp, 0 ); + + locationObject.Property( cellIdDef, cellIdProp, 0 ); + locationObject.Property( locationAreadCodeDef, areadCodeProp, 0 ); + locationObject.Property( countryCodeDef, countryProp, 0 ); + locationObject.Property( networkCodeDef, networkCodeProp, 0 ); + } + + if( (latProp && lonProp) + || (cellIdProp && areadCodeProp && countryProp && networkCodeProp) ) + { + //find out if image for this location is tagged already + GetRelatedImageL( locationId ); + } + else +#endif //LOC_REVERSEGEOCODE + { + // no geo info.. remove the item and proceed for the next. + TLocationSnapshotItem* firstPtr = iMediaItems[0]; + iMediaItems.Remove(0); + delete firstPtr; + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + if ( iMediaItems.Count() > 0 ) + { + FindLocationFromDBL(); + } + } + } + else + { +#ifdef LOC_GEOTAGGING_CELLID + LOG1("Media handling flag = %d", iMediaHandlingFlag); + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0) + { + iMediaHandlingFlag |= KSnapGeoConvertInPendingState; + } + else + { + // go for cell id based geo coding. + if(iGeoConverter == NULL) + { + iGeoConverter = CGeoConverter::NewL(*this); + } + iGeoConverter->ConvertL(iMediaItems[0]->iLocationData.iNetworkInfo); + iMediaHandlingFlag |= KSnapGeoConvertInProgress; + iMediaHandlingFlag &= ~KSnapGeoConvertInPendingState; + } +#else + locationId = DoCreateLocationL( iMediaItems[0]->iLocationData ); + iMediaItems[0]->iLocationId = locationId; + CreateRelationL( iMediaItems[0]->iObjectId, locationId ); + TLocationSnapshotItem* firstPtr = iMediaItems[0]; + iMediaItems.Remove(0); + delete firstPtr; + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + if ( iMediaItems.Count() > 0 ) + { + FindLocationFromDBL(); + } +#endif + } +#ifdef LOC_REVERSEGEOCODE + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0 || + (iMediaHandlingFlag & KReverseGeoCodingInProgress) > 0) +#else + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0) +#endif //LOC_REVERSEGEOCODE + { + // stop n/w info change listener, since device may connect to n/w + // and local trail will receive so many call backs on current n/w info change. + iNetworkInfoChangeListener->StopNwInfoChangeNotifier(); + } + else + { + iNetworkInfoChangeListener->StartNwInfoChangeNotifier(); + } + LOG( "CLocationRecord::HandleNetLocationQueryL(), end" ); + + } + + +#ifdef LOC_GEOTAGGING_CELLID +// -------------------------------------------------------------------------- +// CLocationRecord::ConversionCompletedL() +// -------------------------------------------------------------------------- +// +void CLocationRecord::ConversionCompletedL( const TInt aError, TLocality& aPosition ) + { + + LOG1("CLocationRecord::ConversionCompletedL, begin. Error - %d", aError); + // reset the flag first + iMediaHandlingFlag &= ~KSnapGeoConvertInProgress; + LOG1("iRemapState - %d", iRemapState); + if(aError == KErrNone) + { + iConvertRetry = ETrue; + LOG("Conversion completed successfully"); + if(iRemapState == ERemapNwGeoConverterInProgress) + { + iNewItem.iLocationData.iPosition.SetCoordinate + ( aPosition.Latitude(), aPosition.Longitude(), aPosition.Altitude()); + iNewItem.iLocationData.iQuality = aPosition.HorizontalAccuracy(); + TItemId locationId = DoCreateLocationL( iNewItem.iLocationData ); + iRemapper->UpdateRelationsL( locationId ); + // TODO: remap. +#ifdef LOC_REVERSEGEOCODE + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress)) + { + iRemapState = ERemapRevGeoCodeInProgress; + //Find the address by coordinate, results a call to ReverseGeocodeComplete() + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + + if(iRevGeocoderPlugin) + { + iRevGeocoderPlugin->GetAddressByCoordinateL + ( iNewItem.iLocationData.iPosition, iConnectionOption ); + } + } + else + { + // remap in reverse geocoding pending state. + iRemapState = ERemapRevGeoCodePending; + } +#endif //LOC_REVERSEGEOCODE + } + else if ( iMediaItems.Count() > 0 ) + { + + iMediaItems[0]->iLocationData.iPosition.SetCoordinate + ( aPosition.Latitude(), aPosition.Longitude(), aPosition.Altitude()); + iMediaItems[0]->iLocationData.iQuality = aPosition.HorizontalAccuracy(); + TLocationSnapshotItem* item = iMediaItems[0]; + TItemId locationId = DoCreateLocationL( iMediaItems[0]->iLocationData ); + iMediaItems[0]->iLocationId = locationId; + CreateRelationL( iMediaItems[0]->iObjectId, locationId ); + if((iMediaItems[0]->iFlag & KSnapMediaFile) > 0) + { + iLastMediaItem = *(iMediaItems[0]); + } + iMediaItems.Remove(0); + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; +#ifdef LOC_REVERSEGEOCODE + iLocationItems.Append( item ); +#else + // free resource + delete item; +#endif + } + } + else + { + LOG1("Conversion error - %d", aError); + if(iConvertRetry) + { + LOG("Retry once"); + iConvertRetry = EFalse; + if(iRemapState == ERemapNwGeoConverterInProgress) + { + iRemapState = ERemapNwGeoConverterPending; + } + else if ( iMediaItems.Count() > 0 ) + { + iMediaHandlingFlag |= KSnapGeoConvertInPendingState; + } + } + else + { + if(iRemapState == ERemapNwGeoConverterInProgress) + { + iRemapState = ERemapProgressNone; + } + else if ( iMediaItems.Count() > 0 ) + { + TLocationSnapshotItem* item = iMediaItems[0]; + iMediaItems.Remove(0); + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + delete item; + } + } + + } + + // check the remap item first. + if(iRemapState == ERemapNwGeoConverterPending) + { + // go for cell id based geo coding. + iRemapState = ERemapNwGeoConverterInProgress; + iGeoConverter->ConvertL(iNewItem.iLocationData.iNetworkInfo); + iMediaHandlingFlag |= KSnapGeoConvertInProgress; + } + //check for media queue pending request. + else if((iMediaHandlingFlag & KSnapGeoConvertInPendingState) > 0) + { + // previous media queue geo convert is in pending state. + // go for cell id based geo coding. + iGeoConverter->ConvertL(iMediaItems[0]->iLocationData.iNetworkInfo); + iMediaHandlingFlag |= KSnapGeoConvertInProgress; + iMediaHandlingFlag &= ~KSnapGeoConvertInPendingState; + } + // let's not use multiple access point. +#ifdef LOC_REVERSEGEOCODE + else if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress) && + iLocationItems.Count() > 0) + { + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + + if(iRevGeocoderPlugin) + { + iRevGeocoderPlugin->GetAddressByCoordinateL + ( iLocationItems[0]->iLocationData.iPosition, + iConnectionOption); + } + } + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0 || + (iMediaHandlingFlag & KReverseGeoCodingInProgress) > 0) +#else + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0) +#endif //LOC_REVERSEGEOCODE + { + // stop n/w info change listener, since device may connect to n/w + // and local trail will receive so many call backs on current n/w info change. + iNetworkInfoChangeListener->StopNwInfoChangeNotifier(); + } + else + { + iNetworkInfoChangeListener->StartNwInfoChangeNotifier(); + } + FindLocationFromDBL(); + GeoTaggingCompleted(); + LOG("CLocationRecord::ConversionCompletedL, end"); + } + + +//------------------------------------------------------------------------ +// CLocationRecord::HandleConversionError +//------------------------------------------------------------------------ +// +void CLocationRecord::HandleConversionError(TInt aError) + { + LOG( "CLocationRecord::HandleConversionError(), begin" ); + ARG_USED(aError); + if(iRemapState == ERemapNwGeoConverterInProgress) + { + iRemapState = ERemapProgressNone; + } + else if ( iMediaItems.Count() > 0 ) + { + TLocationSnapshotItem* item = iMediaItems[0]; + iMediaItems.Remove(0); + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + delete item; + } + // let's not use multiple access point. +#ifdef LOC_REVERSEGEOCODE + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress) && + iLocationItems.Count() > 0) + { + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + + if(iRevGeocoderPlugin) + { + TRAP_IGNORE(iRevGeocoderPlugin->GetAddressByCoordinateL + ( iLocationItems[0]->iLocationData.iPosition, + iConnectionOption)); + } + } + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0 || + (iMediaHandlingFlag & KReverseGeoCodingInProgress) > 0) +#else + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0) +#endif //LOC_REVERSEGEOCODE + { + // stop n/w info change listener, since device may connect to n/w + // and local trail will receive so many call backs on current n/w info change. + iNetworkInfoChangeListener->StopNwInfoChangeNotifier(); + } + else + { + iNetworkInfoChangeListener->StartNwInfoChangeNotifier(); + } + TRAP_IGNORE(FindLocationFromDBL()); + GeoTaggingCompleted(); + LOG( "CLocationRecord::HandleConversionError(), end" ); + } + +#endif // LOC_GEOTAGGING_CELLID + +// -------------------------------------------------------------------------- +// CLocationRecord::SetMdeSession +// -------------------------------------------------------------------------- +// EXPORT_C void CLocationRecord::SetMdeSession( CMdESession* aSession ) { + LOG( "CLocationRecord::SetMdeSession(), begin" ); iMdeSession = aSession; +#ifdef LOC_REVERSEGEOCODE + iTagCreator->SetSession( aSession ); +#endif TRAPD(err, iRemapper->InitialiseL( aSession )); if( err != KErrNone ) { delete iRemapper; iRemapper = NULL; } + TRAP(err, InitialiseL() ); + LOG( "CLocationRecord::SetMdeSession(), end" ); } +// -------------------------------------------------------------------------- +// CLocationRecord::InitialiseL +// -------------------------------------------------------------------------- +// +void CLocationRecord::InitialiseL() + { + LOG( "CLocationRecord::InitialiseL(), begin" ); + // namespace defaults + iNamespaceDef = &iMdeSession->GetDefaultNamespaceDefL(); + + // location object definitions + iLocationObjectDef = &iNamespaceDef->GetObjectDefL( Location::KLocationObject ); + iLatitudeDef = &iLocationObjectDef->GetPropertyDefL( Location::KLatitudeProperty ); + iLongitudeDef = &iLocationObjectDef->GetPropertyDefL( Location::KLongitudeProperty ); + iAltitudeDef = &iLocationObjectDef->GetPropertyDefL( Location::KAltitudeProperty ); + LOG( "CLocationRecord::InitialiseL(), end" ); + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::StartTimerL +// -------------------------------------------------------------------------- +// void CLocationRecord::StartTimerL() { - LOG("CLocationRecord::StartTimerL"); + LOG("CLocationRecord::StartTimerL,begin"); if( !iNetworkInfoTimer->IsActive() ) { iNetworkInfoTimer->Start( iInterval, iInterval, TCallBack( UpdateNetworkInfo, this ) ); } + LOG( "CLocationRecord::StartL(), end" ); } + +// -------------------------------------------------------------------------- +// CLocationRecord::GetMdeObjectTimeL +// -------------------------------------------------------------------------- +// TTime CLocationRecord::GetMdeObjectTimeL( TItemId aObjectId ) { + LOG( "CLocationRecord::GetMdeObjectTimeL(), begin" ); CMdENamespaceDef& namespaceDef = iMdeSession->GetDefaultNamespaceDefL(); CMdEObjectDef& objectDef = namespaceDef.GetObjectDefL( Object::KBaseObject ); @@ -1114,11 +2151,79 @@ return timeValue; } + + +// -------------------------------------------------------------------------- +// CLocationRecord::RemappingNeeded +// -------------------------------------------------------------------------- +// EXPORT_C TBool CLocationRecord::RemappingNeeded() { - return iRemapper->ItemsInQueue(); + return ( iRemapper->ItemsInQueue() + && (iRemapState == ERemapProgressNone)); } + + + +// -------------------------------------------------------------------------- +// CLocationRecord::FindLocationWithSameNetInfoL() +// check any location object already exists with same network info +// -------------------------------------------------------------------------- +// +void CLocationRecord::FindLocationWithSameNetInfoL() + { + LOG( "CLocationRecord::FindLocationWithSameNetInfoL(), begin" ); + if(iMediaItems[0]->iLocationData.iNetworkInfo.iCellId > 0 && + iMediaItems[0]->iLocationData.iNetworkInfo.iCountryCode.Length() > 0 && + iMediaItems[0]->iLocationData.iNetworkInfo.iNetworkId.Length() > 0) + { + CMdEPropertyDef& cellIdDef = iLocationObjectDef->GetPropertyDefL( + Location::KCellIdProperty ); + CMdEPropertyDef& locationCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KLocationAreaCodeProperty ); + CMdEPropertyDef& countryCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KCountryCodeProperty ); + CMdEPropertyDef& networkCodeDef = iLocationObjectDef->GetPropertyDefL( + Location::KNetworkCodeProperty ); + + if(iNetLocationQuery) + { + iNetLocationQuery->RemoveObserver(*this); + iNetLocationQuery->Cancel(); + delete iNetLocationQuery; + iNetLocationQuery = NULL; + } + iNetLocationQuery = iMdeSession->NewObjectQueryL( *iNamespaceDef, *iLocationObjectDef, this ); + CMdELogicCondition& cond = iNetLocationQuery->Conditions(); + cond.SetOperator( ELogicConditionOperatorAnd ); + + cond.AddPropertyConditionL( cellIdDef, + TMdEUintEqual( iMediaItems[0]->iLocationData.iNetworkInfo.iCellId) ); + cond.AddPropertyConditionL( locationCodeDef, + TMdEUintEqual( iMediaItems[0]->iLocationData.iNetworkInfo.iLocationAreaCode) ); + cond.AddPropertyConditionL( countryCodeDef, ETextPropertyConditionCompareEquals, + iMediaItems[0]->iLocationData.iNetworkInfo.iCountryCode ); + cond.AddPropertyConditionL( networkCodeDef, ETextPropertyConditionCompareEquals, + iMediaItems[0]->iLocationData.iNetworkInfo.iNetworkId ); + + iNetLocationQuery->FindL(1, 1); + iMediaHandlingFlag |= KLocationQueryInProgress; + // iMediaHandlingFlag |= KNetQueryInProgress; + } + else + { + TLocationSnapshotItem* firstPtr = iMediaItems[0]; + iMediaItems.Remove(0); + delete firstPtr; + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + FindLocationFromDBL(); + } + LOG( "CLocationRecord::FindLocationWithSameNetInfoL(), end" ); + + } + EXPORT_C TBool CLocationRecord::IsLowBattery() { LOG("CLocationRecord::IsLowBattery()"); @@ -1135,7 +2240,526 @@ { return ETrue; } + } + +// -------------------------------------------------------------------------- +// CLocationRecord::GeoTaggingCompleted +// -------------------------------------------------------------------------- +// +void CLocationRecord::GeoTaggingCompleted() + { + LOG( "CLocationRecord::GeoTaggingCompleted(), begin" ); + if((iMediaItems.Count() == 0) +#ifdef LOC_REVERSEGEOCODE + && (iLocationItems.Count() == 0) +#endif //LOC_REVERSEGEOCODE + ) + { + LOG("Geo tagging completed"); + iGeoTaggerObserver.GeoTaggingCompleted(KErrNone); + // fallback to silent +#ifdef LOC_REVERSEGEOCODE + iConnectionOption = ESilent; +#endif //LOC_REVERSEGEOCODE + } + LOG( "CLocationRecord::GeoTaggingCompleted(), end" ); + } + + + + +// -------------------------------------------------------------------------- +// CLocationRecord::TaggingInProgress +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CLocationRecord::TaggingInProgress() + { + LOG( "CLocationRecord::TaggingInProgress(), begin" ); + TBool retVal = EFalse; +#ifdef LOC_REVERSEGEOCODE + if( ((iMediaItems.Count() > 0) || (iLocationItems.Count() > 0) ) + && (iRevGeocoderPlugin && iRevGeocoderPlugin->SilentConnectionAllowed())) +#else + if( iMediaItems.Count() > 0 ) + +#endif //LOC_REVERSEGEOCODE + { +#ifdef LOC_REVERSEGEOCODE + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress)) + { + // start geocoding + + if (iLocationItems.Count() > 0 ) + { + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + + TRAP_IGNORE( iRevGeocoderPlugin->GetAddressByCoordinateL( + iLocationItems[0]->iLocationData.iPosition, + iConnectionOption) ); + + retVal = ETrue; + } + } + else + { + retVal = ETrue; + } +#endif //LOC_REVERSEGEOCODE + if(!(iMediaHandlingFlag & KLocationQueryInProgress)) + { + if(iMediaItems.Count() > 0) + { + HandleFindLocationFromDB(); + retVal = ETrue; + } + } + else + { + retVal = ETrue; + } + } + else + { + // Flash the array to avoid double tagging by photos & localrail. + } + LOG( "CLocationRecord::TaggingInProgress(), end" ); + return retVal; + } + + +// ---------------------------------------------------------------------------- +// CLocationRecord::GetCurrentRegisteredNw() +// ---------------------------------------------------------------------------- +EXPORT_C RMobilePhone::TMobilePhoneNetworkInfoV2& CLocationRecord::GetCurrentRegisteredNw() + { + LOG( "CLocationRecord::GetCurrentRegisteredNw ,begin" ); + return iNetworkInfoChangeListener->GetCurrentRegisterNw(); + } + +// -------------------------------------------------------------------------- +// CLocationRecord::StartGeoTagging +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CLocationRecord::StartGeoTagging(const TConnectionOption aConnectionOption) + { + LOG( "CLocationRecord::StartGeoTagging(), begin" ); + TBool retVal = EFalse; + ARG_USED(aConnectionOption); + if((iMediaItems.Count() > 0) +#ifdef LOC_REVERSEGEOCODE + || (iLocationItems.Count() > 0) +#endif //LOC_REVERSEGEOCODE + ) + { +#ifdef LOC_REVERSEGEOCODE + iConnectionOption = aConnectionOption; + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress)) + { + // start geocoding + if (iLocationItems.Count() > 0 ) + { + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + if(iRevGeocoderPlugin) + { + TRAP_IGNORE( iRevGeocoderPlugin->GetAddressByCoordinateL( + iLocationItems[0]->iLocationData.iPosition, + iConnectionOption) ); + } + retVal = ETrue; + } + } + else + { + retVal = ETrue; + } +#endif //LOC_REVERSEGEOCODE + if(!(iMediaHandlingFlag & KLocationQueryInProgress)) + { + if(iMediaItems.Count() > 0) + { + HandleFindLocationFromDB(); + retVal = ETrue; + } + } + else + { + retVal = ETrue; + } + } + LOG( "CLocationRecord::StartGeoTagging(), end" ); + return retVal; + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::CancelGeoTagging +// -------------------------------------------------------------------------- +// +EXPORT_C void CLocationRecord::CancelGeoTagging() + { +#ifdef LOC_REVERSEGEOCODE + LOG1( "CLocationRecord::CancelGeoTagging(), Connetion opt - %d", + iConnectionOption ); + // set this to default connection. + iConnectionOption = ESilent; +#endif //LOC_REVERSEGEOCODE + } + + +#ifdef LOC_REVERSEGEOCODE + +// -------------------------------------------------------------------------- +// CLocationManagerServer::GetRelatedImages() +// Find any image, already related to this location object +// -------------------------------------------------------------------------- +// +void CLocationRecord::GetRelatedImageL(TItemId aLocID) + { + LOG( "CLocationRecord::GetRelatedImageL(), begin" ); + CMdEObjectDef& imageObjDef = iNamespaceDef->GetObjectDefL( Image::KImageObject ); + if(iImageQuery) + { + iImageQuery->RemoveObserver(*this); + iImageQuery->Cancel(); + delete iImageQuery; + iImageQuery = NULL; + } + + iImageQuery = iMdeSession->NewRelationQueryL( *iNamespaceDef, this ); + User::LeaveIfNull( iImageQuery ); + + iImageQuery->SetResultMode( EQueryResultModeItem ); + + // both left and right condition must match + CMdERelationCondition& filterCond = iImageQuery->Conditions(). + AddRelationConditionL( ERelationConditionSideRight ); + + // left one must be any image object. + filterCond.LeftL().AddObjectConditionL( imageObjDef ); + + // right one must be this location object + filterCond.RightL().AddObjectConditionL( aLocID ); + + iImageQuery->FindL(1, 1); // results to a call to HandleQueryCompleted() + LOG( "CLocationRecord::GetRelatedImageL(), end" ); } + + +// -------------------------------------------------------------------------- +// CLocationRecord::ReverseGeocodeComplete() +// Get address details like country, city.. +// Create country and city tags and attach to the current image/video object +// -------------------------------------------------------------------------- +// +void CLocationRecord::ReverseGeocodeComplete( TInt& aErrorcode, MAddressInfo& aAddressInfo ) + { + LOG( "CLocationRecord::ReverseGeocodeComplete(), begin" ); + TItemId countryTagId(0); + TItemId cityTagId(0); + + iMediaHandlingFlag &= (~KReverseGeoCodingInProgress); + TLocationSnapshotItem* snapshotItem = NULL; + if( aErrorcode == KErrNone ) + { + TPtrC countryPtr( aAddressInfo.GetCountryName() ); + TPtrC cityPtr( aAddressInfo.GetCity() ); + TRAP_IGNORE( iTagCreator->CreateLocationTagsL( countryPtr, countryTagId, + cityPtr, cityTagId ) ); + if ( iRemapState == ERemapRevGeoCodeInProgress) + { + TRAP_IGNORE( iRemapper->AttachGeoTagsL( iTagCreator, countryTagId, cityTagId ) ); + iRemapState = ERemapProgressNone; + } + else + { + if(iLocationItems.Count() > 0) + { + iLocationItems[0]->iCountryTagId = countryTagId; + iLocationItems[0]->iCityTagId = cityTagId; + iLastLocationItem = (*iLocationItems[0]); + + TRAP_IGNORE( iTagCreator->AttachTagsL( + iLocationItems[0]->iObjectId, countryTagId, cityTagId ) ); + } + } + if(iLastMediaItem.iFlag == 0) + { + LOG("Last media item is null\n"); + } + if ( iLastMediaItem.iFlag > 0 && iLastMediaItem.iLocationId == iLastLocationItem.iLocationId ) + { + LOG("Updating country/city\n"); + iLastMediaItem.iCountryTagId = countryTagId; + iLastMediaItem.iCityTagId = cityTagId; + } + + //check other items in the array has same location + for ( TInt index = iLocationItems.Count() - 1; index > 0; index--) + { + if ( iLocationItems[index]->iLocationId == iLastLocationItem.iLocationId ) + { + LOG1("Attached tags in for - %d\n", index); + TRAP_IGNORE( iTagCreator->AttachTagsL( + iLocationItems[index]->iObjectId, countryTagId, cityTagId ) ); + snapshotItem = iLocationItems[index]; + iLocationItems.Remove(index); + delete snapshotItem; + } + } + } + else + { + //handle error + } + + //irrespective of error or not, remove current(first) item to proceed further + if ( iLocationItems.Count() > 0 ) + { + snapshotItem = iLocationItems[0]; + iLocationItems.Remove(0); + delete snapshotItem; + iLocationItems.Compress(); + } + if (aErrorcode == KErrNone) + { + if(iRemapState == ERemapRevGeoCodePending) + { + if(iRevGeocoderPlugin) + { + TRAPD(err, iRevGeocoderPlugin->GetAddressByCoordinateL( iNewItem.iLocationData.iPosition, iConnectionOption );) + if(err == KErrNone) + { + // Remap geo coding in pending state + iRemapState = ERemapRevGeoCodeInProgress; + //Find the address by coordinate, results a call to ReverseGeocodeComplete() + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + } + } + } + else if(iLocationItems.Count() > 0) + { + if(iRevGeocoderPlugin) + { + TRAPD(err, iRevGeocoderPlugin->GetAddressByCoordinateL( + iLocationItems[0]->iLocationData.iPosition, + iConnectionOption) ); + if(err == KErrNone) + { + // queue is not empty process the next. + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + } + } + } + } + + GeoTaggingCompleted(); + if((iMediaHandlingFlag & KSnapGeoConvertInProgress) > 0 || + (iMediaHandlingFlag & KReverseGeoCodingInProgress) > 0) + { + // stop n/w info change listener, since device may connect to n/w + // and local trail will receive so many call backs on current n/w info change. + iNetworkInfoChangeListener->StopNwInfoChangeNotifier(); + } + else + { + iNetworkInfoChangeListener->StartNwInfoChangeNotifier(); + } + LOG( "CLocationRecord::ReverseGeocodeComplete(), end" ); + } + + +// ---------------------------------------------------------------------------- +// CLocationRecord::IsRegisteredAtHomeNetwork() +// ---------------------------------------------------------------------------- +TBool CLocationRecord::IsRegisteredAtHomeNetwork() + { + LOG( "CLocationRecord::IsRegisteredAtHomeNetwork" ); + return iGeoTaggerObserver.IsRegisteredAtHomeNetwork(); + } + +// ---------------------------------------------------------------------------- +// CLocationRecord::GetHomeNetworkInfo() +// ---------------------------------------------------------------------------- +const RMobilePhone::TMobilePhoneNetworkInfoV1& + CLocationRecord::GetHomeNetworkInfo(TBool& aHomeNwInfoAvailableFlag) + { + LOG( "CLocationRecord::GetHomeNetworkInfo" ); + return iGeoTaggerObserver.GetHomeNetworkInfo(aHomeNwInfoAvailableFlag); + } + +// ---------------------------------------------------------------------------- +// CLocationRecord::GetCurrentRegisterNw() +// ---------------------------------------------------------------------------- +RMobilePhone::TMobilePhoneNetworkInfoV2& CLocationRecord::GetCurrentRegisterNw() + { + LOG( "CLocationRecord::GetCurrentRegisterNw ,begin" ); + return GetCurrentRegisteredNw(); + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::HandleTagQuery() +// handle if only gps info available +// -------------------------------------------------------------------------- +// +void CLocationRecord::HandleTagQueryL( CMdEQuery& aQuery ) + { + LOG( "CLocationRecord::HandleTagQueryL(), begin" ); + TItemId countryTagId = 0; + TItemId cityTagId = 0; + TRAPD( error, FindCountryAndCityTagL( aQuery, countryTagId, cityTagId ) ); + if ( error == KErrNone ) + { + LOG1("Media count - %d\n", iMediaItems.Count()); + if ( !countryTagId && !cityTagId ) + { + if ( iMediaItems.Count() > 0 ) + { + iLocationItems.Append( iMediaItems[0] ); + if((iMediaItems[0]->iFlag & KSnapMediaFile) > 0) + { + iLastMediaItem = *(iMediaItems[0]); + } + iMediaItems.Remove(0); + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + } + +#ifdef LOC_REVERSEGEOCODE + if(!(iMediaHandlingFlag & KReverseGeoCodingInProgress) && + iLocationItems.Count() > 0) + { + iMediaHandlingFlag |= KReverseGeoCodingInProgress; + if(iRevGeocoderPlugin) + { + iRevGeocoderPlugin->GetAddressByCoordinateL + ( iLocationItems[0]->iLocationData.iPosition, + iConnectionOption); + } + } +#endif //LOC_REVERSEGEOCODE + } + else + { + + iTagCreator->AttachTagsL( iMediaItems[0]->iObjectId, countryTagId, cityTagId ); + if ( iMediaItems.Count() > 0 ) + { + iMediaItems[0]->iCountryTagId = countryTagId; + iMediaItems[0]->iCityTagId = cityTagId; + TLocationSnapshotItem* item = iMediaItems[0]; + if((iMediaItems[0]->iFlag & KSnapMediaFile) > 0) + { + iLastMediaItem = *item; + } + iMediaItems.Remove(0); + iMediaItems.Compress(); + iMediaHandlingFlag &= ~KLocationQueryInProgress; + delete item; + } + } + + } + if ( iMediaItems.Count() > 0 ) + { + FindLocationFromDBL(); + } + LOG( "CLocationRecord::HandleTagQueryL(), end" ); + } + + +// -------------------------------------------------------------------------- +// CLocationRecord::FindCountryAndCityTagL() +// Go through all attached tags to get location tags only +// -------------------------------------------------------------------------- +// +void CLocationRecord::FindCountryAndCityTagL( CMdEQuery& aQuery, + TItemId& aCountryTagId, TItemId& aCityTagId ) + { + LOG( "CLocationRecord::FindCountryAndCityTagL(), begin" ); + TItemId tagId = 0; + CMdEObject* object = NULL; + TInt error = KErrNone; + + const TInt count = aQuery.Count(); + + for ( TInt i = 0; i < count; i++ ) + { + CMdERelation& relation = static_cast( aQuery.ResultItem( i ) ); + + tagId = relation.RightObjectId(); + TRAP_IGNORE( object = iMdeSession->GetObjectL( tagId ) ); + + if ( !aCountryTagId ) + { + error = object->Uri().Find( KCountry ); + //just make sure 'country' appears first in the tag uri + if ( error == KErrNone ) + { + aCountryTagId = tagId; + continue; + } + } + + if ( !aCityTagId ) + { + error = object->Uri().Find( KCity ); + if ( error == KErrNone ) + { + aCityTagId = tagId; + } + } + + if ( aCountryTagId && aCityTagId ) + { + i = count; + } + } + LOG( "CLocationRecord::FindCountryAndCityTagL(), end" ); + + } + +// -------------------------------------------------------------------------- +// CLocationRecord::GetTagsL() +// -------------------------------------------------------------------------- +// +void CLocationRecord::GetTagsL( TItemId aImageID ) + { + LOG( "CLocationRecord::GetTagsL(), begin" ); + CMdEObjectDef& tagObjectDef = iNamespaceDef->GetObjectDefL( Tag::KTagObject ); + + if(iTagQuery) + { + iTagQuery->RemoveObserver(*this); + iTagQuery->Cancel(); + delete iTagQuery; + iTagQuery = NULL; + } + + iTagQuery = iMdeSession->NewRelationQueryL( *iNamespaceDef, this ); + User::LeaveIfNull( iTagQuery ); + + iTagQuery->SetResultMode( EQueryResultModeItem ); + + // both left and right condition must match + CMdERelationCondition& filterCond = iTagQuery->Conditions(). + AddRelationConditionL( ERelationConditionSideRight ); + + // left one must be this image object. + filterCond.LeftL().AddObjectConditionL( aImageID ); + + // right one must be tag object + filterCond.RightL().AddObjectConditionL( tagObjectDef ); + + iTagQuery->FindL(); // results to a call to HandleQueryCompleted() + LOG( "CLocationRecord::GetTagsL(), end" ); + } + + +#endif //LOC_REVERSEGEOCODE + // End of file + +