A package for converting UMN Mapserver mapscript objects to and from JSON for Python 2.x.
The usage is simple:
# coding: utf-8
import mapscript
import msjson
msobj = mapscript.mapObj('/path/to/mapfile.map')
m = Map(mapscript_=msobj, mapfile_encoding='cp1252')
print m.to_json()
or to convert an object from json.load(s):
json_object = {
'name' : 'Foo',
'imagecolor' : {
'red': 255, 'green': 255, 'blue': 255
}
}
m = Map()
m.mapfile_encoding = 'cp1252'
m.from_json(json_object)
m.mapscript.save('/path/to/mapfile.map')
You can also set the properties directly:
m = Map()
m.name = 'Foo'
m.imagecolor = {'red': 255, 'green': 255, 'blue': 255}
Just make sure that everything after the equal sign is the jsonable representation of the value. For examples of the JSON representation of an object see their documentation.
Note
Only properties necessary for the configuration are serialised. Mapscript properties like numlayers are skipped. But you can easily add them to your configuration.
The serialisation of almost any mapscript.xyzObj is supported, just pass it as an argument to the appropriate msjson class object. Right now the package lacks support for mapscript.fontSetObj and the outputformat list for the mapscript.mapObj [1]. The currently selected outputformat can be exported though through the use of msjson.OutputFormat.
Note
The JSON of a serialised map file can contain more attributes than defined in the map file. This is due to the nature of mapscript where most properties have default values defined. Some properties, like colors have a value for beeing “not set”. These values are also read and transformed into JSON if being configured on the corresponding msjson object.
So if your map file holds no background image color configuration value, but the backgroundcolor property is defined on the Map it is read from the mapscript.mapObj and transformed into JSON.
This behavior may change in the future!
The logic of the package is based on the descriptor pattern in Python and the style of the configuration is borrowed from database ORM libraries like SQLAlchemy.
It may happen that properties on mapscript objects are existant in one version but not in another. Mapscript on Debian Squeeze 6 is of version 5.6.6, Mapscript on Ubunut 8.04 is of Version 6.0.0 (from the UbuntuGIS repository). The Debian version features a autoangle property on the labelObj while the Ubuntu version does not.
Debian 6 Squeeze:
>>> import mapscript
>>> hasattr(mapscript.labelObj(), 'autoangle')
True
Ubuntu 8.04 (UbuntuGIS):
>>> import mapscript
>>> hasattr(mapscript.labelObj(), 'autoangle')
False
This may be true for more properties than autoangle. To circumvent problems with properties that do not exist on certain mapscript versions the logic of MsJSON deals flexible with non-existant properties. When you call to_json() and a non-existant property is encounterd on the mapscript object a value of None is bound to the defined property name. Equally when trying to set a value on a non-existant property the action is skipped if the property doesn’t exist. In each case a DeprecationWarning is issued. Depending on your Python version the output of the warning may be suppressed.
You can create your own Classes for JSON serialisation, there is no need to stick to the predefined classes from the package. Just define your own handlers and you are ready to go:
# coding: utf-8
import mapscript
import msjson
from msjson.base import Base
class MyMap(Base):
base = mapscript.mapObj
# json attribute = mapscript attribute
a_name = msjson.String('name')
a_color = msjson.Color('imagecolor')
numlayers = msjson.Integer('numlayers')
m = MyMap()
m.to_json()
Each class derived from Base must have a class property base wich holds a reference to the corresponding mapscript object. Everything else can be configured as needed.
For every mapscript.xyzObj exists a represention class in the package wich deals with the conversion from and to JSON. There are different kinds of conversion handlers which deal with different aspects of the mapscript behavior in retrieving and setting values. There are Types, Datatypes, Base classes and Classes.
There are classes, so called types, for the most basic data representations in mapscript. These are:
Since these are mostly values they do not have a direct jsonable representation but return values directly with the exception of msjson.Collection and msjson.Size which return lists.
Datatypes represent mapscripts variables and map directly between Python data types and mapscript variables. Like Types, these also do not have a jsonable representation and return values directly. There are the following classes:
Base classes represent a mapscript.xyzObj and may have one or more Types, Datatypes or other Base classes as properties.
Base classes are:
Classes are the top level representations of mapscript objects. Classes include:
Each class has a collection object which wraps around the number of child elements of each class, i.e. the layers of the mapscript.mapObj object, the classes of the mapscript.layerObj object and the styles of the mapscript.classObj object. There is no direct iteration over child elements of an object in mapscript so the Collection class is used for retrieving, removing and inserting child elements.
Types represent the most basic values. They map strings, numbers and certain mapserver specific types to and from python values.
e.g.:
Map(Base):
name = String('name')
res = Float('resolution')
height = Integer('height')
Property base class
Implements the Descriptor pattern. This should be the base for new mapscript class properties.
Parameters: |
|
---|
__get__ always returns a json representation of the Property
__set__ sets the property from a json representation of the Property
Represents a collection of child elements of a mapscript object. The intended use is for layers in a map object, classes in a layer object or styles in a class object.
e.g.:
layers = Collection('getLayer', 'removeLayer', 'insertLayer',
'numlayers')
The JSON representation of the collection is a list of jsonified child items.
Parameters: |
|
---|
Class for mapping Mapserver expressions to and from JSON. getExpressionString() and setExpression() are used on mapscript.classObj to retrieve the expression.
e.g.:
CLASS
EXPRESSION ("[DESCRIPTIO]" == "Naturelle")
END
Class for mapping float numeric values to and from JSON.
Class for retrieving the imagetype from mapObj.
Warning
Setting this is currently not fully functional. Problems arise if the output formats are not set on the mapscript object, but ImageType tries to set one which (yet) does not exist.
e.g.:
MAP
IMAGETYPE "png32"
END
Class for mapping integer values to and from JSON.
Class for getting and setting the projection string on the mapscript mapscript.mapObj or mapscript.layerObj. Uses getProjection() and setProjection() to retrieve projection information.
e.g.:
MAP
PROJECTION
"proj=lcc"
"lat_1=51.16666723333333"
"lat_2=49.8333339"
"lat_0=90"
"lon_0=4.367486666666666"
"x_0=150000.013"
"y_0=5400088.438"
"ellps=intl"
"towgs84=-106.869,52.2978,-103.724,0.3366,-0.457,1.8422,-1.2747"
"units=m"
"no_defs"
END
END
Class for setting and getting the map size in pixels. Uses getSize() and setSize() on the mapscript.mapObj for retrieval of values. The return/set value is a tuple() in the form of (width, height).
e.g.:
MAP
SIZE 1000 1000
END
Datatypes are a handler between mapserver variables and Python data types. In order to provide a consequent API between mapscript and JSON, a dict() is used to map between both.
e.g.:
Map(Base):
# set a data type
status = Status('status')
Represents mapscript variables
see http://mapserver.org/mapscript/variables.html for a complete list of available variables. Uses a mapping dict to transfer between mapscript variable value and python values.
Inherits from Property.
Align data type
Maps alignment properties to or from string representation.
Alignments are: - ‘left’ : mapscript.MS_ALIGN_LEFT - ‘center’ : mapscript.MS_ALIGN_CENTER - ‘right’ : mapscript.MS_ALIGN_RIGHT - None : -1
Boolean data type
Maps mapscript.MS_TRUE and mapscript.MS_FALSE values to and from python boolean conditions. Additionally there’s also a “not set” condition, represented by python’s None and -1 for mapscript.
Connection data type
maps a mapscript connection type to or from a string representation. Mapped connections are:
ImageMode data type
Mapping:
LayerType data type
Mapping:
- ‘point’ : mapscript.MS_LAYER_POINT
- ‘line’ : mapscript.MS_LAYER_LINE
- ‘polygon’ : mapscript.MS_LAYER_POLYGON
- ‘raster’ : mapscript.MS_LAYER_RASTER
- ‘annotation’ mapscript.MS_LAYER_ANNOTATION
- ‘query’ : mapscript.MS_LAYER_QUERY
- ‘circle’ : mapscript.MS_LAYER_CIRCLE
- ‘tileindex’ mapscript.MS_LAYER_TILEINDEX
Position data type
Mapping:
Status data type
Mapping:
Unit data type
Mapping:
Holds the most basic mapscript object handlers. Basic in terms of their properties, not their simpleness. The handlers themselves do not have Types or Datatypes properties. They just return or receive JSON objects.
The Base Class for all Mapserver JSON objects
Can either be used as a descriptor on other classes or as a standalone version. Inherits from Property.
Parameters: |
|
---|
Return a jsonified version of self
Initialise self from a jsonified version
A Color object property
Handles mapscript.colorObj objects. The JSON representation of Color is:
{
'red': [-1, 0-255],
'green': [-1, 0-255],
'blue': [-1, 0-255]
}
The values in square brackets indicate possible values, where -1 means not set and 0-255 is the possible value range.
A HashTable object
Handles mapscript.hashTableObj objects. The JSON representation is a flat, not nested dict().
A rectObj (Extent)
Handles mapscript.rectObj objects. mapscript.rectObj are primarily used on mapscript.mapObj and mapscript.layerObj objects to define the extent. The JSON representation of Rect is:
{
'minx': [-1, ..],
'maxx': [-1, ..],
'miny': [-1, ..],
'maxy': [-1, ..]
}
The values in square brackets indicate possible values where -1 means not set and .. means any floating point number. Obviously the values for minx and miny should be smaller than the values for maxx and maxy. Otherwise the mapscript object will raise an error.
This module contains only classes that do not have other mapscript classes as property but only types, datatypes and base classes. For a full list of properties the mapscript manual can be consulted.
e.g.:
Map(Base):
legend = Legend('legend')
A FontSet object
Handles mapscript.fontSetObj objects.
Warning
This is currently broken. Trying to access the mapscript.fontSetObj . fonts property results in a segmentation fault on the mapscript side.
A Legend object
Handles mapscript.legendObj objects. A legend is usually attached to a Map objects legend attribute.
e.g.:
Map(Base):
legend = Legend('legend')
An OutputFormat object
Handles mapscript.outputFormatObj objects. An OutputFormat object can be used to obtain the outputformat attribute of the mapscript.mapObj object. And it should be part of the outputformatlist attribute of the mapscript.outputFormatObj object. The manual notes for the outputformatlist:
Note
outputformatlist : outputFormatObj[] Array of the available output formats.
Note: Currently only available for C#. A proper typemaps should be implemented for the other languages.
So obtaining a list of outputformats is currently not possible. While it is possible to obtain the number of outputformats registered for a map there exists no possibility to iterate over the outputformats, there’s only a getter method (getOutputFormatByName()) by name, not by index.
e.g.:
Map(Base):
output_format = OutputFormat('outputformat')
A Style object
Handles mapscript.styleObj objects. A Style is part of a collection of Style objects attached to a Class object and is normally not used directly. It can be used to jsonify a mapscript.styleObj object though.
e.g. in a Collection:
Class(Base):
styles = Collection(Style, 'getStyle', 'removeStyle', 'insertStyle'
'numstyles')
or as standalone:
import mapscript
import msjson
ms_style = mapscript.styleObj()
style = msjson.Style(mapscript_=ms_style)
style.to_json()
This module contains the three most advanced classes for dealing with mapscript.classObj, mapscript.layerObj and mapscript.mapObj objects. All of these have a property of type Collection for dealing with their list like child elements.
e.g.:
Class(Base):
debug = Integer('debug')
# ... other properties
styles = Collection(Style, 'getStyle', 'removeStyle', 'insertStyle',
'numstyles'
A Class object
Handles mapscript.classObj objects.
e.g.:
Class(Base):
debug = Integer('debug')
# ... other properties
styles = Collection(Style, 'getStyle', 'removeStyle', 'insertStyle',
'numstyles'
A Layer object
Handles mapscript.layerObj objects
e.g.:
Layer(Base):
name = String('name')
# ... other properties
classes = Collection(Class, 'getClass', 'removeClass',
'insertClass', 'numclasses')
A Map object
Handles mapscript.mapObj objects. This is the top level object in the mapscript hierarchy.
e.g.:
Map(Base):
name = String('name')
# ... other properties
layers = Collection(Layer, 'getLayer', 'removeLayer',
'insertLayer', 'numlayers')
Footnotes
[1] | outputformatlist : outputFormatObj[] Array of the available output formats. Currently only available for C#. A proper typemaps should be implemented for the other languages. |
Contents: