前面的几节主要关注制图标准化,这一节关注的是非标准化制图。所谓非标准制图,简单说来就是没有国家标准或行业标准的地图需要生产,此类地图多偏向专题类型的地图版式。注重地理分析功能的地图,一般并不关注地图的排版,因为地图方式的结果呈现并非由地图专业人员来完成,而是其他开发人员完成,故对于此类地图的生成,并没有规范而言,例如很多地图连比例尺等都没有。
非标准制图在应用上比标准制图涉及的领域更为广阔,使用的人也更多。很多领域例如气象和生态,需要长期监控与出图,而图的规范并没有要求,简单说来需求就是,可以叠加专业数据,需要出的图好看,最重要的,图的生产最好能自动化。需求简单,但是不好下手。因为是非标准制图,没有标准可以依据,大部分的人反而无所适从,不清楚如何配图或者如何布局能够满足要求。通常的手法是建模版,通过自动套用模版来实现制图的排版和自动化。其实这种想法也非常朴实,简单的理由是大部分情况下,如果出的效果图用户可以满意,依据此效果图配模版,不管数据如何变化,我的图在排版既定的情况下,自动生产就可行了,前端加上一个数据处理的自动化,套上出图模版自动化处理的原形就出来了。
但是作为组件的设计者,需要更高程度的对需求进行抽象。抓住需求的本质是我们需要做到的。经验告诉我们,没有规则可循的事难以入手,所以我们需要找到规律。在非标准制图过程中,最为重要的一步就是制定排版的规则。排版的第一步是确定参与排版的对象。这些排版的对象简单说来就是制图的几大要素,指北针,比例尺,以及图例等等。分析这些对象,有两个可变化的地方,一是布局位置,而是样式,因此在设计之前,我们需要弄清楚这些变化之间的关系。
对象的样式是一个人为决定的因素,选择何种类型的样式风格是根据用户喜好自己确定的,例如指北针,中国人的喜好和美国人又有很大区别,所以在GIS软件中会有很多种风格让用户选择,这种风格的选择是易控制的和,可操作的。
对象的布局位置在非标准制图过程中是最关键的,起决定作用的。首先列出以下基本制图对象,主图区,指北针,比例尺,图例,图名。有了这五个基本的制图对象后,我们开始按重要程度分类,最重要的部分是主图区(某些图中需要设置副图区),其次是指北针,比例尺,图名,图例。我们在布局好主图区后就依次可以设置其他次要制图对象。这些次要对象的布局都是散落布局在主图区周围,一般图名是在主图区正上方,比例尺在主图区正下方,图例可左可右的摆放。有了这些层次关系,就可以进一步提出相对定位的概念。事实上参考标准制图会发现,次要对象的部局都是依据主图区来定义距离和位置的,在非标准制图过程中,为了描述位置我们也可以引入这一概念。
上面说了这么多,就是想说明一点如何使非标准制图过程可操作,进而自动化,以ArcGIS为例。如果每个对象都可以描述清楚了,那么这件事情就可行了。开始设计我们的排版组件吧。设计的第一个问题,制图对象哪里来?当然是自己创建。很多人在这里是有分歧的,即使是很有经验的GIS软件工程师也是如此。在本质上所有的制图对象都是Element,创建Element总是很容易的,何不自己设计和创建呢,创建的过程中,我们可以决定对象的样式和布局。对象的创建我们自然就能引入抽象工厂的模式。设计的第二个问题,主图区如何布局?在前面的几节中,我介绍了标准化制图的过程中,主图区如何设计,这里也是一样,我们需要控制主图区。在谈主图区控制前,有个会忽略的问题,自动化过程如何设计?在汶川地震时USGS在地震后立刻就有地震信息描述的参考地图出来了,当然这如果不是自动化过程很难达到,在美国,在一些大的研究机构中ESRI往往是一个长期参与的角色,ESRI负责长期的地图生产和维护,为了便于维护往往会定制化一些过程,这些过程在我们看来就是制图的自动化(衍生出了PLTS产品等等)。因为是非标准化的,我自己根据需要,我尽量提出地图生产过程中的人为因素,排版自动化,输出自动化,打印也自动化。输出是有很多现成可用接口,打印就不行了,如果地图纸面大小不确定还需要自己去调整那就很不容易了,有什么办法去掉这些人为因素呢?最有效的也最简单的思路,依据纸张类型来控制主图区,进而影响排版。纸张类型目前有A5到A0系列。也就是说我只需要确定这六类纸型下的排版方式就能实现我的要求。
还是以地震为例,通常地震数据是可以在地震台网上自动获取的,如果有大的地震发生,我们是可以立刻判断出来的。假设我们在某一地区发生地震,强度很大,达到了我们出图观测的要求,我们需要自动生成地震专题图,制图过程前期,准备程序在地震发生处(经纬度,震级都有),通过地震强度算法生成地震场数据(专题数据),依据设定的渲染算法,分级渲染地震场,制图程序依据地震场的范围确定主图区显示范围,如果纸张类型选定,算法选择纸张是竖版还是横版,其他制图对象都依据主图区的相对位置来布局排版,而后调用打印程序自动出图,或输出。
非标准制图的组件设计:
一些可以参考的代码:
//---------------------设置A4参数-----------------------------
hr=ipNoStdCartoEnvironment->put_PageStyle(esriPageFormA4);
hr=ipNoStdCartoEnvironment->put_PageTitle(CComBSTR("地震影响场专题图A4"));
//相对定位
hr=ipNoStdCartoLayoutManager->SetPageTitlePosition(esriTopMidPoint,0,1.0);
hr=ipNoStdCartoLayoutManager->SetPageLegendPosition(esriTopRightCorner,1.0,-1.0);
hr=ipNoStdCartoLayoutManager->SetPageNorthArrowPosition(esriBottomRightCorner,-1.5,-1.5);
hr=ipNoStdCartoLayoutManager->SetPageScalePosition(esriBottomMidPoint,6,-1.5);
//纸面上主图区的范围 13.6cm x 22cm
IEnvelopePtr ipPortraitEnv(CLSID_Envelope);
IEnvelopePtr ipLandscapeEnv(CLSID_Envelope);
hr=ipPortraitEnv->PutCoords(1.2,4.8,14.8,26.8);
hr=ipLandscapeEnv->PutCoords(1.5,3.3,23.5,16.9);
hr=ipNoStdCartoLayoutManager->SetMainFrameSizeAndPosition(ipPortraitEnv,ipLandscapeEnv);
INoStdCartoFactoryPtr ipNoStdCartoFactory(CLSID_NoStdCartoA4Factory);
hr=ipNoStdCartoLayoutManager->UpdateLayout(ipNoStdCartoFactory);
输出的结果,震级虚构(数据来源是NGCC公开发布的国家400万WGS84数据):
如果地震影响场的倾斜角度大于45度,系统自动调整为竖式排版: