コード例 #1
0
ファイル: common.py プロジェクト: craigds/mapnik2
 def _buildMap(self, params):
     if str(params['crs']) not in self.allowedepsgcodes:
         raise OGCException('Unsupported CRS "%s" requested.' % str(params['crs']).upper(), 'InvalidCRS')
     if params['bbox'][0] >= params['bbox'][2]:
         raise OGCException("BBOX values don't make sense.  minx is greater than maxx.")
     if params['bbox'][1] >= params['bbox'][3]:
         raise OGCException("BBOX values don't make sense.  miny is greater than maxy.")
     if params.has_key('styles') and len(params['styles']) != len(params['layers']):
         raise OGCException('STYLES length does not match LAYERS length.')
     m = Map(params['width'], params['height'], '+init=%s' % params['crs'])
     if params.has_key('transparent') and params['transparent'] == 'FALSE':
         if params['bgcolor']:
             m.background = params['bgcolor']
     else:
         m.background = Color(0, 0, 0, 0)
     maplayers = self.mapfactory.layers
     orderedmaplayers = self.mapfactory.ordered_layers
     mapstyles = self.mapfactory.styles
     mapaggregatestyles = self.mapfactory.aggregatestyles
     # a non WMS spec way of requesting all layers
     if params['layers'] and params['layers'][0] == '__all__':
         for layername in orderedmaplayers:
             layer = copy_layer(layername)
             reqstyle = layer.wmsdefaultstyle
             if reqstyle in mapaggregatestyles.keys():
                 for stylename in mapaggregatestyles[reqstyle]:
                     layer.styles.append(stylename)
             else:
                 layer.styles.append(reqstyle)
             for stylename in layer.styles:
                 if stylename in mapstyles.keys():
                     m.append_style(stylename, mapstyles[stylename])
             m.layers.append(layer)
     else:
         for layerindex, layername in enumerate(params['layers']):
             try:
                 layer = copy_layer(maplayers[layername])
             except KeyError:
                 raise OGCException('Layer "%s" not defined.' % layername, 'LayerNotDefined')
             try:
                 reqstyle = params['styles'][layerindex]
             except IndexError:
                 reqstyle = ''
             if reqstyle and reqstyle not in layer.wmsextrastyles:
                 raise OGCException('Invalid style "%s" requested for layer "%s".' % (reqstyle, layername), 'StyleNotDefined')
             if not reqstyle:
                 reqstyle = layer.wmsdefaultstyle
             if reqstyle in mapaggregatestyles.keys():
                 for stylename in mapaggregatestyles[reqstyle]:
                     layer.styles.append(stylename)
             else:
                 layer.styles.append(reqstyle)
             for stylename in layer.styles:
                 if stylename in mapstyles.keys():
                     m.append_style(stylename, mapstyles[stylename])
                 else:
                     raise ServerConfigurationError('Layer "%s" refers to non-existent style "%s".' % (layername, stylename))
             m.layers.append(layer)
     m.zoom_to_box(Box2d(params['bbox'][0], params['bbox'][1], params['bbox'][2], params['bbox'][3]))
     return m
