--- /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 <AknUtils.h>
+#include <LbsPositionInfo.h>
+#include <Http/mhttpdatasupplier.h>
+#include <HttpErr.h>
+
+#include <EPos_CPosLandmark.h>
+#include <utf.h>
+
+#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<KDefaultRealWidth> latitude;
+ latitude.Num(aPosition.Latitude(), realFormat);
+
+ TBuf8<KDefaultRealWidth> longitude;
+ longitude.Num(aPosition.Longitude(), realFormat);
+
+ // Convert to kilometers
+ const TInt radius = static_cast<TInt>(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);
+}