コード例 #1
0
ファイル: __init__.py プロジェクト: straup/piratemap-tools
	def mm(self, points):

		bbox = self.calculate_bbox_for_points(points)

		if self.method == 'bbox':
			bbox = self.adjust_bbox(bbox, .5)

		self.bbox = bbox

		dims = ModestMaps.Core.Point(self.width, self.height)
		sw = ModestMaps.Geo.Location(bbox[0], bbox[1])
		ne = ModestMaps.Geo.Location(bbox[2], bbox[3])

		provider = ModestMaps.builtinProviders[ 'MICROSOFT_AERIAL' ]()

		if self.method == 'bbox':
			mm_obj = ModestMaps.mapByExtentZoom(provider, sw, ne, self.zoom)
		else:
			mm_obj = ModestMaps.mapByExtent(provider, sw, ne, dims)

		self.mm_provider = provider
		self.mm_obj = mm_obj
		self.mm_markers = modestMMarkers.modestMMarkers(self.mm_obj)

		return True
コード例 #2
0
    def project(self):
        ''' Set map extent from lnglat bounds and zoom '''
        bnds = self.map.lngLatBounds

        sw = MM.Geo.Location(bnds.b, bnds.l)
        ne = MM.Geo.Location(bnds.t, bnds.r)
        z = self.opts['zoom']

        #provider = MM.Microsoft.RoadProvider()
        provider = MM.OpenStreetMap.Provider()

        mm = MM.mapByExtentZoom(provider, sw, ne, z)
        self.mm = mm

        epsg3857 = pyproj.Proj(init='epsg:3857')
        epsg4326 = pyproj.Proj(init='epsg:4326')

        # Resize map to dimensions of tiles
        psw = pyproj.transform(epsg4326, epsg3857, bnds.l, bnds.b)
        pne = pyproj.transform(epsg4326, epsg3857, bnds.r, bnds.t)
        self.map.projBounds.set(psw[0], psw[1], pne[0], pne[1])

        self.map.canvasW = self.viewW = mm.dimensions.x
        self.map.canvasH = self.viewH = mm.dimensions.y
        self.map.projToViewScale = self.map.viewW / self.map.projBounds.width
        self.map.setViewBounds()
コード例 #3
0
    def coords_to_bbox_mmap(self, z, x, y):
        # set up bounding box from coord
        coord = ModestMaps.Core.Coordinate(y, x, z)
        tl = self.projection.coordinateLocation(coord)
        br = self.projection.coordinateLocation(coord.right().down())
        bbox = Polygon.from_bbox((tl.lon, tl.lat, br.lon, br.lat))
        bbox.srid = self.srid

        modest_map = ModestMaps.mapByExtentZoom(self.provider, tl, br, z)
        return bbox, modest_map
コード例 #4
0
ファイル: views.py プロジェクト: poncin/django-geojson-tiles
    def coords_to_bbox_mmap(self, z, x, y):
        # set up bounding box from coord
        coord = ModestMaps.Core.Coordinate(y, x, z)
        tl = self.projection.coordinateLocation(coord)
        br = self.projection.coordinateLocation(coord.right().down())
        bbox = Polygon.from_bbox((tl.lon, tl.lat, br.lon, br.lat))
        bbox.srid = self.srid

        modest_map = ModestMaps.mapByExtentZoom(self.provider, tl, br, z)
        return bbox, modest_map