コード例 #2
0
ファイル: common.py プロジェクト: johnewart/OGCServer
    def _buildMap(self, params):
        if str(params['crs']) not in self.allowedepsgcodes:
            raise OGCException('Unsupported CRS "%s" requested.' % str(params['crs']).upper(), 'InvalidCRS')
        if params['bbox'][0] >= params['bbox'][2]:
            raise OGCException("BBOX values don't make sense.  minx is greater than maxx.")
        if params['bbox'][1] >= params['bbox'][3]:
            raise OGCException("BBOX values don't make sense.  miny is greater than maxy.")

        # relax this for now to allow for a set of specific layers (meta layers even)
        # to be used without known their styles or putting the right # of commas...

        #if params.has_key('styles') and len(params['styles']) != len(params['layers']):
        #    raise OGCException('STYLES length does not match LAYERS length.')
        m = Map(params['width'], params['height'], '+init=%s' % params['crs'])

        if params.has_key('transparent') and params['transparent'] in ('FALSE','False','false'):
            if params['bgcolor']:
                m.background = params['bgcolor']
        elif not params.has_key('transparent') and self.mapfactory.map_attributes.get('bgcolor'):
            m.background = self.mapfactory.map_attributes['bgcolor']
        else:
            m.background = Color(0, 0, 0, 0)

        if params.has_key('buffer_size'):
            if params['buffer_size']:
                m.buffer_size = params['buffer_size']
        else:
            buffer_ = self.mapfactory.map_attributes.get('buffer_size')
            if buffer_:
                m.buffer_size = self.mapfactory.map_attributes['buffer_size']

        # haiti spec tmp hack! show meta layers without having
        # to request huge string to avoid some client truncating it!
        if params['layers'] and params['layers'][0] in ('osm_haiti_overlay','osm_haiti_overlay_900913'):
            for layer_obj in self.mapfactory.ordered_layers:
                layer = copy_layer(layer_obj)
                if not hasattr(layer,'meta_style'):
                    pass
                else:
                    layer.styles.append(layer.meta_style)
                    m.append_style(layer.meta_style, self.mapfactory.meta_styles[layer.meta_style])
                    m.layers.append(layer)        
        # a non WMS spec way of requesting all layers
        # uses orderedlayers that preserves original ordering in XML mapfile
        elif params['layers'] and params['layers'][0] == '__all__':
            for layer_obj in self.mapfactory.ordered_layers:
                # if we don't copy the layer here we get
                # duplicate layers added to the map because the
                # layer is kept around and the styles "pile up"...
                layer = copy_layer(layer_obj)
                if hasattr(layer,'meta_style'):
                    continue
                reqstyle = layer.wmsdefaultstyle
                if reqstyle in self.mapfactory.aggregatestyles.keys():
                    for stylename in self.mapfactory.aggregatestyles[reqstyle]:
                        layer.styles.append(stylename)
                else:
                    layer.styles.append(reqstyle)
                for stylename in layer.styles:
                    if stylename in self.mapfactory.styles.keys():
                        m.append_style(stylename, self.mapfactory.styles[stylename])
                m.layers.append(layer)
        else:
            for layerindex, layername in enumerate(params['layers']):
                if layername in self.mapfactory.meta_layers:
                    layer = copy_layer(self.mapfactory.meta_layers[layername])
                    layer.styles.append(layername)
                    m.append_style(layername, self.mapfactory.meta_styles[layername])
                else:
                    try:
                        # uses unordered dict of layers
                        # order based on params['layers'] request which
                        # should be originally informed by order of GetCaps response
                        layer = copy_layer(self.mapfactory.layers[layername])
                    except KeyError:
                        raise OGCException('Layer "%s" not defined.' % layername, 'LayerNotDefined')
                    try:
                        reqstyle = params['styles'][layerindex]
                    except IndexError:
                        reqstyle = ''
                    if reqstyle and reqstyle not in layer.wmsextrastyles:
                        raise OGCException('Invalid style "%s" requested for layer "%s".' % (reqstyle, layername), 'StyleNotDefined')
                    if not reqstyle:
                        reqstyle = layer.wmsdefaultstyle
                    if reqstyle in self.mapfactory.aggregatestyles.keys():
                        for stylename in self.mapfactory.aggregatestyles[reqstyle]:
                            layer.styles.append(stylename)
                    else:
                        layer.styles.append(reqstyle)

                    for stylename in layer.styles:
                        if stylename in self.mapfactory.styles.keys():
                            m.append_style(stylename, self.mapfactory.styles[stylename])
                        else:
                            raise ServerConfigurationError('Layer "%s" refers to non-existent style "%s".' % (layername, stylename))
                
                m.layers.append(layer)
        m.zoom_to_box(Envelope(params['bbox'][0], params['bbox'][1], params['bbox'][2], params['bbox'][3]))
        return m
コード例 #3
0
ファイル: mapnik.py プロジェクト: abta/MapQuest-Render-Stack
class Renderer :
    
    def __init__(self, map_style, mask_style):
        self.default_map = Map(0,0)

        # only load the mask style if it's provided
        if mask_style is None:
            self.mask_map = None
        else:
            self.mask_map = Map(0,0)

        self.proj = Mercator(18+1)
        self.regions = []
        try :
            load_map(self.default_map, map_style)
            
            # masks may not be provided if it's a single style
            if self.mask_map is not None:
                load_map(self.mask_map, mask_style)

            self.map_proj = Projection(self.default_map.srs)
        except:
            mq_logging.error("Exception caught in Renderer ctor")
            raise
        
    def add_region(self,name,mapfile,wkt_mask_file):
        # ignore attempts to add regions when no mask has been
        # specified with a warning.
        if self.mask_map is not None:
            try:
                m = Map(0,0)
                load_map(m, mapfile)
                mask = Mask(wkt_mask_file)
                self.regions.append((name,m,mask))
            except Exception as ex:
                mq_logging.error("Exception caught adding region (%s)" % str(ex))
        else:
            mq_logging.warning("Cannot add mask (%s) because no mask_style was configured." % name)
    
    def _check_region(self, bbox):
        for r in self.regions:
            intersects,contains = r[2].relate(bbox.minx,bbox.miny,bbox.maxx,bbox.maxy)
            if intersects :
                return contains,r[1],r[0]    
        return None

    def save_rendered_metadata(self, renderer, size, dimensions):
        #save off the meta data if its there
	if renderer is not None:
	    inmem = renderer.find_inmem_metawriter("poi-meta-data")
            if inmem is not None:
       	        #get the bounding boxes and ids out of the mapnik data and save in a feature collection
                return extractFeaturesMNK(inmem)    

	#no data so no feature collection
	return None

    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)
                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)
                render(self.mask_map,image)
                
                # default style
                self.default_map.resize(default_image.width(),default_image.height())
                self.default_map.zoom_to_box(bbox)
                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)
                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)
            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)
