OpenStreetMap Forum

The Free Wiki World Map

You are not logged in.

#1 2007-11-07 20:26:57

Peter Kirst
Member
Registered: 2007-11-07
Posts: 5

gpx Upload with MFC

Hi all,

I want to upload a recorded gpx log direct from my PPC with an MFC based application, but I'd never handled http POSTs before.
Now I set up a function and tested successful it with a test php on my server but it fails on OSM because I don't know how I have to handle the user (email), password.
The server returns StatusCode 200 (no error) but the html page reports
Upload GPS Trace
1 error prohibited this trace from being saved

There were problems with the following fields:
* User can't be blank


Can somebody help me? Here is the code:

BOOL SendTrack(CString csUser, CString csPassWD, CString csFileName, CString csTags, CString csDescription, BOOL bPublic)
{
    CString strFullPath = _T("http://www.openstreetmap.org/trace/create");

    //Just dummy data. This will be replaced by content of the csFileName file
    CString csTestData =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
    <gpx version=\"1.0\" creator=\"Glopus - http://www.glopus.de\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \
        xmlns=\"http://www.topografix.com/GPX/1/0\" \
        xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\"> \
        <time>2007-11-06T20:27:50Z</time> \
    <bounds minlat=\"48.000\" minlon=\"11.000\" maxlat=\"48.100\" maxlon=\"11.1000\"/> \
    <trk> \
    <trkseg>\
    <trkpt lat=\"48.05\" lon=\"11.05\">\
    <time>2004-09-22T04:18:27Z</time>\
    <course>108.550003</course>\
    <speed>0.027221</speed>\
    </trkpt>\
    </trkseg>\
    </trk>\
</gpx>";


    BOOL bSuccess = TRUE;

    CInternetSession session(NULL, 0, PRE_CONFIG_INTERNET_ACCESS);
    CHttpConnection * pServer = NULL;
    CHttpFile * pFile = NULL;

    CString strServerName;
    CString strObject;
    INTERNET_PORT nPort;
    DWORD dwServiceType;
    CHttpFile *pHTTP = 0;
    TCHAR szError[MAX_PATH];

    if (!AfxParseURL(strFullPath, dwServiceType, strServerName, strObject, nPort) || 
            dwServiceType != INTERNET_SERVICE_HTTP)
        return FALSE;
    session.EnableStatusCallback(TRUE);

    pServer = session.GetHttpConnection(strServerName, nPort, csUser, csPassWD);


    try
    {
        CString csPreFileData, csPostFileData, csHeader, csBoundary = "xyzw";
        // I tried to send the Authorization here, but no success
        /*
                                CBase64 Encoder;
        CString UserPW = csUser + _T(":") + csPassWD;
        UserPW = Encoder.Encode(UserPW, UserPW.GetLength());

        csHeader += _T("Authorization: Basic ") + UserPW + _T("\r\n"); 
                                */
        csHeader += _T("Content-Type: multipart/form-data; boundary=") + csBoundary + _T("\r\n");

        // also this was not accepted        /*
         csPreFileData += _T("--") + csBoundary;
        csPreFileData += _T("\r\n");
        csPreFileData += _T("Content-Disposition: form-data; name=\"trace[user]\"");
        csPreFileData += _T("\r\n\r\n");
        csPreFileData += csUser;
        csPreFileData += _T("\r\n");
                                */
        
        csPreFileData += _T("--") + csBoundary;
        csPreFileData += _T("\r\n");
        csPreFileData += _T("Content-Disposition: form-data; name=\"trace[public]\"");
        csPreFileData += _T("\r\n\r\n");
        csPreFileData += bPublic?_T("1"):_T("0");
        csPreFileData += _T("\r\n");
        
        csPreFileData += _T("--") + csBoundary;
        csPreFileData += _T("\r\n");
        csPreFileData += _T("Content-Disposition: form-data; name=\"trace[description]\"");
        csPreFileData += _T("\r\n\r\n");
        csPreFileData += csDescription;
        csPreFileData += _T("\r\n");
        
        csPreFileData += _T("--") + csBoundary;
        csPreFileData += _T("\r\n");
        csPreFileData += _T("Content-Disposition: form-data; name=\"trace[tagstring]\"");
        csPreFileData += _T("\r\n\r\n");
        csPreFileData += csTags;
        csPreFileData += _T("\r\n");
        
        csPreFileData += _T("--") + csBoundary;
        csPreFileData += _T("\r\n");
        csPreFileData += _T("Content-Disposition: form-data; name=\"trace[gpx_file]\"; filename=\"") + csFileName + "\"";
        csPreFileData += _T("\r\n");
        csPreFileData += _T("Content-Type: text/xml");
        csPreFileData += _T("\r\n\r\n");
        
        csPostFileData = _T("\r\n");
        csPostFileData += _T("--") + csBoundary + _T("--");
        csPostFileData += _T("\r\n");
        
        
        DWORD dwSize = (DWORD)csPreFileData.GetLength() + (DWORD)csPostFileData.GetLength() + (DWORD)csTestData.GetLength();

        pHTTP = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject, NULL,1,NULL,"HTTP/1.0",INTERNET_FLAG_RELOAD); 
        
        pHTTP->AddRequestHeaders(csHeader);
        
        pHTTP->SendRequestEx(dwSize, HSR_SYNC | HSR_INITIATE);

#ifdef _UNICODE
        pHTTP->Write(W2A(csPreFileData), csPreFileData.GetLength());
        pHTTP->Write(W2A(csTestData), csTestData.GetLength());
        pHTTP->Write(W2A(csPostFileData), csPostFileData.GetLength());
#else
        pHTTP->Write((LPSTR)(LPCSTR)csPreFileData, csPreFileData.GetLength());
        pHTTP->Write((LPSTR)(LPCSTR)csTestData, csTestData.GetLength());
        pHTTP->Write((LPSTR)(LPCSTR)csPostFileData, csPostFileData.GetLength());
#endif

        pHTTP->EndRequest(HSR_SYNC);

        DWORD dwRet;
        pHTTP->QueryInfoStatusCode(dwRet);
        if (dwRet != 200)
            throw;


        CString csResponse;
        dwSize = (DWORD)pHTTP->GetLength();
        while (0 != dwSize)
        {
            char *szResponse = (LPSTR)malloc(dwSize + 1);
            szResponse[dwSize] = '\0';
            pHTTP->Read(szResponse, dwSize);
            csResponse += CString(szResponse);
            free(szResponse);
            dwSize = (DWORD)pHTTP->GetLength();
        }

        AfxMessageBox(csResponse);

    }

    catch (CException* e)
    {
        e->GetErrorMessage(szError, MAX_PATH);
        e->Delete();
        AfxMessageBox(szError);
        bSuccess = FALSE;
    }

    pHTTP->Close();
    delete pHTTP;

    if ( pServer != NULL )
    {
        pServer->Close();
        delete pServer;
    }
    session.Close();

    return bSuccess;

}

