コード例 #1
0
ファイル: views.py プロジェクト: dbca-wa/firesource
def tile_wms(layer, extent, docsize, dpi, workdir, wmsauth):
    '''
    takes a layer and generates a tiled wms of that layer in the current dir for the
    specified extent and template size
    '''
    logger = logger_setup('tile_wms')
    logger.info('Called with: {0}'.format(
        (layer, extent, docsize, dpi, workdir)))
    if layer.transparent:
        layerimage, outputformat = layer.layer_id + ".png", "PNG"
    else:
        layerimage, outputformat = layer.layer_id + ".jpg", "JPEG"
    sizex = docsize[0] / 25.4 * dpi
    sizey = sizex * (extent[3] - extent[1]) / (extent[2] - extent[0])
    layerurl = "http:" + layer.url.replace("gwc/service/wms", "ows")
    logger.info('layerurl: {0}'.format(layerurl))
    gdaltile = render_to_response('spatial/gdalwms.xml', locals())
    logger.info('gdaltile:')
    logger.info(gdaltile.content)
    with open(layer.layer_id + ".xml", "w") as gdalfile:
        gdalfile.write(gdaltile.content)
    subprocess.check_call(
        "gdal_translate -q -of {0} {1}.xml {2} && convert {2} -transparent white {2}"
        .format(outputformat, layer.layer_id, layerimage),
        shell=True)
    logger.info("layerimage creation successful: {0}".format(layerimage))
    return layerimage
コード例 #2
0
ファイル: views.py プロジェクト: parksandwildlife/firesource
def tile_wms(layer, extent, docsize, dpi, workdir, wmsauth):
    '''
    takes a layer and generates a tiled wms of that layer in the current dir for the
    specified extent and template size
    '''
    logger = logger_setup('tile_wms')
    logger.info('Called with: {0}'.format((layer, extent, docsize, dpi, workdir)))
    if layer.transparent:
        layerimage, outputformat = layer.layer_id + ".png", "PNG"
    else:
        layerimage, outputformat = layer.layer_id + ".jpg", "JPEG"
    sizex = docsize[0] / 25.4 * dpi
    sizey = sizex * (extent[3] - extent[1]) / (extent[2] - extent[0])
    layerurl = "http:" + layer.url.replace("gwc/service/wms", "ows")
    logger.info('layerurl: {0}'.format(layerurl))
    gdaltile = render_to_response('spatial/gdalwms.xml', locals())
    logger.info('gdaltile:')
    logger.info(gdaltile.content)
    with open(layer.layer_id + ".xml", "w") as gdalfile:
        gdalfile.write(gdaltile.content)
    subprocess.check_call("gdal_translate -q -of {0} {1}.xml {2} && convert {2} -transparent white {2}".format(outputformat, layer.layer_id, layerimage), shell=True)
    logger.info("layerimage creation successful: {0}".format(layerimage))
    return layerimage