コード例 #4
0
    def _buildMap(self, params):
        if str(params['crs']) not in self.allowedepsgcodes:
            raise OGCException(
                'Unsupported CRS "%s" requested.' % str(params['crs']).upper(),
                'InvalidCRS')
        if params['bbox'][0] >= params['bbox'][2]:
            raise OGCException(
                "BBOX values don't make sense.  minx is greater than maxx.")
        if params['bbox'][1] >= params['bbox'][3]:
            raise OGCException(
                "BBOX values don't make sense.  miny is greater than maxy.")

        # relax this for now to allow for a set of specific layers (meta layers even)
        # to be used without known their styles or putting the right # of commas...

        #if params.has_key('styles') and len(params['styles']) != len(params['layers']):
        #    raise OGCException('STYLES length does not match LAYERS length.')
        m = Map(params['width'], params['height'], '+init=%s' % params['crs'])

        if params.has_key('transparent') and params['transparent'] in (
                'FALSE', 'False', 'false'):
            if params['bgcolor']:
                m.background = params['bgcolor']
        elif not params.has_key(
                'transparent') and self.mapfactory.map_attributes.get(
                    'bgcolor'):
            m.background = self.mapfactory.map_attributes['bgcolor']
        else:
            m.background = Color(0, 0, 0, 0)

        if params.has_key('buffer_size'):
            if params['buffer_size']:
                m.buffer_size = params['buffer_size']
        else:
            buffer_ = self.mapfactory.map_attributes.get('buffer_size')
            if buffer_:
                m.buffer_size = self.mapfactory.map_attributes['buffer_size']

        # haiti spec tmp hack! show meta layers without having
        # to request huge string to avoid some client truncating it!
        if params['layers'] and params['layers'][0] in (
                'osm_haiti_overlay', 'osm_haiti_overlay_900913'):
            for layer_obj in self.mapfactory.ordered_layers:
                layer = copy_layer(layer_obj)
                if not hasattr(layer, 'meta_style'):
                    pass
                else:
                    layer.styles.append(layer.meta_style)
                    m.append_style(
                        layer.meta_style,
                        self.mapfactory.meta_styles[layer.meta_style])
                    m.layers.append(layer)
        # a non WMS spec way of requesting all layers
        # uses orderedlayers that preserves original ordering in XML mapfile
        elif params['layers'] and params['layers'][0] == '__all__':
            for layer_obj in self.mapfactory.ordered_layers:
                # if we don't copy the layer here we get
                # duplicate layers added to the map because the
                # layer is kept around and the styles "pile up"...
                layer = copy_layer(layer_obj)
                if hasattr(layer, 'meta_style'):
                    continue
                reqstyle = layer.wmsdefaultstyle
                if reqstyle in self.mapfactory.aggregatestyles.keys():
                    for stylename in self.mapfactory.aggregatestyles[reqstyle]:
                        layer.styles.append(stylename)
                else:
                    layer.styles.append(reqstyle)
                for stylename in layer.styles:
                    if stylename in self.mapfactory.styles.keys():
                        m.append_style(stylename,
                                       self.mapfactory.styles[stylename])
                m.layers.append(layer)
        else:
            for layerindex, layername in enumerate(params['layers']):
                if layername in self.mapfactory.meta_layers:
                    layer = copy_layer(self.mapfactory.meta_layers[layername])
                    layer.styles.append(layername)
                    m.append_style(layername,
                                   self.mapfactory.meta_styles[layername])
                else:
                    try:
                        # uses unordered dict of layers
                        # order based on params['layers'] request which
                        # should be originally informed by order of GetCaps response
                        layer = copy_layer(self.mapfactory.layers[layername])
                    except KeyError:
                        raise OGCException(
                            'Layer "%s" not defined.' % layername,
                            'LayerNotDefined')
                    try:
                        reqstyle = params['styles'][layerindex]
                    except IndexError:
                        reqstyle = ''
                    if reqstyle and reqstyle not in layer.wmsextrastyles:
                        raise OGCException(
                            'Invalid style "%s" requested for layer "%s".' %
                            (reqstyle, layername), 'StyleNotDefined')
                    if not reqstyle:
                        reqstyle = layer.wmsdefaultstyle
                    if reqstyle in self.mapfactory.aggregatestyles.keys():
                        for stylename in self.mapfactory.aggregatestyles[
                                reqstyle]:
                            layer.styles.append(stylename)
                    else:
                        layer.styles.append(reqstyle)

                    for stylename in layer.styles:
                        if stylename in self.mapfactory.styles.keys():
                            m.append_style(stylename,
                                           self.mapfactory.styles[stylename])
                        else:
                            raise ServerConfigurationError(
                                'Layer "%s" refers to non-existent style "%s".'
                                % (layername, stylename))

                m.layers.append(layer)
        m.zoom_to_box(
            Envelope(params['bbox'][0], params['bbox'][1], params['bbox'][2],
                     params['bbox'][3]))
        return m
