一下处理过程需要在python2.5与2.6之间切换
Pgsql 8.3.5
postgis1.5
tilecache 2.10
geoserver2.0
openlayers
ext-js
django
1. openlayer显示地图无法显示正确的比例尺
在访问地图时设置地图显示单位必须为 units:'degrees'
2. 图层文字标注出现乱码和重复绘制多个相同名称
Sld设置的group=true似乎没有起作用
layer = new OpenLayers.Layer.WMS( "FirstMap","http://localhost:8080/geoserver/wms",{},{singleTile: true, ratio: 1})
必须设置红色部分的参数,能保证文字不被重复显示
但是在使用tilecache.py预缓冲图块时("http://localhost:9000/tilecache/tilecache.py"),添加了以上红色参数之后导致无法显示地图。
SingleTile:true 参数是作为geoserver的附加属性由openlayer传递到服务器,
所以考虑将此参数通过tilecache.cfg传递到geoserver是否能够起到相同效果?
发现使用了signleTile之后,openlayers将不进行块的缓冲,而是每次请求都到geoserver上去获取,抓包发现singleTile开启的话,请求时将不传递width/height参数,直接请求bbox大小的地理区域,每次移动地图将重新加载整个区域,效率低下;
但是关闭singleTile的话,依次连续请求多个网格块,默认是256x256,导致有些图层比如背景层1024×1024的话将请求4x4个网格块,每个块都将绘制背景的文本标识,因为这些块是离散绘制的所以显示在地图上的话将是重复的文本显示出来了,所以避免这个问题只有如下解决:
1. 放大网格的大小规格,使一定的地理范围尽可能的处在一个网格内被绘制
目前这种方式似乎是最佳方式,tilecache 默认tile规格是256*256,在绘制全国图的时候设置1024*1024方式去请求geoserver,然后使用split_tile.py切割土块即可。
2. 控制这些层的显示属性,限制只有在某些比例尺时被显示
3. 手工编辑地图数据,合并多边形对象,这样就可以防止重复绘制多边形的名称标注,导致一个省份名称绘制多次
Tilecache 为了支持 apache 访问,必须安装到 python/lib/ 目录下,并且 tilecache.cfg 也在这个安装目录下。
Tilecache.cfg修改之后必须重新启动apache服务
如果geoserver实时绘制的话允许同时传递多个层名称给geoserver进行绘制
new OpenLayers.Layer.WMS( "FirstMap",
"http://localhost:8080/geoserver/wms",
{ layers:’shanghai,china,…’})
如果tilecahce加载tile网格块的话,layers属性不能传递多个图层,因为多个图层就是返回多个tile块,只有在tilecache.cfg中配置多个layer名称
[east_china]
type=WMSLayer
url=http://localhost:8080/geoserver/wms
layers=shanghai,jiangshu,zejiang
extension=png
resolutions=0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.00137329101,0.0006,0.0003,0.00015,0.000075,0.000035,0.000018,0.000009,0.0000045
bbox=70,10,130,60
1. tilecache_seed.py提交layers给geoserver 时,如果提交全国所有layers,geoserver将处理每个layer,即使layer与当前可见地理区域不想交,但还是会被循环处理;所以必须改写tilecahe_seed.py程序,检测只有相交的图层传送给geoserver渲染。
改写部分在TileCache/Layers/WMS.py中,
def renderTile(self, tile):
wms = WMSClient.WMS( self.url, {
"bbox": tile.bbox(),
"width": tile.size()[0],
"height": tile.size()[1],
"srs": self.srs,
"format": self.mime_type,
"layers": self.layers,
}, self.user, self.password)
tile.data, response = wms.fetch()
return tile.data
self.layers参数就是tilecache.cfg中参数layers定义的层列表,所以只需要修改这个参数即可。
处理方式: 将tile.bbox()的地理区间与数据库中的省市层最大mbr进行相交测试,只有相交的才提交给geoserver进行处理。
修改之后
测试:
将网格规格调整为256*256,绘制east_china图层第7显示级别,花销48秒
修改代码如下:
def isIntersect(self,rc1,rc2):
if rc1[2] < rc2[0] or rc1[3] < rc2[1] or rc1[0] > rc2[2] or rc1[1] > rc2[3]:
return False
return True
def renderTile(self, tile):
import sys,string
sys.path.append('c:/')
import cities_mbr
layers = self.layers.split(',')
newLayers=[]
for layer in layers:
rc = cities_mbr.G_CITIES_MBR[layer]
rc2 = tile.bbox().split(',')
rc2 = map(float,rc2)
if self.isIntersect(rc,rc2):
newLayers.append(layer)
layers = string.join(map(str,newLayers),',')
if len(newLayers) == 0: #no any insercted layer
layers='china:china_blank_layer' #here i select shanghai as empty city to fill
print layers
wms = WMSClient.WMS( self.url, {
"bbox": tile.bbox(),
"width": tile.size()[0],
"height": tile.size()[1],
"srs": self.srs,
"format": self.mime_type,
#"layers": self.layers,
"layers": layers,
}, self.user, self.password)
print 'x*'*20
print self.url,tile.bbox(),layers
#import sys
#sys.exit(0);
tile.data, response = wms.fetch()
return tile.data
注意以上红色代码,当检索不能匹配任何图层时,需要geoserver返回空白图块,self.layers必须设置一个数据库中可用的图层名称,这个图层只是为了绘制空白块的,所以可以在postgis中创建一个point层即可或者一个空层,然后添加一个远离中国地理区域的一个点即可.
2. 显示比例越小的时候,绘制地图需要更多的时间,那是由于显示的越大绘制的图层就越多。
要使多台机器同时分工绘制地图的话, 可以按层进行分割处理和划分经纬度的方式进行。前者适用与高比例尺的显示,后者就是小比例尺的显示。
小显示比例时,tilecache将图层进行网格化处理,由西至东,由下至上。所以提交给处理机器以不同的bbox即可,处理完成之后再将这些图块重新进行编号即可。()
3. 在低缩放比的情况下放大tile的规格,默认是256×256,将其设置为256×n大小,这样可以提高每次请求的效率,之后再将图块切割为256×256大小的png图块。 这就要求geoserver的sld关闭 <vendor-group>true</vendor-group>开关
测试:
将网格规格调整为1024*1024,绘制east_china图层第7显示级别,花销30秒
将网格规格调整为256*256,绘制east_china图层第7显示级别,花销200秒
图像扩大了16倍,时间缩短了6倍
大图块产生之后切割为小图块,需要重新索引文件编号。
设A规格图块和B规格图块(A*4=B),如果A绘制需要产生400列(0-399),400行(0-399),那B只需要产生100列100行。
Tilecache预处理数据存储方式:
图块数据绘制时按照经度从西到东,维度从南到北的顺序依次绘制出网格图块。
每一列的图块都创建出一个目录,从下标0开始。
绘制方式:
For(x=0;x<columns;x++){
For(y=0;y<rows;y++){
Draw_tile()
}
}
层名称/缩放级别/000/000/列编号/000/000/行图块文件.png
Tilecache的数据存储目录在删除时必须注意停止apache服务
Apache提供tile服务时将自动使用python2.6下的tilecache代码
操作数据库是采用的是pgpostgresql,目前只支持python2.5,所以必须先注视掉c:/python2.6, 打开c:/python2.5