def process(self, tile): #from lat,lng bbox to mapnik bbox p0 = self.map_proj.forward(Coord(tile.bbox[0][1],tile.bbox[0][0])) p1 = self.map_proj.forward(Coord(tile.bbox[1][1],tile.bbox[1][0])) bbox = Box2d(p0,p1) image = Image(tile.size[0],tile.size[1]) features = None result = self._check_region(bbox) if result is not None: if result[0]: result[1].resize(image.width(),image.height()) result[1].zoom_to_box(bbox) self.adjust_language(result(1), tile.lang) render(result[1],image) features = self.save_rendered_metadata(result[1], tile.size, tile.dimensions) else : mq_logging.info("COMPOSITE MAP: %s" % result[2]) default_image = Image(tile.size[0],tile.size[1]) # mask style self.mask_map.resize(image.width(),image.height()) self.mask_map.zoom_to_box(bbox) self.adjust_language(self.mask_map, tile.lang) render(self.mask_map,image) # default style self.default_map.resize(default_image.width(),default_image.height()) self.default_map.zoom_to_box(bbox) self.adjust_language(self.default_map, tile.lang) render(self.default_map,default_image) features = self.save_rendered_metadata(self.default_map, tile.size, tile.dimensions) # composite DST_OUT default_image.composite(image,CompositeOp.dst_out) # current style result[1].resize(image.width(),image.height()) result[1].zoom_to_box(bbox) image.set_alpha(0) self.adjust_language(result[1], tile.lang) render(result[1],image) if features is not None: features.features.extend(self.save_rendered_metadata(result[1], tile.size, tile.dimensions).features) else: features = self.save_rendered_metadata(result[1], tile.size, tile.dimensions) # blend image.blend(0,0,default_image,1.0) else : # use default style self.default_map.resize(image.width(),image.height()) self.default_map.zoom_to_box(bbox) self.adjust_language(self.default_map, tile.lang) render(self.default_map,image) features = self.save_rendered_metadata(self.default_map, tile.size, tile.dimensions) #convert to PIL image image = PIL.Image.frombuffer('RGBA', (image.width(), image.height()), image.tostring(), 'raw', 'RGBA', 0, 3) return RenderResult.from_image(tile, image, features)
def watch(self): try: signal.signal(signal.SIGTERM, handler) os.wait() except KeyboardInterrupt: mq_logging.info('KeyBoardInterrupt') self.kill() sys.exit()
def __init__(self, config, formats, format_args, storage): self.renderers = {} # the config file gives the names of all the styles, separated by # commas, in the [worker] section. each of these styles is then # expected to be a section name, naming the style. this is what # the job is matched against when it comes in. one style name is # one renderer. style_names = csv.reader([config.get('worker', 'styles')],skipinitialspace=True).next() # the styles which will be saved to storage when they are done. # note that it's possible for stuff to not be saved to storage # and this might be reasonable when the work involved in making # that tile is very low. save_names = csv.reader([config.get('worker', 'saved_styles')],skipinitialspace=True).next() # read only styles try: read_only_names = csv.reader([config.get('worker', 'read_only_styles')],skipinitialspace=True).next() except: read_only_names = [] for style_name in style_names: mq_logging.info("Loading '%s' style" % style_name) try : # sanity check - there's no real problem with styles being # defined twice, but it probably indicates a typo or other # error in the config file. if style_name in self.renderers: raise Exception("style '%s' is defined twice." % style_name) # if the style is only to be read from storage if style_name in read_only_names: renderer = StorageRenderer(storage, formats[style_name], format_args, None) else: renderer = self._create(config, style_name, storage, formats, format_args) # if the style name is in the formats config then it's supposed # to be saved to storage. so wrap the renderer in a saving # renderer. if (renderer is not None) and (style_name in save_names): renderer = StorageRenderer(storage, formats[style_name], format_args, renderer) if renderer is None: raise Exception("unable to create renderer from style '%s'." % style_name) self.renderers[style_name] = renderer except Exception as ex: mq_logging.error("failed to load worker configuration for '%s' from: %s (%s)" % (style_name,config, str(ex))) sys.exit(1)
def process(self, tile): #get the list of coverages per tile, and the set of them removing duplicates coverages, uniqueCoverages = self.coverageChecker.checkSubTiles(tile, True) #how many different styles do these coverages map to? # note - have to lowercase and check the coverage names here, or they'll be # missed out or potentially cause a KeyError at runtime. sanitisedNames = [] for coverage in uniqueCoverages: if coverage is not None and coverage.lower() in self.coverages: sanitisedNames.append(coverage.lower()) else: sanitisedNames.append('default') mixedCoverage = len(set([self.coverages[coverage] for coverage in sanitisedNames])) > 1 if mixedCoverage == True: mq_logging.info("Mixed coverage %s for style '%s' at metatile z=%s x=%s y=%s." % (uniqueCoverages, tile.style, tile.z, tile.x, tile.y)) renderers = self._update_coverages(coverages, mixedCoverage, tile) if mixedCoverage is True: #TODO: do these in parallel, especially since the mapware one is done on a remote machine results = [] for renderer in renderers: result = renderer.process(tile) if result is not None: results.append(result) else: results = [] break ret = self._combine(results, coverages) if len(results) > 0 else None else: ret = renderers[0].process(tile) if ret is None: raise "no image rendered for coverage(s) %s" % coverages else: return ret
#worker run loop job_counter = 0 while True: try: job = queue.get_job() except RuntimeError, e: error_message = e.message if error_message.lower().find ("deadlock") == -1: raise else: mq_logging.error("deadlock error get_job: %s" % error_message) continue mq_logging.info("Got task: %s %s %s '%s' id=%d" % (job.z,job.x,job.y,job.style,job.id)) try: img_formats = formats[job.style] #convert the job into a tile for the renderer tile = Tile(job, projection) # find out which renderer we are supposed to be using renderer = renderers.renderer_for(job.style) if renderer is None: raise Exception("Request for renderer `%s', which is not configured." % job.style) except Exception as ex: mq_logging.error("Couldn't fulfill request for z=%s x=%s y=%s style='%s', sending ignore. Error: %s." % (job.z, job.x, job.y, job.style, str(ex))) job.status = dqueue.ProtoCommand.cmdIgnore notify(job, queue)
#worker run loop job_counter = 0 while True: try: job = queue.get_job() except RuntimeError, e: error_message = e.message if error_message.lower().find ("deadlock") == -1: raise else: mq_logging.error("deadlock error get_job: %s" % error_message) continue mq_logging.info("Got task: " + dumptile(job)) try: img_formats = formats[job.style] #convert the job into a tile for the renderer tile = Tile(job, projection) # find out which renderer we are supposed to be using renderer = renderers.renderer_for(job.style) if renderer is None: raise Exception("Request for renderer `%s', which is not configured." % job.style) except Exception as ex: mq_logging.error("Couldn't fulfill request for %s, sending ignore. Error: %s." % (dumptile(job), str(ex))) job.status = dqueue.ProtoCommand.cmdIgnore notify(job, queue)