コード例 #5
0
ファイル: mapnik.py プロジェクト: joto/MapQuest-Render-Stack
class Renderer :
    
    def __init__(self, map_style, mask_style):
        self.default_map = Map(0,0)

        # only load the mask style if it's provided
        if mask_style is None:
            self.mask_map = None
        else:
            self.mask_map = Map(0,0)

        self.proj = Mercator(18+1)
        self.regions = []
        try :
            load_map(self.default_map, map_style)
            
            # masks may not be provided if it's a single style
            if self.mask_map is not None:
                load_map(self.mask_map, mask_style)

            self.map_proj = Projection(self.default_map.srs)
        except:
            mq_logging.error("Exception caught in Renderer ctor")
            raise
        
    def add_region(self,name,mapfile,wkt_mask_file):
        # ignore attempts to add regions when no mask has been
        # specified with a warning.
        if self.mask_map is not None:
            try:
                m = Map(0,0)
                load_map(m, mapfile)
                mask = Mask(wkt_mask_file)
                self.regions.append((name,m,mask))
            except Exception as ex:
                mq_logging.error("Exception caught adding region (%s)" % str(ex))
        else:
            mq_logging.warning("Cannot add mask (%s) because no mask_style was configured." % name)
    
    def _check_region(self, bbox):
        for r in self.regions:
            intersects,contains = r[2].relate(bbox.minx,bbox.miny,bbox.maxx,bbox.maxy)
            if intersects :
                return contains,r[1],r[0]    
        return None

    def save_rendered_metadata(self, renderer, size, dimensions):
        #save off the meta data if its there
        if renderer is not None:
            try: # mapnik 2.1 doesn't have this
                inmem = renderer.find_inmem_metawriter("poi-meta-data")
            except:
                return None
            if inmem is not None:
                # get the bounding boxes and ids out of the mapnik data and save in a feature collection
                return extractFeaturesMNK(inmem)    

        #no data so no feature collection
        return None

    # If the tile has a language parameter, change the datasource definition
    # in the map so that the language setting is taken into account. This is
    # currently a bit of a hack, but can be improved later.
    def adjust_language(self, map, languages):
        if languages:
            for layer in self.default_map.layers:
                try:
                    params = dict(layer.datasource.params()) ## mapnik >= 2.1
                except:
                    params = layer.datasource.params().as_dict() ## mapnik <= 2.0
                if params.get('labelhint', '') != '':
                    lc = []
                    for lines in languages.split("|"):
                        langs = []
                        for lang in lines.split(","):
                            if lang == '_':
                                langs.append("name")
                            else:
                                langs.append("tags->'name:" + lang + "'")
                        langs.append("''")
                        lc.append('coalesce(' + ','.join(langs) + ')')
                    if len(lc) > 1:
                        lc[1] = "'[' || " + lc[1] + " || ']'"
                    if len(lc) > 2:
                        lc[2] = "'[' || " + lc[2] + " || ']'"
                    if len(lc) > 3:
                        lc[3] = "'[' || " + lc[3] + " || ']'"
                    if params.get('labelhint', '') == 'replace-multiline':
                        c = " || E'\\n' || ".join(lc)
                    else:
                        c = " || ' ' || ".join(lc)
                    params['table'] = re.sub(re.compile('(name|\(?coalesce.*) as name', re.DOTALL), "(" + c + ") as name", params['table'])
                    mq_logging.debug(str("QUERY: layer='%s' labelhint='%s' table='%s'" % (layer.name, params.get('labelhint', ''), params['table'])))
                    # the following is a workaround for mapnik >= 2.1
                    d = dict()
                    for p in params:
                       d[str(p)] = str(params[p])
                    layer.datasource = CreateDatasource(d)

    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)