span8
span4
World_Contours.zip
ffs2postgis.fmw
contour-rasterizationpostgis.fmw
rasterizerrunnerpostgis.fmw
最新(发布后)FME 2009或FME 2010需要运行附加的工作区!
这个场景展示了如何从矢量数据为web映射平台准备光栅贴图。该场景使用微软必应地图瓷砖系统,然而,结果可以与谷歌映射和其他映射平台一起使用。
Bing Maps(又名虚拟地球)是一个强大而灵活的工具,可以在互联网上提供数据服务。FME可以在Bing地图的数据准备中发挥重要作用。我已经发布了一个场景,解释了如何将光栅数据转换成Bing地图的光栅贴图层。
我发现Bing Maps tiles非常方便的一点是我们总是知道地面图的tile和像素大小,在整个地球的每一个缩放级别上都是恒定的。这是由球面墨卡托投影定义的。它允许以一种简单的方式设置一些参数。
现在想象一下,我们希望获取一些向量数据,并将其显示在Bing映射或谷歌映射中(注意,这两个链接指向相同的平铺集)。有几种方法可以做到这一点;在本文中,我将只讨论一种方法——光栅化和制作Bing Maps贴图。
这篇文章暗示你知道必应地图如何工作的一些基本知识,什么是瓷砖,quadkeys,和缩放级别。
作为一个源地图,我使用等高线数据VMap 0级。该数据集覆盖全球,详细程度为1:10 0万地图。
等高线给了我们一个有趣的挑战——如果我们在每个缩放级别显示所有的线条,在较低的缩放级别,等高线将完全覆盖山区的背景地图,所以我们必须发明一种算法来为每一个缩放级别选择一定高度的轮廓。例如,1000米的轮廓在任何缩放级别都可以看到,而100米等高线只有当我们放大到比7级更近的时候。
另一方面,它可以是相当有用的,看到所有的轮廓,以获得地球浮雕的感觉。除此之外,对FME桌面和服务器来说,保持所有的轮廓是一个很好的压力测试,所以我发布了两个版本。
我们还希望在每个缩放级别上实现最高质量的光栅贴片。这意味着当我们切换到下一个缩放级别时,我们不能重新采样为一个缩放级别创建的贴片——光栅化应该为每个级别单独进行。
请看下图。我们可以看到当WebMapTiler从源光栅(上面的行)中生成光栅贴图时,光栅贴图是如何淡出的。当我们制作矢量贴片并分别光栅化它们时,我们有一致的质量在所有缩放级别,另外,我们可以控制每一层的内容(下一行):
虚拟地球有19个缩放级别。每一层的瓷砖比上一层多四倍。如果我们想缩小到14-15级,我们应该得到数以千万计的瓷砖,这就是为什么我还要谈论我们必须克服的性能挑战。该过程展示了如何在空间上启用数据库和FME服务器的情况下使用FME的全部功能。
VPF格式的源数据可以从国家地理空间情报局(NGA)网站。为了您的方便,我下载并将数据转换成FFS格式。完整的存档文件可以从附件World_Contours.zip下载。未压缩的,整个数据集占用超过600兆字节。数据包含1000英尺间隔的等高线(有些地方是500英尺,还有一些等高线是不同间隔的)。
为我们的目的存储和检索这些数据量的最佳方法是在一个支持空间的数据库中。在我的例子中,我使用PostGIS数据库(将FFS转换为PostGIS的工作区是附件ffs2postgis.fmw)。
对于那些,害怕数据库的人,我知道我花了一个多小时下载,安装,能够在上面运行PostgreSQL和PostGIS,尽管我不是数据库专家。
在为栅格化准备数据时,我添加了一个过滤器,根据等高线间距选择数据,比如说zoom level 14有所有的等高线,缩放级别13 -只能被10整除,12级的等高线可以被20整除,我们可以用测试器,但是有时候表达式求值器中的一个简单表达式就能很好地完成工作:
@ value(_elevation)% 1000 = = 0 ? 8:(@ value(_elevation)% 500 = = 0 ? 9:(@ value(_elevation)% 200 = = 0 ? 10:(@ value(_elevation)% 100 = = 0 ? 11:(@ value(_elevation)% 20 = = 0 ? 12:(@ value(_elevation)% 10 ? 13:14)))))
用这种方法,我们计算出一个轮廓应该被看到的最高(最小)缩放级别。
在那之后,一个小的循环将允许我们为每一个缩放级别创建几个轮廓。
所以第一个集合只包含第一千等高线,第二,第1000次和第500次,第三,第1000位,500和200,等等。
坡度坡道是一个很好的选择范围广泛的值,如轮廓海拔。使用PythonCaller设置颜色是一种快速而简单的分配fme_color属性的方法。下面是附件工作区中使用的python代码示例:
导入pyfmelogger = pyfme.FMELogfile()类ColorSetter(object):feature): self.elev = feature.getIntAttribute('elevation_ft') if self.elev < 2000: if self.elev < 1000: self.color = '0,' + str(0.24 + 0.0004*self.elev) + ',0' else: self.color = '0.5,' + str(0.24 + 0.0004*self.elev) + ',0.5' elif self.elev <= 6000: if self.elev <= 3500: self.color = str(0.0002*(7000 - self.elev)) + ',' + str(0.0002*(7000 - self.elev)) + ',0' else: self.color = '0.7,' + str(0.0002*(7000 - self.elev)) + ',0' elif self.elev <= 15000: if self.elev < 10000: self.color = '1,' + str(0.0001*(self.elev/2)) + ',0' else: self.color = '1,' + str(0.0001*(15000-self.elev)) + ',0.5' elif self.elev < 25000: self.color = str(0.0001*(25000 - self.elev)) + ',0,' + str(0.0001*(self.elev/3)) else: self.color = '0.5,0.5,1' feature.setAttribute('fme_color',self.color)feature.setAttribute(“fme_fill_color”,self.color)self.pyoutput(特性)
通常情况下,FME使用WebMapTiler transformer从一个输入光栅生成Bing地图贴图。这种方法对向量数据集可能不太适用。将地图栅格化到缩放级别10将生成一张两边各262144像素的图像,这些栅格有点难处理。我们可以栅格化数据集的较小部分然后使用WebMapTileron这些较小的栅格,但这将涉及两个光栅操作(光栅化本身和光栅贴片)。除此之外,如果我们取任意一个网格,我们可能会得到不完整的瓦片,还要把它们拼接在一起。经过一些测试后,我放弃了这条路线,决定尝试直接剪切和栅格化Bing Maps贴图。也就是说,ImageRasterizertransformer应该获得制作独立块所需的准确数据部分。现在我们只有一个光栅变压器。这种变化的另一个积极的副作用是,现在我们不会生产没有任何数据的tile。
我们怎样才能做出这样的分量呢?答案很简单限幅器变压器。我们可以制作矢量贴片多边形用作剪刀,数据集提供了Clippees。这就是理论。如果我们把世界从缩放1级平铺到10级,我们需要创造近150万个快船队。这是一个很多。尽管有了这些改进,当裁剪器数量超过20,000-60,000(取决于裁剪数据的数量)时,我们仍然存在一些性能问题。
我试着用扇形代替Clipper,这让我可以比Clipper更进一步,然而,它需要一些额外的工作来计算四键,然而,它不能用于更深层次的瓷砖。
在我对最终工作流的近似中,下一个逻辑步骤是创建一个由两个(或多个)步骤组成的过程。亚搏在线第一步,我将原始数据集平铺成更小的数据集,其区段与某个缩放级别的平铺区段匹配(例如,7或8在我的测试中),然后对每一个较小的数据集进行相同的平铺和最终栅格化,缩小到14-15级。
事实上,不应该有太多的需要在一个过程中,将一些数据和平铺在整个缩放级别范围从1级(世界)到19级(摩尔-希尔)。世界地图和街道地图有非常不同的内容,即使有些元素是相同的(海岸线,例如),它们通常用完全不同的几何图形来表示——广义的或详细的。
为了管理这样的工作流程,亚搏在线我必须建立以下程序。在第一阶段,原始数据集被分割成更小的部分,以某种方便的格式存储(最好使用空间索引—FFS或某些空间数据库)。第二阶段有两个工作区,一个执行另一个WorkspaceRunner或ServerJobSubmitter变压器。
第一个工作区决定数据的哪个部分(哪个文件或数据库表)应该被取走,第二个工作区知道如何平铺和光栅化输入的内容。
尽管如此,生成和保存多个小数据集而不是一个大数据集的必要性并不是一种理想的解决方案——管理数据存储和分布更加困难,容易松脱部分,等。这就是空间数据库在整个过程中发挥更重要作用的原因。
空间数据库如Oracle,SQL服务器,MySQL或PostGIS在快速读取空间数据子集方面非常有效。如果我们需要从传统的矢量格式(如MapInfo或DGN)中提取一些数据,我们需要读取整个数据集,添加一个多边形来定义感兴趣区域的边界,然后,使用剪切器或其中一种覆盖层。AreaOnAreaOverlayer)获取数据。对于数据库读取器,得到相同的结果只是设置读取器参数的问题,可以出版,因此,从外部工作区设置。
这里发布的最终工作流亚搏在线如下所示。
我们取一个代表我们区域的特性——它可以是一个国家区域或简单的边界框。我们要求参数-最小和最大缩放级别(从哪个缩放级别数据应该被看到),我们还需要指定所谓的“平铺层”(我以前叫它阅读,但就其用途而言,它不是一个很好的词)。
使用光栅化,我们做一个小光栅(1*1或可能10*10像素,以避免任何四舍五入问题),通过WebMapTiler传递这个光栅。我们有VE瓷砖,它们知道自己的四键名称。
然后BoundsExtractor,得到X和Y的最大值和最小值,它们和四键一起作为第二个工作区的参数。
在下面的例子中,我们有28块瓷砖,这意味着我们将执行28个工作区,从缩放级别5到缩放级别7(即平铺级别)。顺便说一句,有人在马达加斯加用FME把TIFF转换成BMP,也许下次会议我会告诉你们我们是怎么知道的,我们如何收集和使用关于用户的统计信息。
现在我们在这28个工作区中做什么呢?我们将从外部工作区发送的参数(平铺区段)应用到数据库读取器。使用选项'Clip',我们只获得我们提交的quadkey中的数据。
在那之后,我们做我们的常规工作-着色和比例选择,如果需要的话。
然后,我们可以简单地通过读入平铺的内容与group进行光栅化并将其保存为PNG文件,或者我们进行额外的平铺。
为什么有些瓷砖会立刻写出来,有些还是平铺的?这取决于平铺水平。再一次,谈到上面的图像-数据读取与瓦片的缩放级别5和6是光栅化,并立即写入。
使用zoom level 7 tile读取的数据也直接光栅化,但在那之前,瓷砖,制作缩放级别为8和9的贴片。
这给了我们很大的灵活性。现在我们可以控制将执行多少个工作区,以及每个工作区将生成多少块tile。当我们增加第一个工作区中的平铺数量(通过增加平铺级别数)时,我们增加了将要执行的工作空间的数量,这意味着每个工作区将有更少的工作要做。或者,如果我们提交更少的平铺,这意味着更少的工作空间,每个工作区有更多的作业(更多的tile)。
下图显示了平铺到(或降低到)缩放级别8。当我尝试用一个工作区平铺所有东西时,36个小时后我不得不放弃了——我没有看到任何工作进展。要么我的FME停滞不前,或者是我不够耐心——剩下的数字告诉我们,再等下去是没有意义的。
当工作区不需要做那么多剪切时,情况开始好转。每个工作区4000块瓷砖似乎比16000块要好得多,每个工作区64到1000个瓦片之间的间隔似乎是最优的。当我们有太多的工作空间时,通过所有其他转换器传递数据的必要性超过了快速剪切的任何优势。
每个wksp的工作空间瓷砖的平铺级别
1 1 16384
16日4096
3 64 1024
4 320 256
5 1344 64
6 5440年16
7 21824年4
如果我们真的需要很多瓷砖,这个过程可能会非常缓慢。取决于不同的条件,我的机器每秒可以生产6到10块瓷砖,这意味着大约每天50万到85万瓷砖。然而,大项目,Canada-wide说,随着细节缩小到14-15级,将需要数以百万计的瓷砖。
上面介绍亚搏在线的工作流非常适合FME服务器技术。
事实上,所有要做的(假设FME服务器已经启动并正在运行)就是用ServerJobSubmitter替换WorkbenchRunner。这个变压器的参数是一样的,一旦做出改变,我们已经准备好用FME Server制作tile。
最初,我们尝试了一台只有一个引擎的FME服务器四核机结果和我们在有FME桌面的机器上得到的结果非常接近,这是意料之中的。随后我们想,不如如果我们在四核机器上安装四个引擎,我们会看到性能的真正提高。然而,很多引擎的性能都不如只有一个引擎(第1列和第5列):
接下来的几个测试比较了在4台机器上的性能,分别使用单台和两台引擎。如你所见,结果非常接近——都在2.5小时左右(列2和4)。
最快的结果是8台单引擎机器。也许,对于两台热机也是一样的,但是当你花钱买一个引擎的时候,要得到相同的结果,多花两倍的钱可能没有多大意义。
为什么会这样?我们检查了任务管理器的CPU消耗,在这个过程的大部分时间里,它是相当低的。在与更有技术经验的安全人员协商后,亚搏在线我们一致认为瓶颈是I/O——我们不能在给定的时间段内编写更多的文件,所以当多个引擎有机会写东西的时候,但结果将是一样的,甚至更糟——仅仅因为我们制造了这样一群人。
然后我们进行了一些简单的性能测试,以了解生成tile的速度有多快。我们把VMap等高线平铺到8级。我们用1来进行平铺过程,2,4,和8的机器,你可以看到,我们的外出时间从两个小时减少到不到20分钟。
然后我们试着,如果我们达到10级和11级,表格显示了这些数字。250000块瓷砖可以在2小时内完成,100万块瓷砖在6.4小时内完成。在一台机器上,大概需要两天的时间。
平铺瓷砖分钟(小时)
8 24,500 18 (0.3)
10245,000 105 (1.75)
11,000,000 384 (6.4)
现在很容易想象,将一个具有多层的大区域平铺到缩放级别14或15可能需要很长的时间或大量的计算资源。
所以,如果我们有无限数量的计算机,我们能多快达到我们的目标?
这个图不涉及总时间;它显示每个工作区的平均时间和最大时间。
这个图所示的过程产生了大约3500块瓦片,一个工作空间大约需要半个小时。当工作区数量增加时,平均时间和最大时间都在下降。82工作区,也就是说,82发动机,这个过程可以在半分钟内完成(如果没有其他瓶颈的话)。
FME服务器现在可以工作云,上面描述的测试也是由我们的同事在WeoGeo。
用FME开始做瓷砖真的很容易。只要瓦片的数量不超过几十万或几百万,只需要FME Desktop就可以开始制作它们。
平铺过程的结果并不局限于单一的映射平台Bing Maps。它可以与谷歌Earth和其他web地图平台一起使用。
如何将数据处理分割为多个工作空间的一般思想并不局限于所描述的过程,甚至更有价值。
FME服务器允许更快的数据生产,如果你的容量很大或者你需要经常更新,这是该走的路。
即使FME服务器不够,FME现在生活在云端,它可以向外扩展。
zip - FFS格式的源数据
ffs2postgis.fmw - Workspace to translate FFS to PostGIS
RasterizerRunnerPostGIS.fmw - Parent Workspace to execute helper workspaces
contour_rasterizationPostGIS.fmw - Helper workspace producing tiles
结果必应地图
结果谷歌地图
上述过程相当复杂,欢迎联络技术支持与任何相关的问题或如果你注意到任何不正常的工作。
©2019安全亚搏在线软件公司|法律