예제 #1
0
def tile_generator(zoom_lvl, tile_width, tile_height, style_sheet,
                   target_storage_path):
    print('\n\t[+]Generating tiles in zoom level -- {}\n'.format(zoom_lvl))
    tiles = get_tile_extent(zoom_lvl, (-180, +90), tile_width, tile_height,
                            360, 180)
    if (not tiles):
        return False
    for key, value in tiles.items():
        map_obj = Map(tile_width, tile_height,
                      '+proj=longlat +datum=WGS84 +no_defs ')
        if (not format_style_sheet(style_sheet, [
                'layer1', 'layer2', 'layer3', 'layer4', 'layer5', 'layer6'
        ], 'Parameter', ['name', 'extent'], '{}, {}, {}, {}'.format(*value),
                                   'tmp.xml')):
            return False
        print('\t\t[+]Rendering tile {} - {} - {} ...'.format(
            zoom_lvl, *key.split(',')))
        load_map(map_obj, 'tmp.xml')  # loads generated XML style sheet
        map_obj.zoom_to_box(Box2d(*value))
        render_to_file(
            map_obj,
            join(target_storage_path,
                 '{}_{}_{}.png'.format(zoom_lvl, *key.split(','))), 'png256')
    # removes temporary XML file, which was generated from template XML
    unlink('tmp.xml')
    return True
예제 #2
0
파일: WMS.py 프로젝트: bnordgren/OGCServer
    def loadXML(self, xmlfile=None, strict=False, xmlstring='', basepath=''):
        """Loads and stores a complete map definition in leiu of a set of layers.
        Stores an empty style of the same name, which is the only option for rendering.
        The map will be rendered as prescribed in the XML."""
        config = ConfigParser.SafeConfigParser()
        map_wms_srs = None
        if self.configpath:
            config.readfp(open(self.configpath))

            if config.has_option('map', 'wms_srs'):
                map_wms_srs = config.get('map', 'wms_srs')

        tmp_map = Map(0,0)
        if xmlfile:
            load_map(tmp_map, xmlfile, strict)
        elif xmlstring:
            load_map_from_string(tmp_map, xmlstring, strict, basepath)
        else:
            raise ServerConfigurationError("Mapnik configuration XML is not specified - 'xmlfile' and 'xmlstring' variables are empty.\
Please set one of this variables to load mapnik map object.")
        # parse map level attributes
        if tmp_map.background:
            self.map_attributes['bgcolor'] = tmp_map.background
        if tmp_map.buffer_size:
            self.map_attributes['buffer_size'] = tmp_map.buffer_size

        if xmlfile is None : 
            # Map objects have no name, so just call it default.
            layer_name = 'default'
        else : 
            # The layer name is the basename of the xml file or the 
            # whole file name
            layer_name = xmlfile
            fname_match = re.match('([A-Za-z0-9_\-\.]+).xml', xmlfile)
            if fname_match is not None : 
                layer_name = fname_match.group(1)
            else : 
                layer_name = xmlfile

        style_name = layer_name
        style_obj = Style()

        # Make the map have attributes expected of layers
        tmp_map.name = layer_name
        map_p = common.Projection(tmp_map.srs)
        if map_wms_srs is None : 
            tmp_map.wms_srs = map_p.epsgstring()
        else : 
            tmp_map.wms_srs = map_wms_srs
        tmp_map.queryable = False

        # set map extent from config file.
        geog_coords = config.get('map','wms_extent').split(',')
        geog_box = Box2d(float(geog_coords[0]), float(geog_coords[1]), float(geog_coords[2]), float(geog_coords[3]))
        proj_box = geog_box.forward(map_p)
        tmp_map.zoom_to_box(proj_box)
        tmp_map.maximum_extent = proj_box

        self.register_style(style_name, style_obj)
        self.register_layer(tmp_map, style_name) 
