mapnavproviderrefapp/src/mnrpmapmodel.cpp
branchRCL_3
changeset 17 1fc85118c3ae
parent 16 8173571d354e
child 18 870918037e16
equal deleted inserted replaced
16:8173571d354e 17:1fc85118c3ae
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  CMnrpMapModel class implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <coemain.h>
       
    21 #include <barsread.h>
       
    22 #include <bautils.h>
       
    23 
       
    24 #include <aknlists.h>
       
    25 #include <AknIconUtils.h>
       
    26 #include <AknWaitDialog.h>
       
    27 
       
    28 #include <fbs.h>
       
    29 #include <imageconversion.h>
       
    30 #include <icl/imagedata.h>
       
    31 
       
    32 #include <lbs.h>
       
    33 #include <lbsposition.h>
       
    34 #include <lbspositioninfo.h>
       
    35 
       
    36 #include <EPos_CPosLandmark.h>
       
    37 #include <EPos_CPosLandmarkDatabase.h>
       
    38 #include <EPos_CPosLandmarkCategory.h>
       
    39 #include <EPos_CPosLmCategoryManager.h>
       
    40 
       
    41 #include "debug.h"
       
    42 #include "mnrpengine.h"
       
    43 #include "mnrputils.h"
       
    44 #include "mnrpappserver.h"
       
    45 
       
    46 #include "mnrpmapviewservice.h"
       
    47 #ifdef RD_MAPNAV_BITMAP_ACCESS
       
    48 #include "mnrpmapimageservice.h"
       
    49 #endif
       
    50 #include "mnrpmapmodel.h"
       
    51 
       
    52 const TInt KUpdateInterval = 1 * 1000 * 1000; // 1 sec
       
    53 const TInt KUpdateTimeout = 10 * 1000 * 1000; // 10 sec
       
    54 
       
    55 const TInt KMaxX = 180;
       
    56 const TInt KMinX = -180;
       
    57 const TInt KMapWidth = KMaxX - KMinX;
       
    58 
       
    59 const TInt KMaxY = 90;
       
    60 const TInt KMinY = -90;
       
    61 const TInt KMapHeight = KMaxY - KMinY;
       
    62 
       
    63 const TReal KDegree = 1.0;
       
    64 const TReal KMinute = KDegree / 60.0;
       
    65 const TReal KSecond = KMinute / 60.0;
       
    66 const TReal KMilliSecond = KSecond / 1000.0;
       
    67 
       
    68 const TReal KMaxCell = 60 * KDegree;
       
    69 const TReal KMinScale = 10 * KMilliSecond; // 0.01 second / 1 px
       
    70 
       
    71 const TInt KBigCellsInView = 2;
       
    72 
       
    73 const TInt KCellDividers[] = { 6, 2, 5 };
       
    74 const TInt KNumCellDividers = 3;
       
    75 
       
    76 const TReal KDefaultRadius = 1; // 1 degree
       
    77 const TReal KRadiusBorderFactor = 1.1; // 110%
       
    78 
       
    79 const TReal KEarthEquator = 40075000;
       
    80 //const TReal KEarthRadius = 6371010;
       
    81 
       
    82 const TInt KLmTextOffset = 3;
       
    83 const TInt KLmTextShadowOffset = 1;
       
    84 
       
    85 const TInt KGridPenSize( 1 );
       
    86 
       
    87 // ============================ LOCAL FUNCTIONS ===============================
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 TPoint AbsoluteToImage( TRealPoint aAbsolute, TReal aImageToAbsoluteScale )
       
    93     {
       
    94     TInt s = ( KMapWidth / 2 + aAbsolute.iX ) / aImageToAbsoluteScale;
       
    95     TInt t = ( KMapHeight / 2 - aAbsolute.iY ) / aImageToAbsoluteScale;
       
    96 
       
    97     return TPoint( s , t );
       
    98     }
       
    99 
       
   100 // ============================ MEMBER CLASSES' FUNCTIONS ===============================
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 //  TRealPoint implementation
       
   104 // -----------------------------------------------------------------------------
       
   105 //
       
   106 
       
   107 TRealPoint::TRealPoint()
       
   108     {
       
   109     TRealX nan;
       
   110     nan.SetNaN();
       
   111 
       
   112     iX = nan;
       
   113     iY = nan;
       
   114     }
       
   115 
       
   116 TRealPoint::TRealPoint( TReal aX, TReal aY )
       
   117     : iX( aX ), iY( aY )
       
   118     {
       
   119     }
       
   120 
       
   121 TRealPoint::TRealPoint( TCoordinate aCoordinate )
       
   122     : iX( aCoordinate.Longitude() ), iY( aCoordinate.Latitude() )
       
   123     {
       
   124     }
       
   125 
       
   126 TCoordinate TRealPoint::Coordinate()
       
   127     {
       
   128     return TCoordinate( iY, iX );
       
   129     }
       
   130 
       
   131 TRealPoint TRealPoint::operator+(
       
   132     const TRealPoint& aRight )
       
   133     {
       
   134     return TRealPoint( this->iX + aRight.iX, this->iY + aRight.iY );
       
   135     }
       
   136 
       
   137 TRealPoint TRealPoint::operator-(
       
   138     const TRealPoint& aRight )
       
   139     {
       
   140     return TRealPoint( this->iX - aRight.iX, this->iY - aRight.iY );
       
   141     }
       
   142 
       
   143 TRealPoint TRealPoint::operator*( const TReal& aRight )
       
   144     {
       
   145     return TRealPoint( this->iX * aRight, this->iY * aRight );
       
   146     }
       
   147 
       
   148 TRealPoint TRealPoint::operator/( const TReal& aRight )
       
   149     {
       
   150     return TRealPoint( this->iX / aRight, this->iY / aRight );
       
   151     }
       
   152 
       
   153 void TRealPoint::Set( TReal aX, TReal aY )
       
   154     {
       
   155     iX = aX;
       
   156     iY = aY;
       
   157     }
       
   158 
       
   159 TBool TRealPoint::IsValid()
       
   160     {
       
   161     return ( !Math::IsNaN( iX ) && !Math::IsNaN( iY ) );
       
   162     }
       
   163 
       
   164 // -----------------------------------------------------------------------------
       
   165 //  CDrawItem implementation
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 CMnrpMapModel::CDrawItem* CMnrpMapModel::CDrawItem::NewLC(
       
   169     const CPosLandmark& aLm )
       
   170     {
       
   171     CDrawItem* self = new (ELeave) CDrawItem;
       
   172     CleanupStack::PushL( self );
       
   173 
       
   174     TPtrC name;
       
   175     aLm.GetLandmarkName( name );
       
   176     self->iText = MnrpUtils::PrintableStringLC( name );
       
   177     CleanupStack::Pop( self->iText );
       
   178 
       
   179     TLocality loc;
       
   180     if ( KErrNone == aLm.GetPosition( loc ) )
       
   181         {
       
   182         self->SetAbsolutePosition( loc );
       
   183         }
       
   184 
       
   185     TPtrC iconFile;
       
   186     TInt iconIndex, maskIndex;
       
   187     if ( KErrNone == aLm.GetIcon( iconFile, iconIndex, maskIndex ) )
       
   188         {
       
   189         AknIconUtils::CreateIconL( self->iBitmap, self->iMask, iconFile, iconIndex, maskIndex );
       
   190         AknIconUtils::PreserveIconData( self->iBitmap );
       
   191         }
       
   192 
       
   193     return self;
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 CMnrpMapModel::CDrawItem* CMnrpMapModel::CDrawItem::NewLC(
       
   200     const CPosLandmark& aLm,
       
   201     CPosLmCategoryManager& aCatman )
       
   202     {
       
   203     CDrawItem* self = NewLC( aLm );
       
   204 
       
   205     if ( !self->iBitmap )
       
   206         {
       
   207         // try icon from category
       
   208         RArray<TPosLmItemId> cats;
       
   209         CleanupClosePushL( cats );
       
   210         aLm.GetCategoriesL( cats );
       
   211 
       
   212         if ( cats.Count() == 1 )
       
   213             {
       
   214             CPosLandmarkCategory* cat = aCatman.ReadCategoryLC( cats[0] );
       
   215 
       
   216             TPtrC iconFile;
       
   217             TInt iconIndex, maskIndex;
       
   218             if ( KErrNone == cat->GetIcon( iconFile, iconIndex, maskIndex ) )
       
   219                 {
       
   220                 AknIconUtils::CreateIconL( self->iBitmap, self->iMask, iconFile, iconIndex, maskIndex );
       
   221                 AknIconUtils::PreserveIconData( self->iBitmap );
       
   222                 }
       
   223 
       
   224             CleanupStack::PopAndDestroy( cat );
       
   225             }
       
   226         CleanupStack::PopAndDestroy( &cats );
       
   227         }
       
   228 
       
   229     return self;
       
   230     }
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 void CMnrpMapModel::CDrawItem::SetAbsolutePosition( const TLocality& aLocality )
       
   236     {
       
   237     iAbsolutePosition = TRealPoint( aLocality.Longitude(), aLocality.Latitude() );
       
   238     }
       
   239 
       
   240 // -----------------------------------------------------------------------------
       
   241 // -----------------------------------------------------------------------------
       
   242 //
       
   243 CMnrpMapModel::CDrawItem::~CDrawItem()
       
   244     {
       
   245     if ( iBitmap )
       
   246         {
       
   247         AknIconUtils::DestroyIconData( iBitmap );
       
   248         }
       
   249     delete iBitmap;
       
   250     delete iMask;
       
   251     delete iText;
       
   252     }
       
   253 
       
   254 // ============================ MEMBER FUNCTIONS ===============================
       
   255 
       
   256 // -----------------------------------------------------------------------------
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 CMnrpMapModel::CMnrpMapModel(
       
   260     MMapModelObserver& aObserver,
       
   261     CMnrpEngine& aEngine )
       
   262     :
       
   263     iObserver( &aObserver ), iEngine( aEngine )
       
   264     {
       
   265     iScale = 1;
       
   266     iViewOrigin.Set( 0, 0 );
       
   267     }
       
   268 
       
   269 // -----------------------------------------------------------------------------
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 CMnrpMapModel::CMnrpMapModel( CMnrpEngine& aEngine )
       
   273     : iEngine( aEngine )
       
   274     {
       
   275     iScale = 1;
       
   276     iViewOrigin.Set( 0, 0 );
       
   277     }
       
   278 
       
   279 // -----------------------------------------------------------------------------
       
   280 // -----------------------------------------------------------------------------
       
   281 //
       
   282 CMnrpMapModel::~CMnrpMapModel()
       
   283     {
       
   284     delete iPositionRequest;
       
   285     iDrawItems.ResetAndDestroy();
       
   286     }
       
   287 
       
   288 // -----------------------------------------------------------------------------
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 EXPORT_C CMnrpMapModel* CMnrpMapModel::NewL(
       
   292     MMapModelObserver& aObserver,
       
   293     CMnrpEngine& aEngine )
       
   294     {
       
   295     CMnrpMapModel* self = new (ELeave) CMnrpMapModel( aObserver, aEngine );
       
   296     CleanupStack::PushL( self );
       
   297     self->ConstructL();
       
   298     CleanupStack::Pop( self );
       
   299     return self;
       
   300     }
       
   301 
       
   302 // -----------------------------------------------------------------------------
       
   303 // -----------------------------------------------------------------------------
       
   304 //
       
   305 EXPORT_C CMnrpMapModel* CMnrpMapModel::NewL( CMnrpEngine& aEngine )
       
   306     {
       
   307     CMnrpMapModel* self = new (ELeave) CMnrpMapModel( aEngine );
       
   308     CleanupStack::PushL( self );
       
   309     self->ConstructL();
       
   310     CleanupStack::Pop( self );
       
   311     return self;
       
   312     }
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // -----------------------------------------------------------------------------
       
   316 //
       
   317 void CMnrpMapModel::ConstructL()
       
   318     {
       
   319     _LIT( KRequestorName, "MnRefProvider" );
       
   320     iPositionRequest = CMnrpPositionRequest::NewL( KRequestorName, *this );
       
   321 
       
   322     TPositionUpdateOptions options;
       
   323     options.SetUpdateInterval( TTimeIntervalMicroSeconds( KUpdateInterval ) );
       
   324     options.SetUpdateTimeOut( TTimeIntervalMicroSeconds( KUpdateTimeout ) );
       
   325     iPositionRequest->SetOptionsL( options );
       
   326 
       
   327     AddCitiesL();
       
   328     }
       
   329 
       
   330 // -----------------------------------------------------------------------------
       
   331 // -----------------------------------------------------------------------------
       
   332 //
       
   333 TBool CMnrpMapModel::CheckDrawItemHasPositionL( CDrawItem& aItem, const CPosLandmark& aLandmark )
       
   334 	{
       
   335     if ( !aItem.AbsolutePosition().IsValid() )
       
   336         {
       
   337         // try to find coordinate by address
       
   338         CPosLandmark* poi = iEngine.AddressToCoordL( aLandmark );
       
   339         if ( poi )
       
   340         	{
       
   341             TLocality pos;
       
   342             poi->GetPosition( pos );
       
   343             aItem.SetAbsolutePosition( pos );
       
   344         	}
       
   345     	delete poi;
       
   346         }
       
   347     
       
   348     return aItem.AbsolutePosition().IsValid();
       
   349 	}
       
   350 
       
   351 // -----------------------------------------------------------------------------
       
   352 // -----------------------------------------------------------------------------
       
   353 //
       
   354 EXPORT_C void CMnrpMapModel::UpdateModelL( CMnrpMapViewService& aService )
       
   355     {
       
   356     ASSERT( iObserver );
       
   357 
       
   358     iDrawItems.ResetAndDestroy();
       
   359 
       
   360     iShowCurrentLocation =
       
   361         aService.CurrentLocationOption() != CMnMapView::ECurrentLocationDisabled;
       
   362 
       
   363     if ( iShowCurrentLocation )
       
   364         {
       
   365         iPositionRequest->FetchNewPosition();
       
   366         }
       
   367 
       
   368     // Add client-defined marks
       
   369     
       
   370     iNumIgnoredLandmarks = 0;
       
   371     TRealPoint min, max;
       
   372 
       
   373     // add non-linked landmarks
       
   374     for ( TInt i = 0; i < aService.LandmarksToShow().Count(); i++)
       
   375         {
       
   376         const CPosLandmark* lm = aService.LandmarksToShow()[i];
       
   377         
       
   378         CDrawItem* item = CDrawItem::NewLC( *lm );
       
   379         if ( CheckDrawItemHasPositionL( *item, *lm ) )
       
   380         	{
       
   381         	iDrawItems.AppendL( item );
       
   382             CleanupStack::Pop( item );
       
   383             AdjustBoundingBox( *item, min, max );
       
   384         	}
       
   385         else
       
   386         	{
       
   387             CleanupStack::PopAndDestroy( item );
       
   388             iNumIgnoredLandmarks++;
       
   389         	}
       
   390         }
       
   391 
       
   392     // add linked landmarks
       
   393     for ( TInt db = 0; db < aService.LandmarksToShowDatabases().Count(); db++ )
       
   394         {
       
   395         const HBufC* uri = aService.LandmarksToShowDatabases()[db];
       
   396 
       
   397         LOG1("MnRefProvider::LinkedLandmarks: database (%S)", uri );
       
   398 
       
   399         CPosLandmarkDatabase* lmdb = CPosLandmarkDatabase::OpenL( *uri );
       
   400         CleanupStack::PushL( lmdb );
       
   401 
       
   402         if ( lmdb->IsInitializingNeeded() )
       
   403             {
       
   404             ExecuteAndDeleteLD( lmdb->InitializeL() );
       
   405             }
       
   406 
       
   407         CPosLmCategoryManager* catman = CPosLmCategoryManager::NewL( *lmdb );
       
   408         CleanupStack::PushL( catman );
       
   409 
       
   410         for ( TInt i = 0; i < aService.LinkedLandmarksToShow(db).Count(); i++)
       
   411             {
       
   412             TPosLmItemId id = aService.LinkedLandmarksToShow(db)[i];
       
   413             LOG1("MnRefProvider::LinkedLandmarks: id (%d)", id );
       
   414 
       
   415             CPosLandmark* lm = lmdb->ReadLandmarkLC( id );
       
   416 
       
   417             CDrawItem* item = CDrawItem::NewLC( *lm, *catman );
       
   418             if ( CheckDrawItemHasPositionL( *item, *lm ) )
       
   419             	{
       
   420             	iDrawItems.AppendL( item );
       
   421                 CleanupStack::Pop( item );
       
   422                 AdjustBoundingBox( *item, min, max );
       
   423             	}
       
   424             else
       
   425             	{
       
   426                 CleanupStack::PopAndDestroy( item );
       
   427                 iNumIgnoredLandmarks++;
       
   428             	}
       
   429 
       
   430             CleanupStack::PopAndDestroy( lm );
       
   431             }
       
   432 
       
   433         CleanupStack::PopAndDestroy( catman );
       
   434         CleanupStack::PopAndDestroy( lmdb );
       
   435         }
       
   436 
       
   437     // Add predefined places
       
   438     AddCitiesL();
       
   439 
       
   440     LOG4("MnRefProvider::BoundingBox: %f, %f, %f, %f", min.iX, min.iY, max.iX, max.iY );
       
   441 
       
   442     // set origin
       
   443     iUseCurrentLocationAsOrigin = EFalse;
       
   444     if ( aService.IsAreaCentralPointSet() )
       
   445         {
       
   446         TCoordinate center;
       
   447         aService.GetAreaCentralPoint( center );
       
   448         iViewOrigin.Set( center.Longitude(), center.Latitude() );
       
   449         }
       
   450     else if ( !Math::IsNaN( max.iX ) ) // others are also valid then
       
   451         {
       
   452         iViewOrigin.Set( ( max.iX + min.iX ) / 2, ( max.iY + min.iY ) / 2 );
       
   453         }
       
   454     else if ( iShowCurrentLocation )
       
   455         {
       
   456         // get current location and use it as center point
       
   457         // this implementation defers location acquiring
       
   458         iUseCurrentLocationAsOrigin = ETrue;
       
   459         // FetchCurrentLocation();
       
   460         iViewOrigin.Set( 0, 0 );
       
   461         }
       
   462     else
       
   463         {
       
   464         iViewOrigin.Set( 0, 0 );
       
   465         }
       
   466 
       
   467     LOG2("MnRefProvider: viewOrigin (%f, %f)", iViewOrigin.iX, iViewOrigin.iY);
       
   468 
       
   469     // set scale
       
   470     TReal desiredScale = 0;
       
   471     TReal radius = 0;
       
   472 
       
   473     if ( !Math::IsNaN( aService.AreaRadius() ) )
       
   474         {
       
   475          // Radius setting is easy in this implementation
       
   476          // because map is rectangular just convert meters to degrees
       
   477         radius = Abs( aService.AreaRadius() ) / KEarthEquator * 360;
       
   478         LOG1("MnRefProvider: user radius (%f)", radius );
       
   479         }
       
   480     else if ( !Math::IsNaN( max.iX ) ) // others are also valid then
       
   481         {
       
   482         // get radius from bounding box
       
   483         radius = Max( Abs( max.iX - min.iX ), Abs( max.iY - min.iY ) );
       
   484         LOG2("MnRefProvider: bounding radius (%f), with border (%f)", radius, radius * KRadiusBorderFactor );
       
   485         radius *= KRadiusBorderFactor;
       
   486         }
       
   487     else
       
   488         {
       
   489         // default radius
       
   490         }
       
   491 
       
   492     if ( radius <= 0 )
       
   493         {
       
   494         radius = KDefaultRadius;
       
   495         LOG1("MnRefProvider: default radius (%f)", radius );
       
   496         }
       
   497 
       
   498     desiredScale = radius / TReal( Max( iScreenSize.iWidth, iScreenSize.iHeight ) );
       
   499 
       
   500     LOG3("MnRefProvider: desired scale (%f), min (%f), max(%f)",
       
   501         desiredScale, KMinScale, MaxScale() );
       
   502 
       
   503     iScale = Max( Min( desiredScale, MaxScale() ), KMinScale );
       
   504     CheckBorders();
       
   505 
       
   506     LOG1("MnRefProvider: scale (%f)", iScale );
       
   507 
       
   508     iObserver->HandleModelUpdateL();
       
   509     }
       
   510 
       
   511 
       
   512 #ifdef RD_MAPNAV_BITMAP_ACCESS
       
   513 // -----------------------------------------------------------------------------
       
   514 // -----------------------------------------------------------------------------
       
   515 //
       
   516 EXPORT_C void CMnrpMapModel::UpdateModelL( const CMnrpMapImageService& aService )
       
   517     {
       
   518     iDrawItems.ResetAndDestroy();
       
   519 
       
   520     iShowCurrentLocation =
       
   521         aService.ShowOptions() & CMnMapImage::EShowOptionCurrentLocation;
       
   522 
       
   523     if ( iShowCurrentLocation )
       
   524         {
       
   525         iPositionRequest->FetchNewPosition();
       
   526         }
       
   527 
       
   528     if ( aService.ShowOptions() & CMnMapImage::EShowOptionLandmarks)
       
   529         {
       
   530 
       
   531         // Add user-defined marks
       
   532         TRealPoint min, max;
       
   533 
       
   534         // add default landmarks
       
   535         CPosLandmarkDatabase* lmdb = CPosLandmarkDatabase::OpenL();
       
   536         CleanupStack::PushL( lmdb );
       
   537 
       
   538         if ( lmdb->IsInitializingNeeded() )
       
   539             {
       
   540             ExecuteAndDeleteLD( lmdb->InitializeL() );
       
   541             }
       
   542 
       
   543         CPosLmCategoryManager* catman = CPosLmCategoryManager::NewL( *lmdb );
       
   544         CleanupStack::PushL( catman );
       
   545 
       
   546         CPosLmItemIterator* iter = lmdb->LandmarkIteratorL();
       
   547         CleanupStack::PushL( iter );
       
   548 
       
   549         TInt count = iter->NumOfItemsL();
       
   550         for ( TInt i = 0; i < count; i++)
       
   551             {
       
   552             TPosLmItemId id = iter->NextL();
       
   553 
       
   554             CPosLandmark* lm = lmdb->ReadLandmarkLC( id );
       
   555 
       
   556             CDrawItem* item = CDrawItem::NewLC( *lm, *catman );
       
   557             if ( CheckDrawItemHasPositionL( *item, *lm ) )
       
   558             	{
       
   559             	iDrawItems.AppendL( item );
       
   560                 CleanupStack::Pop( item );
       
   561                 AdjustBoundingBox( *item, min, max );
       
   562             	}
       
   563             else
       
   564             	{
       
   565                 CleanupStack::PopAndDestroy( item );
       
   566             	}
       
   567 
       
   568             CleanupStack::PopAndDestroy( lm );
       
   569             }
       
   570         CleanupStack::PopAndDestroy( iter );
       
   571         CleanupStack::PopAndDestroy( catman );
       
   572         CleanupStack::PopAndDestroy( lmdb );
       
   573 
       
   574         LOG4("MnRefProvider::BoundingBox: %f, %f, %f, %f", min.iX, min.iY, max.iX, max.iY );
       
   575         }
       
   576 
       
   577     if ( aService.ShowOptions() & CMnMapImage::EShowOptionPois )
       
   578         {
       
   579         // Add predefined places
       
   580         AddCitiesL();
       
   581         }
       
   582 
       
   583     TMnMapImageParams params = aService.MapImageParams();
       
   584 
       
   585     UpdateModel( params );
       
   586     }
       
   587 
       
   588 // -----------------------------------------------------------------------------
       
   589 // -----------------------------------------------------------------------------
       
   590 //
       
   591 EXPORT_C void CMnrpMapModel::UpdateModel( const TMnMapImageParams& aParams )
       
   592     {
       
   593     SetScreenSize( aParams.Size() );
       
   594 
       
   595     TCoordinate center;
       
   596     aParams.GetCenterPoint( center );
       
   597     iViewOrigin.Set( center.Longitude(), center.Latitude() );
       
   598 
       
   599     LOG2("MnRefProvider: viewOrigin (%f, %f)", iViewOrigin.iX, iViewOrigin.iY);
       
   600 
       
   601     // set scale
       
   602     TReal desiredScale = 0;
       
   603     TReal32 width, height;
       
   604     aParams.GetVisibleArea( width, height );
       
   605     TReal radius = Max( width, height );
       
   606 
       
   607     if ( radius <= 0 )
       
   608         {
       
   609         radius = KDefaultRadius;
       
   610         LOG1("MnRefProvider: default radius (%f)", radius );
       
   611         }
       
   612 
       
   613     desiredScale = radius / TReal( Max( iScreenSize.iWidth, iScreenSize.iHeight ) );
       
   614 
       
   615     LOG3("MnRefProvider: desired scale (%f), min (%f), max(%f)",
       
   616         desiredScale, KMinScale, MaxScale() );
       
   617 
       
   618     iScale = Max( Min( desiredScale, MaxScale() ), KMinScale );
       
   619     CheckBorders();
       
   620 
       
   621     LOG1("MnRefProvider: scale (%f)", iScale );
       
   622     }
       
   623 #endif
       
   624 
       
   625 // -----------------------------------------------------------------------------
       
   626 // -----------------------------------------------------------------------------
       
   627 //
       
   628 void CMnrpMapModel::AddCitiesL()
       
   629     {
       
   630     TArray<CPosLandmark*> places = iEngine.KnownPlacesL();
       
   631     for ( TInt i = 0; i < places.Count(); i++)
       
   632         {
       
   633         CPosLandmark* lm = places[i];
       
   634         CDrawItem* item = CDrawItem::NewLC( *lm );
       
   635         item->iOwnPoi = ETrue;
       
   636         iDrawItems.AppendL( item );
       
   637         CleanupStack::Pop( item );
       
   638         }
       
   639     }
       
   640 
       
   641 // -----------------------------------------------------------------------------
       
   642 // -----------------------------------------------------------------------------
       
   643 //
       
   644 EXPORT_C void CMnrpMapModel::GetGrid( CMnrpMapModel::TGrid& aGrid ) const
       
   645     {
       
   646     TReal angle = Min( Width(), Height() );
       
   647 
       
   648     TReal minAngle = Min( iScreenSize.iWidth, iScreenSize.iHeight ) * KMinScale;
       
   649 
       
   650     if ( angle > minAngle )
       
   651         {
       
   652         // 1. Find nice grid scale
       
   653 
       
   654         TInt dividerIndex = 0;
       
   655         TReal cellSize = KMaxCell;
       
   656 
       
   657         while ( cellSize * KBigCellsInView > angle )
       
   658             {
       
   659             cellSize /= KCellDividers[dividerIndex];
       
   660 
       
   661             if ( ++dividerIndex == KNumCellDividers )
       
   662                 {
       
   663                 dividerIndex = 0;
       
   664                 }
       
   665             }
       
   666 
       
   667         aGrid.iAbsoluteGridStep = cellSize;
       
   668 
       
   669         // 2. Find closest grid point
       
   670 
       
   671         TReal x = TInt( iViewOrigin.iX / cellSize ) * cellSize;
       
   672         TReal y = TInt( iViewOrigin.iY / cellSize ) * cellSize;
       
   673 
       
   674         aGrid.iAbsoluteReference = TRealPoint( x, y ).Coordinate();
       
   675         }
       
   676     else
       
   677         {
       
   678         aGrid.iAbsoluteReference = TCoordinate( 0, 0 );
       
   679         aGrid.iAbsoluteGridStep = minAngle / KBigCellsInView;
       
   680         }
       
   681 
       
   682     // convert to screen coordinates
       
   683     aGrid.iReference = AbsoluteToScreen( aGrid.iAbsoluteReference );
       
   684     aGrid.iGridStep = AbsoluteToScreen( aGrid.iAbsoluteGridStep );
       
   685     }
       
   686 
       
   687 // -----------------------------------------------------------------------------
       
   688 // -----------------------------------------------------------------------------
       
   689 //
       
   690 EXPORT_C void CMnrpMapModel::Zoom( TReal aZoomRate )
       
   691     {
       
   692     iScale *= aZoomRate;
       
   693     CheckBorders();
       
   694     }
       
   695 
       
   696 // -----------------------------------------------------------------------------
       
   697 // -----------------------------------------------------------------------------
       
   698 //
       
   699 EXPORT_C void CMnrpMapModel::GoCenter()
       
   700     {
       
   701     iViewOrigin.Set( 0, 0 );
       
   702     CheckBorders();
       
   703     }
       
   704 
       
   705 // -----------------------------------------------------------------------------
       
   706 // -----------------------------------------------------------------------------
       
   707 //
       
   708 EXPORT_C void CMnrpMapModel::MoveTo( TCoordinate aTarget )
       
   709     {
       
   710     iViewOrigin = aTarget;
       
   711     CheckBorders();
       
   712     }
       
   713 
       
   714 // -----------------------------------------------------------------------------
       
   715 // -----------------------------------------------------------------------------
       
   716 //
       
   717 void CMnrpMapModel::CheckBorders()
       
   718     {
       
   719     if ( Height() > KMapHeight || Width() > KMapWidth )
       
   720         {
       
   721         iScale = MaxScale();
       
   722         }
       
   723     if ( iScale < KMinScale )
       
   724         {
       
   725         iScale = KMinScale;
       
   726         }
       
   727     if ( Left() < KMinX )
       
   728         {
       
   729         iViewOrigin.iX = KMinX + Width() / 2;
       
   730         }
       
   731     if ( Right() > KMaxX )
       
   732         {
       
   733         iViewOrigin.iX = KMaxX - Width() / 2;
       
   734         }
       
   735     if ( Top() > KMaxY )
       
   736         {
       
   737         iViewOrigin.iY = KMaxY - Height() / 2;
       
   738         }
       
   739     if ( Bottom() < KMinY )
       
   740         {
       
   741         iViewOrigin.iY = KMinY + Height() / 2;
       
   742         }
       
   743     }
       
   744 
       
   745 // -----------------------------------------------------------------------------
       
   746 // -----------------------------------------------------------------------------
       
   747 //
       
   748 EXPORT_C TReal CMnrpMapModel::Left() const
       
   749     {
       
   750     return iViewOrigin.iX - Width() / 2;
       
   751     }
       
   752 
       
   753 // -----------------------------------------------------------------------------
       
   754 // -----------------------------------------------------------------------------
       
   755 //
       
   756 EXPORT_C TReal CMnrpMapModel::Right() const
       
   757     {
       
   758     return iViewOrigin.iX + Width() / 2;
       
   759     }
       
   760 
       
   761 // -----------------------------------------------------------------------------
       
   762 // -----------------------------------------------------------------------------
       
   763 //
       
   764 EXPORT_C TReal CMnrpMapModel::Top() const
       
   765     {
       
   766     return iViewOrigin.iY + Height() / 2;
       
   767     }
       
   768 
       
   769 // -----------------------------------------------------------------------------
       
   770 // -----------------------------------------------------------------------------
       
   771 //
       
   772 EXPORT_C TReal CMnrpMapModel::Bottom() const
       
   773     {
       
   774     return iViewOrigin.iY - Height() / 2;
       
   775     }
       
   776 
       
   777 // -----------------------------------------------------------------------------
       
   778 // -----------------------------------------------------------------------------
       
   779 //
       
   780 EXPORT_C TReal CMnrpMapModel::Width() const
       
   781     {
       
   782     return TReal( iScreenSize.iWidth ) * iScale;
       
   783     }
       
   784 
       
   785 // -----------------------------------------------------------------------------
       
   786 // -----------------------------------------------------------------------------
       
   787 //
       
   788 EXPORT_C TReal CMnrpMapModel::Height() const
       
   789     {
       
   790     return TReal( iScreenSize.iHeight ) * iScale;
       
   791     }
       
   792 
       
   793 // -----------------------------------------------------------------------------
       
   794 // -----------------------------------------------------------------------------
       
   795 //
       
   796 EXPORT_C TCoordinate CMnrpMapModel::Center() const
       
   797     {
       
   798     return TCoordinate( iViewOrigin.iY, iViewOrigin.iX );
       
   799     }
       
   800 
       
   801 // -----------------------------------------------------------------------------
       
   802 // -----------------------------------------------------------------------------
       
   803 //
       
   804 TArray<CMnrpMapModel::CDrawItem*> CMnrpMapModel::Items() const
       
   805     {
       
   806     // adjust all items to screen coordinates
       
   807     for ( TInt i = 0; i < iDrawItems.Count(); i++ )
       
   808         {
       
   809         iDrawItems[i]->iScreenPosition = AbsoluteToScreen( iDrawItems[i]->iAbsolutePosition );
       
   810         }
       
   811     return iDrawItems.Array();
       
   812     }
       
   813 
       
   814 // -----------------------------------------------------------------------------
       
   815 // -----------------------------------------------------------------------------
       
   816 //
       
   817 CMnrpMapModel::TCurrentLocation CMnrpMapModel::CurrentLocation() const
       
   818     {
       
   819     TCurrentLocation current;
       
   820 
       
   821     TPosition pos;
       
   822     iPosInfo.GetPosition( pos );
       
   823 
       
   824     current.iAbsoluteLocation = pos;
       
   825 
       
   826     if ( !Math::IsNaN( pos.Latitude() ) && !Math::IsNaN( pos.Longitude() ) )
       
   827         {
       
   828         current.iLocation = AbsoluteToScreen( current.iAbsoluteLocation );
       
   829 
       
   830         // calculate error radius in degrees and pixels
       
   831         if ( !Math::IsNaN( pos.HorizontalAccuracy() ) )
       
   832             {
       
   833             current.iAbsoluteErrorDegrees = ( pos.HorizontalAccuracy() / KEarthEquator ) * 360;
       
   834             current.iErrorRadius = current.iAbsoluteErrorDegrees / iScale;
       
   835             }
       
   836         else
       
   837             {
       
   838             current.iErrorRadius = 0;
       
   839             current.iAbsoluteErrorDegrees = 0;
       
   840             }
       
   841 
       
   842         current.iIsValid = ETrue;
       
   843         }
       
   844     else
       
   845         {
       
   846         current.iIsValid = EFalse;
       
   847         }
       
   848 
       
   849     return current;
       
   850     }
       
   851 
       
   852 // -----------------------------------------------------------------------------
       
   853 // -----------------------------------------------------------------------------
       
   854 //
       
   855 EXPORT_C void CMnrpMapModel::SetScreenSize( TSize aScreenSize )
       
   856     {
       
   857     __ASSERT_DEBUG( aScreenSize.iWidth >= 1 && aScreenSize.iHeight >= 1,
       
   858                     Panic( KErrGeneral ) );
       
   859     iScreenSize = aScreenSize;
       
   860     CheckBorders();
       
   861     }
       
   862 
       
   863 // -----------------------------------------------------------------------------
       
   864 // -----------------------------------------------------------------------------
       
   865 //
       
   866 TReal CMnrpMapModel::MaxScale() const
       
   867     {
       
   868     TReal scaleByWidth = KMapWidth / TReal( iScreenSize.iWidth );
       
   869     TReal scaleByHeight = KMapHeight / TReal( iScreenSize.iHeight );
       
   870     return Min( scaleByWidth, scaleByHeight );
       
   871     }
       
   872 
       
   873 // -----------------------------------------------------------------------------
       
   874 // -----------------------------------------------------------------------------
       
   875 //
       
   876 TPoint CMnrpMapModel::AbsoluteToScreen( TRealPoint aAbsolutePoint ) const
       
   877     {
       
   878     TRealPoint realScreen = ( aAbsolutePoint - TRealPoint( Left(), Bottom() ) ) / iScale;
       
   879     return TPoint( realScreen.iX, iScreenSize.iHeight - realScreen.iY );
       
   880     }
       
   881 
       
   882 // -----------------------------------------------------------------------------
       
   883 // -----------------------------------------------------------------------------
       
   884 //
       
   885 EXPORT_C TPoint CMnrpMapModel::AbsoluteToScreen( TCoordinate aAbsolutePoint ) const
       
   886     {
       
   887     TRealPoint real( aAbsolutePoint.Longitude(), aAbsolutePoint.Latitude() );
       
   888     return AbsoluteToScreen( real );
       
   889     }
       
   890 
       
   891 // -----------------------------------------------------------------------------
       
   892 // -----------------------------------------------------------------------------
       
   893 //
       
   894 TInt CMnrpMapModel::AbsoluteToScreen( TReal aDistance ) const
       
   895     {
       
   896     return aDistance / iScale;
       
   897     }
       
   898 
       
   899 // -----------------------------------------------------------------------------
       
   900 // -----------------------------------------------------------------------------
       
   901 //
       
   902 EXPORT_C TCoordinate CMnrpMapModel::ScreenToAbsolute( TPoint aScreenPoint ) const
       
   903     {
       
   904     TReal xdiff = aScreenPoint.iX * iScale;
       
   905     TReal ydiff = aScreenPoint.iY * iScale;
       
   906     return TCoordinate( Top() - ydiff, Left() + xdiff );
       
   907     }
       
   908 
       
   909 // -----------------------------------------------------------------------------
       
   910 // -----------------------------------------------------------------------------
       
   911 //
       
   912 EXPORT_C TReal CMnrpMapModel::ScreenToAbsolute( TInt aDistance ) const
       
   913     {
       
   914     return aDistance * iScale;
       
   915     }
       
   916 
       
   917 // -----------------------------------------------------------------------------
       
   918 // -----------------------------------------------------------------------------
       
   919 //
       
   920 void CMnrpMapModel::AdjustBoundingBox(
       
   921     CMnrpMapModel::CDrawItem& aItem,
       
   922     TRealPoint& aMin,
       
   923     TRealPoint& aMax )
       
   924     {
       
   925     // X
       
   926     if ( !Math::IsNaN( aItem.iAbsolutePosition.iX ) )
       
   927         {
       
   928         if ( Math::IsNaN( aMin.iX ) || aItem.iAbsolutePosition.iX < aMin.iX )
       
   929             {
       
   930             aMin.iX = aItem.iAbsolutePosition.iX;
       
   931             }
       
   932         if ( Math::IsNaN( aMax.iX ) || aItem.iAbsolutePosition.iX > aMax.iX )
       
   933             {
       
   934             aMax.iX = aItem.iAbsolutePosition.iX;
       
   935             }
       
   936         }
       
   937 
       
   938     // Y
       
   939     if ( !Math::IsNaN( aItem.iAbsolutePosition.iY ) )
       
   940         {
       
   941         if ( Math::IsNaN( aMin.iY ) || aItem.iAbsolutePosition.iY < aMin.iY )
       
   942             {
       
   943             aMin.iY = aItem.iAbsolutePosition.iY;
       
   944             }
       
   945         if ( Math::IsNaN( aMax.iY ) || aItem.iAbsolutePosition.iY > aMax.iY )
       
   946             {
       
   947             aMax.iY = aItem.iAbsolutePosition.iY;
       
   948             }
       
   949         }
       
   950     }
       
   951 
       
   952 // -----------------------------------------------------------------------------
       
   953 // -----------------------------------------------------------------------------
       
   954 //
       
   955 void CMnrpMapModel::HandlePositionRequestCompletedL( TInt aError )
       
   956     {
       
   957     if ( !aError )
       
   958         {
       
   959         iPositionRequest->GetPosition( iPosInfo );
       
   960         if ( iObserver )
       
   961             {
       
   962             iObserver->HandleModelUpdateL();
       
   963             }
       
   964         }
       
   965     if ( iShowCurrentLocation )
       
   966         {
       
   967         iPositionRequest->FetchNewPosition();
       
   968         }
       
   969     }
       
   970 
       
   971 // =====================================================
       
   972 // DRAWING METHODS
       
   973 // =====================================================
       
   974 
       
   975 // -----------------------------------------------------------------------------
       
   976 // -----------------------------------------------------------------------------
       
   977 //
       
   978 EXPORT_C void CMnrpMapModel::RenderL(
       
   979     CFbsBitmap& aBitmap,
       
   980     TRect aTargetRect,
       
   981     CFont* aTextFont,
       
   982     CFont* aItemFont ) const
       
   983 	{
       
   984 	// create an off-screen device and context
       
   985 	CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( &aBitmap );
       
   986 	CleanupStack::PushL( bitmapDevice );
       
   987 
       
   988 	CFbsBitGc* gc = NULL;
       
   989 	User::LeaveIfError( bitmapDevice->CreateContext( gc ) );
       
   990 	CleanupStack::PushL( gc );
       
   991 
       
   992     gc->UseFont( aTextFont );
       
   993 
       
   994     // get data
       
   995     TGrid grid;
       
   996     GetGrid( grid );
       
   997 
       
   998     TBool isBackground = EFalse;
       
   999     // background
       
  1000     if ( !isBackground )
       
  1001         {
       
  1002         // no map background, clear map area
       
  1003         gc->Clear( aTargetRect );
       
  1004         }
       
  1005 
       
  1006     gc->SetClippingRect( aTargetRect );
       
  1007     gc->SetOrigin( aTargetRect.iTl );
       
  1008 
       
  1009     DrawGrid( *gc, aTargetRect.Size(), grid );
       
  1010 
       
  1011     gc->DiscardFont(); // text font
       
  1012     gc->UseFont( aItemFont );
       
  1013 
       
  1014     // draw items
       
  1015     DrawLandmarks( *gc, *aItemFont, aTargetRect.Size(), isBackground ); // invert shadow and text color
       
  1016     DrawCurrentLocation( *gc, aTargetRect.Size() );
       
  1017 
       
  1018     // cleanup
       
  1019 
       
  1020     gc->DiscardFont(); // item font
       
  1021 
       
  1022 	CleanupStack::PopAndDestroy( gc );
       
  1023 	CleanupStack::PopAndDestroy( bitmapDevice );
       
  1024 	}
       
  1025 
       
  1026 // -----------------------------------------------------------------------------
       
  1027 // -----------------------------------------------------------------------------
       
  1028 //
       
  1029 EXPORT_C TInt CMnrpMapModel::NumIgnoredLandmarks()
       
  1030 	{
       
  1031 	return iNumIgnoredLandmarks;
       
  1032 	}
       
  1033 
       
  1034 // -----------------------------------------------------------------------------
       
  1035 // -----------------------------------------------------------------------------
       
  1036 //
       
  1037 void CMnrpMapModel::DrawGrid(
       
  1038     CFbsBitGc& aGc,
       
  1039     const TSize& aBoxSize,
       
  1040     CMnrpMapModel::TGrid& aGrid ) const
       
  1041     {
       
  1042     const TRgb KGridLineColor( 128, 128, 128 );
       
  1043 
       
  1044     aGc.SetPenSize( TSize( KGridPenSize, KGridPenSize ) );
       
  1045     aGc.SetPenColor( KGridLineColor );
       
  1046 
       
  1047     if ( aGrid.iGridStep > 0 )
       
  1048         {
       
  1049         // 1. Vertical lines
       
  1050         TInt x = aGrid.iReference.iX;
       
  1051         // find leftmost vertical line
       
  1052         while ( x > 0 )
       
  1053         	{
       
  1054         	x -= aGrid.iGridStep;
       
  1055         	}
       
  1056         x += aGrid.iGridStep;
       
  1057         // draw lines selecting different line colors for major and minor lines
       
  1058         while ( x < aBoxSize.iWidth )
       
  1059             {
       
  1060             DrawVerticalLine( aGc, x, aBoxSize );
       
  1061             x += aGrid.iGridStep;
       
  1062             }
       
  1063 
       
  1064         // 2. Horizontal lines
       
  1065         TInt y = aGrid.iReference.iY;
       
  1066         // find topmost vertical line
       
  1067         while ( y > 0 )
       
  1068         	{
       
  1069         	y -= aGrid.iGridStep;
       
  1070         	}
       
  1071         y += aGrid.iGridStep;
       
  1072         // draw lines selecting different line colors for major and minor lines
       
  1073         while ( y < aBoxSize.iHeight )
       
  1074             {
       
  1075             DrawHorizontalLine( aGc, y, aBoxSize );
       
  1076             y += aGrid.iGridStep;
       
  1077             }
       
  1078         }
       
  1079     }
       
  1080 
       
  1081 // -----------------------------------------------------------------------------
       
  1082 // -----------------------------------------------------------------------------
       
  1083 //
       
  1084 void CMnrpMapModel::DrawVerticalLine( CFbsBitGc& aGc, TInt aX, TSize aBoxSize ) const
       
  1085     {
       
  1086     aGc.DrawLine( TPoint( aX, 0 ), TPoint( aX, aBoxSize.iHeight ) );
       
  1087     }
       
  1088 
       
  1089 // -----------------------------------------------------------------------------
       
  1090 // -----------------------------------------------------------------------------
       
  1091 //
       
  1092 void CMnrpMapModel::DrawHorizontalLine( CFbsBitGc& aGc, TInt aY, TSize aBoxSize ) const
       
  1093     {
       
  1094     aGc.DrawLine( TPoint( 0, aY ), TPoint( aBoxSize.iWidth, aY ) );
       
  1095     }
       
  1096 
       
  1097 // -----------------------------------------------------------------------------
       
  1098 // -----------------------------------------------------------------------------
       
  1099 //
       
  1100 void CMnrpMapModel::DrawLandmarks(
       
  1101     CFbsBitGc& aGc,
       
  1102     CFont& aFont,
       
  1103     const TSize& aBoxSize,
       
  1104     TBool aSwitchColorAndShadow ) const
       
  1105     {
       
  1106     const TSize KItemMarkSize( 3, 3 ); // pixels
       
  1107     const TSize KItemIconSize( 20, 20 ); // pixels
       
  1108 
       
  1109     const TRgb KPoiColor( 0, 0, 192 );
       
  1110     const TRgb KPoiTextColor( 0, 0, 0 );
       
  1111     const TRgb KPoiTextShadowColor( 224, 224, 224 );
       
  1112     const TRgb KLmColor( 255, 0, 0 );
       
  1113     const TRgb KLmTextColor( 255, 0, 0 );
       
  1114     const TRgb KLmTextShadowColor( 224, 224, 224 );
       
  1115 
       
  1116     TArray<CMnrpMapModel::CDrawItem*> items = Items();
       
  1117 
       
  1118     RArray<TRect> textBoxes;
       
  1119 
       
  1120     for ( TInt i = 0; i < items.Count(); i++ )
       
  1121         {
       
  1122         const TPoint& pos = items[i]->Position();
       
  1123         if ( pos.iX >= 0 && pos.iX < aBoxSize.iWidth &&
       
  1124              pos.iY >= 0 && pos.iY < aBoxSize.iHeight )
       
  1125             {
       
  1126             CFbsBitmap* icon = items[i]->Bitmap();
       
  1127             CFbsBitmap* mask = items[i]->Mask();
       
  1128 
       
  1129             if ( icon && mask )
       
  1130                 {
       
  1131                 AknIconUtils::SetSize( icon, KItemIconSize );
       
  1132 
       
  1133                 TRect iconBox( pos, KItemIconSize );
       
  1134                 iconBox.Move( -iconBox.Width() / 2, -iconBox.Height() / 2 );
       
  1135 
       
  1136                 aGc.DrawBitmapMasked(
       
  1137                     iconBox,
       
  1138                     icon,
       
  1139                     KItemIconSize,
       
  1140                     mask,
       
  1141                     EFalse );
       
  1142                 }
       
  1143             else
       
  1144                 {
       
  1145                 if ( items[i]->IsPoi() )
       
  1146                     {
       
  1147                     aGc.SetPenColor( KPoiColor );
       
  1148                     }
       
  1149                 else
       
  1150                     {
       
  1151                     aGc.SetPenColor( KLmColor );
       
  1152                     }
       
  1153 
       
  1154                 TRect markBox( pos, KItemMarkSize );
       
  1155                 markBox.Move( -markBox.Width() / 2, -markBox.Height() / 2 );
       
  1156                 aGc.SetPenSize( KItemMarkSize );
       
  1157                 aGc.Plot( pos );
       
  1158                 }
       
  1159 
       
  1160             if ( items[i]->Text().Length() )
       
  1161                 {
       
  1162                 TPoint textPos( pos );
       
  1163                 textPos.iX += KLmTextOffset;
       
  1164 
       
  1165                 TSize textSize( aFont.TextWidthInPixels( items[i]->Text() ), aFont.HeightInPixels() );
       
  1166                 TRect textBox( textPos, textSize );
       
  1167 
       
  1168                 // verify this textbox does not intersect any previous ones
       
  1169                 TBool overlaps = EFalse;
       
  1170                 for ( TInt b = 0; b < textBoxes.Count(); b++ )
       
  1171                     {
       
  1172                     if ( textBox.Intersects( textBoxes[b] ) )
       
  1173                         {
       
  1174                         overlaps = ETrue;
       
  1175                         break;
       
  1176                         }
       
  1177                     }
       
  1178 
       
  1179                 if ( !overlaps )
       
  1180                     {
       
  1181                     textBoxes.Append( textBox );
       
  1182 
       
  1183                     aGc.SetPenSize( TSize( 1, 1 ) );
       
  1184 
       
  1185                     TRgb textColor, textShadowColor;
       
  1186 
       
  1187 	                if ( items[i]->IsPoi() )
       
  1188 	                    {
       
  1189 	                    textColor = KPoiTextColor;
       
  1190 						textShadowColor = KPoiTextShadowColor;
       
  1191 	                    }
       
  1192 	                else
       
  1193 	                    {
       
  1194 	                    textColor = KLmTextColor;
       
  1195 						textShadowColor = KLmTextShadowColor;
       
  1196 	                    }
       
  1197 
       
  1198                     // text shadow
       
  1199                     TPoint shadowPos( textPos + TPoint( KLmTextShadowOffset, KLmTextShadowOffset ) );
       
  1200                     aGc.SetPenColor( aSwitchColorAndShadow ? textColor : textShadowColor );
       
  1201                     aGc.DrawText( items[i]->Text(), shadowPos );
       
  1202 
       
  1203                     // text itself
       
  1204                     aGc.SetPenColor( aSwitchColorAndShadow ? textShadowColor : textColor );
       
  1205                     aGc.DrawText( items[i]->Text(), textPos );
       
  1206                     }
       
  1207                 }
       
  1208             }
       
  1209         }
       
  1210     textBoxes.Close();
       
  1211     }
       
  1212 
       
  1213 // -----------------------------------------------------------------------------
       
  1214 // -----------------------------------------------------------------------------
       
  1215 //
       
  1216 void CMnrpMapModel::DrawCurrentLocation(
       
  1217     CFbsBitGc& aGc,
       
  1218     const TSize& aBoxSize ) const
       
  1219     {
       
  1220     const TSize KPositionPenSize( 20, 20 );
       
  1221     const TSize KPositionErrorPenSize( 1, 1 );
       
  1222     const TRgb KPositionColor( 255, 255, 0 );
       
  1223 
       
  1224     // draw current location
       
  1225     CMnrpMapModel::TCurrentLocation location = CurrentLocation();
       
  1226 
       
  1227     if ( location.iIsValid )
       
  1228         {
       
  1229         TPoint& pos = location.iLocation;
       
  1230 
       
  1231         if ( pos.iX >= 0 && pos.iX < aBoxSize.iWidth &&
       
  1232              pos.iY >= 0 && pos.iY < aBoxSize.iHeight )
       
  1233             {
       
  1234             if ( location.iErrorRadius )
       
  1235                 {
       
  1236                 TRect circleBox( pos.iX, pos.iY, pos.iX, pos.iY );
       
  1237                 circleBox.Grow( location.iErrorRadius, location.iErrorRadius );
       
  1238 
       
  1239                 aGc.SetPenSize( KPositionErrorPenSize );
       
  1240                 aGc.SetBrushStyle( CGraphicsContext::EVerticalHatchBrush );
       
  1241                 aGc.SetBrushColor( KPositionColor );
       
  1242                 aGc.DrawEllipse( circleBox );
       
  1243                 }
       
  1244 
       
  1245             aGc.SetPenColor( KPositionColor );
       
  1246             aGc.SetPenSize( KPositionPenSize );
       
  1247             aGc.Plot( pos );
       
  1248             }
       
  1249         }
       
  1250     }
       
  1251