我正在尝试使用generate_tiles.py创建图块,每次运行脚本时,都会出现以下错误:
线程 Thread-2 中的异常:回溯(最后一次调用):文件“/usr/lib/python2.7/threading.py”,第 552 行,在 __bootstrap_inner self.run() 文件“/usr/lib/python2. 7/threading.py”,第 505 行,运行中 self.__target(*self.__args, **self.__kwargs) 文件“render_tiles.py”,第 114 行,循环中 self.render_tile(tile_uri, x, y, z ) 文件“render_tiles.py”,第 96 行,在 render_tile mapnik.render(self.m, im) MemoryError
这是我的脚本。
#!/usr/bin/python 从数学导入 pi,cos,sin,log,exp,atan 从子流程导入调用 导入系统,操作系统 从队列导入队列 进口地图尼克 导入线程 随机导入 导入参数解析 custom_fonts_dir = '/usr/share/fonts/' mapnik.register_fonts(custom_fonts_dir) DEG_TO_RAD = pi/180 RAD_TO_DEG = 180/pi # 默认生成的渲染线程数,应该大致等于可用的 CPU 内核数 NUM_THREADS = 4 定义最小最大值(a,b,c): a = 最大值(a,b) a = min(a,c) 返回一个 类谷歌投影: def __init__(self,levels=18): 自我.Bc = [] 自我抄送 = [] 自我.zc = [] 自我.Ac = [] c = 256 对于范围内的 d(0,级别): e = c/2; self.Bc.append(c/360.0) self.Cc.append(c/(2 * pi)) self.zc.append((e,e)) self.Ac.append(c) c *= 2 def fromLLtoPixel(self,ll,zoom): d = self.zc[int(zoom)] e = round(d[0] + float(ll[0]) * self.Bc[zoom]) f = minmax(sin(DEG_TO_RAD * float(ll[1])),-0.9999,0.9999) g = round(d[1] + 0.5*log((1+f)/(1-f))*-self.Cc[zoom]) 返回(例如) def fromPixelToLL(self,px,zoom): e = self.zc [缩放] f = (px[0] - e[0])/self.Bc[缩放] g = (px[1] - e[1])/-self.Cc[缩放] h = RAD_TO_DEG * ( 2 * atan(exp(g)) - 0.5 * pi) 返回(f,h) 类渲染线程: def __init__(self, tile_dir, mapfile, q, printLock, maxZoom): self.tile_dir = tile_dir 自我.q = q self.m = mapnik.Map(256, 256) self.printLock = printLock # 加载样式 XML mapnik.load_map(self.m, mapfile) # 获取投影 self.prj = mapnik.Projection(self.m.srs) # 平铺像素坐标和 LatLong 之间的项目 (EPSG:4326) self.tileproj = GoogleProjection(maxZoom+1) def render_tile(self, tile_uri, x, y, z): # 计算左下角和右上角的像素位置 p0 = (x * 256, (y + 1) * 256) p1 = ((x + 1) * 256, y * 256) # 转换为经纬度 (EPSG:4326) l0 = self.tileproj.fromPixelToLL(p0, z); l1 = self.tileproj.fromPixelToLL(p1, z); # 转换为地图投影(例如墨卡托坐标 EPSG:900913) c0 = self.prj.forward(mapnik.Coord(l0[0],l0[1])) c1 = self.prj.forward(mapnik.Coord(l1[0],l1[1])) # 瓦片的边界框 如果 hasattr(mapnik,'mapnik_version') 和 mapnik.mapnik_version() >= 800: bbox = mapnik.Box2d(c0.x,c0.y, c1.x,c1.y) 别的: bbox = mapnik.Envelope(c0.x,c0.y, c1.x,c1.y) 渲染大小 = 256 self.m.resize(render_size, render_size) self.m.zoom_to_box(bbox) self.m.buffer_size = 128 # 使用默认的 Agg 渲染器渲染图像 im = mapnik.Image(render_size, render_size) mapnik.render(self.m, im) im.save(tile_uri, 'png256') def循环(自我): 而真: #从队列中取出一个tile并渲染它 r = self.q.get() 如果(r == 无): self.q.task_done() 休息 别的: (名称,tile_uri,x,y,z)= r 存在=“” 如果 os.path.isfile(tile_uri): 存在=“存在” 别的: self.render_tile(tile_uri, x, y, z) 字节=os.stat(tile_uri)[6] 空='' 如果字节 == 103: 空=“空瓷砖” self.printLock.acquire() 打印名称,“:”,z,x,y,存在,空 self.printLock.release() self.q.task_done() def render_tiles(bbox, mapfile, tile_dir, minZoom=1,maxZoom=18, name="unknown", num_threads=NUM_THREADS): print "render_tiles(",bbox, mapfile, tile_dir, minZoom, maxZoom, name,")" # 启动渲染线程 队列 = 队列(32) printLock = threading.Lock() 渲染器 = {} 对于我在范围内(num_threads): renderer = RenderThread(tile_dir, mapfile, queue, printLock, maxZoom) render_thread = threading.Thread(target=renderer.loop) render_thread.start() #print "开始渲染线程 %s" % render_thread.getName() 渲染器[i] = render_thread 如果不是 os.path.isdir(tile_dir): os.mkdir(tile_dir) gprj = GoogleProjection(maxZoom+1) ll0 = (bbox[0],bbox[3]) ll1 = (bbox[2],bbox[1]) 对于范围内的 z (minZoom,maxZoom + 1): px0 = gprj.fromLLtoPixel(ll0,z) px1 = gprj.fromLLtoPixel(ll1,z) 打印“fromlattolon” # 检查我们是否有目录 缩放 = "%s" % z 如果不是 os.path.isdir(tile_dir + zoom): os.mkdir(tile_dir + 缩放) 对于范围内的 x (int(px0[0]/256.0),int(px1[0]/256.0)+1): # 验证 x 坐标 如果(x = 2**z): 继续 # 检查我们是否有目录 str_x = "%s" % x 如果不是 os.path.isdir(tile_dir + zoom + '/' + str_x): os.mkdir(tile_dir + zoom + '/' + str_x) 对于范围内的 y(int(px0[1]/256.0),int(px1[1]/256.0)+1): # 验证 x 坐标 如果(y = 2**z): 继续 str_y = "%s" % y tile_uri = tile_dir + 缩放 + '/' + str_x + '/' + str_y + '.png' # 提交要渲染的图块到队列中 t =(名称,tile_uri,x,y,z) queue.put(t) # 通过向队列发送空请求来指示渲染线程退出 对于我在范围内(num_threads): queue.put(无) # 等待挂起的渲染作业完成 queue.join() 对于我在范围内(num_threads): 渲染器[i].join() 如果 __name__ == "__main__": MIN_LON = '29.5732'; MAX_LON = '35.0360'; MIN_LAT = '-1.4840'; MAX_LAT = '4.2144'; bbox = (MIN_LON, MIN_LAT,MAX_LON, MAX_LAT) style_file="/home/mossplix/projects/Dev/mapit/map/static/tilemill/uganda_districts.xml" tile_dir="/home/mossplix/projects/UnicefDev/mapit/map/static/tiles/" min_zoom=7 最大缩放=14 render_tiles(bbox, style_file, tile_dir, min_zoom, max_zoom)
这是 mapnik 配置文件 mapnik config 这是 shapefile。我从 source 编译了 mapnik,所以应该不错。可能是什么问题呢?