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“錯誤”失?。?/p>

  • 無法通過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(修復了一些驗證行號問題)

  • 驗證日志消息的改進

  • 使包含路徑正?;?/p>

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-初始版本