コード例 #3
0
ファイル: views.py プロジェクト: parksandwildlife/firesource
def print(request, dpi=200, fmt="pdf"):
    '''
    If post create/end a map in database
    If get print latest map for workdir specified
    '''
    cachekey = "print.{}?{}".format(fmt, request.META["QUERY_STRING"])
    cacheddata = cache.get(cachekey)
    if cacheddata:
        content, mimetype, filename = cacheddata
        response = http.HttpResponse(content, content_type=mimetype)
        response["Content-Disposition"] = 'inline; filename="{}"'.format(filename)
        return response
    logger = logger_setup('print')
    try:
        spatial_state = json.loads(request.GET["ss"])
    except:
        return http.HttpResponse(subprocess.check_output([GDAL_TRANSLATE, "--version"]))
    cwd = os.getcwd()
    spatialmap = Map(name=request.GET["name"], created_by=request.user, modified_by=request.user)
    spatialmap.layers = spatial_state["layers"]
    spatialmap.center = "POINT ({0} {1})".format(*spatial_state["center"]["coordinates"])
    spatialmap.scale = int(spatial_state["scale"])
    spatialmap.workdir = spatialmap.created_by.email + "-sssprint-" + spatialmap.date_created.strftime("%Y%m%d_%H%M")
    spatialmap.template = "inkscape_a3_landscape"
    workdir = os.path.join("/run/shm", spatialmap.workdir)
    logger.info("Workdir: {0}".format(workdir))
    # take lock for current folder/map
    try:
        os.makedirs(workdir)
        os.chdir(workdir)
        logger.info('Taking a lock in the workdir')
    except:
        return http.HttpResponse("Busy, please try later")
    docsize = document_sizes[spatialmap.template]
    spatialmap.bounds = centerscale_topoly(spatialmap.center, spatialmap.scale, docsize)
    # find out projection for printing eastings/northings
    srid = False
    if spatialmap.center.x > 108 and spatialmap.center.x <= 114: srid = 28349
    elif spatialmap.center.x > 114 and spatialmap.center.x <= 120: srid = 28350
    elif spatialmap.center.x > 120 and spatialmap.center.x <= 126: srid = 28351
    elif spatialmap.center.x > 126 and spatialmap.center.x <= 132: srid = 28352
    elif spatialmap.center.x > 132 and spatialmap.center.x <= 138: srid = 28353
    elif spatialmap.center.x > 138 and spatialmap.center.x <= 144: srid = 28354
    elif spatialmap.center.x > 144 and spatialmap.center.x <= 150: srid = 28355
    elif spatialmap.center.x > 150 and spatialmap.center.x <= 156: srid = 28356
    class bnds: pass
    bnds.xmin, bnds.ymin = round(spatialmap.bounds.extent[0], 5), round(spatialmap.bounds.extent[1], 5)
    bnds.xmid, bnds.ymid = round(spatialmap.center.x, 5), round(spatialmap.center.y, 5)
    bnds.xmax, bnds.ymax = round(spatialmap.bounds.extent[2], 5), round(spatialmap.bounds.extent[3], 5)
    # pbnds is projected bounds
    if srid:
        class pbnds: pass
        from django.contrib.gis.geos.point import Point
        pbnds.xmin, pbnds.ymin = Point(bnds.xmin, bnds.ymin, srid=4283).transform(srid, clone=True)
        pbnds.xmid, pbnds.ymid = Point(bnds.xmid, bnds.ymid, srid=4283).transform(srid, clone=True)
        pbnds.xmax, pbnds.ymax = Point(bnds.xmax, bnds.ymax, srid=4283).transform(srid, clone=True)
        pbnds.xmin, pbnds.ymin = int(round(pbnds.xmin, 0)), int(round(pbnds.ymin, 0))
        pbnds.xmid, pbnds.ymid = int(round(pbnds.xmid, 0)), int(round(pbnds.ymid, 0))
        pbnds.xmax, pbnds.ymax = int(round(pbnds.xmax, 0)), int(round(pbnds.ymax, 0))
    # calculate this from scalebars/km given scalebar is 0.2m
    scalebar_kms = round(spatialmap.scale / 5000, 2)
    # this should asjust for users local time not servers local time. Users offset should be set automatically on map load by browsers offset.
    spatialmap_datetime = datetime.fromtimestamp(time.mktime(time.localtime(calendar.timegm(spatialmap.date_created.timetuple())))).strftime("%a, %d %b %Y %H:%M")
    # Well this is needlessly complex:
    #compositepng, compositejpg, compositepdf, zipped = [(n+".png",n+".jpg",n+".pdf",n+".zip") for n in [spatialmap.map_id + spatialmap.date_created.strftime("_%Y%m%d_%H%M")]][0]
    composite = spatialmap.map_id + spatialmap.date_created.strftime("_%Y%m%d_%H%M")
    compositepng = "{0}.png".format(composite)
    compositejpg = "{0}.jpg".format(composite)
    compositepdf = "{0}.pdf".format(composite)
    # grab user shared_id for login
    wmsauth = "{}:{}".format(request.META["HTTP_REMOTE_USER"], request.META["HTTP_X_SHARED_ID"])
    logger.info("Starting to iterate through layers: {0}".format(spatialmap.layers))
    for index, lyr in enumerate(spatialmap.layers):
        logger.info("Layer: {0}".format(lyr))
        if not RasterLayer.objects.filter(url__startswith="//kmi.dpaw.wa.gov.au/", layer_id=lyr["layer_id"]).order_by("-effective_from").exists():
            if lyr["layer_id"].startswith("resource_tracking_week_base"):
                lyr["layer_id"] = "resource_tracking_printable"
            else:
                continue
        layer = RasterLayer.objects.filter(layer_id=lyr["layer_id"]).order_by("-effective_from")[0]
        logger.info("Layer {0} is a raster layer, call tile_wms".format(layer))
        try:
            lyr["location"] = tile_wms(layer=layer, extent=spatialmap.bounds.extent, docsize=docsize, dpi=dpi, workdir=workdir, wmsauth=wmsauth)
        except Exception as e:
            os.chdir(cwd)
            return http.HttpResponse("<h2>Layer <u>{0}</u> failed to render, try zooming in or disabling this layer and printing again.</h2>workdir: <pre>{1}</pre><br>error: <pre>{2}</pre>".format(layer.name, workdir, e))
    finalpng = "inkscape_" + compositepng
    finaljpg = "inkscape_" + compositejpg
    finalsvg = finaljpg.replace(".jpg", ".svg")
    finalpdf = "inkscape_" + compositepdf
    with open(finalsvg, "w") as inkscapesvg:
        inkscapesvg.write(render_to_response('spatial/{0}.svg'.format(spatialmap.template), locals()).content)
    if fmt == "pdf":
        subprocess.check_call("inkscape {0} --export-dpi={2} --export-pdf={1}".format(finalsvg, finalpdf, dpi), shell=True)
        content = open(finalpdf).read()
        mimetype = "application/pdf"
        filename = spatialmap.name + ".pdf"
    elif fmt == "jpg":
        subprocess.check_call("inkscape {0} --export-dpi={2} --export-png={1} && convert {1} -quality 100% {3}".format(finalsvg, finalpng, dpi, finaljpg), shell=True)
        content = open(finaljpg).read()
        mimetype = "image/jpg"
        filename = spatialmap.name + ".jpg"
    cache.set(cachekey, (content, mimetype, filename), 600)
    response = http.HttpResponse(content, content_type=mimetype)
    response["Content-Disposition"] = 'inline; filename="{}"'.format(filename)
    logger.info('Freeing the workdir lock')
    os.chdir(cwd)
    shutil.rmtree(workdir)
    return response
