def set_center_and_radius(self, lon, lat, radius=None, geographic=True):
     coords = Coord(lon, lat)
     box = Envelope(coords.x - radius, coords.y - radius, coords.x + radius,
                    coords.y + radius)
     if geographic and not self.proj_obj.geographic:
         box = box.forward(self.proj_obj)
     self.zoom_to_box(box)
 def set_center_and_radius(self,lon,lat,radius=None,geographic=True):
     coords = Coord(lon,lat)
     box = Envelope(coords.x - radius,
                   coords.y - radius,
                   coords.x + radius,
                   coords.y + radius)
     if geographic and not self.proj_obj.geographic:
         box = box.forward(self.proj_obj)
     self.zoom_to_box(box)
Beispiel #3
0
 def register_layer(self, layer, defaultstyle, extrastyles=()):
     layername = layer.name
     #差错机制,检测相关参数是否有效
     if not layername:
         #ServerConfigurationError为从ogcserver.exceptions中导入的方法,执行内容为空
         raise ServerConfigurationError(
             'Attempted to register an unnamed layer.')
     if not layer.wms_srs and not re.match('^\+init=epsg:\d+$',
                                           layer.srs) and not re.match(
                                               '^\+proj=.*$', layer.srs):
         raise ServerConfigurationError(
             'Attempted to register a layer without an epsg projection defined.'
         )
     if defaultstyle not in self.styles.keys() + self.aggregatestyles.keys(
     ):
         raise ServerConfigurationError(
             'Attempted to register a layer with an non-existent default style.'
         )
     layer.wmsdefaultstyle = defaultstyle
     # 判断是否为tuple类型,('a',)为tuple类型,aggregates也为tuple类型
     # type(('a',))输出为 tuple
     if isinstance(extrastyles, tuple):
         #
         for stylename in extrastyles:
             # 如果stylename类型为str
             if type(stylename) == type(''):
                 if stylename not in self.styles.keys(
                 ) + self.aggregatestyles.keys():
                     raise ServerConfigurationError(
                         'Attempted to register a layer with an non-existent extra style.'
                     )
             else:
                 ServerConfigurationError(
                     'Attempted to register a layer with an invalid extra style name.'
                 )
         # wmsextrastyles????
         layer.wmsextrastyles = extrastyles
     else:
         raise ServerConfigurationError(
             'Layer "%s" was passed an invalid list of extra styles.  List must be a tuple of strings.'
             % layername)
     # 调用common中Projection
     layerproj = common.Projection(layer.srs)
     env = layer.envelope()
     llp = layerproj.inverse(Coord(env.minx, env.miny))
     urp = layerproj.inverse(Coord(env.maxx, env.maxy))
     if self.latlonbb is None:
         self.latlonbb = Envelope(llp, urp)
     else:
         self.latlonbb.expand_to_include(Envelope(llp, urp))
     self.ordered_layers.append(layer)
     self.layers[layername] = layer
Beispiel #4
0
 def register_layer(self, layer, defaultstyle, extrastyles=()):
     layername = layer.name
     if not layername:
         raise ServerConfigurationError('Attempted to register an unnamed layer.')
     if not layer.wms_srs and not re.match('^\+init=epsg:\d+$', layer.srs) and not re.match('^\+proj=.*$', layer.srs):
         raise ServerConfigurationError('Attempted to register a layer without an epsg projection defined.')
     if defaultstyle not in self.styles.keys() + self.aggregatestyles.keys():
         raise ServerConfigurationError('Attempted to register a layer with an non-existent default style.')
     layer.wmsdefaultstyle = defaultstyle
     if isinstance(extrastyles, tuple):
         for stylename in extrastyles:
             if type(stylename) == type(''):
                 if stylename not in self.styles.keys() + self.aggregatestyles.keys():
                     raise ServerConfigurationError('Attempted to register a layer with an non-existent extra style.')
             else:
                 ServerConfigurationError('Attempted to register a layer with an invalid extra style name.')
         layer.wmsextrastyles = extrastyles
     else:
         raise ServerConfigurationError('Layer "%s" was passed an invalid list of extra styles.  List must be a tuple of strings.' % layername)
     layerproj = common.Projection(layer.srs)
     env = layer.envelope()
     llp = layerproj.inverse(Coord(env.minx, env.miny))
     urp = layerproj.inverse(Coord(env.maxx, env.maxy))
     if self.latlonbb is None:
         self.latlonbb = Envelope(llp, urp)
     else:
         self.latlonbb.expand_to_include(Envelope(llp, urp))
     self.ordered_layers.append(layer)
     self.layers[layername] = layer
