|
1 /* |
|
2 * Copyright (c) 2006 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: CMnrpEngine class implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <coemain.h> |
|
20 #include <aknlists.h> |
|
21 #include <barsread2.h> |
|
22 #include <barsc2.h> |
|
23 |
|
24 #include <lbsposition.h> |
|
25 #include <lbspositioninfo.h> |
|
26 |
|
27 #include <EPos_CPosLandmark.h> |
|
28 #include <EPos_CPosLandmarkDatabase.h> |
|
29 |
|
30 #include <mnrefproviderengine.rsg> |
|
31 |
|
32 #include "../inc/debug.h" |
|
33 #include "mnrpengine.h" |
|
34 |
|
35 _LIT( KCitiesResourceFile, "\\resource\\mnrefproviderengine.rsc"); |
|
36 |
|
37 // ============================ MEMBER FUNCTIONS =============================== |
|
38 |
|
39 // ----------------------------------------------------------------------------- |
|
40 // ----------------------------------------------------------------------------- |
|
41 // |
|
42 CMnrpEngine::CMnrpEngine() |
|
43 { |
|
44 } |
|
45 |
|
46 // ----------------------------------------------------------------------------- |
|
47 // ----------------------------------------------------------------------------- |
|
48 // |
|
49 EXPORT_C CMnrpEngine::~CMnrpEngine() |
|
50 { |
|
51 iPlaces.ResetAndDestroy(); |
|
52 iFileSession.Close(); |
|
53 } |
|
54 |
|
55 // ----------------------------------------------------------------------------- |
|
56 // ----------------------------------------------------------------------------- |
|
57 // |
|
58 EXPORT_C CMnrpEngine* CMnrpEngine::NewL() |
|
59 { |
|
60 CMnrpEngine* self = new (ELeave) CMnrpEngine(); |
|
61 CleanupStack::PushL( self ); |
|
62 self->ConstructL(); |
|
63 CleanupStack::Pop( self ); |
|
64 return self; |
|
65 } |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // ----------------------------------------------------------------------------- |
|
69 // |
|
70 void CMnrpEngine::ConstructL() |
|
71 { |
|
72 User::LeaveIfError( iFileSession.Connect() ); |
|
73 } |
|
74 |
|
75 // ----------------------------------------------------------------------------- |
|
76 // ----------------------------------------------------------------------------- |
|
77 // |
|
78 EXPORT_C TArray<CPosLandmark*> CMnrpEngine::KnownPlacesL() |
|
79 { |
|
80 if ( iPlaces.Count() == 0 ) |
|
81 { |
|
82 TRAP_IGNORE( LoadKnownPlacesL() ); |
|
83 } |
|
84 |
|
85 return iPlaces.Array(); |
|
86 } |
|
87 |
|
88 // ----------------------------------------------------------------------------- |
|
89 // ----------------------------------------------------------------------------- |
|
90 // |
|
91 EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordLC( const CPosLandmark& aAddress ) |
|
92 { |
|
93 CPosLandmark* lm = AddressToCoordL( aAddress ); |
|
94 if ( lm ) |
|
95 { |
|
96 CleanupStack::PushL( lm ); |
|
97 return lm; |
|
98 } |
|
99 else |
|
100 { |
|
101 User::Leave( KErrNotFound ); |
|
102 return NULL; |
|
103 } |
|
104 } |
|
105 |
|
106 // ----------------------------------------------------------------------------- |
|
107 // ----------------------------------------------------------------------------- |
|
108 // |
|
109 EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordL( const CPosLandmark& aAddress ) |
|
110 { |
|
111 TPtrC city, country; |
|
112 aAddress.GetPositionField( EPositionFieldCity, city ); |
|
113 |
|
114 TArray<CPosLandmark*> pois = KnownPlacesL(); |
|
115 |
|
116 if ( city.Length() ) |
|
117 { |
|
118 for ( TInt i = 0; i < pois.Count(); i++ ) |
|
119 { |
|
120 TPtrC poiCity; |
|
121 pois[i]->GetPositionField( EPositionFieldCity, poiCity ); |
|
122 if ( poiCity.CompareF( city ) == 0 ) |
|
123 { |
|
124 return CPosLandmark::NewL( *pois[i] ); |
|
125 } |
|
126 } |
|
127 } |
|
128 |
|
129 return NULL; |
|
130 } |
|
131 |
|
132 // ----------------------------------------------------------------------------- |
|
133 // ----------------------------------------------------------------------------- |
|
134 // |
|
135 EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordLC( const TDesC& aAddress ) |
|
136 { |
|
137 CPosLandmark* lm = AddressToCoordL( aAddress ); |
|
138 if ( lm ) |
|
139 { |
|
140 CleanupStack::PushL( lm ); |
|
141 return lm; |
|
142 } |
|
143 else |
|
144 { |
|
145 User::Leave( KErrNotFound ); |
|
146 return NULL; |
|
147 } |
|
148 } |
|
149 |
|
150 // ----------------------------------------------------------------------------- |
|
151 // ----------------------------------------------------------------------------- |
|
152 // |
|
153 EXPORT_C CPosLandmark* CMnrpEngine::AddressToCoordL( const TDesC& aAddress ) |
|
154 { |
|
155 TArray<CPosLandmark*> pois = KnownPlacesL(); |
|
156 |
|
157 if ( aAddress.Length() ) |
|
158 { |
|
159 for ( TInt i = 0; i < pois.Count(); i++ ) |
|
160 { |
|
161 TPtrC city, country; |
|
162 pois[i]->GetPositionField( EPositionFieldCity, city ); |
|
163 pois[i]->GetPositionField( EPositionFieldCountry, country ); |
|
164 |
|
165 if ( aAddress.FindF( city ) >= 0 ) |
|
166 { |
|
167 return CPosLandmark::NewL( *pois[i] ); |
|
168 } |
|
169 } |
|
170 } |
|
171 |
|
172 return NULL; |
|
173 } |
|
174 |
|
175 // ----------------------------------------------------------------------------- |
|
176 // ----------------------------------------------------------------------------- |
|
177 // |
|
178 EXPORT_C TReal32 CMnrpEngine::DistanceBetweenLandmarks( |
|
179 const CPosLandmark& aFrom, |
|
180 const CPosLandmark& aTo ) |
|
181 { |
|
182 TRealX nan; |
|
183 nan.SetNaN(); |
|
184 TReal32 distance = nan; |
|
185 |
|
186 TLocality locFrom, locTo; |
|
187 |
|
188 if ( aFrom.GetPosition( locFrom ) == KErrNone && |
|
189 aTo.GetPosition( locTo ) == KErrNone ) |
|
190 { |
|
191 TReal32 dist; |
|
192 if ( locFrom.Distance( locTo, dist ) == KErrNone ) |
|
193 { |
|
194 distance = dist; |
|
195 } |
|
196 } |
|
197 return distance; |
|
198 } |
|
199 |
|
200 // ----------------------------------------------------------------------------- |
|
201 // ----------------------------------------------------------------------------- |
|
202 // |
|
203 EXPORT_C void CMnrpEngine::FindClosestPoisL( |
|
204 const CPosLandmark& aReference, |
|
205 RArray<CMnrpEngine::TDistanceToPoi>& aNeighbourPois, |
|
206 TInt aMaxMatches ) |
|
207 { |
|
208 aNeighbourPois.Reset(); |
|
209 TArray<CPosLandmark*> pois = KnownPlacesL(); |
|
210 |
|
211 // calc distances to known places and find out closest ones |
|
212 for ( TInt i = 0; i < pois.Count(); i++ ) |
|
213 { |
|
214 CPosLandmark* poi = pois[i]; |
|
215 |
|
216 TReal32 distance = DistanceBetweenLandmarks( aReference, *poi ); |
|
217 |
|
218 if ( Math::IsNaN( distance ) ) |
|
219 { |
|
220 continue; |
|
221 } |
|
222 |
|
223 TDistanceToPoi newDistToPoi; |
|
224 newDistToPoi.iPoiIndex = i; |
|
225 newDistToPoi.iDistance = distance; |
|
226 |
|
227 for ( TInt k = 0; k < aNeighbourPois.Count(); k++ ) |
|
228 { |
|
229 TDistanceToPoi distToPoi = aNeighbourPois[k]; |
|
230 if ( distance < distToPoi.iDistance ) |
|
231 { |
|
232 // current POI is closer to reference than current neighbour |
|
233 aNeighbourPois.InsertL( newDistToPoi, k ); |
|
234 break; |
|
235 } |
|
236 } |
|
237 |
|
238 if ( aNeighbourPois.Count() < aMaxMatches ) |
|
239 { |
|
240 aNeighbourPois.AppendL( newDistToPoi ); |
|
241 } |
|
242 |
|
243 if ( aNeighbourPois.Count() > aMaxMatches ) |
|
244 { |
|
245 aNeighbourPois.Remove( aNeighbourPois.Count() - 1 ); // remove last |
|
246 } |
|
247 } |
|
248 } |
|
249 |
|
250 // ----------------------------------------------------------------------------- |
|
251 // ----------------------------------------------------------------------------- |
|
252 // |
|
253 CPosLandmark* CMnrpEngine::CreateCloseLandmarkLC( |
|
254 const CPosLandmark& aReference, |
|
255 TReal32 aDistance ) |
|
256 { |
|
257 CPosLandmark* lm = CPosLandmark::NewLC( aReference ); |
|
258 TPtrC oldName; |
|
259 lm->GetLandmarkName( oldName ); |
|
260 |
|
261 // create street in the form of "50 km to <POI name>" |
|
262 const TInt KDistValueLen = 5; // "40000" |
|
263 const TInt KAdditionalChars = 7; // " km to " |
|
264 |
|
265 _LIT( KLocationNameFormat, "%d m to %S" ); |
|
266 _LIT( KLocationNameFormatKm, "%d km to %S" ); |
|
267 |
|
268 HBufC* locName = HBufC::NewLC( oldName.Length() + KDistValueLen + KAdditionalChars ); |
|
269 |
|
270 if ( aDistance < 1000 ) |
|
271 { |
|
272 locName->Des().Format( KLocationNameFormat, TInt( aDistance ), &oldName ); |
|
273 } |
|
274 else |
|
275 { |
|
276 locName->Des().Format( KLocationNameFormatKm, TInt( aDistance / 1000 ), &oldName ); |
|
277 } |
|
278 |
|
279 lm->SetPositionFieldL( EPositionFieldLocationName, *locName ); |
|
280 lm->SetPositionFieldL( EPositionFieldStreet, *locName ); |
|
281 |
|
282 CleanupStack::PopAndDestroy( locName ); |
|
283 return lm; // left in stack |
|
284 } |
|
285 |
|
286 // ----------------------------------------------------------------------------- |
|
287 // ----------------------------------------------------------------------------- |
|
288 // |
|
289 EXPORT_C CPosLandmark* CMnrpEngine::CoordToAddressLC( const TCoordinate& aLocation ) |
|
290 { |
|
291 TArray<CPosLandmark*> pois = KnownPlacesL(); |
|
292 |
|
293 // find closest POI |
|
294 RArray<TDistanceToPoi> matches; |
|
295 CleanupClosePushL( matches ); |
|
296 |
|
297 CPosLandmark* temp = CPosLandmark::NewLC(); |
|
298 TLocality loc( aLocation, 0 ); // accuracy is not used by this implementation |
|
299 temp->SetPositionL( loc ); |
|
300 FindClosestPoisL( *temp, matches, 1 ); // only one match needed |
|
301 CleanupStack::PopAndDestroy( temp ); |
|
302 |
|
303 if ( matches.Count() < 1 ) |
|
304 { |
|
305 User::Leave( KErrNotFound ); |
|
306 } |
|
307 |
|
308 TDistanceToPoi distToPoi = matches[0]; |
|
309 CleanupStack::PopAndDestroy( &matches ); |
|
310 |
|
311 CPosLandmark* lm = CreateCloseLandmarkLC( |
|
312 *pois[distToPoi.iPoiIndex], |
|
313 distToPoi.iDistance ); |
|
314 |
|
315 return lm; // left in stack |
|
316 } |
|
317 |
|
318 // ----------------------------------------------------------------------------- |
|
319 // ----------------------------------------------------------------------------- |
|
320 // |
|
321 EXPORT_C void CMnrpEngine::BestCoordToAddressMatchesL( |
|
322 const TCoordinate& aLocation, |
|
323 RPointerArray<CPosLandmark>& aMatches, |
|
324 TInt aMaxMatches ) |
|
325 { |
|
326 TArray<CPosLandmark*> pois = KnownPlacesL(); |
|
327 |
|
328 // find closest POIs |
|
329 RArray<TDistanceToPoi> matches; |
|
330 CleanupClosePushL( matches ); |
|
331 |
|
332 CPosLandmark* temp = CPosLandmark::NewLC(); |
|
333 TLocality loc( aLocation, 0 ); // accuracy is not used by this implementation |
|
334 temp->SetPositionL( loc ); |
|
335 FindClosestPoisL( *temp, matches, aMaxMatches ); |
|
336 CleanupStack::PopAndDestroy( temp ); |
|
337 |
|
338 for ( TInt i = 0; i < matches.Count(); i++ ) |
|
339 { |
|
340 TDistanceToPoi distToPoi = matches[i]; |
|
341 |
|
342 CPosLandmark* lm = CreateCloseLandmarkLC( |
|
343 *pois[distToPoi.iPoiIndex], |
|
344 distToPoi.iDistance ); |
|
345 |
|
346 aMatches.AppendL( lm ); |
|
347 CleanupStack::Pop( lm ); |
|
348 } |
|
349 CleanupStack::PopAndDestroy( &matches ); |
|
350 } |
|
351 |
|
352 // ----------------------------------------------------------------------------- |
|
353 // ----------------------------------------------------------------------------- |
|
354 // |
|
355 EXPORT_C void CMnrpEngine::FindResourceFileL( |
|
356 const TDesC& aFilePathAndName, |
|
357 TFileName& aRscFile ) |
|
358 { |
|
359 TParse parse; |
|
360 parse.Set( aFilePathAndName, NULL, NULL ); |
|
361 |
|
362 TFindFile finder( iFileSession ); |
|
363 if ( finder.FindByDir( parse.NameAndExt(), parse.Path() ) == KErrNone ) |
|
364 { |
|
365 aRscFile.Copy( finder.File() ); |
|
366 } |
|
367 else |
|
368 { |
|
369 User::Leave( KErrNotFound ); |
|
370 } |
|
371 } |
|
372 |
|
373 // ----------------------------------------------------------------------------- |
|
374 // ----------------------------------------------------------------------------- |
|
375 // |
|
376 EXPORT_C RFs& CMnrpEngine::Fs() |
|
377 { |
|
378 return iFileSession; |
|
379 } |
|
380 |
|
381 // ----------------------------------------------------------------------------- |
|
382 // ----------------------------------------------------------------------------- |
|
383 // |
|
384 void CMnrpEngine::LoadKnownPlacesL() |
|
385 { |
|
386 TFileName resourceFile; |
|
387 FindResourceFileL( KCitiesResourceFile(), resourceFile ); |
|
388 |
|
389 CResourceFile* resFile = CResourceFile::NewLC( iFileSession, resourceFile, 0, 0 ); |
|
390 resFile->ConfirmSignatureL( 0 ); |
|
391 |
|
392 RResourceReader reader; |
|
393 |
|
394 reader.OpenLC( resFile, R_MNREFPROVIDERENGINE_PLACES ); |
|
395 ReadPlacesResourceL( reader ); |
|
396 CleanupStack::PopAndDestroy( &reader ); |
|
397 |
|
398 CleanupStack::PopAndDestroy( resFile ); |
|
399 } |
|
400 |
|
401 // ----------------------------------------------------------------------------- |
|
402 // ----------------------------------------------------------------------------- |
|
403 // |
|
404 void CMnrpEngine::ReadPlacesResourceL( RResourceReader& aReader ) |
|
405 { |
|
406 TInt size = aReader.ReadInt16L(); |
|
407 |
|
408 for ( TInt i = 0; i < size; i++ ) |
|
409 { |
|
410 HBufC* city = aReader.ReadHBufCL(); |
|
411 CleanupStack::PushL( city ); |
|
412 HBufC* country = aReader.ReadHBufCL(); |
|
413 CleanupStack::PushL( country ); |
|
414 |
|
415 TReal64 lat = aReader.ReadReal64L(); |
|
416 TReal64 lon = aReader.ReadReal64L(); |
|
417 |
|
418 CPosLandmark* lm = CPosLandmark::NewLC(); |
|
419 lm->SetLandmarkNameL( *city ); |
|
420 |
|
421 lm->SetPositionFieldL( EPositionFieldCity, *city ); |
|
422 lm->SetPositionFieldL( EPositionFieldCountry, *country ); |
|
423 |
|
424 TLocality coord; |
|
425 coord.SetCoordinate( lat, lon ); |
|
426 lm->SetPositionL( coord ); |
|
427 |
|
428 iPlaces.AppendL( lm ); |
|
429 CleanupStack::Pop( lm ); |
|
430 CleanupStack::PopAndDestroy( country ); |
|
431 CleanupStack::PopAndDestroy( city ); |
|
432 } |
|
433 } |