5.7. 栅格数据与矢量数据的互相转换

在地理信息系统领域里,栅格数据与矢量数据各有千秋,它们互为补充,必要时互相转换,这是由地理信息系统处理方式以及这两种数据格式各自的特点所决定的。

5.7.1. 矢量数据转换成栅格数据

1.点的栅格化

习惯上,矢量数据中的点坐标用X、Y来表示,而在栅格数据中,像元的行、列号用I、J来表示。如图5-20,设O为矢量数据的坐标原点,O′(Xo,Yo)为栅格数据的坐标原点。格网的行平行于X轴,格网的列平行于Y轴。A为制图要素的任一点,则该点在矢量和栅格数据中可分别表示为(X,Y)和(I,J)。

image60

图 5-22 栅格点坐标与矢量点坐标的关系

(公式5-22) image11

由图5-22,不难理解,将点的矢量坐标X、Y转换算为栅格行、列号的公式为(5-22)。

式中,DX、DY分别表示一个栅格的宽和高,当栅格通常为正方形时,DX=DY。[]表示取整。

2.线段的栅格化

在矢量数据中,曲线是由折线来逼近的。因此只要说明了一条直线段如何被栅格化,对任何线划的栅格化过程也就清楚了。图5-23说明了线划栅格化的二种不同方法,即八方向栅格化和全路径栅格化。

image61

图 5-23 二种栅格化方案

    (1) 八方向栅格化

根据矢量的倾角情况,在每行或每列上,只有一个像元被“涂黑”。其特点是在保持八方向连通的前提下,栅格影像看起来最细,不同线划间最不易“粘连”。设1和2为一条直线段的两个端点,其坐标分别为(X1,Y1)、(X2,Y2)。先按上述点的栅格化方法,确定端点1和2所在的行、列号(I1 ,J1)及(I2,J2),并将它们“涂黑”。然后求出这两点位置的行数差和列数差。若行数差大于列数差,则逐行求出本行中心线与过这两点的

(公式5-23)

image47

直线的交点,见公式(5-23)。

image49

其中

(公式5-24)

image52 image53

并按(5-22)式,将其所在的栅格“涂黑”;若行数差小于等于列数差,则逐列求出本列中心线与过这两个端点的直线的交点,见公式(5-24)。

image55

其中

仍按(5-22)式,将其所在的栅格“涂黑”。

用上述公式(5-23)或公式(5-24)来得到栅格坐标,需进行浮点乘法和加法运算,计算量较大。目前,用的较多的矢量数据栅格化的算法是Bresenham算法,该算法仅用整数加法和乘法运算,请读者参考有关书籍。

    (2) 全路径栅格化

全路径栅格化是一种“分带法”,即按行计算起始列号和终止列号(或按列计算起始行号和终止行号)的方法,见图5-23(b)。基于矢量的首末点和倾角a的大小,可以在带内计算出行号或列号(Ia,Ie或Ja,Je):

    当|X2- X1|<|Y2- Y1|时,计算行号Ia,Ie;

    当|X2- X1|≥|Y2- Y1|时,计算列号Ja,Je。

下面给出|X2-X1|≥|Y2-Y1|时的计算过程。

    设当前处理行为第i行,像元边长为m,转换步骤为:

    ① 计算矢量倾角α的正切;

       tgα =(Y2- Y1)/(X2- X1

image57

② 计算起始列号Ja:

    ③ 计算终止列号Je:

image59

④ 将第i行从Ja列开始到Je列为止的中间所有像元“涂黑”;

    ⑤ 若当前处理行不是终止行,则:把本行终止列号Je作为下行的起始列号Ja;行号i增加1,并转③。否则本矢量段栅格化过程结束。

要注意,需将矢量段首点和末点所在的栅格列号分别作为第一行的Ja和最后一行的Je的限制条件,以免使栅格影像变长失真;当首、末点的行号相同时,则直接在首、末两点Ja与Je间“涂黑”就行;若Y2>Y1,则需将首、末点号互换后再使用上式。

当要以任何方向探测栅格影像的存在或者需要知道矢量可能只出现在哪些栅格所覆盖的范围时,全路径栅格化数据结构最为理想。

3.面域的栅格化

面域的栅格化可用种子点填充算法或扫描线种子点填充算法,这两种方法都须先用上述的线段栅格化将面域的边线栅格化且填上边界色;后将填充区内任一点作为填充种子。

    (1) 种子点填充算法

可采用递归方式实现种子点填充算法:对符合填充条件的种子点近邻点赋以和种子点相同的象素值,并以它们作为新的种子点再进行同样的近邻填充,直至不再产生新种子。

算法表示成:

    Seed-Fill-4(x,y,con,value)

   { if (pixel(x,y)<>con)

{ putpixel(x,y,value);

for (i=-1,i<=1;i=i+2)

        Seed-Fill-4(x+i,y,con,value);

      for (i=-1;i<1;i=i+2)

        Seed-Fill-4(x,y+i,con,value);} }

算法中,con为面域的边界色,value为欲填充色。

    (2) 扫描线种子点填充算法

作为上面介绍的简单种子点算法的改进,扫描线种子点填充算法是将每个扫描行中连续待填充段作为一个处理单位,因而减少了对栈空间大小的需求。其算法过程是:

    ① 选择一个种子点Seed(x,y),并将其存入栈内。

    ② 若栈已空,算法结束,否则执行③。

    ③ 从栈中取出要填色的像素,对在同一扫描线上与该点相连的所有需要填色的点进行填色操作,记下进行填色的最左和最右位置: Xleft和Xright。

    ④ 对③的上一行和下一行扫描,在Xlef≤x≤Xright范围内,考察是否全是边界点或已被填色的点,若不完全是,则将要填色的每一段最右位置作为新的种子点存入栈。

    ⑤ 回到②。

5.7.2. 栅格数据转换成矢量数据

1.点的矢量化

 对于任意一个栅格点A而言,将其行、列号I、J转换为其中心点的X、Y的公式如下: X=Xo+(J-0.5)·DX

Y=Yo-(I-0.5)·DY                                               (公式5-25)

2. 线状栅格影像的矢量化

线状栅格影像的矢量化一般采用两种算法思想: 细化矢量化和非细化矢量化。所谓细化矢量化就是首先将具有一定粗细的线状影像进行细化,提取其中轴线(单像素)。然后再沿其中轴线栅格数据进行跟踪矢量化。非细化矢量化的算法思想是不需对线条进行细化,而是从线条上任一点起,先后往线条两端进行跟踪矢量化,其跟踪的判断依据就是起始点处线条的宽度。比较两种算法思想,后者更优于前者,因为细化矢量化除有速度慢的不足外,其矢量化后线条会因为细化而造成线条两头缩短,且会因为线条粗细不匀而造成矢量化的线有毛刺现象。

3.面状栅格数据的矢量化

对于面状栅格数据进行矢量化,只要通过逐行扫描,先找到一个要素集合的边缘点,然后沿面状要素的边缘跟踪,直到整个面域的边界(包括外沿及可能的各内沿)跟踪结束(即封闭)为止。在跟踪过程中,随时将被跟踪到的栅格位置Ik,Jk(k=1,2,…,n)按(5-4)式转换为矢量坐标Xk,Yk,并加以记录。对被矢量化了的面域作上标记,以便在寻找未被矢量化的其它面域时,将其排除。