README.rst 10.1 KB
Newer Older
1
Python MapScript for MapServer 7.4.0 README
2 3 4
===========================================

:Author: MapServer Team
5
:Last Updated: 2019-06-04
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

Introduction
------------

The Python mapscript module provides users an interface to `MapServer <http://mapserver.org>`_
classes on any platform, and has been tested on Python versions 2.7 and 3.5+. 

The Python mapscript module is created using `SWIG <http://www.swig.org.>`_ the
the Simplified Wrapper and Interface Generator. This is used to create MapServer bindings in
many different programming languages. 

+ Language agnostic documentation is available at http://mapserver.org/mapscript/introduction.html
+ Python specific documentation is available at http://mapserver.org/mapscript/python.html

For working with Mapfiles in Python the `mappyfile <https://mappyfile.readthedocs.io/en/latest/>`_ project is 
also available, this allows creating, parsing, formatting, and validating Mapfiles without any dependencies on MapServer. 

Wheels and PyPI
---------------

Python `wheels <https://wheel.readthedocs.io/en/stable/>`_ have been created for Windows and uploaded to 
`PyPI <https://pypi.org/>`_ - the Python Package Index. Note - MapServer binaries still need to be installed on the system, 
and are not included in the wheel itself, see the *Installation* section below. 

Advantages of ready-made wheels on PyPI include:

+ easy installation using `pip <https://pypi.org/project/pip/>`_
+ mapscript can be added as a dependency to `Requirements Files <https://pip.pypa.io/en/stable/user_guide/#id1>`_
+ mapscript can be easily added to a Python `Virtual Environment <https://docs.python-guide.org/dev/virtualenvs/>`_
+ Python2 or Python3 versions of mapscript can be installed and work with a single installation of MapServer

Currently the following wheels are built:

39 40
+ Python 2.7 x64 for MapServer 7.4.0
+ Python 3.6 x64 for MapServer 7.4.0
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

The mapscript wheels have been compiled using Visual Studio 2017 version 15.3 (``MSVC++ 14.11 _MSC_VER == 1911``). 
Linux wheels are also planned, using the `manylinux <https://github.com/pypa/manylinux>`_ project. 

No source distributions will be provided on PyPI - to build from source requires the full MapServer source code,
in which case it is easiest to take a copy of the full MapServer project and run the CMake process detailed below. 

The wheels contain a full test suite and sample data that can be run to check that the installed MapServer is
running correctly. 

..
    py3 SWIG flag adds type annotations

Installation on Windows
-----------------------

To use mapscript you will need to add the MapServer binaries to your system path. 
On Windows you can use the following, replacing ``C:\MapServer\bin`` with the location of your MapServer binaries. 

.. code-block:: bat

    SET PATH=C:\MapServer\bin;%PATH%

Windows binary packages can be downloaded from `GIS Internals <https://www.gisinternals.com/stable.php>`_. 
65 66
To ensure compatibility with the wheels, please use identical release packages, e.g. ``release-1911-x64-gdal-2-3-mapserver-7-4``
for mapscript 7.4. 
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

When using these packages the MapServer path will be similar to ``C:\release-1911-x64-gdal-2-3-mapserver-7-2\bin``. 

Prior to installing mapscript it is recommended to update pip to the latest version with the following command:

.. code-block:: bat

    python -m pip install --upgrade pip

If there are binary wheels available for your system, mapscript can be installed using:

.. code-block:: bat

    pip install mapscript

If you already have mapscript installed and wish to upgrade it to a newer version you can use:

.. code-block:: bat

    pip install mapscript --upgrade

Now you should be able to import mapscript:

.. code-block:: python

    python -c "import mapscript;print(mapscript.msGetVersion())"
93
    MapServer version 7.4.0 OUTPUT=PNG OUTPUT=JPEG OUTPUT=KML SUPPORTS=PROJ SUPPORTS=AGG SUPPORTS=FREETYPE SUPPORTS=CAIRO SUPPORTS=SVG_SYMBOLS SUPPORTS=SVGCAIRO SUPPORTS=ICONV SUPPORTS=FRIBIDI SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER SUPPORTS=SOS_SERVER SUPPORTS=FASTCGI SUPPORTS=THREADS SUPPORTS=GEOS SUPPORTS=PBF INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

If you failed to add the MapServer binaries to your system path you may see one of the following errors:

.. code-block:: python

    ImportError: No module named _mapscript # Python 2.x
    ModuleNotFoundError: No module named '_mapscript' # Python 3.x

If your version of mapscript does not match your version of MapServer you may instead one of the following messages:

.. code-block:: python

    ImportError: DLL load failed: The specified module could not be found.
    ImportError: DLL load failed: The specified procedure could not be found.

Installation on Unix
--------------------

For Unix users there are two approaches to installing mapscript. The first is to install the ``python-mapscript`` package using a package manager. For example on
Ubuntu the following command can be used:

.. code-block:: bat

    sudo apt-get install python-mapscript

The second approach is to build and install the Python mapscript module from source. Full details on compiling MapServer from source are detailed on the
`Compiling on Unix <https://www.mapserver.org/installation/unix.html>`_ page. To make sure Python mapscript is built alongside MapServer the following flag needs to be set:

