MS RFC 33: Removing msLayerWhichItems() from maplayer.c




Steve Lime


steve.lime at

Last Edited:





MapServer 5.0


The function msLayerWhichItems() is a function in maplayer.c that determines exactly which feature attributes need to be retrieved from a given data source. All item-based properties (e.g. CLASSITEM, bound properties, EXPRESSIONs, etc…) are checked and a list (an array) is compiled. At the same time index references are made (e.g. classitemindex, labelitemindex, etc…). The item indexes are used instead of names to access attribute values at runtime.

The problem with this method is that a feature (a shapeObj) used for drawing or the first pass of a query is not the same as that used for presentation (the second pass of a query). The second pass of a query uses msLayerGetShape() which by default requests all attributes of a feature since we don’t know ahead of time which attributes might be output.

By removing msLayerWhichItems() and always retrieving all attributes a feature is a feature whether drawing, querying or outputting via a template so caching features now becomes practical.

Technical Solution

As mentioned earlier msLayerWhichItems() does a couple of things. Some of these functions would need to be retained somehow and are described below.

  1. Layer items array: this array normally would be populated by the msLayerWhichItems() call. Instead it should be populated as a layer is opened in msLayerOpen. (makes sense?)

  2. Index references: linking a attribute name to an index value would have to happen during the course of rendering or querying instead of ahead of time. Basically code that uses attributes would have to first check if the parameter is not NULL, and then if the index reference is not set it would have to call a function like that shown below. While this affects a good number of places in the code base the change is relatively minor. The use of attribute binding isolates much of this code so this change is smaller for version 5.0 that it otherwise would have been.

int msGetItemIndex(char **itemlist, int numitems, char *item) {
  int i;

  if (!itemlist || numitems <= 0 || !item) return -1;

  for (i=0; i<numitems; i++)
    if(strcasecmp(itemlist[i], item) return i;

  return -1; /* failure */
  1. Logical expression handling: expressions maintain their own individual list of items to process so like 2 above this list would have to be created during processing. The code to do this exists as part of msLayerWhichItems() and would be retained under some other name.


this RFC does not address single pass queries, but rather sets the stage for them. Subsequent drawing, query and template output processes would remain unaltered.

General C API Changes

maplayer.c - msLayerWhichItems() goes away. msLayerOpen() now sets the layer->items array.

maputil.c - Binding functions now must assign index references when executed. Same goes for the functions to assign a classObj to a feature.

mapdraw.c - Layeritemindex and classitemindex must now be dynamically assigned values.

Input Driver Changes

It is unclear how each driver made use of the output of msLayerWhichItems(). It may be as easy as calling msLayerGetItems() instead of using msLayerGetItemInfo() in msLayerOpen() in which case we’d loose the msLayerGetItemInfo() function for each driver too (and the main wrapper function). TODO…

mapshape.c - mapsde.c - mapogr.cpp - mappostgis.c - maporaclespatial.c - mapmygis.c -


No changes.


No changes anticipated.

Backwards Compatibility Issues

None. This is a new feature.

Bug ID

None assigned.

Voting History