- 前言
S-57电子海图渲染是电子海图数据可视化的过程,IHO为了保证电子海图显示的标准化和一不致性,制定了S-52《电子海图内容与显示标准》等系列标准和指南,同时以数据文件的形式发布了标准电子海图表达库“PresLib_ex.x.x.dai”,描述了电子海图显示用的颜色表、查找表、点符号描述、线型符号描述和填充模板描述,为电子海图的可视化提供了坚实的基础。
传统电子海图主要应用于航海导航,其显示标准规定了海图符号不随显示比例的变化进行缩放,但海洋GIS 系统需求日益增长,电子海图做为基础底图被广泛的应用 ,但传统渲染方式在经济性、可扩展性、通用性等方面存在诸多不足,因此,建立一种简单通用的适合海洋GIS 系统的S-57 海图渲染方法,对于海洋GIS 的应用和发展具有重要意义。
非航海用户对S-57 海图的调用一般采用2 种方式:一是由专用海图绘制软件渲染S-57 海图生成栅格图像金字塔切片进行调用,但栅格切片在海图矢量拓扑关系操作或运算上存在明显限制,而且不能实现无级缩放显示;二是在应用端直接嵌入专用海图绘制组件,虽然能够保留S-57 海图的矢量性,但一般非航海用户常常希望底图能够进行无级缩放,且在一定范围内,显示符号能随显示比例尺进行缩放。这一点是上述两种方式均难以实现的。
本文根据非航海用户对电子海图显示的特殊需求,尝试基于IHO的电子海图表达库,结合QT框架的跨平台特性,利用栅格绘图的高效性和矢量符号绘制的连续性,既保证电子海图显示的规范性,又保证电子海图的显示的效率。
- 栅格符号与矢量符号渲染比较
- 栅格符号渲染,直接调用显卡驱动实现绘图,CPU占用少,缺点是不能实现无级缩放。
- 矢量符号的渲染,一般采用双缓存技术,首先将矢量符号渲染成内存位图,再由显卡渲染到显示器。优点是实时渲染,显示效果好,能实现无级缩放,缺点是CPU占用率高,复杂面状符号填充效率低。
- 电子海图渲染流程
- 专用海图绘制软件渲染S-57 海图的流程
-
-
切片一般是利用专用海图绘制软件进行分片渲染成位图,并保存备用。
- 电子海图矢量渲染分析
-
目前主流的硬件CPU和显卡条件下,矢量海图的实时渲染一般不会有卡顿,但当有大量的面状填充符号时,由于需要重复绘制,会占用大量占用CPU资源,造成显示不流畅。针对这一问题,经过试验,笔者采用将当前模板符号预生成内存位图,并将内存位图做为画刷纹理,再由系统以位图填充的方式绘制,而位图填充是不需要CPU资源的,这样就解决了复杂面状符号填充是CPU占用率高的问题。下面以QT语言为例,展示部分源码:
//获取模板内存位图
QPixmap * getPattPixMap(QString pattName, float dpiX, float dpiY, float scale)
{
initPatt(paName);
float scaleX = dpiX / 2540.;
float scaleY = dpiY / 2540.;
int width = p_CurPatt->fieldPATD.PAHL/100./25.4*dpiX;
int height = p_CurPatt->fieldPATD.PAVL/100./25.4*dpiY;
QPixmap * pattPixMap = new QPixmap(width, height);
pattPixMap->fill(Qt::transparent);//用透明色填充
QPoint pointUperLeft; // 符号左上角点坐标
pointUperLeft.setX(p_CurPatt->fieldPATD.PBXC);
pointUperLeft.setY(p_CurPatt->fieldPATD.PBXR);
QPainter * pPainter = new QPainter(&pattPixMap);
pPainter->scale(scaleX, scaleY);
pPainter->translate(-pointUperLeft);
for (int i = 0; i < p_CurPatt->s52Layers.size(); i++)
{
// 绘制……
}
delete pPainter;
return pattPixMap;
}
void drawPolyPolgon(QPath path, QPixmap * pixmap)
- 结论
- 采用矢量与栅格渲染技术相结合的方法,既能使电子海图显示实现随显示比例无级缩放,又能保证渲染效率,保证电子海图显示的流畅性。