热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开放GIS标准OGC之路(4)之解密Filter

Filter是一中语言,一种XML实现的语言,这就使得它非常适合于分布式系统。我们接触过的OWS服务都不同程度的使用到它。SLD用它来实现复杂的Rule选择。WFS在所有需要定位操

Filter是一中语言,一种XML实现的语言,这就使得它非常适合于分布式系统。我们接触过的OWS服务都不同程度的使用到它。SLD用它来实现复杂的Rule选择。WFS在所有需要定位操作对象的地方都会使用Filter。这一章我们换一种讨论的方式,我不想再罗列乏味的Tag,然后加上翻译过来的解说。我们应该实实在在的实现一个程序,在实现的过程中完成我们的讨论。

前面的章节我们一直维护着一个WMS服务器“ShapeMapServer”,刚开始我并没有把它当回事,我只是想把它作为一个范例来使用,但是随着话题的深入,这个范例也注定逐渐复杂,功能也慢慢丰富起来。这一章我们将一起来面对这个程序,我们一起来为他增加功能,通过编码我们将对Filter有所体会。我们的任务是改进服务器处理SLD文件的能力,我们将为它增加Filter功能。

先来简单介绍一下OGC的Filter。Filter的作用是构建一个表达式,返回值就是Feature的集合,换句话说Filter就如他的名字一般为我们从一个集合中过滤出一个满足我们要求的子集。而过滤的方法就是Filter定义的操作符。Filter定义了三种操作符:地理操作符(Spatial operators),比较操作符(Comparison operators)和逻辑操作符(Logical operators)。我们来一一解释。

Spatial operators定义了地理属性的操作方式,他们有:Equals,Disjoint,Touches,Within,Overlaps,Crosses,Intersects,Contains,DWithin,

Beyond,BBOX。Comparison operators定义了标量属性的操作方式,他们有:PropertyIsEqualTo,PropertyIsNotEqualTo,PropertyIsLessThan,PropertyIsGreaterThan,

PropertyIsLessThanOrEq,PropertyIsGreaterThanO,PropertyIsLike,PropertyIsNull,

PropertyIsBetween。Logical operators定义了组合这些操作的方式,他们有:And,Or,Not。我们用一个例子来展示他们的作用。假设我们想获得所有人口在一千万以上,并且在我们给定的范围内的城市,我们要这样来构建我们的Filter:

>

Filter就像SQL的where子句,事实上如果你要实现一个强大的WFS服务器,你就不得不提供将Filter翻译成SQL的功能。

现在我们回到我们的任务上来,实现支持Filter的Style。为了能够在一个章节的时间里完成这个任务,我们首先得划定工作范围,也就是需求:

1、 支持所有的操作符;

2、 提供两个函数,sin和cos;

需求很简单,任务却很繁重,我们首先需要增加测试框架。一直以来我们的程序都在“裸奔”而且也不算坏,但是随着结构开始复杂,这种状态就很难维持了,我们需要回归测试。于是我选择NUnit来做这个工作。我并不是要用时下很流行的“TDD”来完成开发,实际上我很喜欢TDD,但是我从来也没有真真掌握它。所以我们只用自动测试框架来测试,仅此而已。

经过一番分析,这个过程是在我的脑海里完成的,我觉得有必要设计一个叫做“StyledLayer”的类,它是从“SharpMap.Layers.Layer”派生来的。这个Layer负责按照Style定义的方式渲染Feature。我们在Style之谜中已经看到Style是由Rule组成的。每一个Rule都有一个Symbolizer代表渲染方式,至多一个Filter来决定哪些Feature将使用这个Rule,还有至多一对Zoom限制来决定这个Rule是否被选择。以前我们一直忽略Rule的这些特性,仅仅使用了Symbolizer,现在我们必须面对它们了。SLD标准文档告诉我们,一个SLD数据块包含多个Rule,每个Feature在渲染的时候都需要通过这些Rule,只要满足Rule的条件,Feature就应该按照Rule定义的Symbolizer渲染一次。顺序与Rule的顺序一致。Rule还可以通过定义ElseFilter来增加分支,整体的过程就是这样了。