예제 #3
0
def make_map(map_output, scale=20000, x_center=622000, y_center=6406000):
    "Make a map as a function of the scale"

    # Compute the scale
    page_size = int(PAGE_FORMAT[1])
    f = math.sqrt(2)**PAGES[page_size]

    # increasing map_x and map_y lead to decreasing font and symbol size: not good
    map_x = int(f * 4600)  # 4600 is the number of pixels for an A4 length

    # if 460: zoom = 13
    map_y = int(map_x / math.sqrt(2))
    m = Map(map_x, map_y)
    load_map(m, MAPNIK_FILE)

    # Bounding box (expressed in EPSG:3857, meters)
    delta_x = f * 0.295 * scale / math.cos(LATITUDE * 2 * math.pi / 360)
    delta_y = delta_x / math.sqrt(2)
    xmin = x_center - delta_x / 2
    xmax = x_center + delta_x / 2
    ymin = y_center - delta_y / 2
    ymax = y_center + delta_y / 2

    bbox = (Envelope(xmin, ymin, xmax, ymax))
    m.zoom_to_box(bbox)
    print("Scale = " + str(m.scale()))

    render_to_file(m, map_output)
예제 #4
0
 def cached_map(self):
     """
     If caching is enabled, ensure that only one map object is
     generated, otherwise generate a fresh one.
     """
     if self._map is not None:
         return self._map
     m = Map(self.image_width, self.image_height)
     load_map(m, self.mapnik_file)
     if self.cache:
         self._map = m
     return m
예제 #5
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.")
     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':
         m.background = params['bgcolor']
     else:
         m.background = Color(0, 0, 0, 0)
     maplayers = self.mapfactory.layers
     mapstyles = self.mapfactory.styles
     mapaggregatestyles = self.mapfactory.aggregatestyles
     for layerindex, layername in enumerate(params['layers']):
         try:
             layer = maplayers[layername]
         except KeyError:
             raise OGCException('Layer "%s" not defined.' % layername,
                                'LayerNotDefined')
         reqstyle = params['styles'][layerindex]
         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(
         Envelope(params['bbox'][0], params['bbox'][1], params['bbox'][2],
                  params['bbox'][3]))
     return m
예제 #6
0
    def __init__(self, content):
        """ With MapRenderer you can render an aktionskarten map in different
            file formats like pdf, svg or png.

            Internally it uses mapnik and cairo to archieve this. A valid style
            has to be defined through `MAPNIK_OSM_XML`. Normally this a carto
            derived `style.xml`. In this file your datasource is specified. This
            can be for instance a postgres+postgis database with imported osm
            data.

            :param content: dict of map content
        """
        # Mapnik uses mercator as internal projection. Our data is encoded in
        # latlon. Therefor we need a transformer for coordindates from longlat
        # to mercator
        proj_merc = Projection('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0\
                                +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m  \
                                +nadgrids=@null +no_defs +over')
        proj_longlat = Projection('+proj=longlat +ellps=WGS84 +datum=WGS84  \
                                   +no_defs')
        transformer = ProjTransform(proj_longlat, proj_merc)

        # our maps should be printable on a DIN A4 page with 150dpi
        self._map = Map(1754, 1240)
        bbox = transformer.forward(Box2d(*content['bbox']))
        self._map.zoom_to_box(bbox)
        self._map.buffer_size = 5

        start = timer()

        # add osm data (background)
        load_map(self._map, current_app.config['MAPNIK_OSM_XML'])

        mid = timer()

        self._add_grid(content['grid'])
        self._add_features(content['features'])
        self._add_legend(content['name'], content['place'], content['datetime'],
                        content['attributes'])

        end = timer()
        print("Map.init - OSM: ", mid - start)
        print("Map.init - Map: ", end - mid)
        print("Map.init - Total: ", end - start)