コード例 #5
0
ファイル: provider.py プロジェクト: gshayer/pycon2012
    def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom):
        # first, figure out the bounding box of the tile we're rendering
        nw = self.layer.projection.projLocation(
            ModestMaps.Core.Point(xmin, ymin))
        se = self.layer.projection.projLocation(
            ModestMaps.Core.Point(xmax, ymax))
        max_lat = max(nw.lat, se.lat)
        min_lat = min(nw.lat, se.lat)
        max_lon = max(nw.lon, se.lon)
        min_lon = min(nw.lon, se.lon)

        bbox = Polygon.from_bbox((min_lon, min_lat, max_lon, max_lat))

        # this obj is used to translate between lat/lon and pixel space
        bound1 = ModestMaps.Geo.Location(min_lat, min_lon)
        bound2 = ModestMaps.Geo.Location(max_lat, max_lon)
        mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom)

        # start drawing each block
        pil_map = Image.new("RGBA", (width, height), (255, 255, 255, 0))
        pil_draw = ImageDraw.Draw(pil_map)

        for block in Block.objects.filter(poly__intersects=bbox):

            # shape
            locs = []
            for c in block.poly.coords[0]:
                pt = ModestMaps.Geo.Location(c[1], c[0])
                loc = mmap.locationPoint(pt)
                locs.append((loc.x, loc.y))

            # color
            count = Crime.objects.filter(pt__within=block.poly).count()

            if count <= HEATMAP_MIN:
                h, s, l = GREEN
            elif count >= HEATMAP_MAX:
                h, s, l = RED
            else:
                scale = float(count - HEATMAP_MIN) / float(HEATMAP_MAX -
                                                           HEATMAP_MIN)

                # scale all channels linearly between START_COLOR and END_COLOR
                h, s, l = [
                    int(scale * (end - start) + start)
                    for start, end in zip(GREEN, RED)
                ]

            block_color = "hsl(%s, %s%%, %s%%)" % (h, s, l)
            pil_draw.polygon(locs, fill=block_color)

        return pil_map
コード例 #6
0
ファイル: __init__.py プロジェクト: MappingKat/modestmaps-py
    def draw_map_bbox (self) :

        if self.ctx.has_key('adjust') :
            self.ctx['bbox'] = self.__adjust_bbox(self.ctx['bbox'], self.ctx['adjust'])
        
        #

        provider = self.load_provider(self.ctx['provider'])

        sw = ModestMaps.Geo.Location(self.ctx['bbox'][0], self.ctx['bbox'][1])
        ne = ModestMaps.Geo.Location(self.ctx['bbox'][2], self.ctx['bbox'][3])
        zoom = self.ctx['zoom']

        self.ctx['map'] = ModestMaps.mapByExtentZoom(provider, sw, ne, zoom)
        return self.ctx['map'].draw()
コード例 #7
0
    def draw_map_bbox(self):

        if self.ctx.has_key('adjust'):
            self.ctx['bbox'] = self.__adjust_bbox(self.ctx['bbox'],
                                                  self.ctx['adjust'])

        #

        provider = self.load_provider(self.ctx['provider'])

        sw = ModestMaps.Geo.Location(self.ctx['bbox'][0], self.ctx['bbox'][1])
        ne = ModestMaps.Geo.Location(self.ctx['bbox'][2], self.ctx['bbox'][3])
        zoom = self.ctx['zoom']

        self.ctx['map'] = ModestMaps.mapByExtentZoom(provider, sw, ne, zoom)
        return self.ctx['map'].draw()
コード例 #8
0
ファイル: provider.py プロジェクト: briandailey/bcn12geo
    def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom):
        # first, figure out the bounding box of the tile we're rendering
        nw = self.layer.projection.projLocation(ModestMaps.Core.Point(xmin, ymin))
        se = self.layer.projection.projLocation(ModestMaps.Core.Point(xmax, ymax))
        max_lat = max(nw.lat, se.lat)
        min_lat = min(nw.lat, se.lat)
        max_lon = max(nw.lon, se.lon)
        min_lon = min(nw.lon, se.lon)

        bbox = Polygon.from_bbox((min_lon, min_lat, max_lon, max_lat))

        # this obj is used to translate between lat/lon and pixel space
        bound1 = ModestMaps.Geo.Location(min_lat, min_lon)
        bound2 = ModestMaps.Geo.Location(max_lat, max_lon)
        mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom)

        # start drawing each block
        pil_map = Image.new("RGBA", (width, height), (255,255,255, 0))
        pil_draw = ImageDraw.Draw(pil_map)

        for block in Block.objects.filter(geom__intersects=bbox):

            # shape
            locs = []
            for c in block.geom.coords[0]:
                pt = ModestMaps.Geo.Location(c[1], c[0])
                loc = mmap.locationPoint(pt)
                locs.append((loc.x, loc.y))

            # color
            count = Crime.objects.filter(pt__within=block.geom).count()

            if count <= HEATMAP_MIN:
                h, s, l = GREEN
            elif count >= HEATMAP_MAX:
                h, s, l = RED
            else:
                scale = float(count - HEATMAP_MIN) / float(HEATMAP_MAX - HEATMAP_MIN)

                # scale all channels linearly between START_COLOR and END_COLOR
                h, s, l = [int(scale*(end-start) + start) for start, end in zip(GREEN, RED)]

            block_color = "hsl(%s, %s%%, %s%%)" % (h, s, l)
            pil_draw.polygon(locs, fill=block_color)
        
        return pil_map
