diff -r 1fc85118c3ae -r 870918037e16 mapnavproviderrefapp/src/mnrpengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mapnavproviderrefapp/src/mnrpengine.cpp Wed Sep 01 12:31:27 2010 +0100 @@ -0,0 +1,433 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CMnrpEngine class implementation +* +*/ + + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include "../inc/debug.h" +#include "mnrpengine.h" + +_LIT( KCitiesResourceFile, "\\resource\\mnrefproviderengine.rsc"); + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +CMnrpEngine::CMnrpEngine() + { + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C CMnrpEngine::~CMnrpEngine() + { + iPlaces.ResetAndDestroy(); + iFileSession.Close(); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C CMnrpEngine* CMnrpEngine::NewL() + { + CMnrpEngine* self = new (ELeave) CMnrpEngine(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CMnrpEngine::ConstructL() + { + User::LeaveIfError( iFileSession.Connect() ); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C TArray CMnrpEngine::KnownPlacesL() + { + if ( iPlaces.Count() == 0 ) + { + TRAP_IGNORE( LoadKnownPlacesL() ); + } + + return iPlaces.Array(); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordLC( const CPosLandmark& aAddress ) + { + CPosLandmark* lm = AddressToCoordL( aAddress ); + if ( lm ) + { + CleanupStack::PushL( lm ); + return lm; + } + else + { + User::Leave( KErrNotFound ); + return NULL; + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordL( const CPosLandmark& aAddress ) + { + TPtrC city, country; + aAddress.GetPositionField( EPositionFieldCity, city ); + + TArray pois = KnownPlacesL(); + + if ( city.Length() ) + { + for ( TInt i = 0; i < pois.Count(); i++ ) + { + TPtrC poiCity; + pois[i]->GetPositionField( EPositionFieldCity, poiCity ); + if ( poiCity.CompareF( city ) == 0 ) + { + return CPosLandmark::NewL( *pois[i] ); + } + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordLC( const TDesC& aAddress ) + { + CPosLandmark* lm = AddressToCoordL( aAddress ); + if ( lm ) + { + CleanupStack::PushL( lm ); + return lm; + } + else + { + User::Leave( KErrNotFound ); + return NULL; + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordL( const TDesC& aAddress ) + { + TArray pois = KnownPlacesL(); + + if ( aAddress.Length() ) + { + for ( TInt i = 0; i < pois.Count(); i++ ) + { + TPtrC city, country; + pois[i]->GetPositionField( EPositionFieldCity, city ); + pois[i]->GetPositionField( EPositionFieldCountry, country ); + + if ( aAddress.FindF( city ) >= 0 ) + { + return CPosLandmark::NewL( *pois[i] ); + } + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C TReal32 CMnrpEngine::DistanceBetweenLandmarks( + const CPosLandmark& aFrom, + const CPosLandmark& aTo ) + { + TRealX nan; + nan.SetNaN(); + TReal32 distance = nan; + + TLocality locFrom, locTo; + + if ( aFrom.GetPosition( locFrom ) == KErrNone && + aTo.GetPosition( locTo ) == KErrNone ) + { + TReal32 dist; + if ( locFrom.Distance( locTo, dist ) == KErrNone ) + { + distance = dist; + } + } + return distance; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMnrpEngine::FindClosestPoisL( + const CPosLandmark& aReference, + RArray& aNeighbourPois, + TInt aMaxMatches ) + { + aNeighbourPois.Reset(); + TArray pois = KnownPlacesL(); + + // calc distances to known places and find out closest ones + for ( TInt i = 0; i < pois.Count(); i++ ) + { + CPosLandmark* poi = pois[i]; + + TReal32 distance = DistanceBetweenLandmarks( aReference, *poi ); + + if ( Math::IsNaN( distance ) ) + { + continue; + } + + TDistanceToPoi newDistToPoi; + newDistToPoi.iPoiIndex = i; + newDistToPoi.iDistance = distance; + + for ( TInt k = 0; k < aNeighbourPois.Count(); k++ ) + { + TDistanceToPoi distToPoi = aNeighbourPois[k]; + if ( distance < distToPoi.iDistance ) + { + // current POI is closer to reference than current neighbour + aNeighbourPois.InsertL( newDistToPoi, k ); + break; + } + } + + if ( aNeighbourPois.Count() < aMaxMatches ) + { + aNeighbourPois.AppendL( newDistToPoi ); + } + + if ( aNeighbourPois.Count() > aMaxMatches ) + { + aNeighbourPois.Remove( aNeighbourPois.Count() - 1 ); // remove last + } + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +CPosLandmark* CMnrpEngine::CreateCloseLandmarkLC( + const CPosLandmark& aReference, + TReal32 aDistance ) + { + CPosLandmark* lm = CPosLandmark::NewLC( aReference ); + TPtrC oldName; + lm->GetLandmarkName( oldName ); + + // create street in the form of "50 km to " + const TInt KDistValueLen = 5; // "40000" + const TInt KAdditionalChars = 7; // " km to " + + _LIT( KLocationNameFormat, "%d m to %S" ); + _LIT( KLocationNameFormatKm, "%d km to %S" ); + + HBufC* locName = HBufC::NewLC( oldName.Length() + KDistValueLen + KAdditionalChars ); + + if ( aDistance < 1000 ) + { + locName->Des().Format( KLocationNameFormat, TInt( aDistance ), &oldName ); + } + else + { + locName->Des().Format( KLocationNameFormatKm, TInt( aDistance / 1000 ), &oldName ); + } + + lm->SetPositionFieldL( EPositionFieldLocationName, *locName ); + lm->SetPositionFieldL( EPositionFieldStreet, *locName ); + + CleanupStack::PopAndDestroy( locName ); + return lm; // left in stack + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C CPosLandmark* CMnrpEngine::CoordToAddressLC( const TCoordinate& aLocation ) + { + TArray pois = KnownPlacesL(); + + // find closest POI + RArray matches; + CleanupClosePushL( matches ); + + CPosLandmark* temp = CPosLandmark::NewLC(); + TLocality loc( aLocation, 0 ); // accuracy is not used by this implementation + temp->SetPositionL( loc ); + FindClosestPoisL( *temp, matches, 1 ); // only one match needed + CleanupStack::PopAndDestroy( temp ); + + if ( matches.Count() < 1 ) + { + User::Leave( KErrNotFound ); + } + + TDistanceToPoi distToPoi = matches[0]; + CleanupStack::PopAndDestroy( &matches ); + + CPosLandmark* lm = CreateCloseLandmarkLC( + *pois[distToPoi.iPoiIndex], + distToPoi.iDistance ); + + return lm; // left in stack + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMnrpEngine::BestCoordToAddressMatchesL( + const TCoordinate& aLocation, + RPointerArray& aMatches, + TInt aMaxMatches ) + { + TArray pois = KnownPlacesL(); + + // find closest POIs + RArray matches; + CleanupClosePushL( matches ); + + CPosLandmark* temp = CPosLandmark::NewLC(); + TLocality loc( aLocation, 0 ); // accuracy is not used by this implementation + temp->SetPositionL( loc ); + FindClosestPoisL( *temp, matches, aMaxMatches ); + CleanupStack::PopAndDestroy( temp ); + + for ( TInt i = 0; i < matches.Count(); i++ ) + { + TDistanceToPoi distToPoi = matches[i]; + + CPosLandmark* lm = CreateCloseLandmarkLC( + *pois[distToPoi.iPoiIndex], + distToPoi.iDistance ); + + aMatches.AppendL( lm ); + CleanupStack::Pop( lm ); + } + CleanupStack::PopAndDestroy( &matches ); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMnrpEngine::FindResourceFileL( + const TDesC& aFilePathAndName, + TFileName& aRscFile ) + { + TParse parse; + parse.Set( aFilePathAndName, NULL, NULL ); + + TFindFile finder( iFileSession ); + if ( finder.FindByDir( parse.NameAndExt(), parse.Path() ) == KErrNone ) + { + aRscFile.Copy( finder.File() ); + } + else + { + User::Leave( KErrNotFound ); + } + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +EXPORT_C RFs& CMnrpEngine::Fs() + { + return iFileSession; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CMnrpEngine::LoadKnownPlacesL() + { + TFileName resourceFile; + FindResourceFileL( KCitiesResourceFile(), resourceFile ); + + CResourceFile* resFile = CResourceFile::NewLC( iFileSession, resourceFile, 0, 0 ); + resFile->ConfirmSignatureL( 0 ); + + RResourceReader reader; + + reader.OpenLC( resFile, R_MNREFPROVIDERENGINE_PLACES ); + ReadPlacesResourceL( reader ); + CleanupStack::PopAndDestroy( &reader ); + + CleanupStack::PopAndDestroy( resFile ); + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +// +void CMnrpEngine::ReadPlacesResourceL( RResourceReader& aReader ) + { + TInt size = aReader.ReadInt16L(); + + for ( TInt i = 0; i < size; i++ ) + { + HBufC* city = aReader.ReadHBufCL(); + CleanupStack::PushL( city ); + HBufC* country = aReader.ReadHBufCL(); + CleanupStack::PushL( country ); + + TReal64 lat = aReader.ReadReal64L(); + TReal64 lon = aReader.ReadReal64L(); + + CPosLandmark* lm = CPosLandmark::NewLC(); + lm->SetLandmarkNameL( *city ); + + lm->SetPositionFieldL( EPositionFieldCity, *city ); + lm->SetPositionFieldL( EPositionFieldCountry, *country ); + + TLocality coord; + coord.SetCoordinate( lat, lon ); + lm->SetPositionL( coord ); + + iPlaces.AppendL( lm ); + CleanupStack::Pop( lm ); + CleanupStack::PopAndDestroy( country ); + CleanupStack::PopAndDestroy( city ); + } + }