예제 #7
0
 def GetMap(self, params):
     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'])
     if params.has_key('transparent') and params['transparent'] == 'FALSE':
         m.background = params['bgcolor']
     else:
         m.background = Color(0, 0, 0, 0)
     maplayers = self.mapfactory.layers
     mapstyles = self.mapfactory.styles
     for layername in params['layers']:
         try:
             layer = maplayers[layername]
         except KeyError:
             raise OGCException('Layer "%s" not defined.' % layername,
                                'LayerNotDefined')
         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(
         Envelope(params['bbox'][0], params['bbox'][1], params['bbox'][2],
                  params['bbox'][3]))
     im = Image(params['width'], params['height'])
     render(m, im)
     im = fromstring('RGBA', (params['width'], params['height']),
                     rawdata(im))
     fh = StringIO()
     im.save(fh, PIL_TYPE_MAPPING[params['format']], quality=100)
     fh.seek(0)
     return Response(params['format'], fh.read())
예제 #8
0
    def __call__(self, layers, system):
        request = system['request']

        # get image width and height
        width = 256
        height = 256

        # get image bbox
        z = int(request.matchdict['z'])
        x = int(request.matchdict['x'])
        y = int(request.matchdict['y'])
        step = max / (2**(int(z) - 1))

        xmin = x * step - max
        ymin = max - y * step
        xmax = (x + 1) * step - max
        ymax = max - (y + 1) * step

        bbox = Box2d(xmin, ymax, xmax, ymin)

        m = Map(width, height)
        load_map(m, abspath_from_asset_spec('osmtm:views/map.xml'))

        for l in layers:
            m.layers.append(l)

        m.zoom_to_box(bbox)

        format = request.matchdict['format']
        if format == 'png':
            im = Image(width, height)
            render(m, im, 1, 1)

            request.response_content_type = 'image/png'
            return im.tostring('png')

        elif format == 'json':
            grid = Grid(width, height)
            render_layer(m, grid, layer=0, fields=['id'])
            utfgrid = grid.encode('utf', resolution=4)
            return json.dumps(utfgrid)
