source: subversion/sites/tile.openstreetmap.org/cgi-bin/export @ 15741

Revision 15741, 4.1 KB checked in by tomhughes, 5 years ago (diff)

Make sure the bounding box makes sense.

  • Property svn:executable set to *
Line 
1#!/usr/bin/python
2
3import cairo
4import cgi
5import mapnik
6import os
7import shutil
8import sys
9import tempfile
10import resource
11
12# Limit maximum CPU time
13# The Postscript output format can sometimes take hours
14resource.setrlimit(resource.RLIMIT_CPU,(300,300))
15
16# Limit memory usage
17# Some odd requests can cause extreme memory usage
18resource.setrlimit(resource.RLIMIT_AS,(4000000000, 4000000000))
19
20# Routine to output HTTP headers
21def output_headers(content_type, filename = "", length = 0):
22  print "Content-Type: %s" % content_type
23  if filename:
24    print "Content-Disposition: attachment; filename=\"%s\"" % filename
25  if length:
26    print "Content-Length: %d" % length
27  print ""
28
29# Routine to output the contents of a file
30def output_file(file):
31  file.seek(0)
32  shutil.copyfileobj(file, sys.stdout)
33
34# Routine to get the size of a file
35def file_size(file):
36  return os.fstat(file.fileno()).st_size
37
38# Routine to report an error
39def output_error(message):
40  output_headers("text/html")
41  print "<html>"
42  print "<head>"
43  print "<title>Error</title>"
44  print "</head>"
45  print "<body>"
46  print "<h1>Error</h1>"
47  print "<p>%s</p>" % message
48  print "</body>"
49  print "</html>"
50
51# Parse CGI parameters
52form = cgi.FieldStorage()
53
54# Validate the parameters
55if not form.has_key("bbox"):
56  # No bounding box specified
57  output_error("No bounding box specified")
58elif not form.has_key("scale"):
59  # No scale specified
60  output_error("No scale specified")
61elif not form.has_key("format"):
62  # No format specified
63  output_error("No format specified")
64else:
65  # Create projection object
66  prj = mapnik.Projection("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over");
67
68  # Get the bounds of the area to render
69  bbox = [float(x) for x in form.getvalue("bbox").split(",")]
70
71  if bbox[0] >= bbox[2] or bbox[1] >= bbox[3]:
72    # Bogus bounding box
73    output_error("Invalid bounding box")
74  else:
75    # Project the bounds to the map projection
76    bbox = mapnik.forward_(mapnik.Envelope(*bbox), prj)
77
78    # Calculate the size of the final rendered image
79    scale = float(form.getvalue("scale"))
80    width = int(bbox.width() / scale / 0.00028)
81    height = int(bbox.height() / scale / 0.00028)
82
83    # Limit the size of map we are prepared to produce
84    if width * height > 4000000:
85      # Map is too large (limit is approximately A2 size)
86      output_error("Map too large")
87    else:
88      # Create map
89      map = mapnik.Map(width, height)
90
91      # Load map configuration
92      mapnik.load_map(map, "/home/jburgess/live/osm.xml")
93
94      # Zoom the map to the bounding box
95      map.zoom_to_box(bbox)
96
97      # Render the map
98      if form.getvalue("format") == "png":
99        image = mapnik.Image(map.width, map.height)
100        mapnik.render(map, image)
101        png = image.tostring("png") 
102        output_headers("image/png", "map.png", len(png))
103        print png
104      elif form.getvalue("format") == "jpeg":
105        image = mapnik.Image(map.width, map.height)
106        mapnik.render(map, image)
107        jpeg = image.tostring("jpeg") 
108        output_headers("image/jpeg", "map.jpg", len(jpeg))
109        print jpeg
110      elif form.getvalue("format") == "svg":
111        file = tempfile.NamedTemporaryFile()
112        surface = cairo.SVGSurface(file.name, map.width, map.height)
113        mapnik.render(map, surface)
114        surface.finish()
115        output_headers("image/svg+xml", "map.svg", file_size(file))
116        output_file(file)
117      elif form.getvalue("format") == "pdf":
118        file = tempfile.NamedTemporaryFile()
119        surface = cairo.PDFSurface(file.name, map.width, map.height)
120        mapnik.render(map, surface)
121        surface.finish()
122        output_headers("application/pdf", "map.pdf", file_size(file))
123        output_file(file)
124      elif form.getvalue("format") == "ps":
125        file = tempfile.NamedTemporaryFile()
126        surface = cairo.PSSurface(file.name, map.width, map.height)
127        mapnik.render(map, surface)
128        surface.finish()
129        output_headers("application/postscript", "map.ps", file_size(file))
130        output_file(file)
131      else:
132        output_error("Unknown format '%s'" % form.getvalue("format"))
Note: See TracBrowser for help on using the repository browser.