Beispiel #5
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)
 def set_center_and_zoom(self, lon, lat, level=0, geographic=True):
     coords = Coord(lon, lat)
     if geographic and not self.proj_obj.geographic:
         coords = coords.forward(self.proj_obj)
     w, h = self.width, self.height
     res = self.get_scale_for_zoom_level(level)
     box = Envelope(coords.x - 0.5 * w * res, coords.y - 0.5 * h * res,
                    coords.x + 0.5 * w * res, coords.y + 0.5 * h * res)
     self.zoom_to_box(box)
Beispiel #7
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
Beispiel #8
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())
Beispiel #9
0
class BaseWMSFactory:
    def __init__(self, configpath=None):
        self.layers = {}
        self.ordered_layers = []
        self.styles = {}
        self.aggregatestyles = {}
        self.map_attributes = {}
        self.map_scale = 1
        self.meta_styles = {}
        self.meta_layers = {}
        self.configpath = configpath
        self.latlonbb = None

    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)

    def register_layer(self, layer, defaultstyle, extrastyles=()):
        layername = layer.name
        if not layername:
            raise ServerConfigurationError(
                'Attempted to register an unnamed layer.')
        if not layer.wms_srs and not re.match('^\+init=epsg:\d+$',
                                              layer.srs) and not re.match(
                                                  '^\+proj=.*$', layer.srs):
            raise ServerConfigurationError(
                'Attempted to register a layer without an epsg projection defined.'
            )
        if defaultstyle not in self.styles.keys() + self.aggregatestyles.keys(
        ):
            raise ServerConfigurationError(
                'Attempted to register a layer with an non-existent default style.'
            )
        layer.wmsdefaultstyle = defaultstyle
        if isinstance(extrastyles, tuple):
            for stylename in extrastyles:
                if type(stylename) == type(''):
                    if stylename not in self.styles.keys(
                    ) + self.aggregatestyles.keys():
                        raise ServerConfigurationError(
                            'Attempted to register a layer with an non-existent extra style.'
                        )
                else:
                    ServerConfigurationError(
                        'Attempted to register a layer with an invalid extra style name.'
                    )
            layer.wmsextrastyles = extrastyles
        else:
            raise ServerConfigurationError(
                'Layer "%s" was passed an invalid list of extra styles.  List must be a tuple of strings.'
                % layername)
        layerproj = common.Projection(layer.srs)
        env = layer.envelope()
        llp = layerproj.inverse(Coord(env.minx, env.miny))
        urp = layerproj.inverse(Coord(env.maxx, env.maxy))
        if self.latlonbb is None:
            self.latlonbb = Envelope(llp, urp)
        else:
            self.latlonbb.expand_to_include(Envelope(llp, urp))
        self.ordered_layers.append(layer)
        self.layers[layername] = layer

    def register_style(self, name, style):
        if not name:
            raise ServerConfigurationError(
                'Attempted to register a style without providing a name.')
        if name in self.aggregatestyles.keys() or name in self.styles.keys():
            raise ServerConfigurationError(
                "Attempted to register a style with a name already in use: '%s'"
                % name)
        if not isinstance(style, Style):
            raise ServerConfigurationError(
                'Bad style object passed to register_style() for style "%s".' %
                name)
        self.styles[name] = style

    def register_aggregate_style(self, name, stylenames):
        if not name:
            raise ServerConfigurationError(
                'Attempted to register an aggregate style without providing a name.'
            )
        if name in self.aggregatestyles.keys() or name in self.styles.keys():
            raise ServerConfigurationError(
                'Attempted to register an aggregate style with a name already in use.'
            )
        self.aggregatestyles[name] = []
        for stylename in stylenames:
            if stylename not in self.styles.keys():
                raise ServerConfigurationError(
                    'Attempted to register an aggregate style containing a style that does not exist.'
                )
            self.aggregatestyles[name].append(stylename)

    def finalize(self):
        if len(self.layers) == 0:
            raise ServerConfigurationError('No layers defined!')
        if len(self.styles) == 0:
            raise ServerConfigurationError('No styles defined!')
        for layer in self.layers.values():
            for style in list(layer.styles) + list(layer.wmsextrastyles):
                if style not in self.styles.keys() + self.aggregatestyles.keys(
                ):
                    raise ServerConfigurationError(
                        'Layer "%s" refers to undefined style "%s".' %
                        (layer.name, style))
