MS RFC 91:层过滤器规范化

日期

2014年7月14日

作者

史蒂夫·莱姆

联系

sdlime@comcast.net

状态

草稿

版本

TBD

1。概述

层过滤器是特定于驱动程序的表达式,在MapServer中使用以下几种方式:

  1. 定义要渲染的要素子集(独立于类)

  2. 为所选查询操作定义要素子集

第一个用例通常适用于不支持某种排序表达式语言(如SQL)的驱动程序。尽管支持PostGIS和Oracle Spatial,但几乎没有理由使用过滤器,因为所需的SQL更好地表达在LAYER DATA语句中。对于非RDMS驱动程序,过滤器可以通过项/值组合或使用MapServer的标准表达式语法定义。

第二个用例适用于使用驱动程序特定语法从数据源中提取特性来定义过滤器的所有驱动程序。这导致了许多问题:

  • mapfile语法中的混淆和不一致

  • 驱动程序之间缺少重要的过滤器

  • 性能限制,因为只有最简单的过滤器易于表示和安全

此外,上述两个用例是相互排斥的,这也会导致用户混淆。依赖过滤器(按属性、按运算符)的现有查询操作在定义和应用新过滤器之前缓存现有过滤器。虽然这一限制可以独立解决,但当使用标准化的过滤器定义时,它将成为一个更易于管理的任务。

2。建议的解决方案

此SLA建议使用作为RFC XX一部分实现的公共表达式语法来标准化过滤器定义。可以处理复杂表达式的Driverscapable会将MapServer表达式转换为内部表示,这将导致 very 显著的性能改进。不具备此功能的驱动程序将对功能应用过滤,方法与本机MapServer形状文件和平铺形状文件相同(通过msxxxlayerNextShape())

2.1驱动滤波器转换

支持复杂表达式(例如PostGIS和Oracle Spatial)的驱动程序将需要实现新的层API函数(Propose MSxxxlayerTranslateFilter(layerObj*layer,expressionObj*filter,char*filterItem)),以将两个简单筛选器和MapServer逻辑表达式转换为本机表示。MapServer逻辑表达式由一系列从左到右处理的令牌组成。然后应该可以将这些令牌转换为驱动程序独立于MapServer处理的本机表示形式——通常是一些SQL风格。

2.2滤波器合并

过滤器合并是从两个表达式中创建一个表达式的过程,它只需要与mapserver查询函数一起使用,这些函数使用过滤器作为其库存处理的一部分,特别是msquerybyfilter()和msquerybyattributes()。如果存在现有的筛选器,它将与 new 过滤器。现有筛选器将像往常一样缓存。因为此操作将导致使用 common 语法此操作可以用常规方法执行:

expressionbj *msmergefilters(expressionbj *filter1,expressionbj *filter2)

随后,如果适用,生成的过滤器将转换为本机表示。

2.3过滤器合并示例

案例1:filteritem和filter“string”(或不区分大小写)

new filter变为逻辑表达式:(([filterItem]=“string”)和(new filter))

案例2:filteritem和filter/string/(或不区分大小写)

新筛选器变为逻辑表达式:(([filterItem]~“string”)和(new filter))

案例3:没有filteritem的过滤器(字符串)

