def render(mapfile, dst_img, mm_width, mm_height, bounds, dpi=300, nztm_style='style-nztm.xml'): ''' Render an image with mapnik from an *.xml style file ''' # create a version of the source style document in NZTM set_projection(mapfile, dst_path=nztm_style) # convert mm to pixels pixel_width = mm_to_pixels(mm_width, dpi) pixel_height = mm_to_pixels(mm_height, dpi) print('Rendering {} @ {} x {} pixels @ {} dpi'.format( dst_img, pixel_width, pixel_height, dpi)) # create the output map m = mapnik.Map(pixel_width, pixel_height) # load style rules & set bounding box mapnik.load_map(m, nztm_style) bbox = mapnik.Envelope(mapnik.Coord(bounds[0], bounds[1]), mapnik.Coord(bounds[2], bounds[3])) m.zoom_to_box(bbox) # render map & save mapnik.render_to_file(m, dst_img) print('Rendered {} @ {} x {} pixels'.format(dst_img, pixel_width, pixel_height))
def render_tile(self, tile_uri, x, y, z): # Calculate pixel positions of bottom-left & top-right p0 = (x * TILE_SIZE, y * TILE_SIZE) p1 = ((x + 1) * TILE_SIZE, (y + 1) * TILE_SIZE) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # These are already in EPSG:4326, no need to project c0 = mapnik.Coord(l0[0], l0[1]) c1 = mapnik.Coord(l1[0], l1[1]) # Bounding box for the tile bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) #print bbox render_size = TILE_SIZE self.m.resize(render_size, render_size) self.m.zoom_to_box(bbox) self.m.buffer_size = 128 # Render image with default Agg renderer im = mapnik.Image(render_size, render_size) mapnik.render(self.m, im) im.save(tile_uri, 'png256') upload_file(self.tile_dir, filename[len(self.tile_dir):], AWS_BUCKET_NAME, AWS_KEY_NAME)
def get_image(self, zoom, tilex, tiley): tileid = zoom + (tilex << 5) + (tiley << (5 + zoom)) objset = self.filter(id=tileid) if not objset: if self.emptytile is None: raise Http404 else: return self.emptytile image = objset[0].pixbuf if image is None: p0 = self.gproj.fromTileToLL(zoom, tilex, tiley + 1) p1 = self.gproj.fromTileToLL(zoom, tilex + 1, tiley) c0 = self.mproj.forward(mapnik.Coord(p0[0], p0[1])) c1 = self.mproj.forward(mapnik.Coord(p1[0], p1[1])) bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) self.map.zoom_to_box(bbox) im = mapnik.Image(256, 256) mapnik.render(self.map, im) image = im.tostring('png256') # update the hard way, django can't handle multikeys objset.update(pixbuf=image) return image
def test_render_grid(): """ test old method """ width, height = 256, 256 m = create_grid_map(width, height) ul_lonlat = mapnik.Coord(142.30, -38.20) lr_lonlat = mapnik.Coord(143.40, -38.80) m.zoom_to_box(mapnik.Box2d(ul_lonlat, lr_lonlat)) grid = mapnik.render_grid(m, 0, key='Name', resolution=4, fields=['Name']) eq_(grid, grid_correct) eq_(resolve(grid, 0, 0), None) # check every pixel of the nw symbol expected = {"Name": "North West"} # top row eq_(resolve(grid, 23, 9), expected) eq_(resolve(grid, 23, 10), expected) eq_(resolve(grid, 23, 11), expected) # core eq_(resolve(grid, 24, 8), expected) eq_(resolve(grid, 24, 9), expected) eq_(resolve(grid, 24, 10), expected) eq_(resolve(grid, 24, 11), expected) eq_(resolve(grid, 24, 12), expected) eq_(resolve(grid, 25, 8), expected) eq_(resolve(grid, 25, 9), expected) eq_(resolve(grid, 25, 10), expected) eq_(resolve(grid, 25, 11), expected) eq_(resolve(grid, 25, 12), expected) # bottom row eq_(resolve(grid, 26, 9), expected) eq_(resolve(grid, 26, 10), expected) eq_(resolve(grid, 26, 11), expected)
def render(self, filename, latitude, longitude, zoom): """ Render a single tile to a given filename. """ print 'Rendering %s' % (filename) x, y = self.tile_projection.fromLLtoPixel([longitude, latitude], zoom) # Calculate pixel positions of bottom-left & top-right half_width = self.width / 2 half_height = self.height / 2 px0 = (x - half_width, y + half_height) px1 = (x + half_width, y - half_height) # Convert tile coords to LatLng ll0 = self.tile_projection.fromPixelToLL(px0, zoom) ll1 = self.tile_projection.fromPixelToLL(px1, zoom) # Convert LatLng to map coords c0 = self.map_projection.forward(mapnik.Coord(ll0[0], ll0[1])) c1 = self.map_projection.forward(mapnik.Coord(ll1[0], ll1[1])) # Create bounding box for the render bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) self.mapnik_map.zoom_to_box(bbox) self.mapnik_map.buffer_size = self.buffer_size # Render image with default renderer image = mapnik.Image(self.width, self.height) mapnik.render(self.mapnik_map, image) image.save(filename, self.filetype)
def render_tile(self, tile_uri, x, y, z): # Calculate pixel positions of bottom-left & top-right p0 = (x * 256, (y + 1) * 256) p1 = ((x + 1) * 256, y * 256) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) # Bounding box for the tile if hasattr(mapnik, 'mapnik_version') and mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) else: bbox = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) render_size = 256 self.m.resize(render_size, render_size) self.m.zoom_to_box(bbox) self.m.buffer_size = 128 # Render image with default Agg renderer im = mapnik.Image(render_size, render_size) mapnik.render(self.m, im) im.save(tile_uri, 'png256')
def test_add_feature(): md = mapnik.MemoryDatasource() eq_(md.num_features(), 0) context = mapnik.Context() context.push('foo') feature = mapnik.Feature(context, 1) feature['foo'] = 'bar' feature.add_geometries_from_wkt('POINT(2 3)') md.add_feature(feature) eq_(md.num_features(), 1) featureset = md.features_at_point(mapnik.Coord(2, 3)) retrieved = [] for feat in featureset: retrieved.append(feat) eq_(len(retrieved), 1) f = retrieved[0] eq_(f['foo'], 'bar') featureset = md.features_at_point(mapnik.Coord(20, 30)) retrieved = [] for feat in featureset: retrieved.append(feat) eq_(len(retrieved), 0)
def render(self, path, tile_x, tile_y, zoom): """ Render a single tile to a given filename. """ print 'Rendering %s' % (path) # Calculate pixel positions of bottom-left & top-right half_width = self.width / 2 half_height = self.height / 2 px0 = (tile_x * self.width, (tile_y + 1) * self.height) px1 = ((tile_x + 1) * self.width, tile_y * self.height) # Convert tile coords to LatLng ll0 = self.tile_projection.fromPixelToLL(px0, zoom) ll1 = self.tile_projection.fromPixelToLL(px1, zoom) # Convert LatLng to map coords c0 = self.map_projection.forward(mapnik.Coord(ll0[0], ll0[1])) c1 = self.map_projection.forward(mapnik.Coord(ll1[0], ll1[1])) # Create bounding box for the render bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) self.mapnik_map.zoom_to_box(bbox) self.mapnik_map.buffer_size = self.buffer_size if self.filetype == 'svg': surface = cairo.SVGSurface(path, self.width, self.height) mapnik.render(self.mapnik_map, surface) surface.finish() else: image = mapnik.Image(self.width, self.height) mapnik.render(self.mapnik_map, image) image.save(path, self.filetype) if self.grid: if self.key: grid = mapnik.Grid(self.width, self.height) else: grid = mapnik.Grid(self.width, self.height, key=self.key) fields = [] if self.fields: fields.extend(self.fields) mapnik.render_layer(self.mapnik_map, grid, layer=0, fields=fields) # then encode the grid array as utf, resample to 1/4 the size, and dump features # this comes from https://github.com/springmeyer/gridsforkids/blob/master/generate_tiles.py # with little consideration grid_utf = grid.encode('utf', resolution=4, features=True) # client code uses jsonp, so fake by wrapping in grid() callback base, ext = os.path.splitext(path) grid_filename = '%s.grid.json' % base print 'Rendering %s' % (grid_path) with open(grid_path, 'wb') as f: f.write('grid(' + json.dumps(grid_utf) + ')')
def test_render_grid(): places_ds = mapnik.PointDatasource() places_ds.add_point(143.10,-38.60,'Name','South East') places_ds.add_point(142.48,-38.60,'Name','South West') places_ds.add_point(142.48,-38.38,'Name','North West') places_ds.add_point(143.10,-38.38,'Name','North East') s = mapnik.Style() r = mapnik.Rule() #symb = mapnik.PointSymbolizer() symb = mapnik.MarkersSymbolizer() symb.allow_overlap = True r.symbols.append(symb) label = mapnik.TextSymbolizer(mapnik.Expression('[Name]'), 'DejaVu Sans Book', 10, mapnik.Color('black') ) label.allow_overlap = True label.displacement = (0,-10) #r.symbols.append(label) s.rules.append(r) lyr = mapnik.Layer('Places') lyr.datasource = places_ds lyr.styles.append('places_labels') m = mapnik.Map(256,256) m.append_style('places_labels',s) m.layers.append(lyr) ul_lonlat = mapnik.Coord(142.30,-38.20) lr_lonlat = mapnik.Coord(143.40,-38.80) m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat)) grid = mapnik.render_grid(m,0,key='Name',resolution=4,fields=['Name']) eq_(grid,grid_correct) eq_(resolve(grid,0,0),None) # check every pixel of the nw symbol expected = {"Name": "North West"} # top row eq_(resolve(grid,23,9),expected) eq_(resolve(grid,23,10),expected) eq_(resolve(grid,23,11),expected) # core eq_(resolve(grid,24,8),expected) eq_(resolve(grid,24,9),expected) eq_(resolve(grid,24,10),expected) eq_(resolve(grid,24,11),expected) eq_(resolve(grid,24,12),expected) eq_(resolve(grid,25,8),expected) eq_(resolve(grid,25,9),expected) eq_(resolve(grid,25,10),expected) eq_(resolve(grid,25,11),expected) eq_(resolve(grid,25,12),expected) # bottom row eq_(resolve(grid,26,9),expected) eq_(resolve(grid,26,10),expected) eq_(resolve(grid,26,11),expected)
def render(self): """ Renders the request, returning a binary in the specified format. """ map_size = self.get_size() map, data_layers = self.factory.getMap(self.map_definition, map_size) geojson_file = tempfile.NamedTemporaryFile(suffix='.json') try: # write the JSON to a temporary file geojson_file.write(str(self)) geojson_file.flush() # find the layer definition(s) in the map xml and update it # to point to our temporary file geojson_dir, geojson_filename = os.path.split(geojson_file.name) for layer in data_layers: layer.datasource = mapnik.Ogr(base=geojson_dir, file=geojson_filename, layer='OGRGeoJSON') # set the map extent if self.bbox_image: # specified extent map_bbox = mapnik.Envelope( mapnik.Coord(self.bbox_image[0], self.bbox_image[1]), mapnik.Coord(self.bbox_image[2], self.bbox_image[3])) map.zoom_to_box(map_bbox) else: # zoom to the extent of our data layers extent = data_layers[0].envelope() for l in data_layers[1:]: extent += layer.envelope() map.zoom_to_box(extent) # if we have a buffer, apply it if self.bbox_image_buffer: extent = map.envelope() units = self.bbox_image_buffer[1].lower() if units == 'map': # map-units buffer = self.bbox_image_buffer[0] extent.expand_to_include(extent.minx - buffer, extent.miny - buffer) extent.expand_to_include(extent.maxx + buffer, extent.maxy + buffer) elif units == 'px': # pixels map.buffer_size = self.bbox_image_buffer[0] extent = map.buffered_envelope() else: self.L.warn("Unknown bbox_image_buffer units: %s", units) # reapply our new extent map.zoom_to_box(extent) # render it return self._render_surface(map, map_size) finally: geojson_file.close()
def _project_envelope(self, bbox): """Project the given bounding box into the rendering projection.""" envelope = mapnik.Box2d(bbox.get_top_left()[1], bbox.get_top_left()[0], bbox.get_bottom_right()[1], bbox.get_bottom_right()[0]) c0 = self._proj.forward(mapnik.Coord(envelope.minx, envelope.miny)) c1 = self._proj.forward(mapnik.Coord(envelope.maxx, envelope.maxy)) return mapnik.Box2d(c0.x, c0.y, c1.x, c1.y)
def test_render_points(): if not mapnik.has_cairo(): return # create and populate point datasource (WGS84 lat-lon coordinates) ds = mapnik.MemoryDatasource() context = mapnik.Context() context.push('Name') f = mapnik.Feature(context, 1) f['Name'] = 'Westernmost Point' f.add_geometries_from_wkt('POINT (142.48 -38.38)') ds.add_feature(f) f = mapnik.Feature(context, 2) f['Name'] = 'Southernmost Point' f.add_geometries_from_wkt('POINT (143.10 -38.60)') ds.add_feature(f) # create layer/rule/style s = mapnik.Style() r = mapnik.Rule() symb = mapnik.PointSymbolizer() symb.allow_overlap = True r.symbols.append(symb) s.rules.append(r) lyr = mapnik.Layer('Places', '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') lyr.datasource = ds lyr.styles.append('places_labels') # latlon bounding box corners ul_lonlat = mapnik.Coord(142.30, -38.20) lr_lonlat = mapnik.Coord(143.40, -38.80) # render for different projections projs = { 'google': '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over', 'latlon': '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs', 'merc': '+proj=merc +datum=WGS84 +k=1.0 +units=m +over +no_defs', 'utm': '+proj=utm +zone=54 +datum=WGS84' } for projdescr in projs.iterkeys(): m = mapnik.Map(1000, 500, projs[projdescr]) m.append_style('places_labels', s) m.layers.append(lyr) dest_proj = mapnik.Projection(projs[projdescr]) src_proj = mapnik.Projection('+init=epsg:4326') tr = mapnik.ProjTransform(src_proj, dest_proj) m.zoom_to_box(tr.forward(mapnik.Box2d(ul_lonlat, lr_lonlat))) # Render to SVG so that it can be checked how many points are there with string comparison svg_file = os.path.join(tempfile.gettempdir(), 'mapnik-render-points-%s.svg' % projdescr) mapnik.render_to_file(m, svg_file) num_points_present = len(ds.all_features()) svg = open(svg_file, 'r').read() num_points_rendered = svg.count('<image ') eq_( num_points_present, num_points_rendered, "Not all points were rendered (%d instead of %d) at projection %s" % (num_points_rendered, num_points_present, projdescr))
def render(self, input_file, extent, lyr_style): proj4lyr = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' county_file = '../datas/county.shp' # river_file = '../datas/river.shp' # capital_file ='Capital3.json' filename = os.path.split(input_file)[1] areaCode = os.path.splitext(filename)[0] output_file = input_file.split('.')[0] + '.png' print areaCode # ----------create map--------------------- m = mapnik.Map(extent.xsize, extent.ysize) mapnik.load_map(m, 'cg_config.xml') # ----------create layer 1----------------- layer = mapnik.Layer('dataraster', proj4lyr) # ----------create layer 1 datasource------ layer.datasource = mapnik.Gdal(file=input_file, band=1, nodata=-999) layer.styles.append(lyr_style) # ----------append layer 1 to map---------- m.layers.append(layer) # ----------create layer 2----------------- layer2 = mapnik.Layer('county', proj4lyr) # Create new styles and add the rules. s_county = m.find_style('county') r_county = s_county.rules[0] r_county.filter = mapnik.Filter('[CITY]=' + areaCode) m.append_style(areaCode, s_county) # ----------create layer 2 datasource------ layer2.datasource = mapnik.Shapefile(file=county_file) layer2.styles.append(areaCode) # ----------append layer 2 to map---------- m.layers.append(layer2) # ----------create layer 3----------------- layer3 = mapnik.Layer('capital', proj4lyr) # Create new styles and add the rules. s_capital = m.find_style('capital') r_capital = s_capital.rules[0] r_capital.filter = mapnik.Filter('[CITY]=' + areaCode) m.append_style('symbol', s_capital) # ----------create layer 3 datasource------ layer3.datasource = mapnik.Shapefile(file=county_file) layer3.styles.append('symbol') # ----------append layer 3 to map---------- m.layers.append(layer3) ll = mapnik.Coord(extent.xmax, extent.ymax) tr = mapnik.Coord(extent.xmin, extent.ymin) map_bbox = mapnik.Box2d(tr, ll) # mapnik.Envelope(tr, ll) m.zoom_to_box(map_bbox) print m.envelope(), m.scale() mapnik.render_to_file(m, output_file, 'png') return 'true'
def to_mercator(self): envelope = mapnik.Box2d(self.get_top_left()[1], self.get_top_left()[0], self.get_bottom_right()[1], self.get_bottom_right()[0]) _proj = mapnik.Projection(_MAPNIK_PROJECTION) bottom_left = _proj.forward(mapnik.Coord(envelope.minx, envelope.miny)) top_right = _proj.forward(mapnik.Coord(envelope.maxx, envelope.maxy)) top_left = mapnik.Coord(bottom_left.x, top_right.y) bottom_right = mapnik.Coord(top_right.x, bottom_left.y) return (bottom_right, bottom_left, top_left, top_right)
def renderImage(self, map_output, mapfile, imgx, imgy, bbox): print "renderImage" m = mapnik.Map(imgx, imgy) mapnik.load_map(m, mapfile) #ll = (1321613.269848, 6475998.706584, 1674460.199655, 6743324.6719772) ll = (1321613.269848, 6475998.706584, 1674460.199655, 6743324.671977) ll = bbox bbox = mapnik.Box2d(mapnik.Coord(ll[0], ll[3]), mapnik.Coord(ll[2], ll[1])) m.zoom_to_box(bbox) mapnik.render_to_file(m, map_output)
def render_tile(self) -> bytes: """ generate tile or load it from redis cache :return: tile as png image in bytes format """ tile_name: str = '/tmp/{}-{}-{}-{}.png'.format( self.request_date_to_string(), self.zoom, self.x_pixel, self.y_pixel) if env.bool("CACHE", default=False): # try if exists to get cache style_xml try: tile_content = cache.get(tile_name) if tile_content: return tile_content except (redis.exceptions.ConnectionError, redis.exceptions.DataError) as exc: print(exc) os.chdir(os.environ['STYLE_PATH']) map: mapnik.Map = mapnik.Map(self.width, self.height) mapnik.load_map_from_string(map, self.generate_date_style_xml()) prj: mapnik.Projection = mapnik.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 +over" ) p0 = self.from_px_to_ll( (self.width * self.x_pixel, self.height * (self.y_pixel + 1)), self.zoom) p1 = self.from_px_to_ll( (self.width * (self.x_pixel + 1), self.height * self.y_pixel), self.zoom) c0 = prj.forward(mapnik.Coord(p0[0], p0[1])) c1 = prj.forward(mapnik.Coord(p1[0], p1[1])) bbox: mapnik.Envelope = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y) map.zoom_to_box(bbox) image: mapnik.Image = mapnik.Image(self.width, self.height) mapnik.render(map, image) # todo generate tile without save it to hdd mapnik.render_to_file(map, tile_name) tile_content: bytes = open(tile_name, 'rb').read() os.remove(tile_name) if env.bool("CACHE", default=False): # upload style_xml file to redis cache cache.set(tile_name, tile_content, ex=env.int("CAHCE_EXPIRE_TIME", default=3600)) return tile_content
def test_point_symbolizer_grid(): width,height = 256,256 sym = mapnik.PointSymbolizer() sym.file = '../data/images/dummy.png' m = create_grid_map(width,height,sym) ul_lonlat = mapnik.Coord(142.30,-38.20) lr_lonlat = mapnik.Coord(143.40,-38.80) m.zoom_to_box(mapnik.Box2d(ul_lonlat,lr_lonlat)) grid = mapnik.Grid(m.width,m.height) mapnik.render_layer(m,grid,layer=0,fields=['Name']) utf1 = grid.encode() eq_(utf1,point_expected,show_grids('point-sym',utf1,point_expected))
def calcTileCoordinates(self, tile, zoom): # Calculate pixel positions of bottom-left & top-right p0 = (tile[0] * 256, (tile[1] + 1) * 256) p1 = ((tile[0] + 1) * 256, tile[1] * 256) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, zoom) l1 = self.tileproj.fromPixelToLL(p1, zoom) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) return c0, c1
def getExtents(self, tile): z = start_zoom + zoomFactor #print tile p0 = (tile[0] * 256, (tile[1] + 1) * 256) p1 = ((tile[0] + 1) * 256, tile[1] * 256) # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = prj.forward(mapnik.Coord(l0[0],l0[1])) c1 = prj.forward(mapnik.Coord(l1[0],l1[1])) tile_extent = (c0.x,c0.y, c1.x,c1.y) return tile_extent, z
def _renderGridinfo(self,x,y,z,l0,l1,tile_uris): for i in range(int(self.tile_countX)): for j in range(int(self.tile_countY)): pt0 = (x + self.tile_size*i, y + self.tile_size*(j+1)) pt1 = (x + self.tile_size*(i+1), y + self.tile_size*j) # Convert to LatLong (EPSG:4326) lt0 = self.tileproj.fromPixelToLL(pt0, z); lt1 = self.tileproj.fromPixelToLL(pt1, z); # Convert to map projection (e.g. mercator co-ords EPSG:900913) ct0 = self.prj.forward(mapnik.Coord(lt0[0],lt0[1])) ct1 = self.prj.forward(mapnik.Coord(lt1[0],lt1[1])) if self.gridMap: mi = 0 for country,_gridMap in self.gridMap.items(): if self.countries[country].intersects(mapnik.Box2d(l0[0],l0[1],l1[0],l1[1])): try: _gridMap.zoom_to_box(mapnik.Box2d(ct0.x,ct0.y, ct1.x,ct1.y)) _gridMap.resize(int(self.tile_size), int(self.tile_size)) _gridMap.buffer_size = 0 grid = mapnik.Grid(int(self.tile_size), int(self.tile_size)) mapnik.render_layer(_gridMap, grid, layer = 1, fields=['symbol_name','wiki']) mapnik.render_layer(_gridMap, grid, layer = 0, fields=['highway','grade','surface','smoothness','ref','int_ref','tracktype','name']) utfgrid = grid.encode('utf',resolution=4) for key1 in utfgrid['data']: for key2,val2 in utfgrid['data'][key1].items(): if val2 in (None,'no',''): del utfgrid['data'][key1][key2] gridname = tile_uris[i*self.tile_countY +j].replace(".jpg",".js") f = codecs.open(gridname + '.tmp','w','utf-8') f.write(json.dumps(utfgrid, ensure_ascii = False)) f.close() if mi > 0: os.system('gzip -f %s' % (gridname + '.tmp')) if os.path.getsize(gridname + '.tmp.gz') > os.path.getsize(gridname+'.gz'): os.remove(gridname + '.gz') os.rename(gridname + '.tmp.gz',gridname+'.gz') else: os.remove(gridname + '.tmp.gz') else: os.rename(gridname + '.tmp.gz',gridname+'.gz') except Exception as E: print E mi += 1
def render(self, zoom, x, y, fmt): p0 = self.gproj.tile_nw(zoom, x, y + 1) p1 = self.gproj.tile_nw(zoom, x + 1, y) c0 = self.mproj.forward(mapnik.Coord(p0[0], p0[1])) c1 = self.mproj.forward(mapnik.Coord(p1[0], p1[1])) bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) im = mapnik.Image(*self.tile_size) m = self.get_map() m.zoom_to_box(bbox) mapnik.render(m, im) return im.tostring('png256')
def __init__(self, geom_type, zoom, m): proj = mapnik.Projection(m.srs) width_of_world_in_pixels = 2**zoom * 256 width_of_world_in_metres = proj.forward(mapnik.Coord( 180, 0)).x - proj.forward(mapnik.Coord(-180, 0)).x width_of_image_in_metres = float( m.width) / width_of_world_in_pixels * width_of_world_in_metres height_of_image_in_metres = float( m.height) / width_of_world_in_pixels * width_of_world_in_metres self.max_x = width_of_image_in_metres self.max_y = height_of_image_in_metres self.min_x = 0 self.min_y = 0 if geom_type == "point": self.geom = geojson.Point((self.max_x / 2, self.max_y / 2)) elif geom_type == "point75": self.geom = geojson.Point((self.max_x * 0.5, self.max_y * 0.75)) elif geom_type == "polygon": self.geom = geojson.Polygon([[(0, 0), (self.max_x, 0), (self.max_x, self.max_y), (0, self.max_y), (0, 0)]]) elif geom_type == "linestring-with-gap": self.geom = geojson.MultiLineString([[ (0, 0.5 * self.max_y), (self.max_x * 0.45, 0.5 * self.max_y), (self.max_x * 0.55, 0.5 * self.max_y), (self.max_x, 0.5 * self.max_y) ]]) elif geom_type == "polygon-with-hole": self.geom = geojson.Polygon([[[0.7 * self.max_x, 0.2 * self.max_y], [0.9 * self.max_x, 0.9 * self.max_y], [0.3 * self.max_x, 0.8 * self.max_y], [0.2 * self.max_x, 0.4 * self.max_y], [0.7 * self.max_y, 0.2 * self.max_y]], [[0.4 * self.max_x, 0.6 * self.max_y], [0.7 * self.max_x, 0.7 * self.max_y], [0.6 * self.max_x, 0.4 * self.max_y], [0.4 * self.max_x, 0.6 * self.max_y]]]) elif geom_type == "linestring": self.geom = geojson.LineString([[0, 0.5 * self.max_y], [self.max_x, 0.5 * self.max_y]]) else: raise MapnikLegendaryError( "Geometry type {} is not supported for legend entries.".format( geom_type))
def num2deg(self, xtile, ytile, zoom): """Convert tile number to coordinates (of the upper corner)""" n = 2.0 ** zoom lon_deg = xtile / n * 360.0 - 180.0 lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n))) lat_deg = math.degrees(lat_rad) return mapnik.Coord(y=lat_deg, x=lon_deg)
def run(): sf = shapelib.open( os.getenv("SWFP_DATADIR") + "/mapnik_render/world_boundaries/world_boundaries_m.shp") d = dbflib.DBFFile( os.getenv("SWFP_DATADIR") + "/mapnik_render/world_boundaries/world_boundaries_m.dbf") num_shapes = sf.info()[0] assert num_shapes == d.record_count() swedish_polygons = 0 for idx in xrange(num_shapes): obj = sf.read_object(idx) rec = d.read_record(idx) if rec['CNTRY_NAME'] == 'Sweden': #print "Sweden: ",obj.vertices() swedish_polygons += 1 assert len(obj.vertices()) == 1 out = [] for vert in obj.vertices()[0]: cd = prj.inverse(mapnik.Coord(vert[1], vert[0])) #print "lat: %s, lon: %s,"%(cd.y,cd.x) out.append(mapper.format_lfv(cd.y, cd.x)) print "Swedpol:", " - ".join(out) print "Swedish polygons: %d" % (swedish_polygons, )
def test_wgs84_inverse_forward(): p = mapnik.Projection('+init=epsg:4326') c = mapnik.Coord(3.01331418311, 43.3333092669) e = mapnik.Box2d(-122.54345245, 45.12312553, 68.2335581353, 48.231231233) # It appears that the y component changes very slightly, is this OK? # so we test for 'almost equal float values' assert_almost_equal(p.inverse(c).y, c.y) assert_almost_equal(p.inverse(c).x, c.x) assert_almost_equal(p.forward(c).y, c.y) assert_almost_equal(p.forward(c).x, c.x) assert_almost_equal(p.inverse(e).center().y, e.center().y) assert_almost_equal(p.inverse(e).center().x, e.center().x) assert_almost_equal(p.forward(e).center().y, e.center().y) assert_almost_equal(p.forward(e).center().x, e.center().x) assert_almost_equal(c.inverse(p).y, c.y) assert_almost_equal(c.inverse(p).x, c.x) assert_almost_equal(c.forward(p).y, c.y) assert_almost_equal(c.forward(p).x, c.x) assert_almost_equal(e.inverse(p).center().y, e.center().y) assert_almost_equal(e.inverse(p).center().x, e.center().x) assert_almost_equal(e.forward(p).center().y, e.center().y) assert_almost_equal(e.forward(p).center().x, e.center().x)
def set_center_and_radius(self, lon, lat, radius=None, geographic=True): coords = mapnik.Coord(lon, lat) box = mapnik.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 createJGW(path): import tempfile EPSG900913 = "+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" S2P = 360.0 / 0.127 MAP_NM = 0.014 MAP_EM = 0.008 MAP_SM = 0.013 MAP_WM = 0.008 if path.count("|") < 9 or path.count("|") > 10 or len(path) < 30: return "Incorrectly formatted string." if path.count("|") == 9: path = path + "|" style, paper, scale, centre, title, club, mapid, start, crosses, cps, controls = path.split( "|") style = style.split("=")[1] paper = paper.split("=")[1] PAPER_W = float(paper.split(",")[0]) PAPER_H = float(paper.split(",")[1]) scale = int(scale.split("=")[1]) centre = centre.split("=")[1] clat = int(centre.split(",")[0]) clon = int(centre.split(",")[1]) projection = mapnik.Projection(EPSG900913) wgs84lat = mapnik.Coord(clon, clat).inverse(projection).y scaleCorrectionFactor = math.cos(wgs84lat * math.pi / 180) scaleCorrected = scale / scaleCorrectionFactor if style == "adhoc": MAP_EM = MAP_WM MAP_NM = MAP_WM MAP_SM = MAP_WM MAP_W = PAPER_W - MAP_WM - MAP_EM MAP_H = PAPER_H - MAP_NM - MAP_SM paperSLat = clat - (MAP_H / 2 + MAP_SM) * scaleCorrected paperNLat = clat + (MAP_H / 2 + MAP_NM) * scaleCorrected paperWLon = clon - (MAP_W / 2 + MAP_WM) * scaleCorrected paperELon = clon + (MAP_W / 2 + MAP_EM) * scaleCorrected PIXEL_W = PAPER_W * S2P PIXEL_H = PAPER_H * S2P fworld = tempfile.NamedTemporaryFile() fworld.write(str((paperELon - paperWLon) / PIXEL_W) + "\n") fworld.write(str(0) + "\n") fworld.write(str(0) + "\n") fworld.write(str((paperSLat - paperNLat) / PIXEL_H) + "\n") fworld.write(str(paperWLon) + "\n") fworld.write(str(paperNLat) + "\n") fworld.seek(0) return fworld
def render_tile(self, z, scale, p0, p1, metawidth, metaheight, debug): # Calculate pixel positions of bottom-left & top-right # Convert to LatLong (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z) l1 = self.tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0], l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0], l1[1])) # Bounding box for the tile bbox = mapnik.Box2d(c0.x, c0.y, c1.x, c1.y) self.m.resize(metawidth * TILE_SIZE, metaheight * TILE_SIZE) self.m.zoom_to_box(bbox) self.m.buffer_size = BUF_SIZE if debug >= 2: self.lock.acquire() print z, bbox, metawidth, metaheight self.lock.release() # Render image with default Agg renderer metaimage = mapnik.Image(metawidth * TILE_SIZE, metaheight * TILE_SIZE) mapnik.render(self.m, metaimage, scale) # save metatile for debug purposes only # metaimage.save("/media/henry/Tools/map/tiles/MyCycleMapHD/" + "%s"%z + "-" + "%s" % (p0[0]/TILE_SIZE) + "-" + "%s" % (p1[1]/TILE_SIZE)+".png", 'png256') for my in range(0, metaheight): for mx in range(0, metawidth): tile = metaimage.view(mx * TILE_SIZE, my * TILE_SIZE, TILE_SIZE, TILE_SIZE) if debug >= 3: self.lock.acquire() print "Tile: x=", p0[0] / TILE_SIZE + mx, "y=", p1[ 1] / TILE_SIZE + my, "z=", z self.lock.release() item = (Command.write, p0[0] / TILE_SIZE + mx, p1[1] / TILE_SIZE + my, z, tile.tostring('png256')) self.writer.put(item) # commit batch if required (SQLite-db) item = (Command.commit, None, None, None, None) self.writer.put(item)
def createJGW(path): import tempfile p = parse_query(path) mapid = p.get('mapid', 'new') SCALE_FACTOR = p['dpi'] / 72.0 EPSG900913 = "+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" S2P = 360.0 * SCALE_FACTOR / 0.127 MAP_NM = 0.014 MAP_EM = 0.008 MAP_SM = 0.013 MAP_WM = 0.008 paper = p['paper'] PAPER_W = float(paper.split(",")[0]) PAPER_H = float(paper.split(",")[1]) scale = int(p['scale']) centre = p['centre'] clat = int(centre.split(",")[0]) clon = int(centre.split(",")[1]) rotation = float(p.get('rotation', '0')) projection = mapnik.Projection(EPSG900913) wgs84lat = mapnik.Coord(clon, clat).inverse(projection).y scaleCorrectionFactor = math.cos(wgs84lat * math.pi / 180) scaleCorrected = scale / scaleCorrectionFactor if p['style'] == "adhoc": MAP_EM = MAP_WM MAP_NM = MAP_WM MAP_SM = MAP_WM MAP_W = PAPER_W - MAP_WM - MAP_EM MAP_H = PAPER_H - MAP_NM - MAP_SM paperSLat = clat - (MAP_H / 2 + MAP_SM) * scaleCorrected paperNLat = clat + (MAP_H / 2 + MAP_NM) * scaleCorrected paperWLon = clon - (MAP_W / 2 + MAP_WM) * scaleCorrected paperELon = clon + (MAP_W / 2 + MAP_EM) * scaleCorrected PIXEL_W = PAPER_W * S2P PIXEL_H = PAPER_H * S2P TopLeftLat = clat + (MAP_H / 2 + MAP_NM) * scaleCorrected * math.cos( rotation) - (MAP_W / 2 + MAP_WM) * scaleCorrected * math.sin(rotation) TopLeftLon = clon - (MAP_W / 2 + MAP_WM) * scaleCorrected * math.cos( rotation) - (MAP_H / 2 + MAP_NM) * scaleCorrected * math.sin(rotation) fworld = tempfile.NamedTemporaryFile() jgwString = str((paperELon - paperWLon)*math.cos(rotation)/PIXEL_W) + "\n" + \ str((paperELon - paperWLon)*math.sin(rotation)/PIXEL_W) + "\n" + \ str((paperNLat - paperSLat)*math.sin(rotation)/PIXEL_H) + "\n" + \ str((paperSLat - paperNLat)*math.cos(rotation)/PIXEL_H) + "\n" + \ str(TopLeftLon) + "\n" + \ str(TopLeftLat) + "\n" fworld.write(jgwString.encode('utf-8')) fworld.seek(0) return fworld
def getExtents(self, tile, tileproj): z = self.TileNav.getZoom() #print tile p0 = (tile[0] * 256, (tile[1] + 1) * 256) p1 = ((tile[0] + 1) * 256, tile[1] * 256) # Convert to LatLong (EPSG:4326) l0 = tileproj.fromPixelToLL(p0, z) l1 = tileproj.fromPixelToLL(p1, z) # Convert to map projection (e.g. mercator co-ords EPSG:900913) extent_geo = (l0[0], l0[1], l1[0], l1[1]) c0 = self.tileParams.getProjection().forward(mapnik.Coord( l0[0], l0[1])) c1 = self.tileParams.getProjection().forward(mapnik.Coord( l1[0], l1[1])) tile_extent = (c0.x, c0.y, c1.x, c1.y) return tile_extent, z, extent_geo