Example #1
0
class TileStacheProvider(object):
    """An object suitable for use as a TileStache provider.

    .. py:attribute:: renderer

        Set this attribute to a renderer instance to use for rendering map tiles.
    """
    def __init__(self, layer):
        super(TileStacheProvider, self).__init__()
        self.renderer = TileFetcher()

    def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom):
        spatial_reference = SpatialReference()

        # this is a special HACK to take account of the fact that the proj4 srs provided by TileStache has the +over
        # parameter and OGR thinks it is different to EPSG:3857
        if srs == TileStache.Geography.SphericalMercator.srs:
            spatial_reference.ImportFromEPSG(3857)
        else:
            spatial_reference.ImportFromProj4(srs)

        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        cr = cairo.Context(surface)
        set_geo_transform(cr, xmin, xmax, ymax, ymin, width, height)
        self.renderer.render_callable(cr, spatial_reference=spatial_reference)()

        im = Image.frombuffer('RGBA', (width, height), surface.get_data(), 'raw', 'BGRA', 0, 1)
        return im
Example #2
0
def run(args):
    srs = SpatialReference()
    if args.epsg is not None:
        srs.ImportFromEPSG(args.epsg)
    elif args.proj is not None:
        srs.ImportFromProj4(args.proj)
    else:
        srs.ImportFromEPSG(4326) # default to WGS84 lat/lng

    left, right, top, bottom = (
        args.left*args.units,
        args.right*args.units,
        args.top*args.units,
        args.bottom*args.units
    )

    if args.width is None and args.height is None:
        print('error: at least one of height or width must be set')
        sys.exit(1)
    elif args.height is None:
        ew, eh = (abs(right-left), abs(top-bottom))
        args.height = max(1, int(args.width * eh / ew))
    elif args.width is None:
        ew, eh = (abs(right-left), abs(top-bottom))
        args.width = max(1, int(args.height * ew / eh))

    size = (args.width, args.height)

    url_patterns = {
        'osm': 'http://otile1.mqcdn.com/tiles/1.0.0/osm/{zoom}/{x}/{y}.jpg',
        'aerial': 'http://oatile1.mqcdn.com/tiles/1.0.0/sat/{zoom}/{x}/{y}.jpg',
    }

    def url_fetcher(url):
        http = httplib2.Http(args.cache_dir)
        rep, content = http.request(url, 'GET')
        if rep.status != 200:
            raise foldbeam.renderer.URLFetchError(str(rep.status) + ' ' + rep.reason)
        return content

    renderer = TileFetcher(
            url_pattern=url_patterns['aerial' if args.aerial else 'osm'],
            url_fetcher=url_fetcher)

    output_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, size[0], size[1])

    context = cairo.Context(output_surface)
    set_geo_transform(context, left, right, top, bottom, size[0], size[1])
    renderer.render_callable(context, spatial_reference=srs)()

    output_surface.write_to_png(args.output)
Example #3
0
 def __init__(self, layer):
     super(TileStacheProvider, self).__init__()
     self.renderer = TileFetcher()
Example #4
0
def run(args):
    srs = SpatialReference()
    srs.ImportFromEPSG(4326) # default to WGS84 lat/lng

    if args.like_filename is not None:
        like_ds = gdal.Open(args.like_filename)
        ox, sx, _, oy, _, sy = like_ds.GetGeoTransform()

        args.width = like_ds.RasterXSize
        args.height = like_ds.RasterYSize

        args.left = ox
        args.right = ox + sx * args.width
        args.top = oy
        args.bottom = oy + sy * args.height
        args.units = 1

        # FIXME: projection
    elif args.cx is not None and args.cy is not None and args.ex is not None and args.ey is not None:
        args.left = args.cx - args.ex * 0.5
        args.right = args.cx + args.ex * 0.5
        args.top = args.cy + args.ey * 0.5
        args.bottom = args.cy - args.ey * 0.5
    elif args.left is None or args.right is None or args.top is None or args.bottom is None:
        print('error: all of left, right, top and bottom extent must be specified')

    if args.epsg is not None:
        srs.ImportFromEPSG(args.epsg)
    elif args.proj is not None:
        srs.ImportFromProj4(args.proj)

    left, right, top, bottom = (
        args.left*args.units,
        args.right*args.units,
        args.top*args.units,
        args.bottom*args.units
    )

    if args.width is None and args.height is None:
        print('error: at least one of height or width must be set')
        sys.exit(1)
    elif args.height is None:
        ew, eh = (abs(right-left), abs(top-bottom))
        args.height = max(1, int(args.width * eh / ew))
    elif args.width is None:
        ew, eh = (abs(right-left), abs(top-bottom))
        args.width = max(1, int(args.height * ew / eh))

    size = (args.width, args.height)

    url_patterns = {
        'osm': 'http://otile1.mqcdn.com/tiles/1.0.0/osm/{zoom}/{x}/{y}.jpg',
        'aerial': 'http://ecn.t1.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=1647',
        #'aerial': 'http://oatile1.mqcdn.com/tiles/1.0.0/sat/{zoom}/{x}/{y}.jpg',
    }

    def url_fetcher(url):
        http = httplib2.Http(args.cache_dir)
        rep, content = http.request(url, 'GET')
        if rep.status != 200:
            raise foldbeam.renderer.URLFetchError(str(rep.status) + ' ' + rep.reason)
        return content

    renderer = TileFetcher(
            url_pattern=url_patterns['aerial' if args.aerial else 'osm'],
            url_fetcher=url_fetcher)


    if args.output.endswith('.tiff'):
        import numpy as np
        image_data = np.zeros((size[1], size[0], 4), dtype=np.uint8)
        output_surface = cairo.ImageSurface.create_for_data(
                image_data, cairo.FORMAT_ARGB32, size[0], size[1])
        context = cairo.Context(output_surface)
        set_geo_transform(context, left, right, top, bottom, size[0], size[1])
        renderer.render_callable(context, spatial_reference=srs)()
        ds = gdal_array.OpenArray(
                np.transpose(image_data[:,:,[2,1,0,3]], (2,0,1)))

        ds.SetGeoTransform((
            left, (right - left) / size[0], 0,
            top, 0, (bottom - top) / size[1]
        ))

        drv = gdal.GetDriverByName('GTiff')
        drv.Delete(args.output)
        drv.CreateCopy(args.output, ds, options=('COMPRESS=LZW',))
    else:
        output_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, size[0], size[1])
        context = cairo.Context(output_surface)
        set_geo_transform(context, left, right, top, bottom, size[0], size[1])
        renderer.render_callable(context, spatial_reference=srs)()
        output_surface.write_to_png(args.output)