新筛选器变为逻辑表达式:((字符串)和(新筛选器)

在旧过滤器已经是本机过滤器并且转换失败的情况下,我们将保留旧过滤器,这样驱动程序至少可以处理该部分,然后返回到mapserver以获取新过滤器。

2.4查询功能简化

msquerybyattribute()函数可以转换为msquerybyfilter()函数的别名。它们做的基本相同:定义一个新的过滤器并使用它执行一个查询。这简化了代码库。需要在msquerybyfilter()中进行一些功能更改,特别是在只返回1个结果(模式=itemquery)时处理这种情况,但这只是结果处理循环底部的一个简单检查。

这不会影响CGI或MapScript API,尽管我们可以选择在以后简化这些API。

2.5未来改进

对这个RFC的研究表明,令牌的链表在某些情况下很难翻译,尽管对于bison/yacc语法是最理想的。例如,如果驱动程序需要向函数调用添加参数:buffer([shape],500)需要转换为buffer(the_geom,500,1),如果很难知道何时在复杂筛选器中输出1。重写令牌处理以使用树存储而不是列表可能是有益的。这种变化不会影响更大的实现方法,而是为更完整的翻译提供了机会。时间会证明一切。

三。实施细节

3.1当前行为总结(按驾驶员)

  • shapefile:支持filteritem和filters->string、regular、logical表达式

  • ogr:支持filteritem和filters->string、regular、logical表达式和native(从“where”开始)

  • postgis:支持filter->native sql片段

  • Oracle Spatial:支持filterItem和filters->string和native(constructs native)

  • sde:支持filter->native sql片段

  • MS SQL Server:支持筛选器->本机SQL代码段

3.2概述

  • 建议对逻辑表达式语法进行有限的添加:

    • 空间运算符语法(例如a intersects b)将被弃用,取而代之的是函数表示法(例如intersects(a,b)=true)。这更符合空间上启用的SQL语法,更易于翻译。

    • beyond/dwithin运算符将 only 存在于函数形式中,它们在逻辑表达式中是无用的,因为它们现在位于

  • 没有对mapscript api的更改

  • 支持复杂表达式(例如postgis、oracle、sde、ms-sql-server、ogr)的驱动程序需要实现转换函数,以从一组表达式/筛选标记构造部分“where”子句。

3.2受影响的文件

此RFC将修改以下文件:

  • h:扩展expressionobj以包含本机_字符串(char *)。这将保存筛选器的本机表达式。

  • 在msquerybyattribute()和msquerybyfilter()中调用合并函数,在所有查询函数中调用转换函数。

  • mapdraw.c:调用msdrawvectorlayer()中的过滤器转换函数

  • maplayer.c:更改/添加层api函数

  • mapshape.c,mappostgis.c,mapogr.c…。:驱动程序功能的更改/添加

  • y:添加基于函数的空间运算符版本,添加布尔标记类型

  • maplexer.l:在表达式上下文中将true/false识别为布尔标记(存储在token->dblval中)

  • mapogcfilter.c/mapogccommonfilter.c:更新表达式写入以使用函数表示法,修复dwithin/beyond处理

笔记:

驱动程序:这可以在驱动程序中逐步实现。至少所有司机 must 实现msxxxlayertranslatefilter(),函数至少应该检测到已经提供了本机过滤器的情况(为了向后兼容)。对于关系数据库,这是过滤器是一个普通的旧字符串表达式的情况。对于ogr,这是普通的旧字符串表达式以“where”开头的地方。在这些情况下,新的本机_字符串应该用筛选字符串内容填充。

mslayerNextShape():可以在此处而不是在驱动程序代码中对公共语法(例如pure-mapserver)筛选器进行评估。ogr、shapefile和tiled shapefile驱动程序现在都这样做,需要更改。只有当筛选器的本机_字符串为空时,才会执行筛选器(这是在msevelExpression()中选中的)。

do {
  rv = layer->vtable->LayerNextShape(layer, shape);
  if(rv != MS_SUCCESS) return rv;

  filter_passed = MS_TRUE;  /* By default accept ANY shape */
  if(layer->numitems > 0 && layer->iteminfo) {
    filter_passed = msEvalExpression(layer, shape, &(layer->filter), layer->filteritemindex);
  }

  if(!filter_passed) msFreeShape(shape);
} while(!filter_passed);

mslayersupportscommonfilters():可以从层API中删除此函数,以便在调用msxxxlayerstranslatefilter()后检查filter->native_字符串。

3.3MapScript

无需更改。

3.4向后兼容性问题

通过使用带有属性和OGC过滤器查询的预定义过滤器,用户可能会感到困惑和/或必须重新构建应用程序的某些方面。例如,他们可能已经在自己的流程中构建了过滤器合并。

4。安全隐患

这个RFC应该通过多层次的翻译来强制表达式,从而使这方面的内容更加健壮。wfs getfeature过滤器的过程将是ogc filter(xml)=>mapserver common expression=>native expression。属性绑定、字符串和日期文本的所有令牌转换都将使用驱动程序提供的任何机制进行转义。例如,postgis提供mspostgisescapesqlparam()。

5。性能影响

令牌替换仅在mslayeropen()中完成,性能影响应忽略不计,因为每个呈现层仅发生一次。在某些操作被卸载到数据库的情况下,性能将大大提高-更少的网络流量,更高效的算法。

对于基于WFS的dwithin/beyond运算符,我们当前将距离值应用于缓冲区,然后将其传递给mapserver。建议的更改将删除该步骤并提高 all 病例。

6。臭虫识别码

#4974:https://github.com/MapServer/MapServer/issues/4974

7。投票历史

2014年8月19日通过,Steve L、Thomas B、Mike S、Stephan M、Daniel M、Perry N、Stephen W、Jeff M、Tom K、Tamas S的+1