diff -r 000000000000 -r c316ab048e9d plugin/poi/geonames/provider/src/Loader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/poi/geonames/provider/src/Loader.cpp Fri Jun 25 12:50:05 2010 +0200 @@ -0,0 +1,264 @@ +/* + * Name : Loader.cpp + * Description : + * Project : This file is part of OpenMAR, an Open Mobile Augmented Reality browser + * Website : http://OpenMAR.org + * + * Copyright (c) 2010 David Caabeiro + * + * All rights reserved. This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 which accompanies this + * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html + * + */ + +#include "Loader.h" + +#include "HttpClient.h" +#include "Entry.h" + +#include +#include +#include +#include + +#include +#include + +#include "Logger.h" + +CLoader* CLoader::NewL(MLandmarkLoaderObserver& aObserver) +{ + CLoader* self = new(ELeave) CLoader(aObserver); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; +} + +CLoader::~CLoader() +{ + delete iEntry; + delete iParser; + delete iClient; +} + +CLoader::CLoader(MLandmarkLoaderObserver& aObserver) + : iObserver(aObserver) +{ +} + +void CLoader::ConstructL() +{ + LOGTXT("[GEONAMES] Creating POI loader"); + + iClient = CHttpClient::NewL(*this); + + _LIT8(KXmlMimeType, "text/xml"); + iParser = Xml::CParser::NewL(KXmlMimeType, *this); + + iEntry = CEntry::NewL(); +} + +void CLoader::RequestL(const TCoordinate& aPosition, TReal32 aRadius) +{ + // Regardless of system locale, always use point as decimal separator character + // Also use a maximum of 6 chars to represent each float + TRealFormat realFormat; + realFormat.iPoint = TChar('.'); + realFormat.iWidth = 8; + realFormat.iPlaces = 5; + + TBuf8 latitude; + latitude.Num(aPosition.Latitude(), realFormat); + + TBuf8 longitude; + longitude.Num(aPosition.Longitude(), realFormat); + + // Convert to kilometers + const TInt radius = static_cast(aRadius / 1000); + + TBuf8<2> langCode; + + // Use device's language to retrieve entries + HBufC* tag = AknLangUtils::DisplayLanguageTagL(); + langCode.Copy(tag->Left(2)); + delete tag; + + // Set a limit to entries retrieved + const TInt maxRows = 20; + + TBuf8<256> uri; + _LIT8(KUri, "http://ws.geonames.org/findNearbyWikipedia?lat=%S&lng=%S&radius=%d&lang=%S&maxRows=%d"); + uri.Format(KUri, &latitude, &longitude, radius, &langCode, maxRows); + + iClient->GetL(uri); +} + +void CLoader::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent) +{ + switch (aEvent.iStatus) + { + case THTTPEvent::EGotResponseHeaders: + { + RHTTPResponse resp = aTransaction.Response(); + TInt status = resp.StatusCode(); + + // Treat any 2xx HTTP code as successful request + TInt error = HTTPStatus::IsSuccessful(status)? KErrNone : KErrGeneral; + + if (error == KErrNone) + iParser->ParseBeginL(); + + iObserver.LandmarkLoaderOpenedL(error); + + break; + } + + case THTTPEvent::EGotResponseBodyData: + { + MHTTPDataSupplier* body = aTransaction.Response().Body(); + + TPtrC8 dataChunk; + body->GetNextDataPart(dataChunk); + iParser->ParseL(dataChunk); + body->ReleaseData(); + + break; + } + + case THTTPEvent::EResponseComplete: + LOGTXT("[GEONAMES] HTTP response complete"); + + iParser->ParseEndL(); + break ; + + case THTTPEvent::ESucceeded: + case THTTPEvent::EFailed: + { + RHTTPResponse resp = aTransaction.Response(); + TInt status = resp.StatusCode(); + + LOGARG("[GEONAMES] HTTP response status code %d", status); + + aTransaction.Close(); + + break; + } + + default: + LOGARG("[GEONAMES] HTTP unknown event %d", aEvent.iStatus); + + iObserver.LandmarkLoaderOpenedL(KErrUnknown); + + aTransaction.Close(); + break; + } +} + +TInt CLoader::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent) +{ + return KErrNone; +} + +void CLoader::OnStartDocumentL(const Xml::RDocumentParameters& aDocParam, TInt aErrorCode) +{} + +void CLoader::OnEndDocumentL(TInt aErrorCode) +{} + +void CLoader::OnStartElementL(const Xml::RTagInfo& aElement, const Xml::RAttributeArray& aAttributes, TInt aErrorCode) +{ + _LIT8(KEntryTag, "entry"); + if (aElement.LocalName().DesC() == KEntryTag) + iState = EValid; + else if (iState == EValid) + iEntry->EnterState(aElement.LocalName().DesC()); +} + +void CLoader::OnEndElementL(const Xml::RTagInfo& aElement, TInt aErrorCode) +{ + _LIT8(KEntryTag, "entry"); + if (aElement.LocalName().DesC() == KEntryTag) + { + NotifyPOIEntryL(); + + iEntry->Reset(); + iState = EInvalid; + } + else + iEntry->ExitState(); +} + +void CLoader::OnContentL(const TDesC8& aBytes, TInt aErrorCode) +{ + iEntry->FeedState(aBytes); +} + +void CLoader::OnStartPrefixMappingL(const RString& /*aPrefix*/, const RString& /*aUri*/, TInt /*aErrorCode*/) +{} + +void CLoader::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt /*aErrorCode*/) +{} + +void CLoader::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/) +{} + +void CLoader::OnSkippedEntityL(const RString& /*aName*/, TInt /*aErrorCode*/) +{} + +void CLoader::OnProcessingInstructionL(const TDesC8& /*aTarget*/, const TDesC8& /*aData*/, TInt /*aErrorCode*/) +{} + +void CLoader::OnError(TInt /*aErrorCode*/) +{} + +TAny* CLoader::GetExtendedInterface(const TInt32 /*aUid*/) +{ + return 0; +} + +/* + * Notify observer of new XML entry + */ +void CLoader::NotifyPOIEntryL() +{ + CPosLandmark* landmark = CPosLandmark::NewLC(); + + HBufC* title = CnvUtfConverter::ConvertToUnicodeFromUtf8L(iEntry->iTitle); + CleanupStack::PushL(title); + landmark->SetLandmarkNameL(*title); + CleanupStack::PopAndDestroy(title); + + HBufC* description = CnvUtfConverter::ConvertToUnicodeFromUtf8L(iEntry->iSummary); + CleanupStack::PushL(description); + landmark->SetLandmarkDescriptionL(*description); + CleanupStack::PopAndDestroy(description); + + TLex8 lex; + + lex.Assign(iEntry->iLat); + TReal32 lat = 0; + lex.Val(lat); + + lex.Assign(iEntry->iLng); + TReal32 lng = 0; + lex.Val(lng); + + lex.Assign(iEntry->iElevation); + TReal32 elevation = 0; + lex.Val(elevation); + + TCoordinate coordinate(lat, lng, elevation); + landmark->SetPositionL(TLocality(coordinate, 0, 0)); + + HBufC* url = HBufC::NewLC(iEntry->iWikipediaUrl.Length()); + url->Des().Copy(iEntry->iWikipediaUrl); + landmark->SetPositionFieldL(EPositionFieldMediaLinksStart, url->Left(KPosLmMaxTextFieldLength)); + CleanupStack::PopAndDestroy(url); + + iObserver.LandmarkLoaderItemCreatedL(*landmark); + + CleanupStack::PopAndDestroy(landmark); +}