plugin/poi/geonames/provider/src/Loader.cpp
changeset 0 c316ab048e9d
--- /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);
+}