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
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)
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 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
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
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)
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())
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)
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
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)
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
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')
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)
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']