Пример #1
0
def WMS(z, x, y, this_layer):
    if "max_zoom" in this_layer:
        if z >= this_layer["max_zoom"]:
            return None
    wms = this_layer["remote_url"]
    req_proj = this_layer.get("wms_proj", this_layer["proj"])
    width = 384  # using larger source size to rescale better in python
    height = 384
    local = config.tiles_cache + this_layer["prefix"] + "/z%s/%s/x%s/%s/y%s." % (z, x / 1024, x, y / 1024, y)
    tile_bbox = "bbox=%s,%s,%s,%s" % tuple(projections.from4326(projections.bbox_by_tile(z, x, y, req_proj), req_proj))

    wms += tile_bbox + "&width=%s&height=%s&srs=%s" % (width, height, req_proj)
    if this_layer.get("cached", True):
        if not os.path.exists("/".join(local.split("/")[:-1])):
            os.makedirs("/".join(local.split("/")[:-1]))
        try:
            os.mkdir(local + "lock")
        except OSError:
            for i in range(20):
                time.sleep(0.1)
                try:
                    if not os.path.exists(local + "lock"):
                        im = Image.open(local + this_layer["ext"])
                        return im
                except IOError, OSError:
                    return None
Пример #2
0
    def ConstructTileUrl(self, x, y):
        if self.server_api == "tms":
            url = self.server_url
            url = url.replace("{zoom}", str(self.zoom))
            url = url.replace("{x}", str(x))
            url = url.replace("{y}", str(y))
            url = url.replace("{-y}", str((1 << self.zoom) - 1 - y))

            sw1 = "{switch:"
            sw2 = url.find(sw1)
            if sw2 != -1:
                sw3 = url.find("}", sw2)
                if sw3 != -1:
                    sw4 = url[sw2:sw3 + 1]
                    sw5 = url[sw2 + len(sw1):sw3]
                    sw6 = random.choice(sw5.split(","))
                    url = url.replace(sw4, sw6)

            return url
        elif self.server_api == "wms":
            a, b, c, d = projections.from4326(
                projections.bbox_by_tile(self.zoom, x, y, self.proj),
                self.proj)
            return self.server_url + "width=%s&height=%s&srs=%s&bbox=%s,%s,%s,%s" % (
                self.tile_width, self.tile_height, self.proj, a, b, c, d)
        else:
            return self.server_url.replace("{quadkey}",
                                           self.ConstructQuadkey(x, y))
Пример #3
0
 def ConstructTileUrl(self, x, y):
     if self.tile_mode == "WMS":
         a, b, c, d = projections.from4326(
             projections.bbox_by_tile(self.zoom, x, y, self.proj),
             self.proj)
         return self.wms_url + "width=%s&height=%s&srs=%s&bbox=%s,%s,%s,%s" % (
             self.tile_width, self.tile_height, self.proj, a, b, c, d)
     else:
         return self.wms_url + "z=%s&x=%s&y=%s&width=%s&height=%s" % (
             self.zoom - 1, x, y, self.tile_width, self.tile_height)
Пример #4
0
def WMS(z, x, y, this_layer):
    if "max_zoom" in this_layer:
        if z >= this_layer["max_zoom"]:
            return None
    wms = this_layer["remote_url"]
    req_proj = this_layer.get("wms_proj", this_layer["proj"])
    width = 384  # using larger source size to rescale better in python
    height = 384
    local = config.tiles_cache + this_layer[
        "prefix"] + "/z%s/%s/x%s/%s/y%s." % (z, x / 1024, x, y / 1024, y)
    tile_bbox = "bbox=%s,%s,%s,%s" % tuple(
        projections.from4326(projections.bbox_by_tile(z, x, y, req_proj),
                             req_proj))

    wms += tile_bbox + "&width=%s&height=%s&srs=%s" % (width, height, req_proj)
    if this_layer.get("cached", True):
        if not os.path.exists("/".join(local.split("/")[:-1])):
            os.makedirs("/".join(local.split("/")[:-1]))
        try:
            os.mkdir(local + "lock")
        except OSError:
            for i in range(20):
                time.sleep(0.1)
                try:
                    if not os.path.exists(local + "lock"):
                        im = Image.open(local + this_layer["ext"])
                        return im
                except (IOError, OSError):
                    return None
    im = Image.open(StringIO.StringIO(urllib2.urlopen(wms).read()))
    if width is not 256 and height is not 256:
        im = im.resize((256, 256), Image.ANTIALIAS)
    im = im.convert("RGBA")

    if this_layer.get("cached", True):
        ic = Image.new(
            "RGBA", (256, 256),
            this_layer.get("empty_color", config.default_background))
        if im.histogram() == ic.histogram():
            tne = open(local + "tne", "wb")
            when = time.localtime()
            tne.write("%02d.%02d.%04d %02d:%02d:%02d" %
                      (when[2], when[1], when[0], when[3], when[4], when[5]))
            tne.close()
            return False
        im.save(local + this_layer["ext"])
        os.rmdir(local + "lock")
    return im
