Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/extras/statistics/create-image.pl
Parent Directory
|
Revision Log
Revision 1856 -
(show annotations)
(download)
(as text)
Sun Feb 14 16:32:08 2016 UTC (9 years, 1 month ago) by amb
File MIME type: text/x-perl
File size: 6096 byte(s)
Sun Feb 14 16:32:08 2016 UTC (9 years, 1 month ago) by amb
File MIME type: text/x-perl
File size: 6096 byte(s)
Add scripts that will process the Routino database and generate maps with highway statistics.
1 | #!/usr/bin/perl |
2 | # |
3 | # OSM data statistics Perl script |
4 | # |
5 | # Part of the Routino routing software. |
6 | # |
7 | # This file Copyright 2008-2016 Andrew M. Bishop |
8 | # |
9 | # This program is free software: you can redistribute it and/or modify |
10 | # it under the terms of the GNU Affero General Public License as published by |
11 | # the Free Software Foundation, either version 3 of the License, or |
12 | # (at your option) any later version. |
13 | # |
14 | # This program is distributed in the hope that it will be useful, |
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | # GNU Affero General Public License for more details. |
18 | # |
19 | # You should have received a copy of the GNU Affero General Public License |
20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 | # |
22 | |
23 | use Graphics::Magick; |
24 | |
25 | # Range of tiles and zoom - PARAMETERS THAT CAN BE EDITED |
26 | |
27 | @xrange=(120..129); # At zoom level 8 |
28 | @yrange=(73..87); # At zoom level 8 |
29 | |
30 | $zbase=6; # Zoom level of images in basemap. |
31 | |
32 | $z=13; # Granularity of data points. |
33 | |
34 | # Base image dimensions |
35 | |
36 | $basescale=2**(8-$zbase); |
37 | |
38 | $width =(1+$#xrange)*256/$basescale; |
39 | $height=(1+$#yrange)*256/$basescale; |
40 | |
41 | # Chosen zoom level |
42 | |
43 | $scale=2**(8-$z); |
44 | $tilesize=256*$scale/$basescale; |
45 | |
46 | # Get the command line arguments |
47 | |
48 | $prefix=$ARGV[0]; |
49 | $name =$ARGV[1]; |
50 | $number=$ARGV[2]+0; |
51 | |
52 | # Graph annotations |
53 | |
54 | $annotation{highway} ="'highway=$name'"; |
55 | $annotation{property} ="$name property"; |
56 | $annotation{speed} ="'maxspeed=$name'"; |
57 | $annotation{transport}="$name allowed"; |
58 | |
59 | # Read in the data |
60 | |
61 | %density=(); |
62 | |
63 | while(<STDIN>) |
64 | { |
65 | ($x,$y,@distances)=split(/ +/); |
66 | |
67 | $distance=$distances[$number]; |
68 | |
69 | if($distance > 0) |
70 | { |
71 | $area=&xy_area($z,$x,$y); |
72 | |
73 | $density{$x,$y}=($distance/$area); |
74 | } |
75 | } |
76 | |
77 | # Find the maximum value |
78 | |
79 | $max=0; |
80 | |
81 | foreach $xy (keys %density) |
82 | { |
83 | $density=$density{$xy}; |
84 | |
85 | $max=$density if($density>$max); |
86 | } |
87 | |
88 | $max=500.0*int(($max+499)/500); |
89 | $max=500.0 if($max<500); |
90 | |
91 | # Create the overlay image |
92 | |
93 | $colour0=&colour(0); |
94 | |
95 | $image=Graphics::Magick->new(size => "${width}x${height}"); |
96 | $image->ReadImage("xc:$colour0"); |
97 | |
98 | foreach $xy (keys %density) |
99 | { |
100 | ($x,$y)=split($;,$xy); |
101 | |
102 | $colour=&colour($density{$x,$y}/$max); |
103 | |
104 | $x1=(($x*$scale)-$xrange[0])*256/$basescale; |
105 | $y1=(($y*$scale)-$yrange[0])*256/$basescale; |
106 | |
107 | if($tilesize==1) |
108 | { |
109 | $image->Draw(primitive => 'point', points => "$x1,$y1", |
110 | fill => $colour, |
111 | antialias => 'false'); |
112 | } |
113 | else |
114 | { |
115 | $x2=$x1+$tilesize-1; |
116 | $y2=$y1+$tilesize-1; |
117 | |
118 | $image->Draw(primitive => 'rectangle', points => "$x1,$y1 $x2,$y2", |
119 | strokewidth => 0, stroke => $colour, fill => $colour, |
120 | antialias => 'false'); |
121 | } |
122 | } |
123 | |
124 | # Create the scale indicator |
125 | |
126 | $indicator=Graphics::Magick->new(size => "${width}x40"); |
127 | $indicator->ReadImage('xc:white'); |
128 | |
129 | foreach $v (0..($width-2*5)) |
130 | { |
131 | $x=$v+5; |
132 | $y1=12; $y2=23; |
133 | $density=$v/($width-2*5); |
134 | |
135 | $indicator->Draw(primitive => 'line', points => "$x,$y1,$x,$y2", |
136 | stroke => &colour($density), |
137 | antialias => 'false'); |
138 | } |
139 | |
140 | $indicator->Annotate(text => "0", font => 'Helvetica', pointsize => '12', style => Normal, |
141 | fill => 'black', |
142 | x => 5, y => 11, align => Left); |
143 | |
144 | foreach $frac (0.25,0.5,0.75) |
145 | { |
146 | $indicator->Annotate(text => $max*$frac, font => 'Helvetica', pointsize => '12', style => Normal, |
147 | fill => 'black', |
148 | x => 5+($width-2*5)*$frac, y => 11, align => Center); |
149 | } |
150 | |
151 | $indicator->Annotate(text => $max, font => 'Helvetica', pointsize => '12', style => Normal, |
152 | fill => 'black', |
153 | x => $width-5, y => 11, align => Right); |
154 | |
155 | $indicator->Annotate(text => "Highway density (metres/square km) for $annotation{$prefix} per zoom $z tile", font => 'Helvetica', pointsize => '14', style => Normal, |
156 | fill => 'black', |
157 | x => $width/2, y => 36, align => Center); |
158 | |
159 | # Create the combined images |
160 | |
161 | $base=Graphics::Magick->new; |
162 | $base->ReadImage("basemap.png"); |
163 | |
164 | $base->Composite(image => $image, compose => Dissolve, x => 0, y => 0, opacity => 50); |
165 | |
166 | $final=Graphics::Magick->new(size => ($base->Get('width')+2)."x".($base->Get('height')+$indicator->Get('height')+3)); |
167 | $final->ReadImage('xc:black'); |
168 | |
169 | $final->Composite(image => $base , compose => Over, x => 1, y => 1 ); |
170 | $final->Composite(image => $indicator, compose => Over, x => 1, y => $base->Get('height')+2); |
171 | |
172 | undef $base; |
173 | undef $image; |
174 | undef $indicator; |
175 | |
176 | # Write out the images |
177 | |
178 | print "Writing '$prefix-$name.png'\n"; |
179 | |
180 | $final->Write("$prefix-$name.png"); |
181 | |
182 | $final->Resize(width => $width/4, height => $final->Get('height')/4); |
183 | $final->Write("$prefix-$name-small.png"); |
184 | |
185 | undef $final; |
186 | |
187 | # |
188 | # Subroutines |
189 | # |
190 | |
191 | sub xy_ll_rad |
192 | { |
193 | my($zoom,$x,$y)=@_; |
194 | |
195 | $PI=3.14159265358979323846; |
196 | |
197 | my($longitude)=$PI*(($x * (2**(1-$zoom)))-1); |
198 | my($latitude)=($PI/2)*((4/$PI)*atan2(exp($PI*(1-($y * (2**(1-$zoom))))),1) - 1); |
199 | |
200 | return ($longitude,$latitude); |
201 | } |
202 | |
203 | |
204 | sub xy_area |
205 | { |
206 | my($zoom,$x,$y)=@_; |
207 | |
208 | $RADIUS=6378.137; |
209 | |
210 | my($width,$height); |
211 | |
212 | if(defined $width{$y}) |
213 | { |
214 | $width=$width{$y}; |
215 | } |
216 | else |
217 | { |
218 | my($lon1,$lat1)=&xy_ll_rad($z,$x ,$y); |
219 | my($lon2,$lat2)=&xy_ll_rad($z,$x+1,$y); |
220 | |
221 | $width=$RADIUS*($lon2-$lon1)*cos($lat1); |
222 | |
223 | $width{$y}=$width; |
224 | } |
225 | |
226 | if(defined $height{$y}) |
227 | { |
228 | $height=$height{$y}; |
229 | } |
230 | else |
231 | { |
232 | my($lon1,$lat1)=&xy_ll_rad($z,$x,$y ); |
233 | my($lon2,$lat2)=&xy_ll_rad($z,$x,$y+1); |
234 | |
235 | $height=$RADIUS*($lat1-$lat2); |
236 | |
237 | $height{$y}=$height; |
238 | } |
239 | |
240 | return $width*$height; |
241 | } |
242 | |
243 | sub colour |
244 | { |
245 | my($density)=@_; |
246 | |
247 | $density=sqrt($density); |
248 | |
249 | $density=0 if($density<0); |
250 | $density=1 if($density>1); |
251 | |
252 | my($r,$g,$b); |
253 | |
254 | if($density<0.5) |
255 | { |
256 | $r=0; |
257 | $g=int(255*(2*$density)); |
258 | $b=int(255*(1-2*$density)); |
259 | } |
260 | else |
261 | { |
262 | $density-=0.5; |
263 | |
264 | $r=int(255*(2*$density)); |
265 | $g=int(255*(1-2*$density)); |
266 | $b=0; |
267 | } |
268 | |
269 | sprintf("#%02x%02x%02x",$r,$g,$b); |
270 | } |
Properties
Name | Value |
---|---|
svn:executable | * |