コード例 #4
0
ファイル: views.py プロジェクト: dbca-wa/firesource
def print(request, dpi=200, fmt="pdf"):
    '''
    If post create/end a map in database
    If get print latest map for workdir specified
    '''
    cachekey = "print.{}?{}".format(fmt, request.META["QUERY_STRING"])
    cacheddata = cache.get(cachekey)
    if cacheddata:
        content, mimetype, filename = cacheddata
        response = http.HttpResponse(content, content_type=mimetype)
        response["Content-Disposition"] = 'inline; filename="{}"'.format(
            filename)
        return response
    logger = logger_setup('print')
    try:
        spatial_state = json.loads(request.GET["ss"])
    except:
        return http.HttpResponse(
            subprocess.check_output([GDAL_TRANSLATE, "--version"]))
    cwd = os.getcwd()
    spatialmap = Map(name=request.GET["name"],
                     created_by=request.user,
                     modified_by=request.user)
    spatialmap.layers = spatial_state["layers"]
    spatialmap.center = "POINT ({0} {1})".format(
        *spatial_state["center"]["coordinates"])
    spatialmap.scale = int(spatial_state["scale"])
    spatialmap.workdir = spatialmap.created_by.email + "-sssprint-" + spatialmap.date_created.strftime(
        "%Y%m%d_%H%M")
    spatialmap.template = "inkscape_a3_landscape"
    workdir = os.path.join("/run/shm", spatialmap.workdir)
    logger.info("Workdir: {0}".format(workdir))
    # take lock for current folder/map
    try:
        os.makedirs(workdir)
        os.chdir(workdir)
        logger.info('Taking a lock in the workdir')
    except:
        return http.HttpResponse("Busy, please try later")
    docsize = document_sizes[spatialmap.template]
    spatialmap.bounds = centerscale_topoly(spatialmap.center, spatialmap.scale,
                                           docsize)
    # find out projection for printing eastings/northings
    srid = False
    if spatialmap.center.x > 108 and spatialmap.center.x <= 114: srid = 28349
    elif spatialmap.center.x > 114 and spatialmap.center.x <= 120: srid = 28350
    elif spatialmap.center.x > 120 and spatialmap.center.x <= 126: srid = 28351
    elif spatialmap.center.x > 126 and spatialmap.center.x <= 132: srid = 28352
    elif spatialmap.center.x > 132 and spatialmap.center.x <= 138: srid = 28353
    elif spatialmap.center.x > 138 and spatialmap.center.x <= 144: srid = 28354
    elif spatialmap.center.x > 144 and spatialmap.center.x <= 150: srid = 28355
    elif spatialmap.center.x > 150 and spatialmap.center.x <= 156: srid = 28356

    class bnds:
        pass

    bnds.xmin, bnds.ymin = round(spatialmap.bounds.extent[0],
                                 5), round(spatialmap.bounds.extent[1], 5)
    bnds.xmid, bnds.ymid = round(spatialmap.center.x,
                                 5), round(spatialmap.center.y, 5)
    bnds.xmax, bnds.ymax = round(spatialmap.bounds.extent[2],
                                 5), round(spatialmap.bounds.extent[3], 5)
    # pbnds is projected bounds
    if srid:

        class pbnds:
            pass

        from django.contrib.gis.geos.point import Point
        pbnds.xmin, pbnds.ymin = Point(bnds.xmin, bnds.ymin,
                                       srid=4283).transform(srid, clone=True)
        pbnds.xmid, pbnds.ymid = Point(bnds.xmid, bnds.ymid,
                                       srid=4283).transform(srid, clone=True)
        pbnds.xmax, pbnds.ymax = Point(bnds.xmax, bnds.ymax,
                                       srid=4283).transform(srid, clone=True)
        pbnds.xmin, pbnds.ymin = int(round(pbnds.xmin,
                                           0)), int(round(pbnds.ymin, 0))
        pbnds.xmid, pbnds.ymid = int(round(pbnds.xmid,
                                           0)), int(round(pbnds.ymid, 0))
        pbnds.xmax, pbnds.ymax = int(round(pbnds.xmax,
                                           0)), int(round(pbnds.ymax, 0))
    # calculate this from scalebars/km given scalebar is 0.2m
    scalebar_kms = round(spatialmap.scale / 5000, 2)
    # this should asjust for users local time not servers local time. Users offset should be set automatically on map load by browsers offset.
    spatialmap_datetime = datetime.fromtimestamp(
        time.mktime(
            time.localtime(calendar.timegm(
                spatialmap.date_created.timetuple())))).strftime(
                    "%a, %d %b %Y %H:%M")
    # Well this is needlessly complex:
    #compositepng, compositejpg, compositepdf, zipped = [(n+".png",n+".jpg",n+".pdf",n+".zip") for n in [spatialmap.map_id + spatialmap.date_created.strftime("_%Y%m%d_%H%M")]][0]
    composite = spatialmap.map_id + spatialmap.date_created.strftime(
        "_%Y%m%d_%H%M")
    compositepng = "{0}.png".format(composite)
    compositejpg = "{0}.jpg".format(composite)
    compositepdf = "{0}.pdf".format(composite)
    # grab user shared_id for login
    wmsauth = "{}:{}".format(request.META["HTTP_REMOTE_USER"],
                             request.META["HTTP_X_SHARED_ID"])
    logger.info("Starting to iterate through layers: {0}".format(
        spatialmap.layers))
    for index, lyr in enumerate(spatialmap.layers):
        logger.info("Layer: {0}".format(lyr))
        if not RasterLayer.objects.filter(
                url__startswith="//kmi.dpaw.wa.gov.au/",
                layer_id=lyr["layer_id"]).order_by("-effective_from").exists():
            if lyr["layer_id"].startswith("resource_tracking_week_base"):
                lyr["layer_id"] = "resource_tracking_printable"
            else:
                continue
        layer = RasterLayer.objects.filter(
            layer_id=lyr["layer_id"]).order_by("-effective_from")[0]
        logger.info("Layer {0} is a raster layer, call tile_wms".format(layer))
        try:
            lyr["location"] = tile_wms(layer=layer,
                                       extent=spatialmap.bounds.extent,
                                       docsize=docsize,
                                       dpi=dpi,
                                       workdir=workdir,
                                       wmsauth=wmsauth)
        except Exception as e:
            os.chdir(cwd)
            return http.HttpResponse(
                "<h2>Layer <u>{0}</u> failed to render, try zooming in or disabling this layer and printing again.</h2>workdir: <pre>{1}</pre><br>error: <pre>{2}</pre>"
                .format(layer.name, workdir, e))
    finalpng = "inkscape_" + compositepng
    finaljpg = "inkscape_" + compositejpg
    finalsvg = finaljpg.replace(".jpg", ".svg")
    finalpdf = "inkscape_" + compositepdf
    with open(finalsvg, "w") as inkscapesvg:
        inkscapesvg.write(
            render_to_response('spatial/{0}.svg'.format(spatialmap.template),
                               locals()).content)
    if fmt == "pdf":
        subprocess.check_call(
            "inkscape {0} --export-dpi={2} --export-pdf={1}".format(
                finalsvg, finalpdf, dpi),
            shell=True)
        content = open(finalpdf).read()
        mimetype = "application/pdf"
        filename = spatialmap.name + ".pdf"
    elif fmt == "jpg":
        subprocess.check_call(
            "inkscape {0} --export-dpi={2} --export-png={1} && convert {1} -quality 100% {3}"
            .format(finalsvg, finalpng, dpi, finaljpg),
            shell=True)
        content = open(finaljpg).read()
        mimetype = "image/jpg"
        filename = spatialmap.name + ".jpg"
    cache.set(cachekey, (content, mimetype, filename), 600)
    response = http.HttpResponse(content, content_type=mimetype)
    response["Content-Disposition"] = 'inline; filename="{}"'.format(filename)
    logger.info('Freeing the workdir lock')
    os.chdir(cwd)
    shutil.rmtree(workdir)
    return response