예제 #9
0
    def loadXML(self, xmlfile=None, strict=False, xmlstring='', basepath=''):
        config = ConfigParser.SafeConfigParser()
        map_wms_srs = None
        if self.configpath:
            config.readfp(open(self.configpath))

            if config.has_option('map', 'wms_srs'):
                map_wms_srs = config.get('map', 'wms_srs')

        tmp_map = Map(0, 0)
        if xmlfile:
            load_map(tmp_map, xmlfile, strict)
        elif xmlstring:
            load_map_from_string(tmp_map, xmlstring, strict, basepath)
        else:
            raise ServerConfigurationError(
                "Mapnik configuration XML is not specified - 'xmlfile' and 'xmlstring' variables are empty.\
Please set one of this variables to load mapnik map object.")
        # get the map scale
        if tmp_map.parameters:
            if tmp_map.parameters['scale']:
                self.map_scale = float(tmp_map.parameters['scale'])
        # parse map level attributes
        if tmp_map.background:
            self.map_attributes['bgcolor'] = tmp_map.background
        if tmp_map.buffer_size:
            self.map_attributes['buffer_size'] = tmp_map.buffer_size
        for lyr in tmp_map.layers:
            layer_section = 'layer_%s' % lyr.name
            layer_wms_srs = None
            if config.has_option(layer_section, 'wms_srs'):
                layer_wms_srs = config.get(layer_section, 'wms_srs')
            else:
                layer_wms_srs = map_wms_srs

            if config.has_option(layer_section, 'title'):
                lyr.title = config.get(layer_section, 'title')
            else:
                lyr.title = ''

            if config.has_option(layer_section, 'abstract'):
                lyr.abstract = config.get(layer_section, 'abstract')
            else:
                lyr.abstract = ''

            style_count = len(lyr.styles)
            if style_count == 0:
                raise ServerConfigurationError(
                    "Cannot register Layer '%s' without a style" % lyr.name)
            elif style_count == 1:
                style_obj = tmp_map.find_style(lyr.styles[0])
                style_name = lyr.styles[0]

                meta_s = extract_named_rules(style_obj)
                if meta_s:
                    self.meta_styles['%s_meta' % lyr.name] = meta_s
                    if hasattr(lyr, 'abstract'):
                        name_ = lyr.abstract
                    else:
                        name_ = lyr.name
                    meta_layer_name = '%s:%s' % (name_, '-'.join(meta_s.names))
                    meta_layer_name = meta_layer_name.replace(' ', '_')
                    self.meta_styles[meta_layer_name] = meta_s
                    meta_lyr = common.copy_layer(lyr)
                    meta_lyr.meta_style = meta_layer_name
                    meta_lyr.name = meta_layer_name
                    meta_lyr.wmsextrastyles = ()
                    meta_lyr.defaultstyle = meta_layer_name
                    meta_lyr.wms_srs = layer_wms_srs
                    self.ordered_layers.append(meta_lyr)
                    self.meta_layers[meta_layer_name] = meta_lyr
                    print meta_layer_name

                if style_name not in self.aggregatestyles.keys(
                ) and style_name not in self.styles.keys():
                    self.register_style(style_name, style_obj)

                # must copy layer here otherwise we'll segfault
                lyr_ = common.copy_layer(lyr)
                lyr_.wms_srs = layer_wms_srs
                self.register_layer(lyr_,
                                    style_name,
                                    extrastyles=(style_name, ))

            elif style_count > 1:
                for style_name in lyr.styles:
                    style_obj = tmp_map.find_style(style_name)

                    meta_s = extract_named_rules(style_obj)
                    if meta_s:
                        self.meta_styles['%s_meta' % lyr.name] = meta_s
                        if hasattr(lyr, 'abstract'):
                            name_ = lyr.abstract
                        else:
                            name_ = lyr.name
                        meta_layer_name = '%s:%s' % (name_, '-'.join(
                            meta_s.names))
                        meta_layer_name = meta_layer_name.replace(' ', '_')
                        self.meta_styles[meta_layer_name] = meta_s
                        meta_lyr = common.copy_layer(lyr)
                        meta_lyr.meta_style = meta_layer_name
                        print meta_layer_name
                        meta_lyr.name = meta_layer_name
                        meta_lyr.wmsextrastyles = ()
                        meta_lyr.defaultstyle = meta_layer_name
                        meta_lyr.wms_srs = layer_wms_srs
                        self.ordered_layers.append(meta_lyr)
                        self.meta_layers[meta_layer_name] = meta_lyr

                    if style_name not in self.aggregatestyles.keys(
                    ) and style_name not in self.styles.keys():
                        self.register_style(style_name, style_obj)
                aggregates = tuple([sty for sty in lyr.styles])
                aggregates_name = '%s_aggregates' % lyr.name
                self.register_aggregate_style(aggregates_name, aggregates)
                # must copy layer here otherwise we'll segfault
                lyr_ = common.copy_layer(lyr)
                lyr_.wms_srs = layer_wms_srs
                self.register_layer(lyr_,
                                    aggregates_name,
                                    extrastyles=aggregates)
                if 'default' in aggregates:
                    sys.stderr.write(
                        "Warning: Multi-style layer '%s' contains a regular style named 'default'. \
This style will effectively be hidden by the 'all styles' default style for multi-style layers.\n"
                        % lyr_.name)
# -*- coding: UTF-8 -*-

#from variables_config import * # Contains shared variables (See http://docs.python.org/faq/programming.html#how-do-i-share-global-variables-across-modules)

# get extent from shp (for mapnik)
from ogr_extent import *

# Retrieve extent and projection using gdal
shp_extent, proj4 = extent_and_proj('departement.shp',
                                    sourcetype='ESRI Shapefile')

import cairo
from mapnik import Style, Rule, Color, Filter, LineSymbolizer, PolygonSymbolizer, TextSymbolizer, label_placement, Shapefile, SQLite, Layer, Map, render, Shapefile, Expression, save_map