Пример #5
0
def WMS (z, x, y, this_layer):
   if "max_zoom" in this_layer:
    if z >= this_layer["max_zoom"]:
      return None   
   wms = this_layer["remote_url"]
   req_proj = this_layer.get("wms_proj", this_layer["proj"])
   width = 384   # using larger source size to rescale better in python
   height = 384
   local = config.tiles_cache + this_layer["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, x/1024, x, y/1024,y)
   tile_bbox = "bbox=%s,%s,%s,%s" % tuple( projections.from4326(projections.bbox_by_tile(z,x,y,req_proj),req_proj))

   wms += tile_bbox + "&width=%s&height=%s&srs=%s"%(width, height, req_proj)
   if this_layer.get("cached", True):
    if not os.path.exists("/".join(local.split("/")[:-1])):
        os.makedirs("/".join(local.split("/")[:-1]))
    try:
      os.mkdir(local+"lock")
    except OSError:
      for i in range(20):
        time.sleep(0.1)
        try:
          if not os.path.exists(local+"lock"):
            im = Image.open(local + this_layer["ext"])
            return im
        except (IOError, OSError):
          return None
   im = Image.open(StringIO.StringIO(urllib2.urlopen(wms).read()))
   if width is not 256 and height is not 256:
    im = im.resize((256,256),Image.ANTIALIAS)
   im = im.convert("RGBA")
   
   if this_layer.get("cached", True):
    ic = Image.new("RGBA", (256, 256), this_layer.get("empty_color", config.default_background)  )
    if im.histogram() == ic.histogram():
       tne = open (local+"tne", "wb")
       when = time.localtime()
       tne.write("%02d.%02d.%04d %02d:%02d:%02d"%(when[2],when[1],when[0],when[3],when[4],when[5]))
       tne.close()
       return False
    im.save(local+this_layer["ext"])
    os.rmdir(local+"lock")
   return im
Пример #6
0
    def ConstructTileUrl (self, x, y):
        if self.server_api == "tms":
            url = self.server_url
            url = url.replace("{zoom}", str(self.zoom))
            url = url.replace("{x}", str(x))
            url = url.replace("{y}", str(y))
            url = url.replace("{-y}", str((1 << self.zoom) - 1 - y))

            sw1 = "{switch:"
            sw2 = url.find(sw1)
            if sw2 != -1:
                sw3 = url.find("}", sw2)
                if sw3 != -1:
                    sw4 = url[sw2 : sw3 + 1]
                    sw5 = url[sw2 + len(sw1) : sw3]
                    sw6 = random.choice(sw5.split(","))
                    url = url.replace(sw4, sw6)

            return url
        elif self.server_api == "wms":
            a, b, c, d = projections.from4326(projections.bbox_by_tile(self.zoom, x, y, self.proj), self.proj)
            return self.server_url + "width=%s&height=%s&srs=%s&bbox=%s,%s,%s,%s" % (self.tile_width, self.tile_height, self.proj, a, b, c, d)
        else:
            return self.server_url.replace("{quadkey}", self.ConstructQuadkey(x, y))
Пример #7
0
 def ConstructTileUrl (self, x, y):
   if self.tile_mode == "WMS":
    a,b,c,d = projections.from4326(projections.bbox_by_tile(self.zoom, x, y, self.proj), self.proj)
    return self.wms_url + "width=%s&height=%s&srs=%s&bbox=%s,%s,%s,%s" % (self.tile_width, self.tile_height, self.proj, a,b,c,d)
   else:
    return self.wms_url + "z=%s&x=%s&y=%s&width=%s&height=%s" % (self.zoom-1, x, y, self.tile_width, self.tile_height)
Пример #8
0
 def ConstructTileUrl (self, x, y):
     a, b, c, d = projections.from4326(projections.bbox_by_tile(self.zoom, x, y, self.proj), self.proj)
     return self.wms_url + "width=%s&height=%s&srs=%s&bbox=%s,%s,%s,%s" % (self.tile_width, self.tile_height, self.proj, a, b, c, d)
Пример #9
0
def twms_main(data):
    """
    Do main TWMS work. 
    data - dictionary of params. 
    returns (error_code, content_type, resp)
    """

    start_time = datetime.datetime.now()

    content_type = "text/html"
    resp = ""
    srs = data.get("srs", "EPSG:4326")
    gpx = data.get("gpx", "").split(",")
    if gpx == ['']:
        gpx = []
    wkt = data.get("wkt", "")
    trackblend = float(data.get("trackblend", "0.5"))
    color = data.get("color", data.get("colour", "")).split(",")
    track = False
    tracks = []
    if len(gpx) == 0:
        req_bbox = projections.from4326(
            (27.6518898, 53.8683186, 27.6581944, 53.8720359), srs)
    else:
        for g in gpx:
            local_gpx = config.gpx_cache + "%s.gpx" % g
            if not os.path.exists(config.gpx_cache):
                os.makedirs(config.gpx_cache)
            if not os.path.exists(local_gpx):
                urllib.urlretrieve(
                    "http://www.openstreetmap.org/trace/%s/data" % g,
                    local_gpx)
            if not track:
                track = GPXParser(local_gpx)
                req_bbox = projections.from4326(track.bbox, srs)
            else:
                track = GPXParser(local_gpx)
                req_bbox = bbox.add(req_bbox,
                                    projections.from4326(track.bbox, srs))
            tracks.append(track)

    req_type = data.get("request", "GetMap")
    version = data.get("version", "1.1.1")
    ref = data.get("ref", config.service_url)
    if req_type == "GetCapabilities":
        content_type, resp = capabilities.get(version, ref)
        return (OK, content_type, resp)

    layer = data.get("layers", config.default_layers).split(",")
    if ("layers" in data) and not layer[0]:
        layer = ["transparent"]

    if req_type == "GetCorrections":
        points = data.get("points", data.get("POINTS", "")).split("=")
        resp = ""
        points = [a.split(",") for a in points]
        points = [(float(a[0]), float(a[1])) for a in points]

        req.content_type = "text/plain"
        for lay in layer:
            for point in points:
                resp += "%s,%s;" % tuple(
                    correctify.rectify(config.layers[lay], point))
            resp += "\n"
        return (OK, content_type, resp)

    force = data.get("force", "")
    if force != "":
        force = force.split(",")
    force = tuple(force)

    filt = data.get("filt", "")
    if filt != "":
        filt = filt.split(",")
    filt = tuple(filt)

    if layer == [""]:
        content_type = "text/html"
        resp = overview.html(ref)
        return (OK, content_type, resp)

    format = data.get("format", config.default_format).lower()
    format = formats.get("image/" + format, format)
    format = formats.get(format, format)
    if format not in formats.values():
        return (ERROR, content_type, "Invalid format")
    content_type = mimetypes[format]

    width = 0
    height = 0
    resp_cache_path, resp_ext = "", ""
    if req_type == "GetTile":
        width = 256
        height = 256
        height = int(data.get("height", height))
        width = int(data.get("width", width))
        srs = data.get("srs", "EPSG:3857")
        x = int(data.get("x", 0))
        y = int(data.get("y", 0))
        z = int(data.get("z", 1)) + 1
        if "cache_tile_responses" in dir(config) and not wkt and (len(gpx)
                                                                  == 0):
            if (srs, tuple(layer), filt, width, height, force,
                    format) in config.cache_tile_responses:

                resp_cache_path, resp_ext = config.cache_tile_responses[(
                    srs, tuple(layer), filt, width, height, force, format)]
                resp_cache_path = resp_cache_path + "/%s/%s/%s.%s" % (
                    z - 1, x, y, resp_ext)
                if os.path.exists(resp_cache_path):
                    return (OK, content_type, open(resp_cache_path,
                                                   "r").read())
        if len(layer) == 1:
            if layer[0] in config.layers:
                if config.layers[layer[0]][
                        "proj"] == srs and width is 256 and height is 256 and not filt and not force and not correctify.has_corrections(
                            config.layers[layer[0]]):
                    local = config.tiles_cache + config.layers[
                        layer[0]]["prefix"] + "/z%s/%s/x%s/%s/y%s." % (
                            z, x / 1024, x, y / 1024, y)
                    ext = config.layers[layer]["ext"]
                    adds = ["", "ups."]
                    for add in adds:
                        if os.path.exists(local + add + ext):
                            tile_file = open(local + add + ext, "r")
                            resp = tile_file.read()
                            return (OK, content_type, resp)
        req_bbox = projections.from4326(projections.bbox_by_tile(z, x, y, srs),
                                        srs)

    if data.get("bbox", None):
        req_bbox = tuple(map(float, data.get("bbox", req_bbox).split(",")))

    req_bbox = projections.to4326(req_bbox, srs)

    req_bbox, flip_h = bbox.normalize(req_bbox)
    box = req_bbox
    #print(req_bbox, file=sys.stderr)
    #sys.stderr.flush()

    height = int(data.get("height", height))
    width = int(data.get("width", width))
    width = min(width, config.max_width)
    height = min(height, config.max_height)
    if (width == 0) and (height == 0):
        width = 350

# layer = layer.split(",")

    imgs = 1.
    ll = layer.pop(0)
    if ll[-2:] == "!c":
        ll = ll[:-2]
        if wkt:
            wkt = "," + wkt
        wkt = correctify.corr_wkt(config.layers[ll]) + wkt
        srs = config.layers[ll]["proj"]
    try:
        result_img = getimg(box, srs, (height, width), config.layers[ll],
                            start_time, force)
    except KeyError:
        result_img = Image.new("RGBA", (width, height))

    #width, height =  result_img.size
    for ll in layer:
        if ll[-2:] == "!c":
            ll = ll[:-2]
            if wkt:
                wkt = "," + wkt
            wkt = correctify.corr_wkt(config.layers[ll]) + wkt
            srs = config.layers[ll]["proj"]

        im2 = getimg(box, srs, (height, width), config.layers[ll], start_time,
                     force)

        if "empty_color" in config.layers[ll]:
            ec = ImageColor.getcolor(config.layers[ll]["empty_color"], "RGBA")
            sec = set(ec)
            if "empty_color_delta" in config.layers[ll]:
                delta = config.layers[ll]["empty_color_delta"]
                for tr in range(-delta, delta):
                    for tg in range(-delta, delta):
                        for tb in range(-delta, delta):
                            if (ec[0] + tr) >= 0 and (ec[0] + tr) < 256 and (
                                    ec[1] + tr
                            ) >= 0 and (ec[1] + tr) < 256 and (
                                    ec[2] + tr) >= 0 and (ec[2] + tr) < 256:
                                sec.add((ec[0] + tr, ec[1] + tg, ec[2] + tb,
                                         ec[3]))
            i2l = im2.load()
            for x in range(0, im2.size[0]):
                for y in range(0, im2.size[1]):
                    t = i2l[x, y]
                    if t in sec:
                        i2l[x, y] = (t[0], t[1], t[2], 0)
        if not im2.size == result_img.size:
            im2 = im2.resize(result_img.size, Image.ANTIALIAS)
        im2 = Image.composite(im2, result_img,
                              im2.split()[3])  # imgs/(imgs+1.))

        if "noblend" in force:
            result_img = im2
        else:
            result_img = Image.blend(im2, result_img, 0.5)
        imgs += 1.

    ##Applying filters
    result_img = filter.raster(result_img, filt, req_bbox, srs)

    #print(wkt, file=sys.stderr)
    #sys.stderr.flush()
    if wkt:
        result_img = drawing.wkt(wkt, result_img, req_bbox, srs,
                                 color if len(color) > 0 else None, trackblend)
    if len(gpx) > 0:
        last_color = None
        c = iter(color)
        for track in tracks:
            try:
                last_color = c.next()
            except StopIteration:
                pass
            result_img = drawing.gpx(track, result_img, req_bbox, srs,
                                     last_color, trackblend)

    if flip_h:
        result_img = ImageOps.flip(result_img)
    image_content = BytesIO()

    if format == "JPEG":
        try:
            result_img.save(image_content,
                            format,
                            quality=config.output_quality,
                            progressive=config.output_progressive)
        except IOError:
            result_img.save(image_content,
                            format,
                            quality=config.output_quality)
    elif format == "PNG":
        result_img.save(image_content,
                        format,
                        progressive=config.output_progressive,
                        optimize=config.output_optimize)
    elif format == "GIF":
        result_img.save(image_content,
                        format,
                        quality=config.output_quality,
                        progressive=config.output_progressive)
    else:  ## workaround for GIF
        result_img = result_img.convert("RGB")
        result_img.save(image_content,
                        format,
                        quality=config.output_quality,
                        progressive=config.output_progressive)
    resp = image_content.getvalue()
    if resp_cache_path:
        try:
            "trying to create local cache directory, if it doesn't exist"
            os.makedirs("/".join(resp_cache_path.split("/")[:-1]))
        except OSError:
            pass
        try:
            a = open(resp_cache_path, "w")
            a.write(resp)
            a.close()
        except (OSError, IOError):
            print("error saving response answer to file %s." %
                  (resp_cache_path),
                  file=sys.stderr)
            sys.stderr.flush()

    return (OK, content_type, resp)
Пример #10
0
def tile_image(layer,
               z,
               x,
               y,
               start_time,
               again=False,
               trybetter=True,
               real=False):
    """
   Returns asked image.
   again - is this a second pass on this tile?
   trybetter - should we try to combine this tile from better ones?
   real - should we return the tile even in not good quality?
   """
    x = x % (2**(z - 1))
    if y < 0 or y >= (2**(z - 1)):
        return None
    if not bbox.bbox_is_in(projections.bbox_by_tile(z, x, y, layer["proj"]),
                           layer.get("data_bounding_box", config.default_bbox),
                           fully=False):
        return None
    global cached_objs, cached_hist_list
    if "prefix" in layer:
        if (layer["prefix"], z, x, y) in cached_objs:
            return cached_objs[(layer["prefix"], z, x, y)]
    if layer.get("cached", True):
        local = config.tiles_cache + layer[
            "prefix"] + "/z%s/%s/x%s/%s/y%s." % (z, x / 1024, x, y / 1024, y)
        ext = layer["ext"]
        if "cache_ttl" in layer:
            for ex in [ext, "dsc." + ext, "ups." + ext, "tne"]:
                f = local + ex
                if os.path.exists(f):
                    if (os.stat(f).st_mtime <
                        (time.time() - layer["cache_ttl"])):
                        os.remove(f)

        gpt_image = False
        try:
            "trying to create local cache directory, if it doesn't exist"
            os.makedirs("/".join(local.split("/")[:-1]))
        except OSError:
            pass
        if not os.path.exists(local + "tne") and not os.path.exists(local +
                                                                    "lock"):
            if os.path.exists(local + ext):  # First, look for tile in cache
                try:
                    im1 = Image.open(local + ext)
                    im1.is_ok = True
                    return im1
                except IOError:
                    if os.path.exists(local + "lock"):
                        return None
                    else:
                        os.remove(local +
                                  ext)  # # Cached tile is broken - remove it

            if layer["scalable"] and (
                    z < layer.get("max_zoom", config.default_max_zoom)
            ) and trybetter:  # Second, try to glue image of better ones
                if os.path.exists(local + "ups." + ext):
                    try:
                        im = Image.open(local + "ups." + ext)
                        im.is_ok = True
                        return im
                    except IOError:
                        pass
                ec = ImageColor.getcolor(
                    layer.get("empty_color", config.default_background),
                    "RGBA")
                ec = (ec[0], ec[1], ec[2], 0)
                im = Image.new("RGBA", (512, 512), ec)
                im1 = tile_image(layer, z + 1, x * 2, y * 2, start_time)
                if im1:
                    im2 = tile_image(layer, z + 1, x * 2 + 1, y * 2,
                                     start_time)
                    if im2:
                        im3 = tile_image(layer, z + 1, x * 2, y * 2 + 1,
                                         start_time)
                        if im3:
                            im4 = tile_image(layer, z + 1, x * 2 + 1,
                                             y * 2 + 1, start_time)
                            if im4:
                                im.paste(im1, (0, 0))
                                im.paste(im2, (256, 0))
                                im.paste(im3, (0, 256))
                                im.paste(im4, (256, 256))
                                im = im.resize((256, 256), Image.ANTIALIAS)
                                if layer.get("cached", True):
                                    try:
                                        im.save(local + "ups." + ext)
                                    except IOError:
                                        pass
                                im.is_ok = True
                                return im
            if not again:
                if "fetch" in layer:
                    delta = (datetime.datetime.now() - start_time)
                    delta = delta.seconds + delta.microseconds / 1000000.
                    if (config.deadline > delta) or (z < 4):
                        im = fetchers.fetch(z, x, y,
                                            layer)  # Try fetching from outside
                        if im:
                            im.is_ok = True
                            return im
        if real and (z > 1):
            im = tile_image(layer,
                            z - 1,
                            int(x / 2),
                            int(y / 2),
                            start_time,
                            again=False,
                            trybetter=False,
                            real=True)
            if im:
                im = im.crop((128 * (x % 2), 128 * (y % 2),
                              128 * (x % 2) + 128, 128 * (y % 2) + 128))
                im = im.resize((256, 256), Image.BILINEAR)
                im.is_ok = False
                return im
    else:
        if "fetch" in layer:
            delta = (datetime.datetime.now() - start_time)
            delta = delta.seconds + delta.microseconds / 1000000.
            if (config.deadline > delta) or (z < 4):
                im = fetchers.fetch(z, x, y,
                                    layer)  # Try fetching from outside
                if im:
                    im.is_ok = True
                    return im
Пример #11
0
def twms_main(data):
    """
    Do main TWMS work. 
    data - dictionary of params. 
    returns (error_code, content_type, resp)
    """

    start_time = datetime.datetime.now()

    content_type = "text/html"
    resp = ""
    srs = data.get("srs", "EPSG:4326")
    gpx = data.get("gpx","").split(",")
    wkt = data.get("wkt","")
    trackblend = float(data.get("trackblend","0.5"))
    color = data.get("color",data.get("colour","")).split(",")
    track = False
    tracks = []
    if len(gpx) == 0:
      req_bbox = projections.from4326((27.6518898,53.8683186,27.6581944,53.8720359), srs)
    else:
      for g in gpx:
        local_gpx = config.gpx_cache + "%s.gpx" % g
        if not os.path.exists (config.gpx_cache):
          os.makedirs(config.gpx_cache)
        if not os.path.exists (local_gpx):
            urllib.urlretrieve ("http://www.openstreetmap.org/trace/%s/data" % g, local_gpx)
        if not track:
          track = GPXParser(local_gpx)
          req_bbox = projections.from4326(track.bbox, srs)
        else:
          track = GPXParser(local_gpx)
          req_bbox = bbox.add(req_bbox, projections.from4326(track.bbox, srs))
        tracks.append(track)

    req_type = data.get("request","GetMap")
    version = data.get("version","1.1.1")
    ref = data.get("ref",config.service_url)
    if req_type == "GetCapabilities":
     content_type, resp = capabilities.get(version, ref)
     return (OK, content_type, resp)

    layer = data.get("layers",config.default_layers).split(",")
    if ("layers" in data) and not layer[0]:
      layer = ["transparent"]

    if req_type == "GetCorrections":
       points = data.get("points",data.get("POINTS", "")).split("=")
       resp = ""
       points = [a.split(",") for a in points]
       points = [(float(a[0]), float(a[1])) for a in points]

       req.content_type = "text/plain"
       for lay in layer:
         for point in points:
           resp += "%s,%s;"% tuple(correctify.rectify(config.layers[lay], point))
         resp += "\n"
       return (OK, content_type, resp)


    force = tuple(data.get("force","").split(","))
    filt  = tuple(data.get("filter","").split(","))
    if layer == [""] :
      content_type = "text/html"
      resp = overview.html(ref)
      return (OK, content_type, resp)

    format = data.get("format", config.default_format).lower()
    format = formats.get("image/" + format, format)
    format = formats.get(format, format)
    if format not in formats.values():
       return (ERROR, content_type, "Invalid format")
    content_type = mimetypes[format]

    width=0
    height=0
    resp_cache_path, resp_ext = "",""
    if req_type == "GetTile":
      width=256
      height=256
      height = int(data.get("height",height))
      width = int(data.get("width",width))
      srs = data.get("srs", "EPSG:3857")
      x = int(data.get("x",0))
      y = int(data.get("y",0))
      z = int(data.get("z",1)) + 1
      if "cache_tile_responses" in dir(config) and not wkt and (len(gpx) == 0):
        if (srs, tuple(layer), filt, width, height, force, format) in config.cache_tile_responses:

          resp_cache_path, resp_ext = config.cache_tile_responses[(srs, tuple(layer), filt, width, height, force, format)]
          resp_cache_path = resp_cache_path+"/%s/%s/%s.%s"%(z-1,x,y,resp_ext)
          if os.path.exists(resp_cache_path):
            return (OK, content_type, open(resp_cache_path, "r").read())
      if len(layer) == 1:
       if layer[0] in config.layers:
        if config.layers[layer[0]]["proj"] == srs and width is 256 and height is 256 and not filt and not force and not correctify.has_corrections(layer[0]):
          local = config.tiles_cache + config.layers[layer[0]]["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, x/1024, x, y/1024,y)
          ext = config.layers[layer]["ext"]
          adds = ["","ups."]
          for add in adds:
           if os.path.exists(local+add+ext):
             tile_file = open(local+add+ext, "r")
             resp = tile_file.read()
             return (OK, content_type, resp)
      req_bbox = projections.from4326(projections.bbox_by_tile(z,x,y,srs),srs)

    if data.get("bbox",None):
      req_bbox = tuple(map(float,data.get("bbox",req_bbox).split(",")))

    req_bbox = projections.to4326(req_bbox, srs)

    req_bbox, flip_h = bbox.normalize(req_bbox)
    box = req_bbox
    #print >> sys.stderr, req_bbox
    #sys.stderr.flush()

    height = int(data.get("height",height))
    width = int(data.get("width",width))
    width = min(width, config.max_width)
    height = min(height, config.max_height)
    if (width == 0) and (height == 0):
      width = 350


   # layer = layer.split(",")

    imgs = 1.
    ll = layer.pop(0)
    if ll[-2:] == "!c":
      ll = ll[:-2]
      if wkt:
        wkt = ","+wkt
      wkt = correctify.corr_wkt(config.layers[ll]) + wkt
      srs = config.layers[ll]["proj"]
    try:
      result_img = getimg(box,srs, (height, width), config.layers[ll], start_time, force)
    except KeyError:
      result_img = Image.new("RGBA", (width,height))


    #width, height =  result_img.size
    for ll in layer:
     if ll[-2:] == "!c":
       ll = ll[:-2]
       if wkt:
         wkt = ","+wkt
       wkt = correctify.corr_wkt(config.layers[ll]) + wkt
       srs = config.layers[ll]["proj"]

     im2 = getimg(box, srs,(height, width), config.layers[ll],  start_time, force)

     if "empty_color" in config.layers[ll]:
      ec = ImageColor.getcolor(config.layers[ll]["empty_color"], "RGBA")
      sec = set(ec)
      if "empty_color_delta" in config.layers[ll]:
        delta = config.layers[ll]["empty_color_delta"]
        for tr in range(-delta, delta):
          for tg in range(-delta, delta):
            for tb in range(-delta, delta):
              if (ec[0]+tr) >= 0  and (ec[0]+tr) < 256 and (ec[1]+tr) >= 0  and (ec[1]+tr) < 256 and(ec[2]+tr) >= 0  and (ec[2]+tr) < 256:
                sec.add((ec[0]+tr,ec[1]+tg,ec[2]+tb,ec[3]))
      i2l = im2.load()
      for x in range(0,im2.size[0]):
        for y in range(0,im2.size[1]):
          t = i2l[x,y]
          if t in sec:
            i2l[x,y] = (t[0],t[1],t[2],0)
     if not im2.size == result_img.size:
         im2 = im2.resize(result_img.size, Image.ANTIALIAS)
     im2 = Image.composite(im2,result_img, im2.split()[3]) # imgs/(imgs+1.))

     if "noblend" in force:
      result_img = im2
     else:
      result_img = Image.blend(im2, result_img, 0.5)
     imgs += 1.

    ##Applying filters
    result_img = filter.raster(result_img, filt, req_bbox, srs)

    #print >> sys.stderr, wkt
    #sys.stderr.flush()
    if wkt:
      result_img = drawing.wkt(wkt, result_img, req_bbox, srs, color if len(color) > 0 else None, trackblend)
    if len(gpx) > 0:
      last_color = None
      c = iter(color)
      for track in tracks:
        try:
          last_color = c.next();
        except StopIteration:
          pass
        result_img = drawing.gpx(track, result_img, req_bbox, srs, last_color, trackblend)

    if flip_h:
      result_img = ImageOps.flip(result_img)
    image_content = StringIO.StringIO()

    if format == "JPEG":
       try:
        result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive)
       except IOError:
        result_img.save(image_content, format, quality=config.output_quality)
    elif format == "PNG":
       result_img.save(image_content, format, progressive=config.output_progressive, optimize =config.output_optimize)
    elif format == "GIF":
       result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive)
    else:       ## workaround for GIF
       result_img = result_img.convert("RGB")
       result_img.save(image_content, format, quality=config.output_quality, progressive=config.output_progressive)
    resp = image_content.getvalue()
    if resp_cache_path:
      try:
        "trying to create local cache directory, if it doesn't exist"
        os.makedirs("/".join(resp_cache_path.split("/")[:-1]))
      except OSError:
         pass
      try:
        a = open(resp_cache_path, "w")
        a.write(resp)
        a.close()
      except (OSError, IOError):
        print >> sys.stderr, "error saving response answer to file %s." % (resp_cache_path)
        sys.stderr.flush()

    return (OK, content_type, resp)
