Mapfile 调整和管理

作者

戴维福塞特

联系

gmail.com的david.fawcett

作者

杰夫麦克纳

联系

jmckenna在gatewaygeomatics.com

最后更新

2021-04-13

介绍

.map文件(‘mapfile’)的内容由MapServer用于配置、数据访问、投影等。由于每次请求地图图像时都会解析 Mapfile ,因此考虑在文件中包含哪些内容以优化性能非常重要。最佳映射文件是不包含或引用任何不需要的内容的映射文件。以下步骤将帮助您管理和优化 Mapfile 。

备注

在优化设置时,强烈建议您查看 MAP= 通过设置来调用MapServer可执行文件 MS_MAP_PATTERNMS_MAP_NO_PATH 或者隐藏 MAP= 参数,如本文档中所建议的 限制 Mapfile 访问 。中列出了保护服务器安全的所有可能环境变量 环境变量

可能要审查的步骤

1.使用MapServer语法文件作为您最喜欢的文本编辑器

虽然它可能不被归类为“优化”,但使用语法文件将颜色编码添加到文本编辑器中的MapServer Mapfile 参数中,可以帮助您节省时间,并使您的MapServer Mapfile 管理工作变得更加轻松。您可以在页面上找到针对MapServer列出的这些语法颜色编码工具的有用列表 MMAP文件编辑

../_images/mapfile-color-syntax.png

2.测试 Mapfile 的速度

如果优化和性能对您很重要,那么请了解并喜欢上MapServer命令行实用程序 Sp2IMGShp2img 将验证您的 Mapfile 是否创建了有效的地图图像,但它还可以显示绘制时间(MapServer处理每个图层和最终地图图像所需的时间长度 -map_debug 3 设置:

shp2img -m osm.map -o ttt.png -map_debug 3

msDrawMap(): rendering using outputformat named png (AGG/PNG).
msDrawMap(): WMS/WFS set-up and query, 0.000s
msDrawMap(): Layer 95 (land13), 0.001s
msDrawMap(): Layer 96 (landuse13), 0.051s
msDrawMap(): Layer 97 (transport_areas13), 0.002s
msDrawMap(): Layer 98 (waterarea13), 0.003s
msDrawMap(): Layer 99 (waterways13), 0.002s
msDrawMap(): Layer 100 (railways13), 0.003s
msDrawMap(): Layer 101 (roads13), 0.024s
msDrawMap(): Layer 102 (aeroways13), 0.002s
msDrawMap(): Layer 103 (buildings13), 0.245s
msDrawMap(): Layer 104 (borders13), 0.197s
msDrawMap(): Layer 105 (places13), 0.078s
msDrawLabelCache(): labelcache_map_edge_buffer = 10
msDrawMap(): Drawing Label Cache, 0.020s
msDrawMap() total time: 0.772s
msSaveImage(ttt.png) total time: 0.056s

上面的示例在中生成地图图像 0.772秒

提示:如果您想要最多的(详细)消息,请尝试 -all_debug 5 而不是设置。

还可以只获取单个层的绘制时间 -l layername 交换机,例如:

shp2img -m osm.map -o ttt.png -map_debug 3 -l buildings13

msDrawMap(): rendering using outputformat named png (AGG/PNG).
msDrawMap(): WMS/WFS set-up and query, 0.000s
msDrawMap(): Layer 103 (buildings13), 0.119s
msDrawLabelCache(): labelcache_map_edge_buffer = 10
msDrawMap(): Drawing Label Cache, 0.001s
msDrawMap() total time: 0.120s
msSaveImage(ttt.png) total time: 0.016s

备注

Sp2IMG 应包含在您的MapServer安装中 (MS4W _用户需要执行 setenv.bat 在使用该实用程序之前)。

3.使用各种配置设置进行调试

回顾 调试MapServer 文档并尝试在映射文件中的映射级设置配置参数,希望从各种来源获得更多信息,例如从Proj库、GDAL库等。

MAP
  ...
  CONFIG "CPL_DEBUG" "ON"
  CONFIG "PROJ_DEBUG" "ON"
  ...
  LAYER
    ...
  END
END

备注

您可以设置 "CPL_DEBUG" "PROJ" 限制返回给PROJ的信息(一般不是GDAL)

4.通过mapserv可执行文件测试完整的映射请求

有时,您的映射文件会使用本地shp2img命令生成有效的地图图像,但是相同的映射文件会在通过Web服务器(如apache)的地图请求中导致错误。在这些情况下,您应该尝试通过您的Web服务器在命令行中使用实际 映射服务器 (或在Windows上, mapserv.exe )实用程序。

以下请求将占用完整的 MAP=...&MODE=map 请求,并尝试将请求保存到图像,或报告错误:

mapserv -nh "QUERY_STRING=MAP=/ms4w/apps/local-demo/local.map&MODE=map" > test.png

您还可以使用它来测试有问题的WMS GetMap请求:

mapserv -nh "QUERY_STRING=SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=41.42710000000000292,-173.4329999999999927,83.74660000000000082,-13.04809999999999981&CRS=EPSG:4326&WIDTH=369&HEIGHT=98&LAYERS=park&STYLES=&FORMAT=image/png&DPI=96&MAP_RESOLUTION=96&FORMAT_OPTIONS=dpi:96&TRANSPARENT=TRUE" > test.png

注: 除了检查您的Web服务器日志外,您还可以使用QGIS获取对您的OWS(WMS/WFS等)的准确请求。服务:请参阅https://github.com/mapserver/mapserver/wiki/Get-the-Raw-WMS-Request-Generated-by-QGIS

../_images/qgis-network-logger.png

5.预测

在映射文件中定义投影有两种方法。您可以使用在线投影参数,也可以为该投影指定EPSG代码。如果您使用 EPSG 编码方法, PROJ 使用EPSG代码作为ID在Proj数据库中查找投影参数。与内联定义投影参数时相比,此数据库查找占用的资源要多得多。使用映射文件中的EPSG代码对每个投影定义执行此查找。

参见

PROJECTION

使用内联投影参数定义的投影

PROJECTION
  "proj=utm"
  "ellps=GRS80"
  "datum=NAD83"
  "zone=15"
  "units=m"
  "north"
  "no_defs"
END

使用EPSG代码定义的投影

PROJECTION
   "init=epsg:26915"
END

优化建议

  • 使用内联投影参数定义代替EPSG代码。

  • 应该说明的是,为了获得最佳性能,您可以让MapServer不按需执行任何投影(换句话说,将所有源数据放在同一投影中,并将MapServer输出请求放在该投影中),但显然这并不总是适用于所有场景。

  • 如果要使用EPSG代码,请从项目中删除所有不需要的投影定义记录 EPSG 数据库。

    备注

    这是低于6版本的项目的常见技巧(其 epsg 文件),但对于项目>=6 a proj.db SQLite数据库用于存储这些EPSG查找代码,其优化需要一些时间来开发和共享)。

