gpx_plot.py
author wim
Wed, 30 Aug 2017 12:37:28 +0200
changeset 10 89108adbc468
parent 4 1b96bb9de1f3
child 12 1d6e37b3ebf2
permissions -rwxr-xr-x
gpx_plot: numpy verijderd uit gpx_plot gpx_reduce: changelog aangepast readme: verbeterd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
     1
#!/usr/bin/env python
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
     2
# -*- coding: utf8 -*-
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
     3
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
     4
'''
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
     5
gpx_plot.py calls gnuplot to draw the gpx-tracks given as arguments.
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
     6
Copyright 2017 willem179
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
     7
Extracted from the code of "gpx_reduce.py"
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
     8
Copyright (C) 2011,2012,2013,2015,2016,2017 travelling_salesman on OpenStreetMap
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
     9
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    10
This program is free software: you can redistribute it and/or modify
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    11
it under the terms of the GNU General Public License as published by
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    12
the Free Software Foundation, either version 3 of the License, or
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    13
(at your option) any later version.
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    14
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    15
This program is distributed in the hope that it will be useful,
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    16
but WITHOUT ANY WARRANTY; without even the implied warranty of
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    18
GNU General Public License for more details.
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    19
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    20
You should have received a copy of the GNU General Public License
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    21
along with this program.  If not, see <http://www.gnu.org/licenses/>.
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    22
'''
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    23
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    24
import datetime
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    25
import sys
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    26
import time
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    27
from math import *
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    28
import xml.etree.ElementTree as etree
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    29
from optparse import OptionParser
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    30
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    31
# the path to the gnuplot binary
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    32
gnuPlotCmd = 'gnuplot'
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    33
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    34
parser = OptionParser('usage: %prog [options] input-file.gpx')
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    35
(options, args) = parser.parse_args()
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    36
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    37
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    38
if len(args) < 1:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    39
    parser.print_usage()
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    40
    exit(2)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    41
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    42
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    43
# use the WGS-84 ellipsoid
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    44
rE = 6356752.314245 # earth's radius
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    45
a = 6378137.0
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    46
b = 6356752.314245179
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    47
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    48
timeformat = '%Y-%m-%dT%H:%M:%SZ'
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    49
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    50
# the linear algebra with lists
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    51
norm = lambda p: sqrt (sum (a * a for a in p))
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    52
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    53
def rotate(x, y, phi):
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    54
    return x*cos(phi) - y*sin(phi), x*sin(phi) + y*cos(phi)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    55
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    56
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    57
def project_to_meters(lat, lon, latm, lonm):
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    58
    # azimuthal map projection centered at average track coordinate
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    59
    lon -= lonm
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    60
    xyz = latlonele_to_xyz(lat, lon, 0.0)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    61
    zy = rotate(xyz[2], xyz[1], radians(90 - latm))
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    62
    lat2 = atan2(zy[0], norm([zy[1], xyz[0]]))
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    63
    lon2 = atan2(xyz[0], -zy[1])
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    64
    x_meters = rE * sin(lon2) * (pi / 2.0 - lat2)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    65
    y_meters = -rE * cos(lon2) * (pi / 2.0 - lat2)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    66
    return x_meters, y_meters
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    67
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    68
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    69
def latlonele_to_xyz(lat, lon, ele):
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    70
    s = sin(radians(lat))
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    71
    c = cos(radians(lat))
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    72
    r = ele + a * b / norm([s*a, c*b])
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    73
    lon = radians(lon)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    74
    return r * c * sin(lon), r * c * (-cos(lon)), r * s
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    75
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    76
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    77
def xyz_to_latlonele(x, y, z):
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    78
    r = norm([x, y, z])
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    79
    if (r == 0):
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    80
        return 0.0, 0.0, 0.0
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    81
    lat = degrees(atan2(z, norm([x, y])))
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    82
    lon = degrees(atan2(x, -y))
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
    83
    ele = r * (1.0 - a * b / norm([a*z, b*x, b*y]))
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    84
    return lat, lon, ele
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    85
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    86
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    87
############################## main function #################################
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    88
tracks = []
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    89
npoints = []
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    90
for fname in args:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    91
    # initialisations
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    92
    tracksegs = []
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    93
    sumx, sumy, sumz = 0.0, 0.0, 0.0
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    94
    ntot = 0    # total number of trackpoints (sum of segments)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    95
    
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    96
    # import xml data from files
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    97
    print 'opening file', fname
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    98
    infile = open(fname)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
    99
    tree = etree.parse(infile)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   100
    infile.close()
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   101
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   102
    gpx = tree.getroot()
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   103
    nsurl = gpx.tag.split ('}')[0][1:]  # == 'http://www.topografix.com/GPX/1/1'
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   104
    etree.register_namespace('', nsurl) # default namespace -> xmlns:.... in the output
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   105
    nsmap = '{' + nsurl + '}'           # prefix for all tags in the tree
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   106
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   107
    # extract data from xml
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   108
    for si, trkseg in enumerate (gpx.findall('.//' + nsmap + 'trkseg')):
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   109
        trkpts = trkseg.findall(nsmap + 'trkpt')
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   110
        n = len(trkpts)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   111
        
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   112
        # extract coordinate values
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   113
        lats = [float(trkpt.get('lat')) for trkpt in trkpts]
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   114
        lons = [float(trkpt.get('lon')) for trkpt in trkpts]
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   115
        eles = [float(trkpt.find(nsmap + 'ele').text) for trkpt in trkpts]
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   116
        try:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   117
            times = [datetime.datetime.strptime(trkpt.find(nsmap + 'time'
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   118
                                       ).text, timeformat) for trkpt in trkpts]
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   119
        except Exception as e:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   120
            print '-- trackpoint without time'
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   121
            times = None
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   122
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   123
        # save original trackseg for plotting
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   124
        tracksegs.append ([ (lats[i], lons[i], eles[i]) for i in range(n) ])
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   125
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   126
        # calculate projected points to work on
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   127
        for i in range(n):
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   128
            x, y, z = latlonele_to_xyz (lats[i], lons[i], eles[i])
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   129
            sumx += x
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   130
            sumy += y
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   131
            sumz += z
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   132
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   133
        print 'segment %d, with %d points:' % (si, n)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   134
        ntot += n
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   135
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   136
    tracks.append (tracksegs)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   137
    npoints.append ((fname.replace ('_','\_'), ntot))   # underscore -> subscripts in gnuplot
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   138
    print 'number of points in track %s = %d:' % (fname, ntot)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   139
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   140
latm, lonm, elesum = xyz_to_latlonele (sumx, sumy, sumz)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   141
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   142
data = []
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   143
xmin, xmax = ymin, ymax = float ('inf'), float ('-inf')
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   144
for tracksegs in tracks:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   145
    for trkseg in tracksegs:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   146
        for lat, lon, ele in trkseg:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   147
            x, y = project_to_meters (lat, lon, latm, lonm)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   148
            data.append ('%f %f' % (x, y))
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   149
            xmin, ymin = min (xmin, x), min (ymin, y)   # determine the x range
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   150
            xmax, ymax = max (xmax, x), max (ymax, y)   # and the y range
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   151
    data.append ('e')
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   152
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   153
dx, dy = xmax - xmin, ymax - ymin   # make x and y ranges equal to the largest
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   154
if dx > dy:                         # and keep ranges centered
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   155
    dr = (dx - dy) / 2
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   156
    ymax += dr
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   157
    ymin -= dr
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   158
else:
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   159
    dr = (dy - dx) / 2
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   160
    xmax += dr
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   161
    xmin -= dr
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   162
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   163
from subprocess import Popen, PIPE
10
89108adbc468 gpx_plot: numpy verijderd uit gpx_plot
wim
parents: 4
diff changeset
   164
plot = Popen ([gnuPlotCmd], stdin=PIPE, stdout=PIPE, stderr=PIPE)
4
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   165
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   166
range = 'set xrange [%f:%f]\nset yrange [%f:%f]\n' % (xmin, xmax, ymin, ymax)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   167
plot.stdin.write (range)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   168
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   169
curves = ','.join ("'-' with linespoints ti '%s: %d punten'" % t for t in npoints)
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   170
plot.stdin.write ('plot ' + curves + '\n')
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   171
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   172
plot.stdin.write ("\n".join (data))
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   173
plot.stdin.write ('\n')
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   174
plot.stdin.flush ()
1b96bb9de1f3 - eerste versie van gpx_plot
wim
parents:
diff changeset
   175
raw_input ('druk')