mappyfile

创建、分析、修改和格式化的python库 MapServer Mapfiles。

  • Python 2和3 兼容

  • 纯Python-无MapServer依赖项

  • 开源许可证(MIT)

演示库功能的在线格式化程序可以在:http://mappyfile.geographika.net上找到。/

关于mappyfile的演示文稿在 FOSS4G Europe 2017 -幻灯片可用 to download here .

_images/class_parsed.png

什么是 mappyfile?

mappyfile 将mapfile作为输入并将其解析为 Abstract syntax tree (AST) 使用 lark 一个python解析库。然后,mappyfile可以将ast转换为字典结构,其中包含dict的键和值,以及Python程序员熟悉的列表。此结构可以直接编辑。或者,可以通过解析更多的映射文件文本并插入字典结构来添加新对象。mappyfile还包括一个“漂亮的打印机”,用于将字典结构导出回mapfile,并使用关键字格式和缩进。

mappyfile 假设了解mapfile格式-a domain specific language (DSL) 由MapServer用于生成地图图像。mappyfile是使用mapscript的一种可能的替代方法。这些定义(来自 MapServer glossary )如下所示:

  • Mapfile 是MapServer用于定义数据连接、映射样式、模板化和服务器指令的声明性语言。它的格式类似于XML,具有层次结构,带有结束结束标记,但格式不是XML。

  • MapScript 是mapserv的cgi应用程序的替代方案,它允许您用多种语言编程mapserver对象API。

下图显示了mappyfile的不同元素,以及它们如何用于修改mapfile:

_images/mappyfile_modules.png

为什么?

  • 从同一源映射文件轻松生成开发、分段和生产映射文件

  • 从单个映射文件为不同的数据集创建映射文件

  • 从Python中创建、操作和测试映射文件

使用mapserver构建应用程序的当前替代方法是使用mapscript。这种方法有许多问题导致了映射文件的开发:

  • 当在Windows上运行时,任何使用C/C++的Python库都需要用MS C/C++ VS2008编译器来编译,这意味着没有使用MyScript的应用程序可以利用MS C/C++ 2015编译器的性能改进

  • 您需要创建一个空日志文件,否则MapServer将无法打开映射(或获取“mssterrorfile():常规错误消息)。打开MS_ErrorFile“错误”失败)

  • 无法通过pypi获得mapscript-最新版本已于2010年上载-https://pypi.python.org/pypi/mapscript/5.6.3.0 UPDATE Windows上的MapServer 7.2的MapScript控制盘现在可用

  • 需要设置工作目录,以便找到mapserver includes(这也适用于mappyfile,但不需要os.chdir和更改脚本或应用程序的工作目录)

  • Mapscript api不是特别的“pythonic”

一个关键的区别是mapyfile只处理文本,所以您不能像使用mapscript那样通过层检索功能或连接到数据库。mapyfile的方法是构建一个mapfile,然后使用mapserv程序来处理这些需求。这项设计受到了Sean Gillies的影响,他是MapScript维护者,工作了几年(直到2006年)。他最近几篇关于mapscript的博客文章有力地说明了如何使用mapfiles而不是mapscript:

“停止,或者至少,最小化您对MapServer各种语言绑定的使用。相反,采用MapServer的领域特定语言(DSL),编写更多称为mapfiles的声明性制图脚本。使用mapserv(或shp2img)程序将这些脚本编译成图像。这是通往幸福和繁荣的道路。

Sean Gillies - Stop using MapScript

稍后的一篇文章列出了这种方法的好处:

“在mapserver mapfile中编码的指令包含一种特定于域的语言。接受地图语言就是从简单性、可用性和可移植性中获益。

Sean Gillies - Declarative Maps

Mapfile作为DSL的概念已经实现了几次。由AllanDoyle编写的 Python Mapfile builder 使用了一种XML方法。

最近,节点模块 node-mapserv 提供对声明性映射文件编程的支持。作者指出:

节点mapserv不是节点的mapscript。相反,它为呈现MapServer映射文件提供了一个简单的声明性API。通过自定义生成新的映射文件和调整现有的映射文件,可以声明性地完成大部分必须使用MapScript才能完成的任务。

作为有趣的脚注,由于 SWIG 它为C.Swig创建包装代码 David Beazley 他后来建造了 PLY 最初基于哪个映射文件。ply是针对python的lex和yacc解析工具的一个实现——mapserver本身用于在c中解析映射文件的工具。

代码示例

本节详细介绍了 mappyfile 类库。有关所有功能和示例,请参见 mappyfile API 文档。

访问值

# open will accept a filename (mappyfile.loads will accept a string)
mapfile = mappyfile.open("./docs/examples/raster.map")

# print the map name
print(mapfile["name"]) # "MyMap"
   
# access layers
layers = mapfile["layers"]
layer2 = layers[1] # access by index

# access classes in a layer
classes = layer2["classes"]

for c in classes:
    print(c["name"])

查询

# load will accept a filename (loads will accept a string)
mapfile = mappyfile.open("./docs/examples/raster.map")

# search for a layer by name
layer = mappyfile.find(mapfile['layers'], 'name', 'sea')
print(layer['name']) # "sea"
   