我们可以用伪代码来描述上述过程:

for rule in rules
   
for feature in features
      symbolizer = rule.Test(feature)
      
if symbolizer then
         symbolizer.Render(feature)
      endif
   endfor
endfor

这段代码对我们的设计将有一定的指导意义,现在让我们把StyledLayer放一放,先来看看Rule。Rule无疑是最重要的概念之一,有必要为它定义一个类,方法就是Test(feature:Feature):Symbolizer。然后是Symbolizer,它的方法是Render(feature:Feature)。Filter呢,我们一直在讨论的Filter并没有出现在这里。Filter将躲在Rule的幕后起作用。Rule的Test方法将会用到SLD文件中定义的Filter表达式。我们现在来看看Test方法的伪代码:

if filter.Test(feature) then
    
return symbolizer
else if elseFilter.Test(feature) then
    
return elseSymbolizer

显然Filter也应该是一个类,而且它也有一个叫Test的方法。除了这点我们还需要注意ElseFilter在这里是如何起作用的,这个设计不是很好,我们修改一下:

if filter.Test(feature) then
    
return symbolizer
return elseRule.Test(feature)

这一次感觉好多了。我在这里提到“感觉”是因为我也说不清为什么这个比上一个好。现在所有基本的设计就完成了。我们有了三个类Rule,Symbolizer和Filter。而且我们已经实现了Rule的方法Test。但是我们还没有实现Filter的Test方法(Symbolizer的设计是我以前就已经完成的,就不再赘述了)。我们知道有三种Filter操作符,每种还有自己的子类操作符。我们可以这样来实现Filter的Test:

switch op:

case And:…

case Or:…

case Not:…

case…

好了我不开玩笑了。毫无疑问,稍微有点OO常识的人都知道Filter其实是一个抽象概念,我们在这里将他定义成接口:IFilter。而他的实现类分别是ComparisonOp,SpatialOp,LogicOp。他们也是抽象概念,就是Abstract类。他们再分别派生出具体的操作符类。

开放GIS标准OGC之路(4)之 解密Filter

开放GIS标准OGC之路(4)之 解密Filter

开放GIS标准OGC之路(4)之 解密Filter

这三张大图占了不少空间,但是也说明了不少问题。

现在来看看另外一个概念Expression。想像一下,如果我们希望比较的是城市男女的比例而不是男人或女人的数量该怎样办,我们需要先从男女数量来计算比例,然后再比较。OGC的标准为我们提供了计算表达式(Expression)来解决这个问题。它包括:Add,Sub,Mul,Div和Function。显然这个Expression也是一个抽象概念,于是我们有了另外一个接口:IExpression。

开放GIS标准OGC之路(4)之 解密Filter

上图也说明了我们的设计。到此所有Filter的设计算是完成了。我们也可以据此开始编码,虽然还不能在我们的服务器中运行,但是可以在测试框架下检查效果。

下面我们需要通过XML文件生成这套Rule的方法。我们将用到工厂类(Factory)来完成这个工作。感谢DotNet提供的反射(Reflect)机制,我们的工厂类可以很容易的与Xml的Tag关联起来,大大简化了代码。由于这不是本章的重点,我就不在这里详细描述了。

实现了从Xml创建Rule我们的任务就基本完成了。现在我们可以来看看效果了。

下图是原来的渲染效果,它只是使用了一个Symbolizer来渲染线段,这里是SLD文件。

>

 

开放GIS标准OGC之路(4)之 解密Filter

下图是新的渲染效果,我们希望“Amazon”流域的所有河流除了原来的效果外还用蓝色的粗线渲染一次,这里是SLD文件

>

 

开放GIS标准OGC之路(4)之 解密Filter

 代码


推荐阅读
  • 【重识云原生】第四章云网络4.8.3.2节——Open vSwitch工作原理详解
    2OpenvSwitch架构2.1OVS整体架构ovs-vswitchd:守护程序,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换flow-basedswitchin ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • Jquery 跨域问题
    为什么80%的码农都做不了架构师?JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
author-avatar
laosiji
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有