コード例 #9
0
ファイル: provider.py プロジェクト: danabauer/djangocon2011
    def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom):
        nw = self.layer.projection.projLocation(ModestMaps.Core.Point(xmin, ymin))
        se = self.layer.projection.projLocation(ModestMaps.Core.Point(xmax, ymax))
        max_lat = max(nw.lat, se.lat)
        min_lat = min(nw.lat, se.lat)
        max_lon = max(nw.lon, se.lon)
        min_lon = min(nw.lon, se.lon)

        bound1 = ModestMaps.Geo.Location(min_lat, min_lon)
        bound2 = ModestMaps.Geo.Location(max_lat, max_lon)
        mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom)

        pil_map = Image.new("RGBA", (width, height), (255,255,255, 0))
        pil_draw = ImageDraw.Draw(pil_map)

        bbox = Polygon.from_bbox((min_lon, min_lat, max_lon, max_lat))

        for block in Block.objects.filter(poly__intersects=bbox):

            # shape
            locs = []
            for c in block.poly.coords[0]:
                pt = ModestMaps.Geo.Location(c[1], c[0])
                loc = mmap.locationPoint(pt)
                locs.append((loc.x, loc.y))
            
            # color
            count = Crime.objects.filter(pt__within=block.poly).count()

            if count <= HEATMAP_MIN:
                h, s, l = START_COLOR
            elif count >= HEATMAP_MAX:
                h, s, l = END_COLOR
            else:
                scale = float(count - HEATMAP_MIN) / float(HEATMAP_MAX - HEATMAP_MIN)
                
                # scale all channels linearly between START_COLOR and END_COLOR
                h, s, l = [int(scale*(end-start) + start)
                                    for start, end in zip(START_COLOR, END_COLOR)]

            pil_draw.polygon(locs, fill="hsl(%s, %s%%, %s%%)" % (h, s, l), outline="rgb(255, 255, 255)")
        
        return pil_map
コード例 #10
0
            dimensions = ModestMaps.Core.Point(width, height)
            locationA = ModestMaps.Geo.Location(latA, lonA)
            locationB = ModestMaps.Geo.Location(latB, lonB)

            map = ModestMaps.mapByExtent(provider, locationA, locationB,
                                         dimensions)

        elif options.extent and options.zoom:
            latA, lonA = options.extent[0], options.extent[1]
            latB, lonB = options.extent[2], options.extent[3]

            locationA = ModestMaps.Geo.Location(latA, lonA)
            locationB = ModestMaps.Geo.Location(latB, lonB)
            zoom = options.zoom

            map = ModestMaps.mapByExtentZoom(provider, locationA, locationB,
                                             zoom)

        else:
            raise BadComposure("Error: not really sure what's going on.")

    except BadComposure, e:
        print >> sys.stderr, parser.usage
        print >> sys.stderr, ''
        print >> sys.stderr, '%s --help for possible options.' % __file__
        print >> sys.stderr, ''
        print >> sys.stderr, e
        sys.exit(1)

    if options.verbose:
        print map.coordinate, map.offset, '->', outfile, (map.dimensions.x,
                                                          map.dimensions.y)
コード例 #11
0
            dimensions = ModestMaps.Core.Point(width, height)
            locationA = ModestMaps.Geo.Location(latA, lonA)
            locationB = ModestMaps.Geo.Location(latB, lonB)

            map = ModestMaps.mapByExtent(provider, locationA, locationB, dimensions)
    
        elif options.extent and options.zoom:
            latA, lonA = options.extent[0], options.extent[1]
            latB, lonB = options.extent[2], options.extent[3]

            locationA = ModestMaps.Geo.Location(latA, lonA)
            locationB = ModestMaps.Geo.Location(latB, lonB)
            zoom = options.zoom

            map = ModestMaps.mapByExtentZoom(provider, locationA, locationB, zoom)
    
        else:
            raise BadComposure("Error: not really sure what's going on.")

    except BadComposure, e:
        print >> stderr, parser.usage
        print >> stderr, ''
        print >> stderr, '%s --help for possible options.' % __file__
        print >> stderr, ''
        print >> stderr, e
        exit(1)

    if options.verbose:
        print map.coordinate, map.offset, '->', outfile, (map.dimensions.x, map.dimensions.y)
