Alle eigenen gpx Tracks in einer Map darstellen

Komoot kann das nicht, und bikemap auch nicht: Alle eigenen Routen in einer Map darstellen.

Dabei wäre das doch eine schicke Sache: man würde auf einen Blick sehen, welche Gegenden man kennt, und welche nicht. Damit man immer auf den ausgetretenen Pfaden unterwegs ist…

Ich hab mir kurzerhand eine solche Ansicht gebastelt.

Alle Routen

Zu sehen sind nicht alle meine Routen, sondern nur die in Deutschland, und nur die der letzten Jahre. Man kann auf die Routen klicken (wenn man sie trifft…); es wird dann ein kleines Infopopup gezeigt.

Implementation

Ich habe die gpxviewer JavaScript Lib von Chris Peplin genommen und für meine Bedürfnisse angepasst: https://github.com/peplin/gpxviewer.

Diese Javascript Implementation verwendet einen sinnvollen Trick: um die Datengrößen zu reduzieren, werden nur die Trackpoints genommen, die einen bestimmten Abstand vom Vorgängerpunkt haben. Ich hab das mal überprüft und gesehen, dass die Einparungen zwischen 70% und 90% liegen. Da ist es dann naheliegend, garnicht erst die großen gpx zu laden und im Browser zu parsen, sondern diese gleich serverseitig zu minifizieren. Das Script dazu hab ich mir in Python geschrieben und verwendet die gpxpy Library https://github.com/tkrajina/gpxpy.

def close_enough (point):
    lat = point.latitude
    lon = point.longitude
    global lastlon, lastlat,used,skipped

    # print 'Point at ({0},{1}) -> {2}'.format(point.latitude, point.longitude, point.elevation)

    #  Verify that this is far enough away from the last point to be used.
    latdiff = lat - lastlat;
    londiff = lon - lastlon;
    if math.sqrt(latdiff*latdiff + londiff*londiff) >  mintrackpointdelta:
        lastlon = lon;
        lastlat = lat;
        used +=1;
        return True;
    else:
        skipped +=1;
        return False;

def minify(infile):
    gpx_file = open(infile, 'r')
    gpx = gpxpy.parse(gpx_file)
    for track in gpx.tracks:
        for segment in track.segments:
            segment.points[:] = [point for point in segment.points if close_enough(point)]

    print 'used {0} skipped {1}'.format(used, skipped)
    return gpx

Gesteuert wird die Map über ein JSON File, welches die Routen und Infos zu diesen enthält:

[
                {
                  "file" : "/tracks/gpx/generated/201406-berlin-kopenhagen/20140618.gpx",
                  "name" : "Berlin-Kopenhagen: Tag 5",
                  "von" : "Schwaan",
                  "nach" : "Marielyst",
                  "distanz" : 22,
                  "standardOpts" : {
                      "strokeColor" : "#99cccc",
                      "strokeWidth" : 5
                  },
                  "highlightOpts" : {
                      "strokeColor" : "#ff0000",
                      "strokeWidth" : 5
                  }
                }
]
Die Opts Parameter können genutzt werden, um einzelne Tracks anders darszustellen.