MS RFC 79:层屏蔽

日期

2011/11/30

作者

托马斯堡

作者

艾伦布德罗

联系

t在terriscope.fr的端口

联系

地图齿轮网的Aboudreault

最后编辑

2012/05/11

状态

实施

版本

地图服务器6.2

1。概述

对于某些应用程序,需要屏蔽一个或多个层,以便仅在返回的图像中呈现与另一组功能相交的功能。如果所有数据都存储在PostGIS中,那么用SQL连接来实现这一目标相对来说是微不足道的,但是如果要屏蔽的层或用作遮罩的层来自shapefile或栅格数据源,那么任务就变得更为复杂甚至不可能了。

这方面的一个示例用例可能是为给定客户机呈现meteo数据,但仅限于客户机购买服务的区域。在这种情况下,Meteo数据只应在表示购买区域的一组多边形覆盖的区域上呈现。

另一个给定输入DEM栅格的示例用例可能是仅渲染高程包含在给定范围内的数据。

为了实现这些目标,当前的RFC建议引入“遮罩”层,其中只有与给定遮罩相交的特性才会呈现到最终图像上。

2。建议的解决方案

为了处理所有层类型,这个RFC建议在像素级别实现层屏蔽,并添加一个“mask”mapfile关键字。mask关键字放在层级别,并接受一个参数,该参数是应用作遮罩的另一个mapfile层的名称。

在渲染时实现遮罩的机制是:

  • 用作遮罩的每个层都在其自己的临时图像中呈现。所有的过滤和样式都是照常进行的,这意味着可以执行栅格分类/过滤,以及样式级别的geomtransforms等。

  • 当一个图层引用一个遮罩时,它会以自己的临时图像呈现,与设置不透明度时的渲染方式相同。和以前一样,所有类型的过滤/转换都可以在屏蔽层上执行。

  • 将遮罩层混合到最终的地图图像上,但仅限于遮罩图像中设置的像素。

遮罩使用示例:

LAYER
 NAME "parcels"
 TYPE POLYGON
 STATUS OFF
 DATA "the_geom from parcels where clientid='%token%'"
 CLASS
  STYLE
   COLOR 0 0 0
  END
 END
END

LAYER
 NAME "meteo"
 STATUS ON
 TYPE RASTER
 DATA "raster.tif"
 MASK "parcels"
END

备注

用作遮罩的层 will 如果其状态设置为默认,或如果其状态设置为“开”,并且层名称包含在请求的层中,则在最终地图图像中呈现。此功能的大多数用户可能希望将遮罩层设置为关闭状态。

三。实施细节

  • 解析器将有一个mask关键字添加到其中,需要一个字符串

  • layerObj将添加两个属性:

    • char*mask layer:应用作遮罩的层的名称

    • imageobj*mask image:对于已被另一层引用为遮罩的层,这将包含用于确定在最终地图图像上可以呈现数据的位置的像素。这是为了防止遮罩层在被多个层引用时被多次渲染。

  • 在msdrawlayer()中,如果当前层引用了一个遮罩层:

    • 通过对msdrawlayer()的另一个调用创建和呈现临时映像。

    • 创建临时图像并将其呈现为与设置了图层->不透明度相同的代码路径。

    • 第二个临时图像的alpha通道被篡改,并为第一个临时图像中未设置的所有像素设置为0。

    • 第二个临时图像被混合到最终的地图图像中,再次遵循代码路径,就好像已经设置了层->不透明度。

3.1受影响的文件

此RFC将修改/创建以下文件:

mapserver.h/mapfile.c/mapfile.h/maplexer.l/mapcopy.c: parser and new layerObj members
mapdraw.c: implementation in msDrawLayer()
maplabel.c: implementation for dropping labels from the labelcache if they don't
            intersect the mask layer in msAddLabel()

3.2MapScript

必须添加getter和setter以编程方式向layerobj添加一个掩码。预计不会有其他问题。

3.4向后兼容性问题

此更改提供了新的功能,没有考虑向后兼容性问题。

第四章。限制

  • 查询:遮罩是在像素级别完成的,因此查询数据源的所有操作都不会遮罩特性。

  • 矢量渲染器:矢量渲染器不支持屏蔽操作(SVG,PDF)

  • 标签:在labelcache阶段,通常在渲染完所有层后执行标签。

    • 对于作为遮罩引用的层,层的labelcache将设置为off,这将导致所有标签直接添加到临时遮罩图像,而不是添加到labelcache。当然,不建议在用作遮罩的图层上添加标签(即,除非有人发现有令人信服的用例这样做)

    • 如果要屏蔽的层具有标签,则这些标签在通过labelcache时有可能在屏蔽区域之外呈现。为了克服这个问题,在将labelpoint添加到labelcache之前,将进行一个测试,以确保labelpoint包含在屏蔽区域中。请注意,标签文本本身可能呈现在屏蔽区域之外,但这不应成为问题。如果将遮罩层设置为labelcache false,则渲染的标签将在像素级别自动过滤掉,尽管可能会出现截断的标签。

5。错误处理

除了经典的情况外,这里没有特殊的情况需要处理(解析错误、由掩码引用的无效层、选择的渲染器无效)

6。臭虫识别码

https://github.com/MapServer/MapServer/issues/4111

7。投票历史

从托马斯布、迈克尔斯、斯蒂芬、阿塞法伊、弗兰克、塔马斯、丹尼尔、杰夫麦克、汤克、奥利维埃、史蒂文+1通过。