コード例 #12
0
ファイル: provider.py プロジェクト: antonis123/maps
    def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom):
        # start drawing each block
        pil_map = Image.new("RGBA", (width, height), (255,255,255, 0))
        pil_draw = ImageDraw.Draw(pil_map)
        
        # return empty images
        if zoom < 11:
            return pil_map

        # first, figure out the bounding box of the tile we're rendering
        nw = self.layer.projection.projLocation(ModestMaps.Core.Point(xmin, ymin))
        se = self.layer.projection.projLocation(ModestMaps.Core.Point(xmax, ymax))
        max_lat = max(nw.lat, se.lat)
        min_lat = min(nw.lat, se.lat)
        max_lon = max(nw.lon, se.lon)
        min_lon = min(nw.lon, se.lon)
        
        # Converting polygon to OSGB36 in order to compare with the ones we have in
        # the database
        shp = ShpParser()
        min_p = shp.convert_point_to_OSGB36(min_lat, min_lon)
        max_p = shp.convert_point_to_OSGB36(max_lat, max_lon)
        
        bbox = Polygon.from_bbox((min_p[0], min_p[1], max_p[0], max_p[1]))
        
        # this obj is used to translate between lat/lon and pixel space
        bound1 = ModestMaps.Geo.Location(min_lat, min_lon)
        bound2 = ModestMaps.Geo.Location(max_lat, max_lon)
        mmap = ModestMaps.mapByExtentZoom(self.provider, bound1, bound2, zoom)

        neighbourhoods = False
        polys = None
        max_x = None
        min_x = None
        
        try:
            # If zoom < 15 we draw postcode polygons, otherwise neighbourhoods
            if zoom < 15 or self.type == "None":
                polys = Neighbourhood.objects.filter(poly__intersects=bbox)
                neighbourhoods = True
            else:
                polys = Postcode.objects.filter(poly__intersects=bbox)
                
            print "Painting", polys.count(), "blocks"
            
            # Have to find the city where the polygons belong in
            _city = None
            if self.type != "None":
                for poly in polys:
                    if _city is not None:
                        break
                    if poly.poly and isinstance(poly.poly, geos.MultiPolygon):
                        for inside_poly in poly.poly:
                            if _city is None:
                                # Find the city if we haven't found it yet
                                cities = Council.objects.filter(poly__intersects=inside_poly)
                                if len(cities) > 0:
                                    _city = cities[0].convexhull.name
                                    break
                    else: # Probably unneeded as eventually we only have Multipolygons in our db 
                        if _city is None:
                            # Find the city if we haven't found it yet
                            cities = Council.objects.filter(poly__intersects=inside_poly)
                            if len(cities) > 0:
                                _city = cities[0].convexhull.name
                                break
                        
            print "City:", _city
                
            if len(polys) > 0 and self.type != "None":        
                if neighbourhoods:
                    _name = _city+"_neighbourhood_max_"+self.type
                    max_x = float(Statistics.objects.filter(name=_name).all()[0].stat)
                    _name = _city+"_neighbourhood_min_"+self.type
                    min_x = float(Statistics.objects.filter(name=_name).all()[0].stat)
                else:
                    _name = _city+"_postcode_max_"+self.type
                    max_x = float(Statistics.objects.filter(name=_name).all()[0].stat)
                    _name = _city+"_postcode_min_"+self.type
                    min_x = float(Statistics.objects.filter(name=_name).all()[0].stat)
                        
                print "max:", max_x, "min:", min_x
                          
            # For all the polygons we've retrieved from the database (in OSGB36 format)
            for poly in polys:
                _city = None
                if poly.poly and isinstance(poly.poly, geos.MultiPolygon):
                    for inside_poly in poly.poly:
                        
                        if _city is None:
                            # Find the city if we haven't found it yet
                            cities = Council.objects.filter(poly__intersects=inside_poly)
                            if len(cities) > 0:
                                _city = cities[0].convexhull.name
    
                        self._paint_poly(inside_poly, shp, mmap, pil_draw, _city,
                                         max_x, min_x, neighbourhoods)
                else: # Probably unneeded as eventually we only have Multipolygons in our db 
                    if _city is None:
                        # Find the city if we haven't found it yet
                        cities = Council.objects.filter(poly__intersects=inside_poly)
                        if len(cities) > 0:
                            _city = cities[0].convexhull.name
                    self._paint_poly(poly.poly, shp, mmap, pil_draw, _city,
                                     max_x, min_x, neighbourhoods)
        except Exception, err:
            print err
