.. _rfc37:

******************************************************************************
 MS RFC 37: MapServer Spatial Reference Improvements and Additions
******************************************************************************

:Author: Howard Butler
:Contact: hobu.inc at gmail.com
:Author: Frank Warmerdam
:Contact: warmerdam at pobox.com
:Status: Draft

Purpose
==============================================================================

To provide MapServer with the ability to set its PROJECTION information from 
directly from the datasource itself, in an 
attempt to lessen the burden related to dealing with coordinate system 
information on users.  These improvements will be optionally available and
not interfere with previous PROJECTION definition methods.  

The History of Spatial References in MapServer
==============================================================================

MapServer's spatial reference support is quite anemic by many standards.  
While most of the data sources MapServer interacts with support describing 
the spatial reference of contained layers, MapServer has historically dropped 
the information on the floor or completely ignored it.  

MapServer's reprojection machinery keys off the fact that a LAYER's 
PROJECTION is different than the MAP's.  When this is the case, MapServer 
reprojects the LAYER's data to the MAP's spatial reference during a map draw. 

Definition
----------

MapServer has historically used two different approaches for defining the 
spatial reference of its data -- EPSG/ESRI codes in the form: 

::

    PROJECTION
        "init=epsg:4326"
    END

And PROJ.4-formated definitions in the form:

::

    PROJECTION
        "proj=cea"
        "lon_0=0"
        "lat_ts=45"
        "x_0=0"
        "y_0=0"
        "ellps=WGS84"
        "units=m"
        "no_defs"
    END

OGR datasources also support a form of AUTO projection type, but it is 
not widely advertised or regularized:

::

    LAYER
        CONNECTIONTYPE OGR
        PROJECTION
            "AUTO"
        END
    END



Performance Observations
------------------------

MapServer's current spatial reference story is focussed on two things -- 
simple description and ensuring that unnecessary data reprojection doesn't 
happen.  MapServer currently uses PROJ.4 directly to do its data reprojection, 
and this is the impetus for defining coordinate systems in PROJ.4 format.  For
people wanting the best performance but still requiring data reprojection, 
defining your spatial references in PROJ.4 format is a must.  

Alternatively, the EPSG/ESRI code definition of MapServer's spatial references 
allows MapServer to offload the lookup of PROJ.4 descriptions to PROJ.4 itself, 
with a simple file-based lookup table.  This mechanism is currently a 
bottleneck, however, as each lookup requires trolling through a file to 
match the given identifier and returning the PROJ.4 definition.

.. note::
    This penalty was lessened in early 2009 by the addition of a caching 
    mechanism in PROJ.4 that allows subsequent lookups to be fast.

Usability
---------

The usability of these two mechanism can be a nightmare for users.  First, 
most of the spatial reference descriptions that people work with are of the 
WKT variety -- not PROJ.4.  While it is straightforward to set the PROJECTION 
information for data with a known EPSG value, custom projections or those 
not generally available in the EPSG database require the user to somehow 
translate their WKT into PROJ.4 format and paste it into their mapfile.  

Additionally, http://spatialreference.org exists to help
ease this pain, but it is ultimately a stopgap, and not a permanent 
solution to the problem.  It is not practical to be downloading the 
spatial reference for each and every layer in a mapfile on every map draw 
from a website.  spatialreference.org does provide some conversion utilities 
to allow a user to paste in WKT and have it return MapServer PROJECTION blocks,
but this approach still foists pain and misery on the users.

Specification Features
==============================================================================

MapServer will continue to behave as before, and the user can opt-in for 
AUTO projection support by using the AUTO keyword in a projection object as 
so:

::

    # Use the what the layer defines as the projection definition.  
    # This may not be available for all data sources or layer types 
    # (shapefile, SDE, OGR, etc.).
    PROJECTION
        AUTO
    END



Implementation Details
==============================================================================

It is important that MapServer's previous spatial reference definition 
behavior be preserved.  First, drastically changing the PROJECTION definitions 
would mean a lot of unnecessary mapfile churn.  Second, continuing to define 
spatial references in PROJ.4 format as before will be the most performant.

Implementation of this RFC will encompass two items:

1) Addition of a method to the LAYER virtual table .

2) Additional methods will be added for drivers to be able to convert 
   from their native projection description type (ESRI WKT, OGC WKT, PROJ.4, etc)
   into PROJ.4 for setting on the projectionObj.

3) PROJECTION will support an explicit AUTO keyword


Virtual Table Method
--------------------

To support AUTO projection definitions,
drivers need to have the ability to return spatial reference information.
MapServer's layer plugin architecture provides mechanisms for interacting with 
MapServer layer providers, but there is currently no regularized method for 
returning the spatial reference information from providers.  The following 
virtual table member is proposed:

::
  
    int (*LayerGetAutoProjection)(layerObj *layer, projectionObj *projection)


Additional methods
-----------------------

The msOGCWKT2ProjectionObj method already exists, but a few more would be 
added to allow drivers that implement LayerGetAutoProjection to generate 
a projectionObj.

* msESRIWKT2ProjectionObj
* msOGCWKT2ProjectionObj


Driver-specific implementations
-------------------------------

The following drivers will have implementations provided to support TYPE AUTO 
spatial reference definitions:

* Shapefile 
* OGR
* GDAL Raster
* ArcSDE
* PostGIS


Files Affected
==============================================================================


::

    mapserver.h
    mapfile.c
    mapscript/swiginc/projection.i
    maplayer.c
    mapproject.h
    mapproject.c
    mapsde.c
    mapogr.cpp
    mapraster.c
    mappostgis.c
    . 
    .
    .
    
Backward Compatibility Issues
==============================================================================

All work described in this RFC will provide optional capabilities to MapServer 
and no backward compatibility issues are expected.

Documentation
==============================================================================

This RFC will stand as primary documentation for the feature until such time 
as the methods and practices described in this document are integrated into 
the regular MapServer documentation framework. 