# note: requires mapnik SVN r822 or greater.

# Example of reprojecting the extent for the netherlands in epsg:28992 to google mercator and then back to the original netherlands extent.

import sys

try:
  from mapnik import ProjTransform, Projection, Envelope
except ImportError, E:
  sys.exit('Requires Mapnik SVN r822 or greater:\n%s' % E)

# http://spatialreference.org/ref/epsg/28992/
# http://mapnik.dbsgeo.com/days/2009-01-25
amersfoort_extent = Envelope(13599.999985,306799.999985,277999.999985,619299.999985)
amersfoort_proj = Projection('+init=epsg:28992')

merc_proj = 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 +wktext  +no_defs')

transform = ProjTransform(amersfoort_proj,merc_proj)

merc_extent = transform.forward(amersfoort_extent)
if transform.backward(merc_extent).__repr__() == amersfoort_extent.__repr__():
 print 'Transformation successful!'
 print 'Original Dutch Extent: %s' % amersfoort_extent
 print 'Merc Extent: %s' % merc_extent
else:
 print 'Reprojection failure...'
Beispiel #11
0
class BaseWMSFactory:
    def __init__(self, configpath=None):
        self.layers = {}
        self.ordered_layers = []
        self.styles = {}
        self.aggregatestyles = {}
        self.map_attributes = {}
        self.meta_styles = {}
        self.meta_layers = {}
        self.configpath = configpath
        self.latlonbb = None

    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.")
        # 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)

    def register_layer(self, layer, defaultstyle, extrastyles=()):
        layername = layer.name
        if not layername:
            raise ServerConfigurationError('Attempted to register an unnamed layer.')
        if not layer.wms_srs and not re.match('^\+init=epsg:\d+$', layer.srs) and not re.match('^\+proj=.*$', layer.srs):
            raise ServerConfigurationError('Attempted to register a layer without an epsg projection defined.')
        if defaultstyle not in self.styles.keys() + self.aggregatestyles.keys():
            raise ServerConfigurationError('Attempted to register a layer with an non-existent default style.')
        layer.wmsdefaultstyle = defaultstyle
        if isinstance(extrastyles, tuple):
            for stylename in extrastyles:
                if type(stylename) == type(''):
                    if stylename not in self.styles.keys() + self.aggregatestyles.keys():
                        raise ServerConfigurationError('Attempted to register a layer with an non-existent extra style.')
                else:
                    ServerConfigurationError('Attempted to register a layer with an invalid extra style name.')
            layer.wmsextrastyles = extrastyles
        else:
            raise ServerConfigurationError('Layer "%s" was passed an invalid list of extra styles.  List must be a tuple of strings.' % layername)
        layerproj = common.Projection(layer.srs)
        env = layer.envelope()
        llp = layerproj.inverse(Coord(env.minx, env.miny))
        urp = layerproj.inverse(Coord(env.maxx, env.maxy))
        if self.latlonbb is None:
            self.latlonbb = Envelope(llp, urp)
        else:
            self.latlonbb.expand_to_include(Envelope(llp, urp))
        self.ordered_layers.append(layer)
        self.layers[layername] = layer

    def register_style(self, name, style):
        if not name:
            raise ServerConfigurationError('Attempted to register a style without providing a name.')
        if name in self.aggregatestyles.keys() or name in self.styles.keys():
            raise ServerConfigurationError("Attempted to register a style with a name already in use: '%s'" % name)
        if not isinstance(style, Style):
            raise ServerConfigurationError('Bad style object passed to register_style() for style "%s".' % name)
        self.styles[name] = style

    def register_aggregate_style(self, name, stylenames):
        if not name:
            raise ServerConfigurationError('Attempted to register an aggregate style without providing a name.')
        if name in self.aggregatestyles.keys() or name in self.styles.keys():
            raise ServerConfigurationError('Attempted to register an aggregate style with a name already in use.')
        self.aggregatestyles[name] = []
        for stylename in stylenames:
            if stylename not in self.styles.keys():
                raise ServerConfigurationError('Attempted to register an aggregate style containing a style that does not exist.')
            self.aggregatestyles[name].append(stylename)

    def finalize(self):
        if len(self.layers) == 0:
            raise ServerConfigurationError('No layers defined!')
        if len(self.styles) == 0:
            raise ServerConfigurationError('No styles defined!')
        for layer in self.layers.values():
            for style in list(layer.styles) + list(layer.wmsextrastyles):
                if style not in self.styles.keys() + self.aggregatestyles.keys():
                    raise ServerConfigurationError('Layer "%s" refers to undefined style "%s".' % (layer.name, style))