map_output = 'france'
m = Map(300, 300, proj4)

m.background = Color('steelblue')

t = TextSymbolizer(Expression('[CODE_DEPT]'), 'DejaVu Sans Book', 8,
                   Color('black'))

f = Expression(
    "[CODE_DEPT]<>'75' and [CODE_DEPT]<>'92' and [CODE_DEPT]<>'93' and [CODE_DEPT]<>'94'"
)
t.allow_overlap = 1
t.label_placement = label_placement.POINT_PLACEMENT
s1 = Style()
r1 = Rule()
r1.symbols.append(t)
r1.filter = f
예제 #11
0
        def _render(value, system):
            request = system['request']

            if not isinstance(value, tuple):
                value = (None, value)

            layer_name, collection = value

            if not hasattr(collection, 'features'):
                raise ValueError('renderer is not passed a feature collection')

            # get image width and height
            try:
                img_width = int(request.params.get('img_width', 256))
            except:
                request.response_status = 400
                return 'incorrect img_width'
            try:
                img_height = int(request.params.get('img_height', 256))
            except:
                request.response_status = 400
                return 'incorrect img_height'

            # get image format
            try:
                img_format = request.params.get(
                    'img_format', request.matchdict.get('format', 'png'))
                img_format = str(img_format)
            except:
                request.response_status = 400
                return 'incorrect img_format'

            # get image bbox
            img_bbox = request.params.get('img_bbox',
                                          request.params.get('bbox'))
            if img_bbox:
                try:
                    img_bbox = map(float, img_bbox.split(','))
                except ValueError:
                    request.response_status = 400
                    return 'incorrect img_bbox'
                img_bbox = Box2d(*img_bbox)

            m = Map(img_width, img_height)
            load_map(m, mapfile)

            if len(m.layers) == 0:
                raise ValueError('no layer in the mapnik map')

            # if no layer_name is provided then, by convention, use
            # the first layer in the mapnik map
            if layer_name is None:
                layer_name = m.layers[0].name

            layer = self._set_layer_in_map(m, layer_name)
            layer.datasource = self._create_datasource(collection)

            m.zoom_to_box(img_bbox or layer.envelope())

            im = Image(img_width, img_height)
            render(m, im, 1, 1)

            # get the image format from the request

            request.response.content_type = 'image/%s' % img_format
            return im.tostring(img_format)
예제 #12
0
파일: common.py 프로젝트: nimix/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'])

        transparent = params.get('transparent', '').lower() == 'true'

        # disable transparent on incompatible formats
        if transparent and params.get('format', '') == 'image/jpeg':
            transparent = False

        if transparent:
            # transparent has highest priority
            pass
        elif params.has_key('bgcolor'):
            # if not transparent use bgcolor in url
            m.background = params['bgcolor']
        else:
            # if not bgcolor in url use map background
            if mapnik_version() >= 200000:
                bgcolor = self.mapfactory.map_attributes.get('bgcolor', None)
            else:
                bgcolor = self.mapfactory.map_attributes.get(
                    'background-color', None)

            if bgcolor:
                m.background = bgcolor
            else:
                # if not map background defined use white color
                m.background = Color(255, 255, 255, 255)

        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 len(layer.wmsextrastyles) > 1 and reqstyle == 'default':
                        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
예제 #13
0

if __name__ == "__main__":
    mapfile = "my_styles/mapnik2normal.xml"

    map_uri = "map.png"

    lat = 49.25
    lon = 7.0
    if len(sys.argv) == 2:
        zoom = int(sys.argv[1])
    else:
        zoom = 13
    imgx = 500
    imgy = 400

    ll = center_to_bbox(lat, lon, zoom, imgx, imgy)
    m = Map(imgx, imgy)
    load_map(m, mapfile)
    prj = Projection(
        "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m"
        " +nadgrids=@null +no_defs +over")
    c0 = prj.forward(Coord(ll[0], ll[1]))
    c1 = prj.forward(Coord(ll[2], ll[3]))
    bbox = Box2d(c0.x, c0.y, c1.x, c1.y)
    m.zoom_to_box(bbox)
    im = Image(imgx, imgy)
    render(m, im)
    view = im.view(0, 0, imgx, imgy)  # x,y,width,height
    view.save(map_uri, 'png')