6.用途包括

在MapServer4.10中实现的映射文件 INCLUDE 参数可能是帮助管理大型 Mapfile 的最佳方法之一(您可能会争辩说,这不是对速度的“优化”,而是因为它对于管理具有多个层的大型 Mapfile 非常重要)。

除了显而易见的层之外,映射文件的任何部分都可以通过Include引用。

备注

Include的常见文件扩展名包括: .lyr.包含 ,甚至 .map 。您可以随心所欲地为它们命名任何文件扩展名。

你可以拥有这样的东西:

MAP
  ...
  WEB
    INCLUDE "metadata.include"
  END
  ...
  INCLUDE "elevation.lyr"
  INCLUDE "country.lyr"
  INCLUDE "city.lyr"
  ...
END

哪里 metadata.include 可能包含:

METADATA
  "wms_title"          "WMS Demo Server"  ##required
  "wms_onlineresource" "http://yourpath/cgi-bin/mapserv.exe?"   ##required
  "wms_srs"            "EPSG:3857 EPSG:4326 EPSG:4269 EPSG:3978"  ##recommended
  "wms_enable_request" "*"   ##necessary
END

7.层次

对于 Mapfile 中状态为打开或默认的每个图层,MapServer将加载该图层并准备显示,即使该图层从未显示。

优化建议

  • 构建精简 Mapfile ,仅包含您计划使用的层。

  • 关闭不必要的层;MapServer显示的层越多,花费的时间就越多。让打开的地图视图仅显示确定用户方向所需的最小值,并允许用户根据需要打开其他图层。这对于远程WMS或非常大的栅格尤其适用。

  • 与关闭图层相关的是打开图层,但使用minscaledenom和maxscaledenom确定图层可用的缩放级别。如果地图的显示超出了图层的minscaledenom和maxscaledenom范围,那么mapserver可以跳过该图层的处理。它也产生了一个非常酷的效果,国家边界神奇地变为国家边界。

  • 如果你有一个复杂的应用程序,可以考虑使用多个简单而具体的 Mapfile 来代替一个大的“无所不能”的 Mapfile 。

  • 在类似的脉络中,每个类也支持minscaledenom和maxscaledenom。如果您的数据集具有与不同缩放级别相关的数据,那么您可能会发现这是一个非常方便的技巧。例如,给Minscaledenom 1:1000000,县道Minscaledenom 1:100000,街道Maxscaledenom 1:50000。新数据神奇地出现,你会得到很酷的效果,但是当整个国家都在眼前时,你不会让MapServer试图绘制国家的道路!

  • 类按顺序处理,并将一个特性分配给匹配的第一个类。因此,尝试将最常用的类放在类列表的顶部,这样MapServer就不必在找到匹配项之前尝试那么多的类。例如,如果您想突出显示怀俄明州的单一状态,您可能会这样做:

CLASS
   EXPRESSION ('[NAME]' eq 'WY'])
   STYLE
     COLOR 255 0 0
   END