Beispiel #12
0
def project(coords, projection):
    """Reproject coords from WGS84 to given projection"""
    bbox = Envelope(coords[0], coords[1])
    return bbox.forward(projection)
 def zoom_max(self):
     max_extent = Envelope(-179.99999694572804,-85.0511285163245,179.99999694572804,85.0511287798066)
     if not self.proj_obj.geographic:
         max_extent = max_extent.forward(self.proj_obj)
     self.zoom_to_box(max_extent)
Beispiel #14
0
class BaseWMSFactory:
    def __init__(self, configpath=None):
        self.layers = {}
        self.ordered_layers = []
        self.styles = {}
        self.aggregatestyles = {}
        self.map_attributes = {}
        self.meta_styles = {}
        self.meta_layers = {}
        self.configpath = configpath
        self.latlonbb = None

    #定义方法:加载XML配置文件
    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)
#注册图层

    def register_layer(self, layer, defaultstyle, extrastyles=()):
        layername = layer.name
        #差错机制,检测相关参数是否有效
        if not layername:
            #ServerConfigurationError为从ogcserver.exceptions中导入的方法,执行内容为空
            raise ServerConfigurationError(
                'Attempted to register an unnamed layer.')
        if not layer.wms_srs and not re.match('^\+init=epsg:\d+$',
                                              layer.srs) and not re.match(
                                                  '^\+proj=.*$', layer.srs):
            raise ServerConfigurationError(
                'Attempted to register a layer without an epsg projection defined.'
            )
        if defaultstyle not in self.styles.keys() + self.aggregatestyles.keys(
        ):
            raise ServerConfigurationError(
                'Attempted to register a layer with an non-existent default style.'
            )
        layer.wmsdefaultstyle = defaultstyle
        # 判断是否为tuple类型,('a',)为tuple类型,aggregates也为tuple类型
        # type(('a',))输出为 tuple
        if isinstance(extrastyles, tuple):
            #
            for stylename in extrastyles:
                # 如果stylename类型为str
                if type(stylename) == type(''):
                    if stylename not in self.styles.keys(
                    ) + self.aggregatestyles.keys():
                        raise ServerConfigurationError(
                            'Attempted to register a layer with an non-existent extra style.'
                        )
                else:
                    ServerConfigurationError(
                        'Attempted to register a layer with an invalid extra style name.'
                    )
            # wmsextrastyles????
            layer.wmsextrastyles = extrastyles
        else:
            raise ServerConfigurationError(
                'Layer "%s" was passed an invalid list of extra styles.  List must be a tuple of strings.'
                % layername)
        # 调用common中Projection
        layerproj = common.Projection(layer.srs)
        env = layer.envelope()
        llp = layerproj.inverse(Coord(env.minx, env.miny))
        urp = layerproj.inverse(Coord(env.maxx, env.maxy))
        if self.latlonbb is None:
            self.latlonbb = Envelope(llp, urp)
        else:
            self.latlonbb.expand_to_include(Envelope(llp, urp))
        self.ordered_layers.append(layer)
        self.layers[layername] = layer

# 注册style

    def register_style(self, name, style):
        # 差错处理,是否输入name,name是否已经存在,style类型是否正确
        if not name:
            raise ServerConfigurationError(
                'Attempted to register a style without providing a name.')
        if name in self.aggregatestyles.keys() or name in self.styles.keys():
            raise ServerConfigurationError(
                "Attempted to register a style with a name already in use: '%s'"
                % name)
        if not isinstance(style, Style):
            raise ServerConfigurationError(
                'Bad style object passed to register_style() for style "%s".' %
                name)
        # 在对象的style属性的dict中添加style
        self.styles[name] = style

