2. Transforming

Please note this page is currently a draft and subject to further updates.

mappyfile parses a Mapfile and turns it into a Abstract Syntax Tree (AST). The mappyfile transformer class then turns this tree into a Python dictionary. This provides the Python developer with a familiar data structure that can be used to edit the Mapfile further.

For example taking the Mapfile below:

MAP
    EXTENT -180 -90 180 90
    NAME 'MyMap'
    WEB
        METADATA
            'wms_enable_request' '*'
            'wms_feature_info_mime_type' 'text/html'
        END
    END
    PROJECTION
        "init=epsg:4326"
    END
    LAYER
        PROCESSING 'BANDS=1'
        PROCESSING 'CONTOUR_ITEM=elevation'
        PROCESSING 'CONTOUR_INTERVAL=20'
        EXTENT -180 -90 180 90
        NAME 'rgb'
        TYPE RASTER
        DATA '../data/raster/bluemarble.tif'
        TEMPLATE 'raster.template.html'
    END
END

The following code can be used to see the dictionary structure (represented here as a JSON object):

import mappyfile
import json
mf = mappyfile.open("./docs/examples/after.map")

with open("./docs/examples/sample.json", "w") as f:
    json.dump(mf, f, indent=4)

Output:

{
    "__type__": "map", 
    "extent": [
        -180, 
        -90, 
        180, 
        90
    ], 
    "name": "MyMap", 
    "web": {
        "__type__": "web", 
        "metadata": {
            "wms_enable_request": "*", 
            "wms_feature_info_mime_type": "text/html", 
            "__type__": "metadata"
        }
    }, 
    "projection": [
        "init=epsg:4326"
    ], 
    "layers": [
        {
            "__type__": "layer", 
            "processing": [
                "BANDS=1", 
                "CONTOUR_ITEM=elevation", 
                "CONTOUR_INTERVAL=20"
            ], 
            "extent": [
                -180, 
                -90, 
                180, 
                90
            ], 
            "name": "rgb", 
            "type": "RASTER", 
            "data": "../data/raster/bluemarble.tif", 
            "template": "raster.template.html"
        }
    ]
}

Notes on the above:

  • Objects that can have multiple instances in a Mapfile will be stored in lists (order is important).

  • Most objects have a set of key/value pairs. PROJECTION however is treated as a list (see http://www.mapserver.org/mapfile/projection.html).

  • Some keys are already quoted e.g. in the METADATA object items such as “wms_enable_request” are strings rather than keywords.

  • Some keys are duplicated within an object. E.g.

    PROCESSING "BANDS=1"
    PROCESSING "CONTOUR_ITEM=elevation"
    PROCESSING "CONTOUR_INTERVAL=20"
    

    These are turned into lists:

    "processing": [
        "'BANDS=1'",
        "'CONTOUR_ITEM=elevation'",
        "'CONTOUR_INTERVAL=20'"
    ],
    

Python dictionaries map closely to JSON data structures, which means the Mapfile dictionary structure can be formalised into a JSONSchema.

2.1. Mappyfile Additions

In order to ensure that no information is lost when inputting and outputting a Mapfile, mappyfile makes use of hidden properties to store additional data. This data is not outputted as part of the pprint. For example a hidden property is used to store objects of the same type e.g. LAYERs, CLASSes, STYLEs