END
CLASS
   STYLE
   COLOR 128 128 128
   END
END

但这样做效率会更高,因为98%的病例会在第一次尝试时匹配:

CLASS
  EXPRESSION ('[NAME]' ne 'WY'])
  STYLE
    COLOR 128 128 128
  END
END
CLASS
  STYLE
    COLOR 255 0 0
  END
END

8.是的,数据格式很重要

这通常不是在文档中编写的,而是经常在实践研讨会中教授的(因为也许读者或开发人员在阅读这里的文档时,如果它的想法或软件设计的目的不同,就会被冒犯,因为一些人可能会认为某些格式“不酷”,但实际上,我们不在乎在这里是否酷,我们关心的是让MapServer变得更快)。因此,以下建议是由本文档(免责声明)的作者提出的,可能会冒犯一些读者,因此建议读者酌情处理。

尽管MapServer可以读取任何支持的GDAL vectorraster 源(而且并非所有用户都会预先设置分片缓存),因此仍建议MapServer采用以下方法以获得最佳的数据格式性能。

优化建议

  • 就显示速度而言,MapServer的最佳/最佳数据源为 .shp (用于向量)和 GeoTIFF (用于栅格)。

  • 对于数据库,将显示MapServer PostGIS 层的速度非常快,在MapServer源代码中包含了一些专门用于PostGIS+MapServer绘制速度的自定义技巧。因此,推荐使用PostGIS。

  • SpatiaLite 建议那些需要可移植格式的人使用,并且与MapServer配合使用非常好。

  • 无论您选择哪种格式,一定要查看与该特定格式相关的GDAL格式(驱动程序)页面,并启用索引(空间或属性索引)。

  • 栅格,当然还有GeoTIFF,也应该包含概视图,通过 gdaladdo 实用程序。

  • 栅格图层还可以包括各种 PROCESSING directives ,特定于MapServer中的栅格显示(例如显示特定的带区,或选择重采样方法,但对于重采样,请使用最快的显示选项与显示质量进行实验)。

  • 如果您确实使用.shp文件(许多文件仍在使用),则必须始终在MapServer中通过 希普特里 实用程序。

  • 只要有可能,使您的源数据集尽可能轻量级,将有助于MapServer处理您的数据(对于矢量,这可能意味着删除未使用的数据字段)。

  • 如前所述,如果您必须将不同的栅格或矢量一起显示为一个“马赛克”,请实现 瓦片索引 ,将马赛克实现为MapServer中的单个层。

  • GDAL的虚拟格式(VRT)对于马赛克或按需转换数据也非常强大,并且具有特定的VRT驱动程序指令 vectorraster

  • 有时,将.shp文件(Shapefile)拆分为较小的文件会使其在MapServer中更高效地显示; shp2tile 实用程序是实现这一点的一个很好的命令行工具。

备注

对于Windows用户, MS4W 包括shp2tier实用程序和上面提到的所有实用程序。

9.通过MapCache启用缓存

如果 Mapfile 提供任何与OGC相关的服务(例如WMS、WFS等)您应该考虑启用 MapCache ,这是一个用于您的服务的apache模块。缓存公共地图范围的公共地图结果(作为图像文件,或在SQLite数据库中),显然将极大地提高速度,并抵消上面提到的任何格式讨论/好处/论点。

10.符号

加载映射文件时,符号文件中列出的每个栅格符号都位于文件系统中并被加载。

优化建议

  • 只有当您知道栅格符号将被应用程序使用时,才在符号文件中包含栅格符号。

11.字体

要加载字体,MapServer会打开一个查找文件(通常命名为fonts.list或fonts.txt) FONTSET 它包含字体的别名和该字体文件的路径。如果您的Fonts.list文件包含很长的字体列表,则MapServer将需要更多时间来定位和加载您需要的字体。

优化建议

  • 将fonts.list中的条目限制为实际使用的字体。

12.使用MapScrip

您最喜欢的语言(如PHP或Python)中的MapScrip可以用来动态操作 Mapfile 。一些常见的使用案例包括:

  • 将图层添加到现有 Mapfile

  • 修改现有层

  • 按需生成新的 Mapfile /服务

这里的选项是无限的,适用于您可以使用MapScrip执行的操作。中列出了可用参数和函数(方法)的完整列表 Swig MapScript API引用

13.不要暴露您的地图路径

如果您的 Mapfile 提供OGC服务,则这一点更为明显,例如在 wms_onlineresource 参数,默认情况下,该参数必须包含 MAP=path/to/your/mapfile ,但公开公共服务器上的路径可能会使您的文件系统受到可能的恶意攻击。您应该花一些时间来查看文档中可能的步骤 限制 Mapfile 访问

至少,您应该启用 MS_MAPFILE environment variable 因此,您CGI映射服务器请求和您的Online资源OGC请求不需要可见的map=Path。WMS服务器文档有几个 examples 如何启用这些环境变量。