# 注册aggregatestyles

    def register_aggregate_style(self, name, stylenames):
        if not name:
            raise ServerConfigurationError(
                'Attempted to register an aggregate style without providing a name.'
            )
        if name in self.aggregatestyles.keys() or name in self.styles.keys():
            raise ServerConfigurationError(
                'Attempted to register an aggregate style with a name already in use.'
            )
        self.aggregatestyles[name] = []
        for stylename in stylenames:
            if stylename not in self.styles.keys():
                raise ServerConfigurationError(
                    'Attempted to register an aggregate style containing a style that does not exist.'
                )
            # 在对象的aggregatestyles属性的dict中添加name关键字,及其内容
            self.aggregatestyles[name].append(stylename)

    def finalize(self):
        if len(self.layers) == 0:
            raise ServerConfigurationError('No layers defined!')
        if len(self.styles) == 0:
            raise ServerConfigurationError('No styles defined!')
        for layer in self.layers.values():
            for style in list(layer.styles) + list(layer.wmsextrastyles):
                if style not in self.styles.keys() + self.aggregatestyles.keys(
                ):
                    raise ServerConfigurationError(
                        'Layer "%s" refers to undefined style "%s".' %
                        (layer.name, style))
Beispiel #15
0
from mapnik import render, Image, Map, load_map, Projection, Coord, Envelope

projection = 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")


map = Map(600, 600)
load_map(map, "simple.xml")
bbox = Envelope(Coord(-179.999999975, -85.0511287776),
                Coord(179.999999975, 85.0511287776))
map.zoom_to_box(bbox.forward(projection))
image = Image(600, 600)
render(map, image)
with open('test.png', 'w') as image_file:
    image_file.write(image.tostring('png'))
Beispiel #16
0
# note: requires mapnik SVN r822 or greater.

# Example of reprojecting the extent for the netherlands in epsg:28992 to google mercator and then back to the original netherlands extent.

import sys

try:
    from mapnik import ProjTransform, Projection, Envelope
except ImportError, E:
    sys.exit('Requires Mapnik SVN r822 or greater:\n%s' % E)

# http://spatialreference.org/ref/epsg/28992/
# http://mapnik.dbsgeo.com/days/2009-01-25
amersfoort_extent = Envelope(13599.999985, 306799.999985, 277999.999985,
                             619299.999985)
amersfoort_proj = Projection('+init=epsg:28992')

merc_proj = 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 +wktext  +no_defs'
)

transform = ProjTransform(amersfoort_proj, merc_proj)

merc_extent = transform.forward(amersfoort_extent)
if transform.backward(merc_extent).__repr__() == amersfoort_extent.__repr__():
    print 'Transformation successful!'
    print 'Original Dutch Extent: %s' % amersfoort_extent
    print 'Merc Extent: %s' % merc_extent
else:
    print 'Reprojection failure...'
 def zoom_max(self):
     max_extent = Envelope(-179.99999694572804, -85.0511285163245,
                           179.99999694572804, 85.0511287798066)
     if not self.proj_obj.geographic:
         max_extent = max_extent.forward(self.proj_obj)
     self.zoom_to_box(max_extent)
Beispiel #18
0
#!/usr/bin/env python

from mapnik import Coord, Envelope, Projection, forward_, inverse_
import sys

if (len(sys.argv) < 2):
    print sys.argv[0] + " <epsg:code> <Coord or Envelope>"
    sys.exit(1)
else:
    epsg = sys.argv[1]
    p = Projection('+init=%s' % epsg)
    coord = map(float, sys.argv[2].split(','))
    if len(coord) == 2:
        long_lat = Coord(*coord)
        print 'Forwarded:',
        print p.forward(long_lat)
        print
        print 'Inversed:',
        print p.inverse(long_lat)
    elif len(coord) == 4:
        extent = Envelope(*coord)
        print 'Forwarded:',
        print forward_(extent, p)
        print
        print 'Inversed:',
        print inverse_(extent, p)
Beispiel #19
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'])

        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