EOMapX序

来源:互联网 发布:网络暴力的成因 编辑:程序博客网 时间:2024/05/19 00:11

EOMapX并不是最近才开始写的,以前都忙于自以为荣耀的项目或者工作的事情,或者忙于自以为理直气壮地心情的事情,或者忙于羞于启齿的人的本质上的懒惰。只能说最近开始了比较认真的整理,比以前多走了一步。 

EOMapX依旧是基于典型的ActiveX+数据库的模式,这种模式总的来讲比较健壮和稳定,切入也比较容易。

很早的时候我就选择了ATL,其实使用MFC并不有什么坏处,因为无论是ATL还是MFC都可以将庞大的库静态链接而不用发布依赖库,而且实际上我们在关键性的模块上,MFC能够影响效率的地方非常少,反而在很多代码上,MFC能够极大的方便我们。

GDI+自从我接触开始,就觉得它是GIS开发的首选,优异的的图形表现力极大地方便了开发,从速度上来讲,GDI+要比GDI速度上提高不少。下面是数据:

在同一位置反复绘制30000个四边形的时间(单位毫秒,一共取2组数据,前一个为GDI+的,后一个为GDI的)
2219 3172
2140 3141

在不同位置反复绘制30000个四边形的时间(
90%被裁减掉了)
94 94
94 109

在不同位置反复绘制30000个四边形的时间(未被裁减,全部绘制在窗口内)
1922 2953
1922 2953

绘制一个30000顶点的边形的时间(
90%的顶点被窗口裁减掉了)
0 0
0 0

绘制一个30000顶点的边形的时间(未被裁减,全部绘制在窗口内)
31 8578
31 8500

 

而且在绘制过程中GDI+没有闪烁,GDI有明显的闪烁,尤其在同一位置反复绘制的时候。时间有GetTickCount函数取得,上面的时间包括顶点赋值时间。从上面的数据来看,尤其是多顶点多边形GDI比GDI+差的太多了。

GDI+已经可以支持Alpha,以前使用GDI制作透明半透明效果实在是太费劲了。但是GDI+有个遗憾的地方就是不支持位运算,这在绘制橡皮线的时候很不方便,好在我们在使用GDI+的同时也依旧可以使用GDI。

想要开发一个GIS组件,第一步就是要组织数据,在我的应用中,矢量的数据无非就是点(Point)、线(Polyline)、面(Polygon)。很多人会在应用中并不只使用到这三种要素,比如文本(Text),圆弧(Arc)等,还有的可能使用其它的高阶曲线或者非连续曲线。对于文本,我的理解是它本身就是一个标注,或者为点标注或者为线标注,或者为面标注,我们可以关闭图形仅显示标注来实现文本的绘制。而对于圆弧,如果是单独的圆弧还是可以处理的,如果一个多边形中带有圆弧就不是很好处理了,因为DrawPolygon并不包含圆弧段,我的做法是用一段折线来模拟圆弧,因此圆弧也就不在基本元数据之列,这里要说明的是,模拟圆弧不等于丢弃了圆弧,只是在显示的时候用模拟段处理,数据存储的时候以圆弧信息存储。对于其它曲线(比如样条曲线),一般都不在GIS考虑之列,这主要是源于测绘,测绘中往往很少对曲线作精确的描述。

基本要素确定之后,在实际应用中往往还有些复合要素,比如中国地图,中国地图是在绘制的时候我们除了要绘制大陆轮廓线,还要绘制台湾岛,海南岛等等,但这些岛屿应该是一个整体,还有日本由四个主要的部分组成,因此,我们还需要将多边形进行组合。除此之外,还有比如一个四合院的房子,外面有个多边形,里面的多边形是个孔洞,在绘制的时候就要注意。这些都是需要考虑的问题。

数据组织好之后,主要的工作就开始了,表现这些矢量图形,绘制图形的第一步就是坐标转换,一般说来,不管GDI+提供了如何强大的坐标变换功能,在使用之时都需要谨慎考虑,就是是否能完全满足我们的需要,如果还有犹豫,EOMapX采用的方法是自己转换,因为这样不是什么难事,毕竟只是二维的点变换。

对于点的表现主要是符号。点符号的表现相对于来说简单点,EOMapX采用的符号是TrueType字体。这种字体对于GIS点符号来说是一种既方便又好用的东西。比较麻烦的是要做到精确定位。目前EOMapX在点符号定位上还算比较可以的,这是一种自我安慰罢了,因为我并未在TrueType字体的规格方式上下太多的功夫,呵呵。

线型的表现我目前还没有找到什么比较有效的方法。基本上通过复合叠加,还算能够实现一些效果,比如铁路什么的。无论是点符号还是线型,这都是跟ArcInfo学习的。对于线来说,还有一点需要说明的是线性标注,就是文字沿着线的方向均匀分布,这一点在道路标注上非常有用。EOMapX的做法就是计算整个折线段的长度,除于字数,然后逐字计算每个字的标注点,一个一个进行标注。


        
// 计算长度
        float fds = 0.0f;

        
for ( j=1; j<nCount; j++ )
        {
            nplength 
= __line_length_f( pts[j-1], pts[j] );
            fds 
+= nplength;
        }

        
// 字符长度
        long nTxtLen = lstrlen( sTxt ); // 这里不考虑英文数字集中

对于封闭的多边形来说,填充是必要的,但最有意思的是计算标注点,多边形的标注点如果说是矢量计算的话,我不认为这是一个很明智的选择,ArcInfo提供一种标注点的计算方法,最简单的点就是外包矩形的中心,这个点往往自己都不知道在什么地方。其次是形心,形心对于有些多边形来讲经常都不在多边形的内部,我们可以将其平移至多边形内部作为标注点,但平移后的点形态就不如形心的好。最好的一种就是ArcInfo描述的,就是将多边形逐步的往内收缩,直至收缩成一个点,这个点就是多边形的标注点,我至少对于矢量图形还没有什么好的算法能快速实现这个思路,在图像采集中对于栅格位图有这个算法,如果大家有可以指教的地方不胜感激。EOMapX采用的是另外一种方式。

对于多边形,如果是复合实体,标注点的计算就更为复杂了,比如有的对象是由多个岛组成的,可能还有孔洞,再复杂点孔洞中还有岛,岛中还有孔洞...,这就有点麻烦了,不过EOMapX我自认还是处理了这些问题,至少看起来还不错,呵呵,自吹一下。

今天先说到这里,下次再论。

 

原创粉丝点击