def __init__(self, map_style, mask_style): self.default_map = Map(0,0) # only load the mask style if it's provided if mask_style is None: self.mask_map = None else: self.mask_map = Map(0,0) self.proj = Mercator(18+1) self.regions = [] try : load_map(self.default_map, map_style) # masks may not be provided if it's a single style if self.mask_map is not None: load_map(self.mask_map, mask_style) self.map_proj = Projection(self.default_map.srs) except: mq_logging.error("Exception caught in Renderer ctor") raise
class Renderer : def __init__(self, map_style, mask_style): self.default_map = Map(0,0) # only load the mask style if it's provided if mask_style is None: self.mask_map = None else: self.mask_map = Map(0,0) self.proj = Mercator(18+1) self.regions = [] try : load_map(self.default_map, map_style) # masks may not be provided if it's a single style if self.mask_map is not None: load_map(self.mask_map, mask_style) self.map_proj = Projection(self.default_map.srs) except: mq_logging.error("Exception caught in Renderer ctor") raise def add_region(self,name,mapfile,wkt_mask_file): # ignore attempts to add regions when no mask has been # specified with a warning. if self.mask_map is not None: try: m = Map(0,0) load_map(m, mapfile) mask = Mask(wkt_mask_file) self.regions.append((name,m,mask)) except Exception as ex: mq_logging.error("Exception caught adding region (%s)" % str(ex)) else: mq_logging.warning("Cannot add mask (%s) because no mask_style was configured." % name) def _check_region(self, bbox): for r in self.regions: intersects,contains = r[2].relate(bbox.minx,bbox.miny,bbox.maxx,bbox.maxy) if intersects : return contains,r[1],r[0] return None def save_rendered_metadata(self, renderer, size, dimensions): #save off the meta data if its there if renderer is not None: inmem = renderer.find_inmem_metawriter("poi-meta-data") if inmem is not None: #get the bounding boxes and ids out of the mapnik data and save in a feature collection return extractFeaturesMNK(inmem) #no data so no feature collection return None def process(self, tile): #from lat,lng bbox to mapnik bbox p0 = self.map_proj.forward(Coord(tile.bbox[0][1],tile.bbox[0][0])) p1 = self.map_proj.forward(Coord(tile.bbox[1][1],tile.bbox[1][0])) bbox = Box2d(p0,p1) image = Image(tile.size[0],tile.size[1]) features = None result = self._check_region(bbox) if result is not None: if result[0]: result[1].resize(image.width(),image.height()) result[1].zoom_to_box(bbox) render(result[1],image) features = self.save_rendered_metadata(result[1], tile.size, tile.dimensions) else : mq_logging.info("COMPOSITE MAP: %s" % result[2]) default_image = Image(tile.size[0],tile.size[1]) # mask style self.mask_map.resize(image.width(),image.height()) self.mask_map.zoom_to_box(bbox) render(self.mask_map,image) # default style self.default_map.resize(default_image.width(),default_image.height()) self.default_map.zoom_to_box(bbox) render(self.default_map,default_image) features = self.save_rendered_metadata(self.default_map, tile.size, tile.dimensions) # composite DST_OUT default_image.composite(image,CompositeOp.dst_out) # current style result[1].resize(image.width(),image.height()) result[1].zoom_to_box(bbox) image.set_alpha(0) render(result[1],image) if features is not None: features.features.extend(self.save_rendered_metadata(result[1], tile.size, tile.dimensions).features) else: features = self.save_rendered_metadata(result[1], tile.size, tile.dimensions) # blend image.blend(0,0,default_image,1.0) else : # use default style self.default_map.resize(image.width(),image.height()) self.default_map.zoom_to_box(bbox) render(self.default_map,image) features = self.save_rendered_metadata(self.default_map, tile.size, tile.dimensions) #convert to PIL image image = PIL.Image.frombuffer('RGBA', (image.width(), image.height()), image.tostring(), 'raw', 'RGBA', 0, 3) return RenderResult.from_image(tile, image, features)
def convert_loc(line): britishProj = Projection('+init=epsg:27700') # British National Grid c = Coord(float(line[2]), float(line[3])) c = britishProj.inverse(c) ## Coord now in Lat/Lng return c
class Renderer : def __init__(self, map_style, mask_style): self.default_map = Map(0,0) # only load the mask style if it's provided if mask_style is None: self.mask_map = None else: self.mask_map = Map(0,0) self.proj = Mercator(18+1) self.regions = [] try : load_map(self.default_map, map_style) # masks may not be provided if it's a single style if self.mask_map is not None: load_map(self.mask_map, mask_style) self.map_proj = Projection(self.default_map.srs) except: mq_logging.error("Exception caught in Renderer ctor") raise def add_region(self,name,mapfile,wkt_mask_file): # ignore attempts to add regions when no mask has been # specified with a warning. if self.mask_map is not None: try: m = Map(0,0) load_map(m, mapfile) mask = Mask(wkt_mask_file) self.regions.append((name,m,mask)) except Exception as ex: mq_logging.error("Exception caught adding region (%s)" % str(ex)) else: mq_logging.warning("Cannot add mask (%s) because no mask_style was configured." % name) def _check_region(self, bbox): for r in self.regions: intersects,contains = r[2].relate(bbox.minx,bbox.miny,bbox.maxx,bbox.maxy) if intersects : return contains,r[1],r[0] return None def save_rendered_metadata(self, renderer, size, dimensions): #save off the meta data if its there if renderer is not None: try: # mapnik 2.1 doesn't have this inmem = renderer.find_inmem_metawriter("poi-meta-data") except: return None if inmem is not None: # get the bounding boxes and ids out of the mapnik data and save in a feature collection return extractFeaturesMNK(inmem) #no data so no feature collection return None # If the tile has a language parameter, change the datasource definition # in the map so that the language setting is taken into account. This is # currently a bit of a hack, but can be improved later. def adjust_language(self, map, languages): if languages: for layer in self.default_map.layers: try: params = dict(layer.datasource.params()) ## mapnik >= 2.1 except: params = layer.datasource.params().as_dict() ## mapnik <= 2.0 if params.get('labelhint', '') != '': lc = [] for lines in languages.split("|"): langs = [] for lang in lines.split(","): if lang == '_': langs.append("name") else: langs.append("tags->'name:" + lang + "'") langs.append("''") lc.append('coalesce(' + ','.join(langs) + ')') if len(lc) > 1: lc[1] = "'[' || " + lc[1] + " || ']'" if len(lc) > 2: lc[2] = "'[' || " + lc[2] + " || ']'" if len(lc) > 3: lc[3] = "'[' || " + lc[3] + " || ']'" if params.get('labelhint', '') == 'replace-multiline': c = " || E'\\n' || ".join(lc) else: c = " || ' ' || ".join(lc) params['table'] = re.sub(re.compile('(name|\(?coalesce.*) as name', re.DOTALL), "(" + c + ") as name", params['table']) mq_logging.debug(str("QUERY: layer='%s' labelhint='%s' table='%s'" % (layer.name, params.get('labelhint', ''), params['table']))) # the following is a workaround for mapnik >= 2.1 d = dict() for p in params: d[str(p)] = str(params[p]) layer.datasource = CreateDatasource(d) def process(self, tile): #from lat,lng bbox to mapnik bbox p0 = self.map_proj.forward(Coord(tile.bbox[0][1],tile.bbox[0][0])) p1 = self.map_proj.forward(Coord(tile.bbox[1][1],tile.bbox[1][0])) bbox = Box2d(p0,p1) image = Image(tile.size[0],tile.size[1]) features = None result = self._check_region(bbox) if result is not None: if result[0]: result[1].resize(image.width(),image.height()) result[1].zoom_to_box(bbox) self.adjust_language(result(1), tile.lang) render(result[1],image) features = self.save_rendered_metadata(result[1], tile.size, tile.dimensions) else : mq_logging.info("COMPOSITE MAP: %s" % result[2]) default_image = Image(tile.size[0],tile.size[1]) # mask style self.mask_map.resize(image.width(),image.height()) self.mask_map.zoom_to_box(bbox) self.adjust_language(self.mask_map, tile.lang) render(self.mask_map,image) # default style self.default_map.resize(default_image.width(),default_image.height()) self.default_map.zoom_to_box(bbox) self.adjust_language(self.default_map, tile.lang) render(self.default_map,default_image) features = self.save_rendered_metadata(self.default_map, tile.size, tile.dimensions) # composite DST_OUT default_image.composite(image,CompositeOp.dst_out) # current style result[1].resize(image.width(),image.height()) result[1].zoom_to_box(bbox) image.set_alpha(0) self.adjust_language(result[1], tile.lang) render(result[1],image) if features is not None: features.features.extend(self.save_rendered_metadata(result[1], tile.size, tile.dimensions).features) else: features = self.save_rendered_metadata(result[1], tile.size, tile.dimensions) # blend image.blend(0,0,default_image,1.0) else : # use default style self.default_map.resize(image.width(),image.height()) self.default_map.zoom_to_box(bbox) self.adjust_language(self.default_map, tile.lang) render(self.default_map,image) features = self.save_rendered_metadata(self.default_map, tile.size, tile.dimensions) #convert to PIL image image = PIL.Image.frombuffer('RGBA', (image.width(), image.height()), image.tostring(), 'raw', 'RGBA', 0, 3) return RenderResult.from_image(tile, image, features)
h = RAD_TO_DEG * (2 * atan(exp(g)) - 0.5 * pi) return Coord(f, h) 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) GOOGLE_PROJECTION = GoogleProjection() LATLONG_PROJECTION = Projection(LATLONG_PROJECTION_DEF) MERCATOR_PROJECTION = Projection(MERCATOR_PROJECTION_DEF) ##### Geographic coordinate transformation def LLToMerc(coord): """Converts a Coord(lon,lat) or Box2d(l,b,r,t) to OSM Mercator (x,y).""" return MERCATOR_PROJECTION.forward(coord) def mercToLL(coord): """Converts an OSM Mercator Coord(x,y) or Box2d(l,b,r,t) to (lon,lat).""" return MERCATOR_PROJECTION.inverse(coord)