コード例 #13
0
ファイル: mapgift.py プロジェクト: galvanic/MapGift
def make_map(provider, area, zoom, by_centre, map_size=(1200,800), verbose=False):
    """
    zoom:   integer, the zoom level (altitude)
            min 12; max 15 in this case

    Returns a map instance (not image!)
    """
    if type(area) in (str, unicode):
        area = area.lower()
    zoom = int(zoom)

    provider = PROVIDERS[provider.lower()]

    if verbose:
        title = 'Making map with the following characteristics:'
        print '\n%s' % title
        print '-' * len(title)
        if type(area) in (str, unicode):
            print 'Area:     %s' % area.title()
        else:
            print 'Area:     %s' % area
        print 'Zoom:     %d' % zoom
        if type(provider) == str:
            print 'Provider: %s' % provider.title().replace('_', ' ')
        else:
            print 'Provider: %s' % provider.__name__
        print 'Height:   %dpx' % map_size[1]
        print 'Width:    %dpx' % map_size[0]
        print

    if type(provider) == str:
        provider = MM.builtinProviders[provider]()
    else: # it must be a custom provider
        provider = provider()

    if by_centre:
        if type(area) in (str, unicode):
            centre = CENTRE[area]
        elif type(area) == tuple:
            centre = area
        width  = map_size[0]
        height = map_size[1]

        m = MM.mapByCenterZoom( provider,
                                MM.Geo.Location(*centre),
                                zoom,
                                MM.Core.Point(width, height))
        if verbose:
            print m.pointLocation(MM.Core.Point(0,0))           # to get the upper left corner geo coordinates
            print m.pointLocation(MM.Core.Point(width,height))  # to get the lower right corner geo coordinates
    
    else: # by box
        if type(area) in (str, unicode):
            map_box = MAP_BOX[area]
        elif type(area) == tuple:
            map_box = area
        left_upper_corner  = MM.Geo.Location(*map_box[0])
        right_lower_corner = MM.Geo.Location(*map_box[1])

        m = MM.mapByExtentZoom( provider,
                                left_upper_corner,
                                right_lower_corner,
                                zoom)
    return m
