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
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))
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)
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
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
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))
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)
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)
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)
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
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)
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