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 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 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)
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 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 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)
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
# 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...'
#!/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)