# search for all layers in a group
for layer in mappyfile.findall(mapfile['layers'], 'group', 'my_group'):
    print(layer['name'])

修改值

# update the map name
mapfile["name"] = "MyNewMap"

# update a layer name
layers = mapfile["layers"]
layer = layers[0]
layer["name"] = "MyLayer"

# update the error file path in the map config section
# note key names can be lower or upper case

mapfile["config"]["ms_errorfile"] = "/ms4w/tmp/ms_error.txt"

# update the web metadata settings

mapfile["web"]["metadata"]["wms_format"] = "image/png"
print(mappyfile.dumps(mapfile["web"])) # print out just the WEB section

# alternatively we can parse the Mapfile syntax and load it directly

s = """
    METADATA
        'wms_enable_request' '*'
        'wms_feature_info_mime_type' 'text/html'
        'wms_format' 'image/jpg'
    END"""

metadata = mappyfile.loads(s)
mapfile["web"]["metadata"] = metadata
print(mappyfile.dumps(mapfile))

添加项目

添加新层:

layers = mapfile["layers"]

new_layer_string = """
LAYER
    NAME 'land'
    TYPE POLYGON
    DATA '../data/vector/naturalearth/ne_110m_land'
    CLASS
        STYLE
            COLOR 107 208 107
            OUTLINECOLOR 2 2 2
            WIDTH 1
        END
    END
END
"""

new_layer = mappyfile.loads(new_layer_string)
layers.insert(0, new_layer) # can insert the new layer at any index

将新类添加到层:

# find a layer using its name
layer = mappyfile.find(mapfile["layers"], "name", "sea")

new_class_string = """
CLASS
    NAME 'highlights'
    STYLE
        COLOR 107 208 107
        OUTLINECOLOR 2 2 2
        WIDTH 1
    END
END
"""

new_class = mappyfile.loads(new_class_string)
layer["classes"].insert(1, new_class) # can insert the new class at any index
print(mappyfile.dumps(mapfile))

发展路线图

导致1.0版发布的未来开发计划包括:

  • 设置一种插入“linters”的简单方法,以检查各种映射文件设置和规则(例如,为WFS正确配置)

  • 创建一个jupyter笔记本演示mappyfile的用法

  • 向文档添加插件页

  • 添加使用yaml创建映射文件的示例

  • 创建新的 prune 从映射文件中删除冗余默认设置的函数

发行版

0.9.0 2020年7月14日

  • 已更新架构以包括 minVersionmaxVersion 要为映射文件定义不同版本的元数据关键字

  • 一个新的 schema 用于为不同版本的MapServer导出映射文件架构的命令行工具

  • 允许基于特定版本的MapServer验证映射文件

  • 当错误的dict被传递到打印机时,添加更好的错误消息

  • 将py38添加到持续集成测试中

  • 向连续集成测试添加命令行脚本

  • 固定 CONNECTIONOPTIONS 格式化输出

  • 更新至lark parser 0.9.0

  • #109 -基于MapServer版本添加验证

  • #96 -未加引号的Unicode字符串会导致分析错误

  • #102 -增加了对非引号字符串中重音拉丁语的支持(第96期)-谢谢@erezsh

  • #97 -允许使用否定表达式

  • #101 -修正问题#97(一元否定)-谢谢@erezsh

  • #85 -非逻辑表达式的编码

  • #100 -允许非方括号NOT表达式(问题85)-谢谢@erezsh

0.8.4 2020年1月11日

  • 更新至lark parser 0.7.8

  • #95 -允许从中输入映射文件 io.StringIO 以及从一个文件-感谢@ianturton的请求

  • #93 -修复以确保读取后关闭映射文件

  • #89 -属性中带有空格的列表表达式无法解析-谢谢@ianturton的修复

0.8.3 2019年10月6日

  • 更新至lark parser 0.7.7

  • 更新至jsonref 0.2

  • 使用Appveyor向GitHub添加自动发布

  • 使用Appveyor向PyPI添加自动发布

  • 向JSON架构添加缺少的类属性

  • CaseInsensitiveOrderedDict和表达式的附加测试

  • #37 -就像在过滤器里没有被识别-谢谢@ianturton的修复

  • #87 -JSON schema add join tag-感谢@hugbe8进行修复

0.8.2 2019年3月29日

  • #74 -包含unicode的映射文件可能在mappyfile.load中失败,使用python2.7,谢谢@ianturton

  • #73 -Deepcopy不工作(python3>=3.5)-谢谢@guardeivid

  • 添加对cluster关键字以及架构更改和测试的支持

0.8.1 2019年2月27日

  • 修复映射文件中根对象的注释

  • 修复重复元数据键和注释的问题

  • 修复readthedocs构建

  • 向项目中添加更多用于测试的示例映射文件

0.8.0 2019年2月24日

  • 更新代码以使用lark 0.6.6(请参见71)

  • Pprint的new end_comment选项-在每个结束END语句处添加一个具有块类型的注释,例如END # MAP(请参见请求 #69

  • 添加 **kwargs 到主API以允许插件具有更大的灵活性

  • 修复与python 3.7.2相关的拒绝警告(感谢@tigerfoot提供报告)

  • 与新的JSonSchema 3.0.0版本一起测试使用