Пример #12
0
def tile_image (layer, z, x, y, start_time, again=False, trybetter = True, real = False):
   """
   Returns asked image.
   again - is this a second pass on this tile?
   trybetter - should we try to combine this tile from better ones?
   real - should we return the tile even in not good quality?
   """
   x = x % (2 ** (z-1))
   if y<0 or y >= (2 ** (z-1)):
     return None
   if not bbox.bbox_is_in(projections.bbox_by_tile(z,x,y,layer["proj"]), layer.get("data_bounding_box",config.default_bbox), fully=False):
     return None
   global cached_objs, cached_hist_list
   if "prefix" in layer:
     if (layer["prefix"], z, x, y) in cached_objs:
      return cached_objs[(layer["prefix"], z, x, y)]
   if layer.get("cached", True):
    local = config.tiles_cache + layer["prefix"] + "/z%s/%s/x%s/%s/y%s."%(z, x/1024, x, y/1024,y)
    ext = layer["ext"]
    if "cache_ttl" in layer:
      for ex in [ext, "dsc."+ext, "ups."+ext, "tne"]:
       f = local+ex
       if os.path.exists(f):
         if (os.stat(f).st_mtime < (time.time()-layer["cache_ttl"])):
           os.remove(f)

    gpt_image = False
    try:
      "trying to create local cache directory, if it doesn't exist"
      os.makedirs("/".join(local.split("/")[:-1]))
    except OSError:
      pass
    if not os.path.exists(local+"tne") and not os.path.exists(local+"lock"):
      if os.path.exists(local+ext):                     # First, look for tile in cache
        try:
            im1 = Image.open(local+ext)
            im1.is_ok = True
            return im1
        except IOError:
          if os.path.exists(local+"lock"):
            return None
          else:
            os.remove(local+ext)                                # # Cached tile is broken - remove it


      if layer["scalable"] and (z<layer.get("max_zoom", config.default_max_zoom)) and trybetter:      # Second, try to glue image of better ones
          if os.path.exists(local+"ups."+ext):
              try:
                  im = Image.open(local+"ups."+ext)
                  im.is_ok = True
                  return im
              except IOError:
                  pass
          ec = ImageColor.getcolor(layer.get("empty_color", config.default_background), "RGBA")
          ec = (ec[0],ec[1],ec[2],0)
          im = Image.new("RGBA", (512, 512), ec)
          im1 = tile_image(layer, z+1,x*2,y*2, start_time)
          if im1:
           im2 = tile_image(layer, z+1,x*2+1,y*2, start_time)
           if im2:
            im3 = tile_image(layer, z+1,x*2,y*2+1, start_time)
            if im3:
              im4 = tile_image(layer, z+1,x*2+1,y*2+1, start_time)
              if im4:
                im.paste(im1,(0,0))
                im.paste(im2,(256,0))
                im.paste(im3,(0,256))
                im.paste(im4,(256,256))
                im = im.resize((256,256),Image.ANTIALIAS)
                if layer.get("cached", True):
                  try:
                    im.save(local+"ups."+ext)
                  except IOError:
                    pass
                im.is_ok = True
                return im
      if not again:
        if "fetch" in layer:
          delta = (datetime.datetime.now() - start_time)
          delta = delta.seconds + delta.microseconds/1000000.
          if (config.deadline > delta) or (z < 4):
            im = fetchers.fetch(z,x,y,layer)    # Try fetching from outside
            if im:
              im.is_ok = True
              return im
    if real and (z>1):
          im = tile_image(layer, z-1, int(x/2), int(y/2), start_time,  again=False, trybetter=False, real=True)
          if im:
            im = im.crop((128 * (x % 2), 128 * (y % 2), 128 * (x % 2) + 128, 128 * (y % 2) + 128))
            im = im.resize((256,256), Image.BILINEAR)
            im.is_ok = False
            return im
   else:
      if "fetch" in layer:
          delta = (datetime.datetime.now() - start_time)
          delta = delta.seconds + delta.microseconds/1000000.
          if (config.deadline > delta) or (z < 4):
            im = fetchers.fetch(z,x,y,layer)    # Try fetching from outside
            if im:
              im.is_ok = True
              return im