def render(qs,options): kwargs = {} if options: if ';' in options: for item in options.split(';'): if ':' in item: k,v = item.split(':') kwargs[k] = v width = int(kwargs.get('width',600)) height = int(kwargs.get('height',600)) #field = kwargs.get('field',None) if hasattr(qs,'_meta'): # it looks like a model qs = qs.objects.all() m = mapnik.Map(width,height) m.aspect_fix_mode = mapnik.aspect_fix_mode.GROW_CANVAS adapter = PostgisLayer(qs) lyr = adapter.to_mapnik() sty = adapter.get_default_style() lyr.styles.append('style') m.append_style('style',sty) #m.background = mapnik.Color('green') m.srs = lyr.srs m.layers.append(lyr) m.zoom_all() #print mapnik.save_map_to_string(m) mod = qs.query.get_meta().module_name # TODO - need way to properly cache vs. always overwriting... name = '%s_%s_%s_%s.png' % (mod,width,height,random()) map_graphic = os.path.join(graphics,name) mapnik.render_to_file(m,str(map_graphic)) url = os.path.join(settings.MEDIA_URL,'mapgraphics',name) return mark_safe(force_unicode('<img src="%s" />' % smart_str(url)))
def show(self, **kwargs): timeit = kwargs.get('timeit') if timeit: start = time.time() # todo - we should check for postgis support, and otherwise # use the MemoryDatasource lyr_adapter = PostgisLayer(self) lyr_adapter.show(**kwargs) if timeit: elapsed = (time.time() - start) / 60 print 'render time: %s seconds' % elapsed
def draw_map(uids, user, width, height, autozoom=False, bbox=None, show_extent=False, map_name='default'): """Display a map with the study region geometry. """ map = get_object_or_404(MapConfig, mapname=map_name) if not width: width = map.default_width if not height: height = map.default_height mapfile = str(map.mapfile.path) # Create a blank image and map draw = mapnik.Image(width, height) m = mapnik.Map(width, height) # load_map is NOT thread safe (?) # load_map_from_string appears to work #mapnik.load_map(m, mapfile) xmltext = open(mapfile).read() mapnik.load_map_from_string(m, xmltext) log.debug("Completed load_map_from_string(), Map object is %r" % m) # Create the mapnik layers features = get_features(uids, user) for model, pks in features: try: geomfield = model.mapnik_geomfield() except AttributeError: geomfield = 'geometry_final' if geomfield not in [str(x.name) for x in model._meta.fields]: continue if not issubclass(model, FeatureCollection): try: style = model.mapnik_style() except AttributeError: style = default_style() style_name = str('%s_style' % model.model_uid()) # tsk mapnik cant take unicode m.append_style(style_name, style) adapter = PostgisLayer(model.objects.filter(pk__in=pks), field_name=geomfield) lyr = adapter.to_mapnik() lyr.styles.append(style_name) m.layers.append(lyr) # Grab the bounding coordinates and set them if specified # first, assume default image extent x1, y1 = map.default_x1, map.default_y1 x2, y2 = map.default_x2, map.default_y2 if not bbox and autozoom and features and len(features) > 0: x1, y1, x2, y2 = auto_extent(features, map.default_srid) if bbox: try: x1, y1, x2, y2 = [float(x) for x in bbox.split(',')] except: pass bbox = mapnik.Envelope(mapnik.Coord(x1, y1), mapnik.Coord(x2, y2)) if show_extent and features and len(features) > 0: # Shows a bounding box for the extent of all specified features # Useful for overview maps x1, y1, x2, y2 = auto_extent(features, map.default_srid) ps = mapnik.PolygonSymbolizer(mapnik.Color('#ffffff')) ps.fill_opacity = 0.8 ls = mapnik.LineSymbolizer(mapnik.Color('#ff0000'), 2.0) r = mapnik.Rule() r.symbols.append(ps) r.symbols.append(ls) extent_style = mapnik.Style() extent_style.rules.append(r) m.append_style('extent_style', extent_style) lyr = mapnik.Layer("Features Extent") bbox_sql = """ (select 1 as id, st_setsrid(st_makebox2d(st_point(%s,%s),st_point(%s,%s)), %s) as geometry_final) as aoi """ % (x1, y1, x2, y2, map.default_srid) lyr.datasource = mapnik.PostGIS( host=connection.settings_dict['HOST'], user=connection.settings_dict['USER'], password=connection.settings_dict['PASSWORD'], dbname=connection.settings_dict['NAME'], table=bbox_sql, geometry_field='geometry_final', estimate_extent='False', extent='%s,%s,%s,%s' % (x1, y1, x2, y2)) lyr.styles.append('extent_style') m.layers.append(lyr) # Render image and send out the response m.zoom_to_box(bbox) mapnik.render(m, draw) img = draw.tostring('png') # if testing via django unit tests, close out the connection conn = connection.settings_dict if conn['NAME'] != settings_dbname: del m return img