.. code-block:: bat

    -DWITH_PYTHON=ON

To configure the path of the mapscript installation location ``-DCMAKE_INSTALL_PREFIX`` can be set, e.g. 

.. code-block:: bat

    sudo cmake .. -DCMAKE_INSTALL_PREFIX=/usr

When installing the `DESTDIR <https://cmake.org/cmake/help/latest/envvar/DESTDIR.html>`_ variable can be set (note ``DESTDIR`` is not used on Windows)
to install mapscript to a non-default location. E.g.

.. code-block:: bat

    make install DESTDIR=/tmp

In summary the ``install`` target runs the ``setup.py install`` command using custom paths (when set) similar to below:

    python setup.py install --root=${DESTDIR} --prefix={CMAKE_INSTALL_PREFIX}

Quickstart
----------

Some basic examples of what can be done with mapscript are shown below. Note - before running any scripts using mapscript, 
you will need to add the MapServer binaries to your system path, see the *Installation* section above. 

To open an existing Mapfile:

.. code-block:: python

    >>> import mapscript
    >>> test_map = mapscript.mapObj(r"C:\Maps\mymap.map")
    >>> extent = test_map.extent

Create a layer from a string:

.. code-block:: python

    >>> import mapscript
    >>> layer = mapscript.fromstring("""LAYER NAME "test" TYPE POINT END""")
    >>> layer
    <mapscript.layerObj; proxy of C layerObj instance at ...>
    >>> layer.name
    'test'
    >>> layer.type == mapscript.MS_LAYER_POINT
    True

Building the Mapscript Module
-----------------------------

The mapscript module is built as part of the MapServer CMake build process. This is configured using the ``mapserver/mapscript/CMakeLists.txt`` file. 

Before the switch to CMake MapServer mapscript was built using distutils and ``setup.py``. Now the ``setup.py.in`` file is used as a template that
is filled with the MapServer version number and used to created wheel files for distribution, or install mapscript directly on the build machine.  

The build process works as follows. 

+ CMake runs SWIG. This uses the SWIG interface files to create a ``mapscriptPYTHON_wrap.c`` file, 
  and a ``mapscript.py`` file containing the Python wrapper to the mapscript binary module. 
+ CMake then uses the appropriate compiler on the system to compile the ``mapscriptPYTHON_wrap.c`` file into a Python binary module -
  ``_mapscript.pyd`` file on Windows, and a ``_mapscript.so`` file on Unix. 

``CMakeLists.txt`` is configured with a ``pythonmapscript-wheel`` target that copies all the required files to the output build folder where they are then packaged
into a Python wheel. The wheel can be built using the following command:

.. code-block:: bat

    cmake --build . --target pythonmapscript-wheel

The ``pythonmapscript-wheel`` target creates a virtual environment, creates the Python wheel, installs it to the virtual environment and finally runs the test
suite. This process runs commands similar to the following:
 
.. code-block:: bat

    python -m pip install virtualenv
    virtualenv mapscriptvenv
    python -m pip install --upgrade pip
    pip install -r requirements-dev.txt
    python setup.py bdist_wheel
    pip install --no-index --find-links=dist mapscript
    python -m pytest --pyargs mapscript.tests

SWIG can also be run manually, without using CMake. This may allow further optimizations and control on the output. 

.. code-block:: bat

    cd C:\Projects\mapserver\build
    SET PATH=C:\MapServerBuild\swigwin-3.0.12;%PATH%
    swig -python -shadow -o mapscript_wrap.c ../mapscript.i

SWIG has several command line options to control the output, examples of which are shown below:

.. code-block:: bat
    
    swig -python -shadow -modern -templatereduce -fastdispatch -fvirtual -fastproxy 
    -modernargs -castmode -dirvtable -fastinit -fastquery -noproxydel -nobuildnone 
    -o mapscript_wrap.c ../mapscript.i

Testing
-------

The mapscript module includes a test suite and a small sample dataset to check the output and MapServer installation. It is recommended
`pytest <https://docs.pytest.org/en/latest/>`_ is used to run the tests. This can be installed using:

.. code-block:: bat

    pip install pytest

Make sure the MapServer binaries are on the system path, and that the PROJ_LIB variable has been set as this is required for many of the tests. 

.. code-block:: bat

235 236
    SET PATH=C:\release-1911-x64-gdal-2-3-mapserver-7-4\bin;%PATH%
    SET PROJ_LIB=C:\release-1911-x64-gdal-2-3-mapserver-7-4\bin\proj\SHARE
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256

Finally run the command below to run the test suite: 

.. code-block:: bat

    pytest --pyargs mapscript.tests

Credits
-------

+ Steve Lime (developer)
+ Sean Gillies (developer)
+ Frank Warmerdam (developer)
+ Howard Butler (developer)
+ Norman Vine (cygwin and distutils guru)
+ Tim Cera (install)
+ Michael Schultz (documentation)
+ Thomas Bonfort (developer)
+ Even Rouault (developer)
+ Seth Girvin (Python3 migration, documentation and builds)
257
+ Claude Paroz (Python3 migration)