예제 #14
0
    def loadXML(self, xmlfile=None, strict=False, xmlstring='', basepath=''):
        config = ConfigParser.SafeConfigParser()
        #声明变量,用于保存 map中的wms_srs
        map_wms_srs = None
        if self.configpath:
            config.readfp(open(self.configpath))

            if config.has_option('map', 'wms_srs'):
                map_wms_srs = config.get('map', 'wms_srs')
        #声明变量tmp_map保存Map(0,0),Map从mapnik模块中导入,此处详见doc/mapnik_help.text
        tmp_map = Map(0, 0)
        #支持文件模式和字符串格式的输入
        if xmlfile:
            load_map(tmp_map, xmlfile, strict)
        elif xmlstring:
            load_map_from_string(tmp_map, xmlstring, strict, basepath)
        else:
            #差错机制
            raise ServerConfigurationError(
                "Mapnik configuration XML is not specified - 'xmlfile' and 'xmlstring' variables are empty.\
Please set one of this variables to load mapnik map object.")
        # parse map level attributes
        #解析地图图层特征参数
        #背景颜色(待查)
        if tmp_map.background:
            self.map_attributes['bgcolor'] = tmp_map.background
        #buffer大小(待查)
        if tmp_map.buffer_size:
            self.map_attributes['buffer_size'] = tmp_map.buffer_size
        #对tmp_map中layers中所有lyr,进行参数解析
        for lyr in tmp_map.layers:
            layer_section = 'layer_%s' % lyr.name
            layer_wms_srs = None
            if config.has_option(layer_section, 'wms_srs'):
                layer_wms_srs = config.get(layer_section, 'wms_srs')
            else:
                layer_wms_srs = map_wms_srs

            if config.has_option(layer_section, 'title'):
                lyr.title = config.get(layer_section, 'title')
            else:
                lyr.title = ''

            if config.has_option(layer_section, 'abstract'):
                lyr.abstract = config.get(layer_section, 'abstract')
            else:
                lyr.abstract = ''

            style_count = len(lyr.styles)
            #必须设定有lyr.styles
            if style_count == 0:
                raise ServerConfigurationError(
                    "Cannot register Layer '%s' without a style" % lyr.name)
            elif style_count == 1:
                #.find_style方法为mapnik中Map类的方法?????
                style_obj = tmp_map.find_style(lyr.styles[0])
                style_name = lyr.styles[0]
                # 对style_obj进行处理,提取参数返回为 style类
                meta_s = extract_named_rules(style_obj)
                if meta_s:
                    # BaseWMSFactory类的meta_styles属性
                    self.meta_styles['%s_meta' % lyr.name] = meta_s
                    # 判断lyr是否含有abstract属性
                    if hasattr(lyr, 'abstract'):
                        name_ = lyr.abstract
                    else:
                        name_ = lyr.name
                    # 将meta_s.names中的字符串序列用“-”连接
                    meta_layer_name = '%s:%s' % (name_, '-'.join(meta_s.names))
                    # 将meta_layer_name中的空格全部替换为“_”
                    meta_layer_name = meta_layer_name.replace(' ', '_')
                    self.meta_styles[meta_layer_name] = meta_s
                    meta_lyr = common.copy_layer(lyr)
                    meta_lyr.meta_style = meta_layer_name
                    meta_lyr.name = meta_layer_name
                    meta_lyr.wmsextrastyles = ()
                    meta_lyr.defaultstyle = meta_layer_name
                    meta_lyr.wms_srs = layer_wms_srs
                    self.ordered_layers.append(meta_lyr)
                    self.meta_layers[meta_layer_name] = meta_lyr
                    print meta_layer_name
                # 如果aggregatestyles和styles中没有style_name的关键字,则注册style。.register_style为本类定义的方法
                if style_name not in self.aggregatestyles.keys(
                ) and style_name not in self.styles.keys():
                    self.register_style(style_name, style_obj)

                # must copy layer here otherwise we'll segfault
                # c此处必须拷贝图层,否则将出现段错误
                # common
                lyr_ = common.copy_layer(lyr)
                lyr_.wms_srs = layer_wms_srs
                #register_layer为本类定义的一个方法,
                self.register_layer(lyr_,
                                    style_name,
                                    extrastyles=(style_name, ))

            # 当style_count > 1时,处理步骤与style_count = 1时大致相同,
            elif style_count > 1:
                for style_name in lyr.styles:
                    style_obj = tmp_map.find_style(style_name)

                    meta_s = extract_named_rules(style_obj)
                    if meta_s:
                        self.meta_styles['%s_meta' % lyr.name] = meta_s
                        if hasattr(lyr, 'abstract'):
                            name_ = lyr.abstract
                        else:
                            name_ = lyr.name
                        meta_layer_name = '%s:%s' % (name_, '-'.join(
                            meta_s.names))
                        meta_layer_name = meta_layer_name.replace(' ', '_')
                        self.meta_styles[meta_layer_name] = meta_s
                        meta_lyr = common.copy_layer(lyr)
                        meta_lyr.meta_style = meta_layer_name
                        print meta_layer_name
                        meta_lyr.name = meta_layer_name
                        meta_lyr.wmsextrastyles = ()
                        meta_lyr.defaultstyle = meta_layer_name
                        meta_lyr.wms_srs = layer_wms_srs
                        self.ordered_layers.append(meta_lyr)
                        self.meta_layers[meta_layer_name] = meta_lyr

                    if style_name not in self.aggregatestyles.keys(
                    ) and style_name not in self.styles.keys():
                        self.register_style(style_name, style_obj)
                # 与style_count = 1时的不同之处,
                aggregates = tuple([sty for sty in lyr.styles])
                aggregates_name = '%s_aggregates' % lyr.name
                self.register_aggregate_style(aggregates_name, aggregates)
                # must copy layer here otherwise we'll segfault
                lyr_ = common.copy_layer(lyr)
                lyr_.wms_srs = layer_wms_srs
                self.register_layer(lyr_,
                                    aggregates_name,
                                    extrastyles=aggregates)
                if 'default' in aggregates:
                    sys.stderr.write(
                        "Warning: Multi-style layer '%s' contains a regular style named 'default'. \
This style will effectively be hidden by the 'all styles' default style for multi-style layers.\n"
                        % lyr_.name)
예제 #15
0
        return join(dirname(args['xml']), basename)

    demfile = getfilename('dem')
    hillshadefile = getfilename('hillshade')

    # create hillshade
    from osgeo.gdal import DEMProcessing, DEMProcessingOptions, Open
    #   alg --- 'ZevenbergenThorne' or 'Horn'
    print 'creating hillshading in', hillshadefile, '...'
    DEMProcessing(hillshadefile,
                  demfile,
                  'hillshade',
                  zFactor=args['hillshade'],
                  combined=True)

m = Map(args['size'][0], args['size'][1])

load_map(m, args['xml'])

m.zoom_all()
if args['scale']:
    m.zoom(args['scale'] / m.scale_denominator())

if args['center']:
    mapcoordcenter = Projection(m.srs).forward(
        Coord(args['center'][1], args['center'][0]))
    center = m.view_transform().forward(mapcoordcenter)
    m.pan(int(center.x), int(center.y))

print 'scale denominator', m.scale_denominator()
print 'writing to', args['output']