Exemple #1
0
    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)
Exemple #6
0
    #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)