コード例 #14
0
ファイル: compose.py プロジェクト: migurski/paperwalking
def main(apibase, password, print_id, paper_size, orientation=None, layout=None, provider=None, bounds=None, zoom=None, geotiff_url=None):
    """
    """
    yield 60
    
    print 'Print:', print_id
    print 'Paper:', paper_size

    if orientation and bounds and zoom and provider and layout:
    
        print 'Orientation:', orientation
        print 'Bounds:', bounds
        print 'Layout:', layout
        print 'Provider:', provider
        print 'Size:', get_preview_map_size(orientation, paper_size)
        
        print_data = {'pages': []}
        print_pages = print_data['pages']
        
        north, west, south, east = bounds
        width, height = get_preview_map_size(orientation, paper_size)
        
        northwest = mm.Geo.Location(north, west)
        southeast = mm.Geo.Location(south, east)
        
        # we need it to cover a specific area
        mmap = mm.mapByExtentZoom(TemplatedMercatorProvider(provider),
                                  northwest, southeast, zoom)
                              
        # but we also we need it at a specific size
        mmap = mm.Map(mmap.provider, mm.Core.Point(width, height), mmap.coordinate, mmap.offset)
        
        out = StringIO()
        mmap.draw(fatbits_ok=True).save(out, format='JPEG')
        preview_url = append_print_file(print_id, 'preview.jpg', out.getvalue(), apibase, password)
        
        print 'Sent preview.jpg'
        
        yield 60
        
        zdiff = min(18, zoom + 2) - zoom
        print 'Zoom diff:', zdiff
        
        # we need it to cover a specific area
        mmap = mm.mapByExtentZoom(TemplatedMercatorProvider(provider),
                                  northwest, southeast, zoom + zdiff)
                              
        # but we also we need it at a specific size
        mmap = mm.Map(mmap.provider, mm.Core.Point(width * 2**zdiff, height * 2**zdiff), mmap.coordinate, mmap.offset)
        
        out = StringIO()
        mmap.draw(fatbits_ok=True).save(out, format='JPEG')
        print_url = append_print_file(print_id, 'print.jpg', out.getvalue(), apibase, password)
        
        print 'Sent print.jpg'
        
        page_nw = mmap.pointLocation(mm.Core.Point(0, 0))
        page_se = mmap.pointLocation(mmap.dimensions)
        
        page_data = {'print': 'print.jpg', 'preview': 'preview.jpg', 'bounds': {}}
        page_data['bounds'].update({'north': page_nw.lat, 'west': page_nw.lon})
        page_data['bounds'].update({'south': page_se.lat, 'east': page_se.lon})
        print_pages.append(page_data)
        
        rows, cols = map(int, layout.split(','))
        
        if rows > 1 and cols > 1:
            for (row, col) in product(range(rows), range(cols)):
                
                yield 60
                
                sub_mmap = get_mmap_page(mmap, row, col, rows, cols)
                sub_part = '%(row)d,%(col)d' % locals()
                sub_name = 'print-%(sub_part)s.jpg' % locals()
        
                out = StringIO()
                sub_mmap.draw(fatbits_ok=True).save(out, format='JPEG')
                append_print_file(print_id, sub_name, out.getvalue(), apibase, password)
                
                print 'Sent', sub_name
                
                prev_cen = sub_mmap.pointLocation(mm.Core.Point(sub_mmap.dimensions.x / 2, sub_mmap.dimensions.y / 2))
                prev_dim = mm.Core.Point(sub_mmap.dimensions.x / 2**zdiff, sub_mmap.dimensions.y / 2**zdiff)
                prev_mmap = mm.mapByCenterZoom(sub_mmap.provider, prev_cen, sub_mmap.coordinate.zoom - zdiff, prev_dim)
                prev_name = 'preview-%(sub_part)s.jpg' % locals()
        
                out = StringIO()
                prev_mmap.draw(fatbits_ok=True).save(out, format='JPEG')
                append_print_file(print_id, prev_name, out.getvalue(), apibase, password)
                
                print 'Sent', prev_name
                
                page_nw = sub_mmap.pointLocation(mm.Core.Point(0, 0))
                page_se = sub_mmap.pointLocation(sub_mmap.dimensions)
                
                page_data = {'part': sub_part, 'print': sub_name, 'preview': prev_name, 'bounds': {}}
                page_data['bounds'].update({'north': page_nw.lat, 'west': page_nw.lon})
                page_data['bounds'].update({'south': page_se.lat, 'east': page_se.lon})
                print_pages.append(page_data)
        
        print_data_url = append_print_file(print_id, 'print-data.json', json.dumps(print_data, indent=2), apibase, password)
        print 'Sent', print_data_url
    
    elif geotiff_url:
        
        # we'll need pages_data, a few other things
        raise Exception("I'm pretty sure support for geotiffs is currently broken, with the new atlas feature.")
    
        print 'URL:', geotiff_url
        
        filename = prepare_geotiff(geotiff_url)
        print_img, preview_img, (north, west, south, east), orientation = adjust_geotiff(filename, paper_size)
        os.unlink(filename)
        
        print_img.save(os.path.dirname(filename)+'/out.jpg')
        
        out = StringIO()
        print_img.save(out, format='JPEG')
        append_print_file(print_id, 'print.jpg', out.getvalue(), apibase, password)
        
        out = StringIO()
        preview_img.save(out, format='JPEG')
        preview_url = append_print_file(print_id, 'preview.jpg', out.getvalue(), apibase, password)
        
        zoom = infer_zoom(print_img.size[0], print_img.size[1], north, west, south, east)

    else:
        print 'Missing orientation, bounds, zoom, provider, layout and geotiff_url'
        yield ALL_FINISHED
        return
    
    yield 10
    
    paper = '%(orientation)s-%(paper_size)s' % locals()

    print 'Finishing...'
    finish_print(apibase, password, print_id, north, west, south, east, zoom, paper, print_data_url)
    
    print '-' * 80
    
    yield ALL_FINISHED