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正確配置)
  • 為不同版本的MapServer生成架構,并允許根據特定版本驗證映射文件
  • 創建一個jupyter筆記本演示mappyfile的用法
  • 向文檔添加插件頁
  • 添加使用yaml創建映射文件的示例
  • 創建新的 prune 從映射文件中刪除冗余默認設置的函數

發行版?

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