Thanks,
Peter

Last edited by Peter Kirst (2007-11-07 20:27:30)

Offline

#2 2007-11-07 21:20:29

Lambertus
Administrator
From: Apeldoorn (NL)
Registered: 2007-03-17
Posts: 3,269
Website

Re: gpx Upload with MFC

I assume you've found the 0.5 API documentation and HTTP protocol description in the wiki?


Mapping tools: Garmin GPSmap 60CSx, Giant Terrago 2002

Offline

#3 2007-11-08 08:05:51

Peter Kirst
Member
Registered: 2007-11-07
Posts: 5

Re: gpx Upload with MFC

The first yes, but the second is new. I'll try it, thanks.

Offline

#4 2007-11-08 20:27:52

Peter Kirst
Member
Registered: 2007-11-07
Posts: 5

Re: gpx Upload with MFC

sad
Doesn't work anyway. The PUT request sample describes a diffent target: Create a node. But I want to upload a gpx. Beside this it describes the old 0.4 protocol. Additional hints?

Offline

#5 2007-11-08 21:32:01

Lambertus
Administrator
From: Apeldoorn (NL)
Registered: 2007-03-17
Posts: 3,269
Website

Re: gpx Upload with MFC

Nope, I haven't programmed against the API yet. Can you not combine the info in both pages, imho this should be possible.

Trying something else, do you know you can use JOSM for uploading GPX files? Maybe that can solve your problem...


Mapping tools: Garmin GPSmap 60CSx, Giant Terrago 2002

Offline

#6 2007-11-09 16:46:21

Peter Kirst
Member
Registered: 2007-11-07
Posts: 5

Re: gpx Upload with MFC

I tried a lot of combinations but I'm a beginner in such HTTP talk and this is probably the reason. hmm I can upload GPX with other tools. And probably I have no problems if I use Perl or the libs described here http://wiki.openstreetmap.org/index.php/Batch_Upload But this is not possible for my project.

Offline

#7 2007-11-10 12:15:25

Peter Kirst
Member
Registered: 2007-11-07
Posts: 5

Re: gpx Upload with MFC

The URL I tried because it is used by the web interface. But of cause I also tried "http://www.openstreetmap.org/api/0.5/gpx/create", but it doesn't help. Only the response is different: Error 500.
Unfortunately the put request descibed here http://wiki.openstreetmap.org/index.php … cification is different. It just sends a header with Authorization and the data is the xml with the node info.
For gpx I have to submit additiona parameters like trace[gpx_file] and trace[public].
It would help to istall a sniffer and collect the traffic e.g. from JOSM but I never did such things and I wont destroy my system.

Offline

#8 2007-11-12 00:24:42

Thomas Wood
Member
From: London, UK
Registered: 2007-11-12
Posts: 10

Re: gpx Upload with MFC

JOSM doesn't yet deal with GPX uploads afaik, there are plans to implement it soon.

It may be worthwhile contacting the dev@ mailing list for support with this api method, I don't think that it is extensively used yet.

Offline

#9 2008-04-15 13:51:45

tomhenne
Member
Registered: 2008-04-15
Posts: 1

Re: gpx Upload with MFC

Hi Peter, Thomas,

I would like to do the same. I'm one of the developers of Run.GPS, a Pocket PC and Smartphone based software for sports and outdoor activities. Our users would like to upload their tracks directly to OpenStreetMap.org (e.g. http://www.gps-sport.net/forums/thread/ … nStreetMap) and I think that would make sense.

In Run.GPS there is a "synchronize tracks" function so you could easily upload all new tracks with one click.

As said on this page:
http://wiki.openstreetmap.org/index.php/Batch_Upload
one would have to upload to http://www.openstreetmap.org/api/0.5/gpx/create and provide basic authentication information (base64 encoded).

@Peter: did you get it working, finally? I think your code looks alright.

Cheers

Tom

Offline

#10 2008-04-22 23:16:55

Richard
Member
From: Charlbury, UK
Registered: 2007-04-24
Posts: 360
Website

Re: gpx Upload with MFC

There was a problem with the GPX upload method but TomH has fixed it.

Offline

Board footer

Powered by FluxBB