0.7.6(2018年10月13日)

  • 从API和代码库中删除了已弃用的 write 的函数

  • 更新偏移量验证以允许属性绑定-请参阅https://github.com/mapserver/docs/pull/256

  • #68 -对python3中的默认订单dict进行支持酸洗

  • #67 -修复python 3.6中语法正则表达式的拒绝警告

  • #65 -处理十六进制颜色半透明

0.7.5(2018年9月14日)

  • 为值列表保存标记

  • 更新自述文件并修复示例代码

0.7.4(2018年9月7日)

  • 模运算符的支持

  • 允许自定义变压器与Kwargs一起使用

0.7.3(2018年8月23日)

  • 两个新的CLI程序- formatvalidate

  • 将lark解析器更新为0.6.4(修复了一些验证行号问题)

  • 验证日志消息的改进

  • 使包含路径正常化

0.7.2(2018年7月24日)

  • 将lark解析器更新为0.6.2和相关更改-谢谢@erezsh

  • mappyfile.findall 返回列表而不是生成器

  • SYMBOLSET 现在支持的文件(解析和转换)

  • #63 -为单个字符串正确设置投影值

  • #61 -删除mappyfile.findall()中的引号

0.7.1(2018年7月10日)

  • Breaking Change utils.dictfind 更名 utils.findkey

  • 新字典更新功能-允许使用yaml轻松创建映射文件

  • 允许窗体的任何自定义隐藏元数据标记 __property__ 在dicts中用于自定义处理

  • 架构验证更新,包括rangeitem和cluster

  • 添加了Appveyor生成

  • #56 无法分析包含:的表达式

  • #54 修复包含的Windows CWD名称问题-谢谢@ianturton

0.7.0(2018年4月4日)

  • 最终确定验证API

  • 最终确定的 Mapfile 注释API

  • 新的 dictfind 功能

  • 在表达式中允许非字符串函数参数

  • 在变压器中使用无灵敏度有序ICT

  • UTF评论

  • JSonSchema更新和修复

0.6.2(2018年2月24日)

  • Breaking Change - mappyfile.load 方法现在接受一个类似文件的对象,而不是文件名来匹配其他Python库中的用法。一个新的 mappyfile.open 方法允许直接用文件名打开。

  • 新的保留评论功能- 实验性

  • 添加基本插件系统

  • 更新架构文档(修复位置、自动和添加新默认值)

  • 修复包含行上带有注释的问题

  • #50 允许geotransform参数使用end关键字

  • #49 在分析器中允许非ASCII字符

  • #47 添加缺少的表达式运算符-除法、乘法和幂。

0.6.1(2018年2月6日)

  • 对setup.py的修复

0.6.0(2018年1月17日)

  • 语法和变换器的广泛重构

  • 删除 Earley 语法

  • 分析时忽略空白

  • JSON模式修复

  • #45 设置固定的依赖范围

  • Experimental -包括令牌位置

  • Experimental -包含验证意见

0.5.1(2018年1月5日)

  • #45 Remove unnecessary parser keyword`

0.5.0(2017年11月1日)

  • 外接程序JSonSchema和验证类

  • #44 Includes should be relative to Mapfile`

0.4.3(2017年8月28日)

  • #36 Create a unique logger for mappyfile logger`

  • #35 添加对缺少算术表达式的支持,并在tox中运行flake8`-谢谢@loicgrasser

  • #33 修复最大递归限制计数`-谢谢@loicgrasser

0.4.0(2017年8月18日)

  • 添加一个LALR语法和解析器,现在8K行映射文件的解析速度提高了12倍

  • 使用JSonSchema添加一个实验验证模块

  • #30 flake8支持`-谢谢@loicgrasser

  • #28 添加对嵌套include的相对路径的支持`-谢谢@loicgrasser

  • #25 Expression grammar not allowing !`

0.3.2

  • 修复为单个语法,但在所有语法之前添加换行符 END 保持可接受性能的关键字

0.3.1

  • 附加的可选语法允许复合数据之间没有换行符,如果解析失败则返回到此语法(否则,大多数用例会遭受3倍的性能损失)

0.3.0

  • 允许直接分析多个复合数据(例如 CLASS..END CLASS..END

  • 允许直接分析 METADATAVALIDATION 阻碍

  • 打开映射文件时 UTF-8 会检查

  • #23 Alternative NE and EQ comparisons not defined`

  • #22 Handle AUTO Projection setting`

  • #21 INCLUDES throw error when no cwd set`

  • #20 Only the first FORMATOPTION is kept after transform`

  • #19 IMAGEMODE FEATURE throws parsing error`

  • #18 CONFIG keyword not capitalised`

旧版本

  • 0.2.2-对语法的各种修复,并允许备用比较运算符

  • 0.2.1-新 findall 函数,请参见https://github.com/geographika/mappyfile/pull/12-谢谢@jenselme

  • 0.2.0-切换到lark解析器

  • 0.1.0-初始版本