source: subversion/utils/osmAtHome/osmAtHome.pl @ 2021

Last change on this file since 2021 was 1559, checked in by nickburch, 14 years ago

Add a stub -h option

  • Property svn:executable set to *
File size: 8.5 KB
Line 
1#!/usr/bin/perl
2use LWP::Simple;
3#-----------------------------------------------------------------------------
4# OpenStreetMap @ Home
5#
6# This program will:
7# - get a request from the almien website for a map that needs rendering
8# - render it, using tools such as xmlstarlet and inkscape on your computer
9# - upload the result to the almien website, for public display
10#
11# This program will use considerable amounts of system resource (cpu, memory, disk)
12# It is designed for use by a few trusted users, who will create maps and not
13# upload malicious data.  Hence, the script includes a password which is required
14# to upload the resultant map back to the almien website.
15#
16# You can run this program without a password, and it will render maps from
17# OSM data and save them on your disk.
18#
19# Contact OJW on the Openstreetmap wiki for help using this program
20#-----------------------------------------------------------------------------
21# Copyright 2006, Oliver White
22#
23# This program is free software; you can redistribute it and/or
24# modify it under the terms of the GNU General Public License
25# as published by the Free Software Foundation; either version 2
26# of the License, or (at your option) any later version.
27#
28# This program is distributed in the hope that it will be useful,
29# but WITHOUT ANY WARRANTY; without even the implied warranty of
30# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31# GNU General Public License for more details.
32#
33# You should have received a copy of the GNU General Public License
34# along with this program; if not, write to the Free Software
35# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
36#-----------------------------------------------------------------------------
37
38my $Password = "user|password";  # Ask OJW for a password to use this script
39
40my $args = shift;
41if($args eq "-h") {
42        print "OpenStreetMap @ Home Client\n\n";
43        print "You will need a username and password for the almien site to participate.\n";
44        print "See http://wiki.openstreetmap.org/index.php/OSM%40home for details\n";
45        exit 1;
46}
47
48# Process
49ProcessRequestFromWeb($Password);
50exit;
51
52#-----------------------------------------------------------------------------
53# Gets latest copy of osmarender from repository
54#-----------------------------------------------------------------------------
55sub UpdateOsmarender(){
56  foreach $File(("osm-map-features.xml", "osmarender.xsl", "Osm_linkage.png", "somerights20.png")){
57 
58    DownloadFile(
59    "http://almien.co.uk/OSM/Places/Download/$File",
60    $File,
61    1,
62    "Osmarender ($File)");
63  }
64}
65
66#-----------------------------------------------------------------------------
67# Gets a request from almien for a map that needs rendering, and does it
68#-----------------------------------------------------------------------------
69sub ProcessRequestFromWeb(){
70  my ($Password) = @_;
71  DownloadFile(
72    "http://almien.co.uk/OSM/Places/?action=random", 
73    "random.txt",
74    0,
75    "Rendering requests");
76 
77  ProcessRequest("random.txt", $Password);
78}
79
80#-----------------------------------------------------------------------------
81# Processes a textfile containing request for a map-rendering
82#-----------------------------------------------------------------------------
83sub ProcessRequest(){
84  my ($File, $Password) = @_;
85 
86  # File comprises pipe-separated fields
87  open(IN, "<", $File);
88  my ($Version, $ID, $Width, $URL) = split(/\|/, <IN>);
89  close IN;
90 
91  if($Version != 2){
92    print STDERR "A new version of this script is available\n";
93    print STDERR "Not processing requests, as the interface may have changed\n";
94    print STDERR "Please download latest script and run that instead of this one\n";
95    exit;
96  }
97  if($ID == -1){
98    print STDERR "Nothing to do!\nSleeping for 1 hour: press Ctrl-C to quit\n";
99    sleep(3600);
100    exit 1;
101  }
102 
103  UpdateOsmarender();
104 
105  print STDERR "Using interface version $Version\n";
106  print STDERR "Downloading $ID from $URL\n";
107 
108  foreach $OldFile("output.png", "output.svg", "data.osm"){
109    unlink $OldFile if(-f $OldFile);
110  }
111 
112  # Get the OSM data
113  DownloadFile($URL, "data.osm.gz", 0, "OSM data for location (ID $ID)");
114  # Decompress data
115  `gunzip data.osm.gz`;
116 
117  # Transform it to SVG
118  xml2svg("output.svg");
119 
120  # Render it to PNG
121  svg2png("output.svg", "output.png", $Width);
122
123  # Upload it
124  upload("output.png", $ID, $Password);
125 
126  # Say where to find the result
127  print "Done. View the result at\nhttp://almien.co.uk/OSM/Places/?id=$ID\n";
128}
129
130#-----------------------------------------------------------------------------
131#
132#-----------------------------------------------------------------------------
133sub DownloadFile(){
134  my ($URL, $File, $UseExisting, $Title) = @_;
135 
136  print STDERR "Downloading: $Title...";
137 
138  if($UseExisting){
139    mirror($URL, $File);
140    }
141  else{
142    getstore($URL, $File);
143    }
144 
145  printf STDERR " done, %d bytes\n", -s $File;
146 
147}
148
149#-----------------------------------------------------------------------------
150# Transform an OSM file (using osmarender) into SVG
151#-----------------------------------------------------------------------------
152sub xml2svg(){
153  my($SVG) = @_;
154  my $Cmd = sprintf("%sxmlstarlet tr %s %s > %s",
155    "nice ", # Blank this out for use on windows
156    "osmarender.xsl",
157    "osm-map-features.xml",
158    $SVG);
159  print STDERR "Transforming...";
160  `$Cmd`;
161  print STDERR " done\n";
162}
163
164#-----------------------------------------------------------------------------
165# Render a SVG file
166#-----------------------------------------------------------------------------
167sub svg2png(){
168  my($SVG, $PNG, $Size) = @_;   
169  my $Cmd = sprintf("%sinkscape -w %d -D -b FFFFFF -e %s %s", 
170    "nice ", # Blank this out for use on windows
171    $Size,
172    $PNG, 
173    $SVG);
174  print STDERR "Rendering...";
175  `$Cmd`;
176  print STDERR " done\n";
177}
178
179
180#-----------------------------------------------------------------------------
181# Upload a rendered map to almien
182#-----------------------------------------------------------------------------
183sub upload(){
184  my ($File, $ID, $Password) = @_;
185  $URL = "http://almien.co.uk/OSM/Places/upload.php";
186 
187  my $ua = LWP::UserAgent->new(env_proxy => 0,
188    keep_alive => 1,
189    timeout => 60);
190  $ua->protocols_allowed( ['http'] );
191  $ua->agent("OsmAtHome");
192
193  my $res = $ua->post($URL,
194    Content_Type => 'form-data',
195    Content => [ file => [$File], id => $ID, mp => $Password ]);
196   
197  if(!$res->is_success()){
198    die("Post error: " . $res->error);
199  } 
200}
201
202#-----------------------------------------------------------------------------
203# Modifying this script:
204#
205# You probably won't have the exact same setup as me, so this script might need
206# some changes to work properly.  Since I only expect a handful of people to run
207# this script, I think they can probably modify it themselves to suit their
208# computer's configuration.  Here's some of the things to look at:
209#
210# Location of inkscape - I've just called it "inkscape", but you can change that to
211# the path of your inkscape program if it's elsewhere
212#
213# Location of xmlstarlet - on Windows, it's c:\xml\xml.exe by default, so change that
214#
215# "Nice" statements - the script uses the nice keyword to give the rendering
216# low scheduling priority, so it doesn't lock-up your computer and stop your desktop
217# working.  Remove this on Windows, as it won't work
218#
219# Other SVG->PNG renderers - careful, as many renderers don't render the same area of
220# the SVG.  It would probably be a good idea if we all used inkscape, as that makes the
221# generated images much more predictable in terms of where the edges are exactly.
222#
223# Other XSLT programs - this is easier, as you can pick any one.  I've used xmlstarlet,
224# but other people prefer xsltproc, xalan, etc.  If you use a different program,
225# you'll need to update the command-line options this script supplies, so that
226# it does the right thing.
227#
228#-----------------------------------------------------------------------------
229# Testing:
230#
231# To test changes to this script without affecting other users, simply comment-out
232# the upload() function call, so that renders things and leaves them on your
233# computer, rather than trying to upload the result.
234#
235# To test the effect of changes to the osmarender files, comment-out the
236# UpdateOsmarender() function call, so that it keeps your modified version of
237# osmarender, instead of downloading a new copy each time.
238#
239# To render a particular town, look-up the town's ID at almien.co.uk/OSM/Places,
240# then hardcode that ID in the script rather than downloading IDs from the web
241#-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.