def to_envelope(bounds): """ Translate a bounds object into an equivalent mapnik envelope (either mapnik.Envelope (0.7.2) or mapnik.Box2d (2+). """ return envelope(Coord(bounds.west, bounds.north), Coord(bounds.east, bounds.south))
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 = getattr(layer, 'maximum_extent', 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 = Box2d(llp, urp) else: self.latlonbb.expand_to_include(Box2d(llp, urp)) self.ordered_layers.append(layer) self.layers[layername] = layer
def getTileRange(envLL, z, ntiles=1): """Returns the tile number range (fromx, tox, fromy, toy) that covers the Box2d at the specified zoom level.""" topleft = Coord(envLL.minx, envLL.maxy) bottomright = Coord(envLL.maxx, envLL.miny) tltile = getTileAtLL(topleft, z, ntiles) brtile = getTileAtLL(bottomright, z, ntiles) return (tltile[0], brtile[0], tltile[1], brtile[1])
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)
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)
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
def test_add_feature(self): md = self.makeOne() self.failUnlessEqual(md.num_features(), 0) md.add_feature(self.makeFeature('Point(2 3)', foo='bar')) self.failUnlessEqual(md.num_features(), 1) from mapnik import Coord retrieved = md.features_at_point(Coord(2, 3)).features self.failUnlessEqual(len(retrieved), 1) f = retrieved[0] self.failUnlessEqual(f['foo'], 'bar') retrieved = md.features_at_point(Coord(20, 30)).features self.failUnlessEqual(len(retrieved), 0)
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 convertEastingNorthing(self, eastingnorthing): from mapnik import Projection, Coord britishProjection = Projection( '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs' ) c = Coord(float(eastingnorthing[0]), float(eastingnorthing[1])) c = britishProjection.inverse(c) return [c.y, c.x]
#!/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)
def inverse(self, x, y): if not self.proj: self.proj = Projection('+init=%s:%s' % (self.namespace, self.code)) return self.proj.inverse(Coord(x, y))
def GetCapabilities(self, params): if not self.capabilities: capetree = ElementTree.fromstring(self.capabilitiesxmltemplate) elements = capetree.findall('{http://www.opengis.net/wms}Capability//{http://www.opengis.net/wms}OnlineResource') for element in elements: element.set('xlink:href', self.opsonlineresource) self.processServiceCapabilities(capetree) rootlayerelem = capetree.find('{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer') rootlayername = ElementTree.Element('{http://www.opengis.net/wms}Name') if self.conf.has_option('map', 'wms_name'): rootlayername.text = to_unicode(self.conf.get('map', 'wms_name')) else: rootlayername.text = '__all__' rootlayerelem.append(rootlayername) rootlayertitle = ElementTree.Element('{http://www.opengis.net/wms}Title') if self.conf.has_option('map', 'wms_title'): rootlayertitle.text = to_unicode(self.conf.get('map', 'wms_title')) else: rootlayertitle.text = 'OGCServer WMS Server' rootlayerelem.append(rootlayertitle) rootlayerabstract = ElementTree.Element('{http://www.opengis.net/wms}Abstract') if self.conf.has_option('map', 'wms_abstract'): rootlayerabstract.text = to_unicode(self.conf.get('map', 'wms_abstract')) else: rootlayerabstract.text = 'OGCServer WMS Server' rootlayerelem.append(rootlayerabstract) layerexgbb = ElementTree.Element('{http://www.opengis.net/wms}EX_GeographicBoundingBox') exgbb_wbl = ElementTree.Element('{http://www.opengis.net/wms}westBoundLongitude') exgbb_wbl.text = str(self.mapfactory.latlonbb.minx) layerexgbb.append(exgbb_wbl) exgbb_ebl = ElementTree.Element('{http://www.opengis.net/wms}eastBoundLongitude') exgbb_ebl.text = str(self.mapfactory.latlonbb.maxx) layerexgbb.append(exgbb_ebl) exgbb_sbl = ElementTree.Element('{http://www.opengis.net/wms}southBoundLatitude') exgbb_sbl.text = str(self.mapfactory.latlonbb.miny) layerexgbb.append(exgbb_sbl) exgbb_nbl = ElementTree.Element('{http://www.opengis.net/wms}northBoundLatitude') exgbb_nbl.text = str(self.mapfactory.latlonbb.maxy) layerexgbb.append(exgbb_nbl) rootlayerelem.append(layerexgbb) for epsgcode in self.allowedepsgcodes: rootlayercrs = ElementTree.Element('{http://www.opengis.net/wms}CRS') rootlayercrs.text = epsgcode.upper() rootlayerelem.append(rootlayercrs) for layer in self.mapfactory.ordered_layers: layerproj = Projection(layer.srs) layername = ElementTree.Element('{http://www.opengis.net/wms}Name') layername.text = to_unicode(layer.name) env = layer.envelope() layerexgbb = ElementTree.Element('{http://www.opengis.net/wms}EX_GeographicBoundingBox') ll = layerproj.inverse(Coord(env.minx, env.miny)) ur = layerproj.inverse(Coord(env.maxx, env.maxy)) exgbb_wbl = ElementTree.Element('{http://www.opengis.net/wms}westBoundLongitude') exgbb_wbl.text = str(ll.x) layerexgbb.append(exgbb_wbl) exgbb_ebl = ElementTree.Element('{http://www.opengis.net/wms}eastBoundLongitude') exgbb_ebl.text = str(ur.x) layerexgbb.append(exgbb_ebl) exgbb_sbl = ElementTree.Element('{http://www.opengis.net/wms}southBoundLatitude') exgbb_sbl.text = str(ll.y) layerexgbb.append(exgbb_sbl) exgbb_nbl = ElementTree.Element('{http://www.opengis.net/wms}northBoundLatitude') exgbb_nbl.text = str(ur.y) layerexgbb.append(exgbb_nbl) layerbbox = ElementTree.Element('{http://www.opengis.net/wms}BoundingBox') if layer.wms_srs: layerbbox.set('CRS', layer.wms_srs) else: layerbbox.set('CRS', layerproj.epsgstring()) layerbbox.set('minx', str(env.minx)) layerbbox.set('miny', str(env.miny)) layerbbox.set('maxx', str(env.maxx)) layerbbox.set('maxy', str(env.maxy)) layere = ElementTree.Element('{http://www.opengis.net/wms}Layer') layere.append(layername) layertitle = ElementTree.Element('{http://www.opengis.net/wms}Title') if hasattr(layer,'title'): layertitle.text = to_unicode(layer.title) if layertitle.text == '': layertitle.text = to_unicode(layer.name) else: layertitle.text = to_unicode(layer.name) layere.append(layertitle) layerabstract = ElementTree.Element('{http://www.opengis.net/wms}Abstract') if hasattr(layer,'abstract'): layerabstract.text = to_unicode(layer.abstract) else: layerabstract.text = 'no abstract' layere.append(layerabstract) if layer.queryable: layere.set('queryable', '1') layere.append(layerexgbb) layere.append(layerbbox) style_count = len(layer.wmsextrastyles) if style_count > 0: extrastyles = layer.wmsextrastyles if style_count > 1: extrastyles = ['default'] + [x for x in extrastyles if x != 'default'] for extrastyle in extrastyles: style = ElementTree.Element('{http://www.opengis.net/wms}Style') stylename = ElementTree.Element('{http://www.opengis.net/wms}Name') stylename.text = to_unicode(extrastyle) styletitle = ElementTree.Element('{http://www.opengis.net/wms}Title') styletitle.text = to_unicode(extrastyle) style.append(stylename) style.append(styletitle) if style_count > 1 and extrastyle == 'default': styleabstract = ElementTree.Element('{http://www.opengis.net/wms}Abstract') styleabstract.text = to_unicode('This layer\'s default style that combines all its other named styles.') style.append(styleabstract) layere.append(style) rootlayerelem.append(layere) self.capabilities = ElementTree.tostring(capetree,encoding='UTF-8') response = Response('text/xml', self.capabilities) return response
To install mapnik via aptitude use something like apt-get install python-mapnik. Might need to apt-cache search on some distros. Alternatively http://mapnik.org/ """ from mapnik import Projection, Coord from decimal import Decimal DB_HOST = "localhost" DB_USER = "******" DB_PASSWORD = "******" DB_DATABASE = "database" britishProj = Projection('+init=epsg:27700') # British National Grid con = MySQLdb.Connect(host=DB_HOST, user=DB_USER, passwd=DB_PASSWORD, db=DB_DATABASE) cursor = con.cursor() cursor.execute("SELECT postcode, eastings, northings FROM %s", (DB_DATABASE)) results = cursor.fetchall() for result in results: val = Coord(float(result[1]), float(result[2])) val = britishProj.inverse(c) #cursor.execute("UPDATE uk_postcode_dev SET latitude='%f', longitude='%f' WHERE postcode='%s'" % (val.y, val.x, result[0])) print result[0] print val.y, val.x
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')
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'] render_to_file(m, args['output'])
import sys from mapnik import Box2d, Coord, Projection, ProjTransform latlon = Projection('+proj=latlong +datum=WGS84') 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 +wktext +no_defs' ) max_4326 = 85.0511287798066 max_3785 = 20037508.3427892 transform = ProjTransform(latlon, merc) if len(sys.argv) == 3: ll = transform.forward(Coord(float(sys.argv[1]), float(sys.argv[2]))) if (ll.y > max_3785): print(' '.join([str(ll.x), str(max_3785)])) elif (ll.y < -max_3785): print(' '.join([str(ll.x), str(-max_3785)])) else: print(' '.join([str(ll.x), str(ll.y)])) elif len(sys.argv) == 5: minx, miny, maxx, maxy = (float(sys.argv[1]), float(sys.argv[2]), float(sys.argv[3]), float(sys.argv[4])) if (miny < -max_4326): miny = -max_4326 if (maxy > max_4326):
def LLToPixel(self, coord, zoom): d = self.zc[zoom] e = round(d[0] + coord.x * self.Bc[zoom]) f = minmax(sin(DEG_TO_RAD * coord.y), -0.9999, 0.9999) g = round(d[1] + 0.5 * log((1 + f) / (1 - f)) * -self.Cc[zoom]) return Coord(e, g)
def pixelToLL(self, coord, zoom): e = self.zc[zoom] f = (coord.x - e[0]) / self.Bc[zoom] g = (coord.y - e[1]) / -self.Cc[zoom] h = RAD_TO_DEG * (2 * atan(exp(g)) - 0.5 * pi) return Coord(f, h)
def eastings_northings_to_lat_lng(eastings, northings): c = Coord(eastings, northings) c = BRITISH_PROJECTION.inverse(c) return c.y, c.x
def forward(self, x, y): if not self.proj: self.proj = Projection('+init=%s:%s' % (self.namespace, self.code)) return self.proj.forward(Coord(x, y))
def envLLToPixel(self, env, zoom): lb = self.LLToPixel(Coord(env.minx, env.miny), zoom) rt = self.LLToPixel(Coord(env.maxx, env.maxy), zoom) return Box2d(lb.x, lb.y, rt.x, rt.y)
def envPixelToLL(self, env, zoom): lb = self.pixelToLL(Coord(env.minx, env.miny), zoom) rt = self.pixelToLL(Coord(env.maxx, env.maxy), zoom) return Box2d(lb.x, lb.y, rt.x, rt.y)
def GetCapabilities(self, params): if not self.capabilities: capetree = ElementTree.fromstring(self.capabilitiesxmltemplate) elements = capetree.findall('Capability//OnlineResource') for element in elements: element.set('xlink:href', self.opsonlineresource) self.processServiceCapabilities(capetree) rootlayerelem = capetree.find('Capability/Layer') rootlayername = ElementTree.Element('Name') if self.conf.has_option('map', 'wms_name'): rootlayername.text = to_unicode( self.conf.get('map', 'wms_name')) else: rootlayername.text = '__all__' rootlayerelem.append(rootlayername) rootlayertitle = ElementTree.Element('Title') if self.conf.has_option('map', 'wms_title'): rootlayertitle.text = to_unicode( self.conf.get('map', 'wms_title')) else: rootlayertitle.text = 'OGCServer WMS Server' rootlayerelem.append(rootlayertitle) rootlayerabstract = ElementTree.Element('Abstract') if self.conf.has_option('map', 'wms_abstract'): rootlayerabstract.text = to_unicode( self.conf.get('map', 'wms_abstract')) else: rootlayerabstract.text = 'OGCServer WMS Server' rootlayerelem.append(rootlayerabstract) latlonbb = ElementTree.Element('LatLonBoundingBox') latlonbb.set('minx', str(self.mapfactory.latlonbb.minx)) latlonbb.set('miny', str(self.mapfactory.latlonbb.miny)) latlonbb.set('maxx', str(self.mapfactory.latlonbb.maxx)) latlonbb.set('maxy', str(self.mapfactory.latlonbb.maxy)) rootlayerelem.append(latlonbb) for epsgcode in self.allowedepsgcodes: rootlayercrs = ElementTree.Element('SRS') rootlayercrs.text = epsgcode.upper() rootlayerelem.append(rootlayercrs) for epsgcode in self.allowedepsgcodes: rootbbox = ElementTree.Element('BoundingBox') rootbbox.set('SRS', epsgcode.upper()) proj = Projection('+init=' + epsgcode) bb = self.mapfactory.latlonbb minCoord = Coord(bb.minx, bb.miny).forward(proj) maxCoord = Coord(bb.maxx, bb.maxy).forward(proj) rootbbox.set('minx', str(minCoord.x)) rootbbox.set('miny', str(minCoord.y)) rootbbox.set('maxx', str(maxCoord.x)) rootbbox.set('maxy', str(maxCoord.y)) rootlayerelem.append(rootbbox) for layer in self.mapfactory.ordered_layers: layerproj = Projection(layer.srs) layername = ElementTree.Element('Name') layername.text = to_unicode(layer.name) env = layer.envelope() llp = layerproj.inverse(Coord(env.minx, env.miny)) urp = layerproj.inverse(Coord(env.maxx, env.maxy)) latlonbb = ElementTree.Element('LatLonBoundingBox') latlonbb.set('minx', str(llp.x)) latlonbb.set('miny', str(llp.y)) latlonbb.set('maxx', str(urp.x)) latlonbb.set('maxy', str(urp.y)) layerbbox = ElementTree.Element('BoundingBox') if layer.wms_srs: layerbbox.set('SRS', layer.wms_srs) else: layerbbox.set('SRS', layerproj.epsgstring()) layerbbox.set('minx', str(env.minx)) layerbbox.set('miny', str(env.miny)) layerbbox.set('maxx', str(env.maxx)) layerbbox.set('maxy', str(env.maxy)) layere = ElementTree.Element('Layer') layere.append(layername) layertitle = ElementTree.Element('Title') if hasattr(layer, 'title'): layertitle.text = to_unicode(layer.title) if layertitle.text == '': layertitle.text = to_unicode(layer.name) else: layertitle.text = to_unicode(layer.name) layere.append(layertitle) layerabstract = ElementTree.Element('Abstract') if hasattr(layer, 'abstract'): layerabstract.text = to_unicode(layer.abstract) else: layerabstract.text = 'no abstract' layere.append(layerabstract) if layer.queryable: layere.set('queryable', '1') layere.append(latlonbb) layere.append(layerbbox) style_count = len(layer.wmsextrastyles) if style_count > 0: extrastyles = layer.wmsextrastyles if style_count > 1: extrastyles = ['default'] + [ x for x in extrastyles if x != 'default' ] for extrastyle in extrastyles: style = ElementTree.Element('Style') stylename = ElementTree.Element('Name') stylename.text = to_unicode(extrastyle) styletitle = ElementTree.Element('Title') styletitle.text = to_unicode(extrastyle) style.append(stylename) style.append(styletitle) if style_count > 1 and extrastyle == 'default': styleabstract = ElementTree.Element('Abstract') styleabstract.text = to_unicode( 'This layer\'s default style that combines all its other named styles.' ) style.append(styleabstract) layere.append(style) rootlayerelem.append(layere) self.capabilities = ElementTree.tostring(capetree, encoding='UTF-8') response = Response('application/vnd.ogc.wms_xml', self.capabilities) return response
def __init__(self, conf, mapfactory, opsonlineresource): self.conf = conf self.mapfactory = mapfactory if self.conf.has_option('service', 'allowedepsgcodes'): self.allowedepsgcodes = map( lambda code: 'epsg:%s' % code, self.conf.get('service', 'allowedepsgcodes').split(',')) else: raise ServerConfigurationError( 'Allowed EPSG codes not properly configured.') capetree = ElementTree.fromstring(self.capabilitiesxmltemplate) elements = capetree.findall('Capability//OnlineResource') for element in elements: element.set('{http://www.w3.org/1999/xlink}href', opsonlineresource) self.processServiceCapabilities(capetree) rootlayerelem = capetree.find( '{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer' ) for epsgcode in self.allowedepsgcodes: rootlayercrs = ElementTree.Element('SRS') rootlayercrs.text = epsgcode.upper() rootlayerelem.append(rootlayercrs) for layer in self.mapfactory.layers.values(): layerproj = Projection(layer.srs) layername = ElementTree.Element('Name') layername.text = layer.name env = layer.envelope() llp = layerproj.inverse(Coord(env.minx, env.miny)) urp = layerproj.inverse(Coord(env.maxx, env.maxy)) latlonbb = ElementTree.Element('LatLonBoundingBox') latlonbb.set('minx', str(llp.x)) latlonbb.set('miny', str(llp.y)) latlonbb.set('maxx', str(urp.x)) latlonbb.set('maxy', str(urp.y)) layerbbox = ElementTree.Element('BoundingBox') layerbbox.set('SRS', layerproj.epsgstring()) layerbbox.set('minx', str(env.minx)) layerbbox.set('miny', str(env.miny)) layerbbox.set('maxx', str(env.maxx)) layerbbox.set('maxy', str(env.maxy)) layere = ElementTree.Element('Layer') layere.append(layername) if layer.title: layertitle = ElementTree.Element('Title') layertitle.text = layer.title layere.append(layertitle) if layer.abstract: layerabstract = ElementTree.Element('Abstract') layerabstract.text = layer.abstract layere.append(layerabstract) if layer.queryable: layere.set('queryable', '1') layere.append(latlonbb) layere.append(layerbbox) if len(layer.wmsextrastyles) > 0: for extrastyle in [layer.wmsdefaultstyle] + list( layer.wmsextrastyles): style = ElementTree.Element('Style') stylename = ElementTree.Element('Name') stylename.text = extrastyle styletitle = ElementTree.Element('Title') styletitle.text = extrastyle style.append(stylename) style.append(styletitle) layere.append(style) rootlayerelem.append(layere) self.capabilities = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' + ElementTree.tostring( capetree)