Abstract
This document tries to give an overview of the Python/MapScript Objects and their syntax. It is a start of the documentation for Python/MapScript. Information given here refers to MapServer version 3.6. A basic knowledge of mapserver, map definition files, Python and HTML is recommended. Example lines are in plain roman style.
Last Updated: 24-2-2003
Table of Contents
In this HOWTO you will find information and examples how to install and use Python/MapScript. Since no documentation previously existed this document will surely not cover all topics, it should be regarded as a starting point for people who want to work with Python/MapScript.
This document assumes some previous knowledge or experience, especially with the following:
Familiarity with fundamental aspects of managing the MapServer software and the web server.
Familiarity with the scripting language Python.
The MapServer/MapScript software is installed and functioning on a web server.
If you're not experienced with Python, you should read the tutorial available in http://www.python.org or another equivalent tutorial, since the language has some tricks that are not quite intuitive, and that should remove some of the pain of getting the extension to work. The following instructions are Linux/Unix specific.
There are two ways to build the extension. If you like tasks and challenges go and swig, compile and install all the stuff by hand. Another way is to use an install script that Norman Vine made, which makes things much easier. It is available from http://www.vso.cape.com/~nhv/files/python/mapscript/setup.py. Copy this file to $MAPSERV_HOME/mapscript/python.
Changes on setup.py activate swig_cmd "-shadow" and disable "-DWIN32" enable all needed macros and libraries
In the same directory you will find a link to mapscript.i. This is the interface file for SWIG. Make sure that this file has the section SWIGPYTHON defined as follows:
#ifdef SWIGPYTHON // For Python, errors reported via the ms_error structure are translated // into RuntimeError exceptions. (Chris Chamberlin <cdc@aracnet.com>) %{ static void _raise_ms_exception(void) { char errbuf[256]; errorObj *ms_error = msGetErrorObj(); snprintf(errbuf, 255, "%s: %s %s\n", ms_error->routine, msGetErrorString(ms_error->code), ms_error->message); _SWIG_exception(SWIG_RuntimeError, errbuf); } #define raise_ms_exception() { _raise_ms_exception(); return NULL; } %} %except { $function errorObj *ms_error = msGetErrorObj(); if ( (ms_error->code != MS_NOERR) && (ms_error->code != -1) ) raise_ms_exception(); } #endif // SWIGPYTHONNow you should edit the setup.py script and make some changes to reflect your personal system settings (libraries, paths, etc.). First of all you need to
python Python 2.1.2 (#11, Jul 11 2002, 15:03:40) [GCC 2.95.2 19991024 (release)] on linux2 Type "copyright", "credits" or "license" for more information. >>> import mapscript >>> mapscript.MS_VERSION '3.6.1'If setup.py or python complain about unresolved symbols get some help here.
Access to the mapserver API is provided largely through a series of classes. These will be resumed in the following chapter. It is not intended to give a detailed description of the object's methods and attributes. Therefore, please have a look at Perl MapScript Reference. Examples with explicit comments are used to illustrate the implementation of Python/Mapscript classes an functions. For using the Python/Mapscript module you have to import it like conventional Python modules:
>>> import mapscript
or:
>>> from mapscript import *
General information about the usage of modules can be found at the Python Tutorial section on modules!
Many mapfile parameters take constant values, according to the listing in Perl MapScript Reference .
Example:
>>> from mapscript import * # 1) >>> myMap = mapObj('/map/data/mapfile.map') # 2) >>> myMap.units = MS_INCHES # 3) >>> height = getattr(myMap, 'height') # 4) >>> setattr(myMap.web, 'imagepath', '/tmp/') # 5) 1): Import mapscript module. 2): Create a map object of the mapfile 'mapfile.map' 3): Assign the constant value 'MS_INCHES' to the map object's attribute 'units'. 4): Using the python function getattr(object,name) to access the attribute 'height' of 'myMap'. 5): Using python function setattr(object, name, value) for assigning a value to the object's attribute.
mapObj mapObj(string mapfilename) """Open a specified map definition file."""
Example:
>>> myMap = mapObj('demo.map') # 1) 1): If the filename is undefined, an empty mapObj is created and initialized.
The map object's attributes are conform to "members" performed in the 'mapObj' section of Perl MapScript Reference.
Example:
>>> minExtX = myMap.extent.minx # 1) >>> myMap.interlace = MS_TRUE # 2) >>> myMap.legend.keysizex = 18 # 3) >>> myMap.legend.label.font = "conhobold" # 4) >>> num_layers = myMap.numlayers # 5) >>> myMap.scalebar.color = myMap.addColor(255,255,255) # 6) >>> myMap.scalebar.width = 50 # 7) 1): The attribute 'extent' returns a rectObj; the attribute 'minx' of a recObj returns a double value for the left x-coordinate of a rectangle; this value is assigned to a variable named minExtX. 2): mapObj's attribute 'interlace' is set on MS_TRUE. 3): The attribute 'keysize' of myMap's legend is set to 18. 4): The attribute font of the legend's label is set to an other font type. 5): The 'numlayers'-attribute of 'myMap' returns an int value, which is assigned to a variable. 6): The attribute 'color' (int) of myMap's scalebar is set to the color, which is added to the current map object by using the method addColor(r,g,b). 7): The attribute 'witdh' of myMap's scalebar is set to 50.
Methods of the mapObj class are listed in the Perl MapScript Reference.
Example:
from mapscript import* myMap = mapObj('/path/to/mapfile/map.map') # 1) img = myMap.draw() # 2) while myMap.nextLabel(): # 3) lcmo = myMap.nextLabel() if lcmo.status: # 4) print "lcmo: %s"%(lcmo.string) shp = lcmo.poly for i in range (shp.numlines): # 5) print i part = shp.get(i) print "nr-lines: %d"%(i) for j in range (part.numpoints): n_point = part.get(j) print "nr: %s x: %s / y: %s"%(j,n_point.x,n_point.y) 1): Generating a new mapObj. 2): Creating an imgObj by using the mapObject's method draw(). imgObj is required create labels. 3): While iterating the labelcache a labelCacheMemberObj is created for every label layer. 4): If the status of the labelCacheMemberObj is 1, the particular label's name is printed and a shapeObj is created using the 'poly'-attribute of labelCacheMemberObj. 5): This Iteration prints the point of the label borders for the number of lines of the shape 'shp'.
layerObj layerObj(mapObj)
Example:
>>> myLayer = layerObj(myMap) # 1) 1): Normally you obtain layerObj from an existing layer within a map, however you can create a new layer.
cp.: Perl MapScript Reference: layerObj members.
Example:
>>> num_classes = myLayer.numclasses # 1) >>> result_cache = myLayer.resultcache # 2) 1): Attribute numclasses returns the number of classes of 'myLayer'. 2): Resultcache returns a resultCacheObj, which holds the results of a query against this layer.
cp.: Perl MapScript Reference: layerObj methods.
Note that the 'queryByAttributes' method is used like this: int queryByAttributes(mapObj map, char qitem, char qstring, int mode)
Example:
>>> qryresult = myLayer.queryByPoint(myMap,n_point,MS_SINGLE,0) # 1) >>> resultmember = myLayer.getResult(0) # 2) >>> myLayer.open(myMap.shapepath) # 3) 0 >>> myShape = shapeObj(-1) # 4) >>> myLayer.getShape(myShape,-1,0) # 5) 0 >>> myShape.bounds.minx # 6) 3293309.60720301 >>> myLayer.close() # 7) 1): QueryByPoint(mapObj,pointObj,integer mode, double buffer)queries a single layer using a point, returns integer. 2): GetResult(integer member)Retrieves the nth member of the result cache created by the previous query, ie. queryByPoint, returns resultCacheMemberObj. 3): Allows access to the layer's shapefile. The layerObj must be opened for using its deposited shape data. layerObj.open(character path); returns integer 0 on success, else 1 is returned. 4): Generates an empty shapeObj. 5): Gets myLayer's shape and puts it into 'myShape'; returns integer 0 on success, else 1 is returned. 6): Returns attribute bounds.minx of 'myShape' 7): After using the shape file must be closed.
classObj classObj(layerObj) """Creates a new class object from the given layerObj and returns a classObj."""
Example:
>>> myClass = classObj(myLayer) # 1) >>> myClass # 2) C classObj instance at _e42e1708_p_classObj> 1): Create a new classObj, by a given layerObj. 2): Print the new instance on the python shell.
cp.: Perl MapScript Reference: classObj members.
Example:
>>> myLayer = myMap.getLayer(1) # 1) >>> myClass = myLayer.getClass(0) # 2) >>> myClass.status = 1 # 3) 1): Create a layerObj of one layer, given by the layer-index of the layers of the current map object. 2): Create a classObj of one class, given by the class-index of the classes of the current layer object. 3): Assign an int value to the attribute 'status' of the class object 'myClass'; the status of 'MyClass' will than be MS_ON.
cp.: Perl MapScript Reference: classObj methods.
Example:
>>> myClass.setExpression('([AREA] > 500)') # 1) 0 >>> myIcon = myClass.createLegendIcon(myMap, myLayer, 8, 8) # 2) 1): Set an expression on the current classObj, return value is integer. 2): Create a legend icon for the current classObj, return value is image.
imageObj imageObj(width, height) """Create a new image object with the parameters Pixel width and height."""
Example:
>>> img = imageObj(500,500) # 1) 1): Creates the new image object 'img'.
cp.: Perl MapScript Reference: imageObj members.
Example:
>>> img.imageurl = '/mapserver/tmp' # 1) 1): Set the base URL for IMAGEPATH. This is the URL that will take the web browser to IMAGEPATH to get the images.
cp.: Perl MapScript Reference: imageObj methods.
Example:
>>> img.saveImage('/path/to/out.png',MS_PNG,0,0,0)
1): void saveImage(character filename, type, transparent, interlace,
quality)
labelObj labelObj()
Example:
>>> myLabel = labelObj() # 1) 1): Create an instance of label object.
cp.: Perl MapScript Reference: labelObj members.
Example:
>>> l.size = 8 # 1)
1): Set new value for int label.size.
labelCacheObj labelCacheObj()
Example:
>>> myLabelCache = labelCacheObj() # 1) 1): Create an instance of labelCacheObj.
cp.: Perl MapScript Reference: labelCacheObj members.
Example:
>>> num_label myLabelCache.numlabels # 1) 1): Return the number of labels of the current labelCacheObj.
labelCacheMemberObj labelCacheMemberObj()
Example:
>>> myLabelCacheMember = labelCacheMemberObj() # 1) 1): Create an instance of labelCacheMemberObj.
markerCacheMemberObj markerCacheMemberObj()
Example:
>>> myMarkerCacheMember = markerCacheMemberObj() # 1) 1): Creates an instance of markerCacheMemberObj.
cp.: Perl MapScript Reference: webObj members.
Example:
>>> img.imageurl = '/mapserver/tmp' # 1) 1): Set the base URL for IMAGEPATH. This is the URL that will take the web browser to IMAGEPATH to get the images.
referenceMapObj referenceMapObj()
Example:
>>> myRefMap = referenceMapObj() # 1) 1): Create an instance of referenceMapObj.
cp.: Perl MapScript Reference: referenceMapObj members.
Example:
>>> myRefMap.status = MS_ON # 1) 1): Turn status of referenceMapObj to MS_ON.
queryMapObj queryMapObj()
Example:
>>> myQueryMap = QueryMapObj() # 1) 1): Create an instance of QueryMapObj.
cp.: Perl MapScript Reference: colorObj members.
Example:
>>> myColor.red = 255 # 1) 1): Attribute red is set to integer 255.
pointObj pointObj()
Example:
>>> myPoint = pointObj() # 1) 1): Create an instance of pointObj.
cp.: Perl MapScript Reference: pointObj members.
Example:
>>> myPoint.x = 100 # 1) >>> pointx = myPoint.x # 2) >>> pointy = myPoint.y # 3) 1): Assign integer pixel value to the x coordinate of pointObj 'myPoint'. 2): Current x-coordinate of 'myPoint' is assigned to variable 'pointx'. 3): Current y-coordinate of 'myPoint' is assigned to variable 'pointy'.
cp.: Perl MapScript Reference: pointObj methods.
Example:
>>> n_distance = myPoint.distanceToPoint(otherPoint) # 1)
1): double distanceToPoint(pointObj); returns the
distance between two points
cp.: Perl MapScript Reference: lineObj members.
Example:
>>> n_points = myLine.numpoints # 1) 1): Assign int numpoints to variable 'n_points'.
cp.: Perl MapScript Reference: lineObj methods.
Example:
>>> myShapefile = shapefileObj('/path/to/data/file',-1) # 1) >>> myShape = shapeObj(MS_SHAPE_POLYGON) # 2) >>> myShapefile.get(0, myShape) # 3) >>> myLine = myShape.get(0) # 4) >>> for i in range(myLine.mumpoints): # 5) ... myPoint = myLine.get(i) ... print myPoint 1): Create an instance of shapefileObj; shapefileObj shapefileObj(filename,type) 2): Generate the shapeObj 'myShape'; shapeObj shapeObj(type) 3): Retrieve a shape of 'myShapefile' by index; get(integer index,shapeObj) - returns integer, -1 if index is < 0 or >= number of shapes 4): Generate a lineObj by a given shapeindex; lineObj shapeObj.get(integer index) 5): The attribute numpoints of lineObj returns the lineObject's number of points. Range is used to iterate through numpoints and creates a pointObj for every value of myLine.numpoints.
shapeObj shapeObj()
Example:
>>> myShape = shapeObj() # 1) 1): Creates an instance of shapeObj.
cp.: Perl MapScript Reference: shapeObj members.
Example:
>>> n_extents = myShape.bounds # 1) >>> n_minx = myShape.bounds.minx # 2) >>> n_miny = myShape.bounds.miny # 3) >>> n_maxx = myShape.bounds.maxx # 4) >>> n_maxy = myShape.bounds.maxy # 5) >>> numlines = myShape.numlines # 6) 1) to 6): Different parameters are read out from 'myShape' and assigned to varaibles
cp.: Perl MapScript Reference: shapeObj methods.
Example:
Please see lineObj section or shapefileObj section for more information.
shapefileObj shapefileObj(filename,type)
Example:
>>> myShpfile = shapefileObj('lakes',-1) # 1) >>> if not hasattr(myShpfile,'bounds'): ... print "Unable to open lakes shapefile" ... 1): Create a shapfileObj from a existing file. No extension is necessary. For existing files type should be -1. To create an empty file type can be MS_SHAPEFILE_POINT, MS_SHAPEFILE_ARC, MS_SHAPEFILE_POLYGON, or MS_SHAPEFILE_MULTIPOINT.To Close a shapefile you've opened you need to undefine the reference, ie. "myShpfile = None"
cp.: Perl MapScript Reference: shapeObj members.
Example:
>>> n_extents = myShpfile.bounds >>> n_minx = n_extents.minx >>> n_miny = n_extents.miny >>> n_maxx = n_extents.maxx >>> n_maxy = n_extents.maxy >>> n_numshapes = myShpfile.numshapes >>> typeno = myShpfile.type
cp.: Perl MapScript Reference: shapefileObj methods.
Example:
>>> myMap = mapObj('mapfile.map') # 1) >>> myLayer = layerObj(myMap) # 2) >>> newshpf = shapefileObj("newshpfname", 5) # 3) >>> poly = 400 # 4) >>> shpf = shapefileObj("data_shapefile", -1) # 5) >>> shpo = new shapeObj(-1) # 6) >>> shpf.get(poly, shpo) # 7) >>> newshpf.add(shpo) # 8) >>> newrect = newshpf.bounds # 9) >>> newminx = newrect.minx >>> newminy = newrect.miny >>> newmaxx = newrect.maxx >>> newmaxy = newrect.maxy >>> newshpf = None 10) 1): Open the map. 2): Create the layer object to query. 3): Create a new shapefile for the selection set. 4): Set index value for selected shape. 5): Create a shapefile object for getting queried shape. 6): Create shape object for storing queried shape. 7): Retrieve shape into shape object. 8): Put shape into new shapefile. 9): Get the extent of the new shapefile. 10): Close new shapefile.
cp.: Perl MapScript Reference: rectObj members.
Example:
>>> x = myRect.minx # 1) 1): Value of attribute minx (double left) is assigned varaible 'x'.
cp.: Perl MapScript Reference: rectObj methods.
Example:
myRect = draw(myMap,myLayer,myImage,1,'text') # 1) 1): Draw(mapObj,layerObj,imageObj,integer classindex,character text); returns integer, 0 on success. Draw an individual rectangle using layerObj. (The class_index is used to classify the feature based on the classes defined for layerObj. The text string is used to annotate the shape.)
cp.: Perl MapScript Reference: itemObj members.
Example:
>>> myItem.name = 'a_item' # 1) 1): Assigns 'a_item' to "myItem.name".
resultCacheObj resultCacheObj()
Example:
>>> myResultCache = resultCacheObj() # 1) 1): Generates a resultCacheObj.
resultCacheMemberObj resultCacheMemberObj()
Example:
>>> myResultMember = resultCacheMemberObj() # 1) 1): Generates a resultCacheMemberObj.
cp.: Perl MapScript Reference: resultCacheMemberObj members.
Example:
>>> shaperecnum = myResultMember.shapeindex # 1) 1): Returns the shapeindex of 'myResultMember'.
projectionObj projectionObj(string)
Example:
>>> myProjObj = projectionObj('proj=utm,ellps=GRS80,zone=15,north,no_defs') # 1) 1): Generates projectionObj 'myProjObj'.
cp.: Perl MapScript Reference: projectionObj members.
Example:
>>> nr_args = myProjObj.numargs # 1) 1): Returns integer numargs - actual number of projection args.
scalebarObj scalebarObj()
Example:
>>> myScalebar = scalebarObj() 1): Generates a scalebarObj().
cp.: Perl MapScript Reference: referenceMapObj members.
Example:
>>> n_height = myScalebar.height # 1) 1): Assigns the height of 'myScalebar to variable 'n_height'.
cp.: Perl MapScript Reference: referenceMapObj members.
Example:
>>> l_height = myLegend.height # 1) 1): Assigns the height of 'myLegend to variable 'l_height'.
While trying to build applications with python-mapscript it seemed that the DBFfile support that comes with mapscript included, is when used via python-mapscript rather unstable. We experienced segmentation faults pretty often. Therefor we used the dbf functions of the python binding of Frank Warmerdam's shapelib: pyshapelib (provided by Bernhard Herzog) for reading and writing dbf files.
The documentation to the DBFFile functions of the shapelib can be found here.
cp.: http://mapserver.gis.umn.edu/doc36/perlmapscript-reference.html#dbfinfo
DBFInfoObj msDBFCreate(string dbf_filename) """Creates a new DBF-file with the give name and returns a DBFInfoObj. Omit an extension or if the extension is *.shp/SHP or *.shx/SHX it is converted in *.dbf/DBF.""" DBFInfoObj msDBFOpen(string dbf_filname, string access_parameters) """Opens an existing DBF-file with the give name and returns a DBFInfoObj. Access parameters can be "rb" (readonly) or "r+" (append)."""
cp.: http://mapserver.gis.umn.edu/doc36/perlmapscript-reference.html#dbfinfo
int msDBFAddField(DBFInfoObj dbffilehandlename, string field_name, int field_type, int field_width, int field_decimals)
"""Adds a field to a dbf-file."""
int msDBFGetFieldCount(DBFInfoObj dbffilehandlename)
"""Returns the number of fields of a dbf-file."""
int msDBFWriteStringAttribute(DBFInfoObj dbffilehandlename, int record_nr, int field_nr, string attribute)
"""Adds a string atttribute to a dbf record."""
string msDBFReadStringAttribute(DBFInfoObj dbffilehandlename, int record_nr, int field_nr)
"""Returns the string value of the specified dbf record."""
None msDBFClose(DBFInfoObj dbffilehandlename)
"""Close the dbf file and flush the last changes."""
Example:
""" Extracts basic descriptive information from the shapefile.
"""
""" Starting this script on command line with an argument given: python shpinfo.py your_shp
"""
"""Module import
"""
from mapscript import *
from string import *
import sys
import os
"""Definition of dictionaries for shape types and dbffield types.
"""
shp_type = {'1':'Point','3':'Line','5':'Polygon','8':'MulitPoint'}
dbffield_type = {'0':'String','1':'Integer','2':'Double','3':'Invalid'}
def open_shpfile(name):
"""Open ShapeFile and return shapeFileObj"""
if os.access(sys.argv[1] + ".shp", os.F_OK):
shp = shapefileObj(sys.argv[1], -1)
else:
print "Can't access shapefile"
sys.exit(2)
return shp
def print_shpinfo(shp):
"""Print shapefile Information ..."""
print "Shape : \t%s" % split(shp.source,'/')[-1]
print "Path : \t%s" % join(split(shp.source,'/')[1:-1],'/')
print "Type : \t%s" % shp_type[str(shp.type)]
print "No. Shapes : \t%s" % shp.numshapes
print "Bounds : \t(%f,%f) (%f,%f)" % (shp.bounds.minx,shp.bounds.miny,shp.bounds.maxx,shp.bounds.maxy)
print split(shp.source,'/')[-1]
dbf = msDBFOpen("/%s/%s.dbf" % (join(split(shp.source,'/')[1:-1],'/'),str(split(shp.source,'/')[-1])),"rb")
print "\tName Type Length Decimals";
print "\t---------------- ------- ------ --------";
for field_nr in range(0,dbf.nFields):
print "\t%-16s %-7s %6d %8d" % (dbf.getFieldName(field_nr), dbffield_type[str(dbf.getFieldType(field_nr))], dbf.getFieldWidth(field_nr), dbf.getFieldDecimals(field_nr) )
recnr = msDBFGetRecordCount(dbf)
print "Nr. of records: %s" % str(recnr)
""" Open shapefile, passed as argument while starting the script from command line.
"""
""" Passed args are stored as a list of strings in sys.argv.
"""
if __name__ == "__main__":
shp = open_shpfile(sys.argv[1])
print_shpinfo(shp)
Copyright (c) 2002, M. Schulz, in medias res GmbH - Freiburg, Germany.
This documentation is covered by the same Open Source license as the MapServer software. See MapServer's License and Credits page for the complete text.
No liability for the contents of this document can be accepted. Use the concepts, examples and other content at your own risk. As this is a new edition of this document, there may be errors and inaccuracies that may be damaging to your system. Although this is highly unlikely, the author(s) do not take any responsibility for that: proceed with caution.
Send any comments or suggestions to the document author(s).
Add a Comment |