1 | # OJW 2007 GPLv3/later |
---|
2 | import cairo |
---|
3 | import math |
---|
4 | import sys |
---|
5 | from xml.sax import saxutils |
---|
6 | from UserDict import UserDict |
---|
7 | from xml.sax import make_parser |
---|
8 | import os |
---|
9 | from os.path import join, getsize |
---|
10 | deg2rad = 0.0174532925 |
---|
11 | M_PI = 3.1415926535 |
---|
12 | |
---|
13 | class MapObject: |
---|
14 | def __init__(self,width,height,surface, Outline): |
---|
15 | self.width = width |
---|
16 | self.height = height |
---|
17 | self.surface = surface |
---|
18 | self.outline = Outline |
---|
19 | self.ctx = cairo.Context(surface) |
---|
20 | self.ctx.set_font_size(30) |
---|
21 | self.ctx.set_source_rgb(0,0,0) |
---|
22 | |
---|
23 | def drawBorder(self): |
---|
24 | border=5 |
---|
25 | self.ctx.rectangle(border,border,self.width-2*border, self.height-2*border) |
---|
26 | self.ctx.stroke() |
---|
27 | |
---|
28 | def point(self,x,y): |
---|
29 | self.ctx.arc(x, y, 5.0, 0, 2*M_PI); |
---|
30 | self.ctx.fill(); |
---|
31 | def pointLL(self,lat,lon): |
---|
32 | x = self.outline.xpos(lon) * self.width |
---|
33 | y = self.outline.ypos(lat) * self.height |
---|
34 | #print "%f,%f -> %f,%f" % (lat,lon,x,y) |
---|
35 | self.ctx.arc(x, y, 1.0, 0, 2*M_PI); |
---|
36 | self.ctx.fill(); |
---|
37 | |
---|
38 | def finish(self): |
---|
39 | self.ctx.stroke() |
---|
40 | |
---|
41 | class TracklogInfo(MapObject, saxutils.DefaultHandler): |
---|
42 | def __init__(self, directory): |
---|
43 | self.W = 180; |
---|
44 | self.E = -180; |
---|
45 | self.N = -90; |
---|
46 | self.S = 90; |
---|
47 | self.count = 0 |
---|
48 | for root, dirs, files in os.walk(directory): |
---|
49 | for file in files: |
---|
50 | if(file.endswith(".gpx")): |
---|
51 | filename = join(root, file) |
---|
52 | parser = make_parser() |
---|
53 | parser.setContentHandler(self) |
---|
54 | parser.parse(filename) |
---|
55 | self.count = self.count + 1 |
---|
56 | print "Lat %f to %f, Long %f to %f" % (self.S,self.N,self.W,self.E) |
---|
57 | self.dLat = self.N - self.S |
---|
58 | self.dLon = self.E - self.W |
---|
59 | self.ratio = self.dLon / self.dLat |
---|
60 | |
---|
61 | def startElement(self, name, attrs): |
---|
62 | if(name == 'trkpt'): |
---|
63 | lat = float(attrs.get('lat', None)) |
---|
64 | lon = float(attrs.get('lon', None)) |
---|
65 | self.S = min(lat, self.S) |
---|
66 | self.N = max(lat, self.N) |
---|
67 | self.W = min(lon, self.W) |
---|
68 | self.E = max(lon, self.E) |
---|
69 | def valid(self): |
---|
70 | if(self.W >= self.E): |
---|
71 | return(0) |
---|
72 | if(self.S >= self.N): |
---|
73 | return(0) |
---|
74 | return(1) |
---|
75 | |
---|
76 | def xpos(self,lon): |
---|
77 | return((lon - self.W) / self.dLon) |
---|
78 | def ypos(self,lat): |
---|
79 | return((lat - self.S) / self.dLat) |
---|
80 | |
---|
81 | |
---|
82 | class Tracklog(MapObject, saxutils.DefaultHandler): |
---|
83 | def draw(self, file): |
---|
84 | parser = make_parser() |
---|
85 | parser.setContentHandler(self) |
---|
86 | parser.parse(file) |
---|
87 | |
---|
88 | def startElement(self, name, attrs): |
---|
89 | if(name == 'trkpt'): |
---|
90 | lat = attrs.get('lat', None) |
---|
91 | lon = attrs.get('lon', None) |
---|
92 | self.pointLL(float(lat),float(lon)) |
---|
93 | |
---|
94 | class TracklogDir(Tracklog): |
---|
95 | def drawDir(self, directory): |
---|
96 | count = 0 |
---|
97 | for root, dirs, files in os.walk(directory): |
---|
98 | for file in files: |
---|
99 | if(file.endswith(".gpx")): |
---|
100 | filename = join(root, file) |
---|
101 | print " %d/%d:%s" % (count, self.outline.count, filename) |
---|
102 | self.draw(filename) |
---|
103 | count = count + 1 |
---|
104 | |
---|
105 | # Find out the extents of the data |
---|
106 | directory = "eg/" |
---|
107 | print "Calculating extents" |
---|
108 | Outline = TracklogInfo(directory) |
---|
109 | if(not Outline.valid): |
---|
110 | print "Couldn't calculate extents" |
---|
111 | sys.exit() |
---|
112 | |
---|
113 | width = 10000 |
---|
114 | height = int(width / Outline.ratio) |
---|
115 | print "Creating image %d x %d" % (width,height) |
---|
116 | |
---|
117 | surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) |
---|
118 | Tracklog = TracklogDir(width, height, surface, Outline) |
---|
119 | Tracklog.drawDir(directory) |
---|
120 | Tracklog.drawBorder() |
---|
121 | |
---|
122 | surface.write_to_png("output.png") |
---|
123 | |
---|