MS RFC 2: Creating line features and/or shapes using WKT

Author:Steve Lime
Contact:steve.lime at DNR.STATE.MN.US
Version:MapServer 4.8

Description: Developing inline features or shapes within MapScript can be a bit cumbersome. One alternative would be to allow users to define feature using the Well-Known Text format. The proposed solution would allow users to use this format:

  1. within a mapfile
  2. via URL
  3. via MapScript
  4. via MapServer query template

Instead of writing a new WKT parser we would provide access to underlying GEOS or OGR functionality to do this. Notes about the actual implementation are included below.

Files affected

  • mapfile.h => new constant, WKT
  • maplexer.l => recognize the new constant
  • mapfile.c => process new mapfile parameter with FEATURE block (WKT), and update URL parsing in a similar manner
  • mapgeos.cpp => wrap GEOS WKT reading/writing code
  • mapogr.cpp => wrap OGR WKT reading/writing code
  • mapprimitive.c => wrap the GEOS and OGR WKT writer/reading code, this would be the “public” interface
  • maptemplate.c => update the shpxy tag with a “-wkt” option so it would output the WKT version of a shape. Placing here would allow us to take advantage of the projection support already in place, plus any future options (thining, buffers and so on).
  • mapscript/swiginc/shape.i => update constructor to pass a WKT string and to define a “toString” method that would output a WKT string. Similar modifications would have to be made within PHP/MapScript, patterned after the SWIG-based interface.

Backwards compatibility issues

N/A, new functionality

Implementation Details

  • The C API will take the form:
shapeObj *msShapeFromWKT( const char * );
char *msShapeToWKT( shapeObj * );

These are contrary to some of the older code (e.g. msLayerNextShape()). However there are 2 places the WKT APIs will be used: 1) MapScript and 2) creating inline features via URL or MapFiles. In both cases the above functions would be preferred.

  • In MapScript, creating a shape will take the form of an overloaded constructor, e.g.:

    $shape = new shapeObj($mapscript::MS_SHAPE_LINE); OR $shape = new shapeObj(‘LINESTRING(0 0,1 1,1 2)’);

  • In MapScript, a toWKT() method will be added to shapeObj object.

  • WKT is geometry only. The attributes, index, tileindex, classindex, and text fields do not exist in WKT and will have to be set “elsewhere”.

  • There is no widely supported, or standardized approach to “measure” values in WKT though Refractions does support it in “EWKT”. For now it is assumed that measure values will not be preserved from WKT.

  • There is a well defined way of including Z coordinates and these should be carried through if MapServer is built with Z and M support enabled.

  • Development will be accompanied by a set of tests. Sean Gillies has already created a test case or two.

Transformations shapeObj to WKT

  • MS_SHAPE_POINT: If numlines and numpoints are one, then this is converted to a POINT object in WKT. If there are more points, this is converted to a MULTIPOINT object.
  • MS_SHAPE_LINE: if numlines is 1 then this will be translated to a LINESTRING otherwise it will be translated to a MULTILINESTRING.
  • MS_SHAPE_POLYGON: MapServer does not keep track of interior and exterior rings in a shape, since the scanline rasterization mechanism of GD does not require this information. However, when converting to WKT we need to know whether we have a single polygon with holes, or multiple polygons (more than one exterior ring). If numlines is 1, we can directly translate to POLYGON(), otherwise the rings will need to be analysed to identify outer rings, and to associate inner rings with their outher ring. If more than one outer ring exist, a MULTIPOLYGON will be produced, otherwise a POLYGON will be produced.
  • MS_SHAPE_NULL: This results in an empty WKT string.

Transformations WKT to shapeObj

  • POINT: Translates to an MS_SHAPE_POINT object with one point and one line.
  • LINESTRING: Translates to an MS_SHAPE_LINE object with one line.
  • POLYGON: Translates to an MS_SHAPE_POLYGON object with one line for the outer ring and one line for each inner ring.
  • MULTIPOINT: Translates to an MS_SHAPE_POINT object with one line, and one point for each line.
  • MULTILINESTRING: Translates to an MS_SHAPE_LINE object with one line for each linestring in the container.
  • MULTIPOLYGON: Translates into an MS_SHAPE_POLYGON with each ring of each polygon being a line in the resulting polygon object.
  • GEOMETRYCOLLECTION: Treat as MULTIPOINT, MULTILINESTRING or MULTIPOLYGON if the contents are all compatible, otherwise throw an exception.

Bug ID (primary bug, addition entries for MapScript and OGR will follow)

Voting history

Vote proposed by Steve Lime on 9/4/2005, result was +4 (3 non-voting members).

Voting +1: Lime, Warmerdam, Morissette, Gillies

Proposal passes and will move forward.