Search code examples
strava

Strava api to export GPX file of activity


I am well able to download my GPX file of an activity when logged in to Strava and calling this link: https://www.strava.com/activities/5656012590/export_original I get the original gpx. It looks as I need it.

Is there a v3 api way? I would like to access it with the swagger generated code, a la

new ActivitiesApi(getApiClientWithToken(token)).getLoggedInAthleteActivities(System.currentTimeSeconds().toInteger(), 0, 1, 30)

(Groovy code, this works for getting activities)

The only thing I found is https://www.strava.com/api/v3/routes/{id}/export_gpx. But from what I see in the Api response of activities, there is no route attached to it. In activities I can see an 'externalId' which is set to something like '123456123.gpx' and I can see the polylines from the map. But converting polylines sounds like too much effort now and I guess it misses some points. Accessing the externalID, I have no idea.

In the end I don't really care how to get the GPX. If it is a cURL call with passing the token via post and then downloading it, would be fine, as well as getting it with the Java API from swagger. I would prefer the latter option though.


Solution

  • Closest I could get is using the streams API as described in other posts.

            StreamSet streamSet = streamsApi.getActivityStreams(activityId as long, ['latlng', 'altitude', 'time'], true)
    
            def altitudes = streamSet.getAltitude().getData()
            def latLong = streamSet.getLatlng().getData()
            def times = streamSet.getTime().getData()
    
            ArrayList<StreamData> data = []
            for (int i = 0; i < times.size(); i++) {
                StreamData streamData = new StreamData()
                streamData.id = activityId as long
                streamData.time = times[i]
                streamData.startTime = startTime
                streamData.altitude = altitudes[i]
                streamData.latitude = latLong[i][0]
                streamData.longitude = latLong[i][1]
                data << streamData
            }
    

    and then building my own GPX file from it:

        def stringWriter = new StringWriter()
        def gpxBuilder = new MarkupBuilder(stringWriter)
    
        gpxBuilder.mkp.xmlDeclaration(version: "1.0", encoding: "utf-8")
        gpxBuilder.gpx() {
            metadata() {
                time(startTime)
            }
            trk() {
                name(NEW_ACTIVITY_NAME)
                type(convertedType)
                trkseg() {
                    for (def item : streamData) {
                        trkpt(lat: item.latitude, lon: item.longitude) {
                            ele(item.altitude)
                            time(UtcTimeString)
                        }
                    }
                }
            }
        }
    
        stringWriter.toString()
    

    Uploading this to Strava works well.