如何设置透明覆盖 WMS 图层的样式
Posted
技术标签:
【中文标题】如何设置透明覆盖 WMS 图层的样式【英文标题】:How to style transparent overlayed WMS layer 【发布时间】:2011-11-30 02:43:28 【问题描述】:我在谷歌地图v3中成功overlayed a WMS layer,但是,由于瓷砖上的信息在透明时是黑色的,所以在深色背景(如卫星地图)上看不太清楚,例如看一些瓷砖:
(This was the WMS link 检索该图块)
问题:如何修改上述 WMS 请求,将前景色(目前为黑色)更改为自定义颜色(例如红色)? 换句话说,如何设置图层样式?服务器显然能够为这一层执行此操作,因为可以通过their web map application(仅适用于 IE)执行此操作,您可以在其中选择颜色。例如,请参阅此地图图像:
(The following link 用于检索图像 - 请注意它包含比例和徽标,因此它不是正确的平铺。)
不幸的是,这个 Web 应用程序不使用 WMS 来获取这个样式化的地图,所以我不能只是将样式化参数复制到 WMS 请求中。 我必须通过 WMS 请求进行样式设置(因为这种其他请求格式是专有的,检索整个地图 - 不是为图块设计的 - 而且它似乎不支持 WGS 坐标) - 如何我应该这样做吗?
我尝试过:
-
看WMS documentation,尤其是version 1.1.1
看看SLDs,但它似乎很难掌握......
查看 WMS 服务器的 GetCapabilites command output
另外,查看DescribeLayer 和GetStyles 所需图层(HLMCR)的命令输出后,我什至不知道该图层是否支持WMS 上的样式...
我迷路了,如果你指出我正确的方向,我将不胜感激 - 或者如果它甚至可以在 WMS 中解决(对于这一层),我将不胜感激。
“不可能”对我来说也是一个有用的答案!
提前致谢。
【问题讨论】:
由于 WMS 是将空间数据转换为图像的服务,因此您必须为服务提供样式以进行渲染并在响应中将该图像发回给您; SLD是去这里的方式。您可以创建自己的样式,然后使用 SLD_BODY 参数或指向末尾带有该 SLD 样式的 URL 的 SLD 参数发送附加该样式的请求。 提到的服务似乎已经不存在了,以下哪个服务提供了类似的层(捷克语不是我的强项):http://geoportal.uhul.cz/wms_mysl/service.svc/get?request=GetCapabilities&service=WMS&
或http://geoportal.uhul.cz/wms_oprl/service.svc/get?request=GetCapabilities&service=WMS&
【参考方案1】:
乍一看,这是一个 Mapserver 5.x 实现,getCapabilities 指出 UserDefinedSymbolization SupportSLD="1" 在 Map 级别启用,这意味着所有层都应该继承它。
因此,理论上您应该能够在 GET 请求中或在某个文件中提供 SLD,并将 SLD 的 URL 提供给 GET 请求,然后一切就绪。
编写 SLD 会很烦人,但是如果您认为自己有一些 SLD 应该可以工作但没有用,请将其粘贴到此处。
【讨论】:
感谢 jlivni。你有一些简单的例子,可以很容易地为我的目的重写吗?我只需要更改一个属性的一种颜色(前景色)。以及如何获取该属性的名称,该名称用于在 SLD 中引用它。谢谢【参考方案2】:使用从 WMS 读取图像并重新着色的包装脚本:
包装器
这是一个用 php 编写的示例:
<?php
$url = $_GET['url'];
$im = imagecreatefrompng($url);
if($im && imagefilter($im, IMG_FILTER_COLORIZE, 255, 0, 0, 0))
// this line is only needed if original image has transparency (32bit/pixel)
// and you want to preserve that transparency
imagesavealpha($im, true);
header('Content-type: image/png');
imagepng($im);
else
echo 'Conversion failed.';
imagedestroy($im);
exit;
?>
然后,您无需调用 WMS 链接,而是调用包装器并将 WMS 链接作为参数传递 (recolor_png.php?url=...)。包装器读取原始图像并返回带有彩色版本的新 PNG。不要忘记您作为参数传递的链接必须经过 urlencoded 才能正常工作(所有特殊字符都替换为其 %XX 十六进制表示法)。在 javascript 中,您可以使用 encodeURIComponent() 方法来做到这一点。
这是一个在我的服务器上使用您的链接和上述包装器的工作示例:
http://www.digilog.de/pub/***/recolor_png2.php?url=http%3A%2F%2Fgeoportal2.uhul.cz%2Fwms_oprl%2F%3FSERVICE%3DWMS%26REQUEST%3DGetMap%26SERVICE%3DWMS%26VERSION%3D1.1.1%26LAYERS%3DHMLCR%26FORMAT%3Dimage%2Fpng%3B%2520mode%3D24bit%26FGCOLOR%3D0xFF0000%26TRANSPARENT%3DTRUE%26SRS%3DEPSG%3A4326%26BBOX%3D16.58935546875%2C49.37522008143603%2C16.600341796875%2C49.38237278700955%26WIDTH%3D256%26HEIGHT%3D256%26STYLES%3D
这是生成的图像(半透明版本):
(来源:digilog.de)
没有半透明输出的相同包装器(从代码中删除了imagesavealpha):
http://www.digilog.de/pub/***/recolor_png.php?url=http%3A%2F%2Fgeoportal2.uhul.cz%2Fwms_oprl%2F%3FSERVICE%3DWMS%26REQUEST%3DGetMap%26SERVICE%3DWMS%26VERSION%3D1.1.1%26LAYERS%3DHMLCR%26FORMAT%3Dimage%2Fpng%3B%2520mode%3D24bit%26FGCOLOR%3D0xFF0000%26TRANSPARENT%3DTRUE%26SRS%3DEPSG%3A4326%26BBOX%3D16.58935546875%2C49.37522008143603%2C16.600341796875%2C49.38237278700955%26WIDTH%3D256%26HEIGHT%3D256%26STYLES%3D
以及生成的不透明图像:
(来源:digilog.de)
我会将这些包装器留在网上几天供您测试。
缓存
由于这种转换是处理器密集型的,因此向包装器添加一些缓存代码可能是明智之举:
从给定的 URL 创建一个哈希码,例如:$hash=md5($url) 检查存储子文件夹中是否存在名为 $hash.png 的图像 如果是:从文件中读取图像并返回 否则:创建图像,将其保存为 $hash.png 的子文件夹并立即返回如果您希望您的 WMS 内容会随着时间的推移而发生变化:还要检查缓存图像的创建日期,如果它们太旧(例如一个月左右),请清除它们。因此,对 WMS 地图的任何更改都会在最长一个月后波及您的系统。
【讨论】:
嗨@Jpspy!感谢您的回答!由于延迟增加,这当然不是一个理想的解决方案,但它相当简单和优雅,所以如果其他一切都失败了,这对我来说是一个很好的“补救解决方案” - 谢谢!我已经生成了图像并将其添加到您的答案中。没有正确转换抗锯齿存在一个小问题 - 有黑色的残余暗示。也许是因为它是 PNG 并且抗锯齿是半透明的。你知道如何改变整个图像的色调吗?我认为这会有所帮助。谢谢! 我找到了something,但是逐个像素地重新着色地图图块会非常慢......理想的情况是像你一样为此调用一个 php 函数。 没问题。如果您的原始图像是透明的,则必须在代码中再添加一行以激活透明 PNG 输出:imagesavealpha($im, true);
在行 $im = imagecreatefrompng($url);
之后。我将把它添加到上面的代码中并添加第二个包装器。
谢谢!仍然有一点点黑色(尝试缩小,在 mozilla 中按 Ctrl+)。你知道为什么吗?
不。看起来实际上像一个 PHP 错误。您可以使用imagefilter($im, IMG_FILTER_COLORIZE, 255, -255, -255)
使红色流血更多一点。但基本上所有半透明的边缘都有一种奇怪的黑色。【参考方案3】:
WMS 链接已经有一些自定义参数,可让您完全按照您的要求进行操作。 链接如下:
http://geoportal2.uhul.cz/mapserv/php/mapserv3.php?project=oprl_2011&mode=map&mapsize=256%20256&layers=HMLCR%20&x=1322616184548&map_SMO_class_0_color=0%200%200&map_HMLCR_class_0_color=255%200%200&mapext=-679915.1258015268%20-1062651.2224427482%20-679660.3694656485%20-1062461.062442748
如果您检查它,您会注意到在所有 url 编码参数之间有一个有趣的参数称为:map_HMLCR_class_0_color
如果您将其值更改为绿色(其 RGB 代码为 0,255,0),则图层将呈现为绿色。颜色以 RGB 代码表示。还有另一个参数 map_SMO_class_0_color 但我不明白它的作用。也许它设计了一些在该请求中不可见的功能?
绿色示例:
http://geoportal2.uhul.cz/mapserv/php/mapserv3.php?project=oprl_2011&mode=map&mapsize=256%20256&layers=HMLCR%20&x=1322616184548&map_SMO_class_0_color=0%20100%20200&map_HMLCR_class_0_color=0%20255%200&mapext=-679915.1258015268%20-1062651.2224427482%20-679660.3694656485%20-1062461.062442748
产生以下内容:
地图服务器中关于 rgb 颜色表示的注释
RGB 三元组必须在请求中写成如下:
R G B
(请注意,空格是必需的)。 谁的 URl 编码表示是:
R%20G%20B
因为 %20 是 URL 中空间的编码方式。
【讨论】:
嗨 unicoletti,这不是 WMS 链接!这是服务器上的另一个请求接口,用于检索完整的地图。我知道我可以做到这一点,正如您在我的问题中看到的那样我已经发布了一个如何将图层着色为红色的示例! 我正在寻找一种如何使用 WMS 做到这一点的方法。以上是关于如何设置透明覆盖 WMS 图层的样式的主要内容,如果未能解决你的问题,请参考以下文章