Proposed RFC on COLORRAMP Support (Bug 1305)

Bill Binko bill at BINKO.NET
Tue Sep 27 02:24:49 EDT 2005


Hello, all

I have put together a straw man RFC to try to get Bug #1305 put to bed.  
The hang-up has been over syntax (primarily), so I have put together a 
proposal that you're welcome to beat to death.  However, I'd like to get 
consensus on a format so that I can implement it and move on.

I hope I've formatted this correctly: please ding me if there's 
information I'm missing.

Thanks
Bill
-------------- next part --------------
===============================================================
  MS RFC 8(?): Color Range Mapping of Continuous Feature Values
===============================================================

:Date: 2005/09/27
:Author: Bill Binko
:Contact: bill at binko.net
:Last Edited: $Date: 2005/09/27 03:48:24 $
:Status: Proposed

Description: This proposal addresses the need to be able to easily
map continuous feature values to a continuous range of colors.  This RFC is
the result of (and my interpretation of) the discussion that
surrounded Bug #1305.

A preliminary patch has already been applied to Mapserver 4.6+ (before
the RFC process was in place), however, there is little consensus on the
format being used and there is no support for proper display of
legends for classes using ColorRanges.

Background
~~~~~~~~~~~~~~~~~
This work started as a patch that I created to be able to quickly
visualize data with a large range of values.  In particular, I was
wishing to map property values, and various ratios that could take on
a large range of values.  To me, the natural way to do this was to set
a max value, a min value and what colors those mapped to.  The patch I
wrote had Mapserver do a linear interpolation of the value for each
feature on to that color range.

The initial syntax for this feature simply added 5 new keywords to the
STYLE block and looked as follows:

STYLE
  COLOR 60 60 60
  MINCOLOR 0 0 0
  MAXCOLOR 255 255 0
  MINVALUE 0.0
  MAXVALUE 300000.0
  GRADIENTITEM "sale_price"
END

After some discussion, the term Gradient was shown to be problematic.
Also, the number of new keywords seemed high.  After some discussion,
the syntax was changed to this format:

STYLE
    COLORRANGE 0 0 0  255 255 0 # black to yellow
    DATARANGE 0.0 100.0
    RANGEITEM "foobar"
END

While this is still just a set of keywords under a Style, it seemed
simpler and is now working in the Mapserver 4.6 branch.

Current Syntax Problems
~~~~~~~~~~~~~~~~~
Several people pointed out that the current syntax could be improved
by:

1) Moving the new keywords into a block
2) Adding a METHOD keyword with the type of interpolation used
('linear' being the first defined type, 'logarithmic' being a
potential second type, etc.
3) Adding an INTERVALS keyword that would limit the number of colors
actually used by rounding values before interopolation.
4) Moving all of the keywords out of the Style block.
5) Allowing the ColorRange to be defined separately so that it can be reused

Current Opinions
~~~~~~~~~~~~~~~~~
It seems that the current opinion is that this is valuable, but not
yet clear enough.  Hence the need for this RFC and the discussion it
will (hopefully) provide.

There seems to be consensus on #1-4 from the previous section.  Please
correct me if I'm wrong on this.

Allowing the ColorRange to be defined separately seems to be
problematic (in my view) as the "DATARANGE" parameter is fairly
specific to the layer you're drawing.  Because of this difficulty, I
would like to table that requirement temporarily and see if we can
meet the rest of the goals.

Proposed New Syntax
~~~~~~~~~~~~~~~~~
To meet the above needs, I propose the following new Block Syntax:

COLORRANGE
	RANGEITEM 'itemname' #required
	MINCOLOR 0 0 0 #optional - default = Black
	MAXCOLOR 255 255 0 #optional -default = White
	MINVALUE 0.0 #optional - default = 0
	MAXVALUE 100.0 #optional - default = 1
	INTERVALS 10 #optional - default = 0 (unlimited)
	METHOD LINEAR #optional - default = 'LINEAR'
END

I propose that this block lives at the CLASS level.  My reasons for
putting it at the CLASS, rather than the LAYER (or above) level are as
follows:

1) CLASS is the lowest level that can define a Legend entry (by using
   a named class)
2) Allows multiple COLORANGES to be applied to a single layer
   (i.e. Red->Yellow and Yellow->Green to make a contiguous
   Reg->Yellow->Green).
3) Allows "out of bounds" values to be highlighted separately (with a
   different CLASS).

(If we wish to provide this capability on the OUTLINECOLOR, then I
would suggest we create a OUTLINECOLORRANGE block with identical format.)

Note: I am (and have always been) flexible on all of the keyword names
and formats here.  However, given the discussion that's gone on around
(and around) this, I thought I'd put a straw man up and start here.

Proposed Legend Format
~~~~~~~~~~~~~~~~~
I have posted a mockup of how I believe legends should look at 

http://mapserver.gis.umn.edu/bugs/attachment.cgi?id=324&action=view

The format only changes the height of the legend (which is already
dynamic) so it should not have major layout implications.
(Nit-picking about how tall the colorbar should be can be worked out
during implementation.)

I have not started the legend support, and would like some help in
this area.  However, I do believe it is straightforward, and I will do
it on my own if there are no volunteers.

Mapscript Issues
~~~~~~~~~~~~~~~~~
As Sean Gillies mentioned in the discussion, this should be
encapsulated in Mapscript as a class.  While I disagree with his
putting it on the LAYER (see above), the rest of his suggestions all
seem right in line.

I Propose a class named ColorRamp with the following read/write attributes:

Color minColor
Color maxColor
double minValue
double maxValue
String rangeItem
String method
int intervals

and two methods

Color findColor(double value)
double findValue(Color color)

ColorRamps can be obtained through an appropriate constructor or
through a new (read/write) attribute on the ClassObj object:

ColorRange colorRange

Note: I will need help in adding these to Mapscript as I do not have
the SWIG experience to do it well.

Files affected
~~~~~~~~~~~~~~~~~

I will update this list as the RFC evolves, but right now, these are
what I see:

- mapfile.h => Change Keywords
- maplexer.l => Change Keywords
- mapfile.c => process new Keywords
- mapscript/swiginc/*.i => various interface modifications to fit the
  above requirements
- maplegend.c => Add new Legend support
- mapdraw.c => update existing ColorRange code to use new keywords &
  add intervals and LOGARITHMIC method

Backwards compatabilty issues
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Right now, certain code _requires_ that there is a COLOR attribute set
on any layer that is going to be displayed.  Either this will need to
be changed, or we will have to decide what that means if both a COLOR
and a COLORRANGE are defined.  One option is to use the COLOR for any
values that are outside of the range.

Implementation Details
~~~~~~~~~~~~~~~~~~~~~~

I will update this after more feedback is generated.

I believe I can accomplish all of the modifications needed except for
the Mapscript API without additional input once the Syntax is
determined.  Estimated time would be 1 week after voting.

Bug ID
~~~~~~~~

Currently this is being tracked by bug #1305

Voting history
~~~~~~~~~~~~~~~~~

None




More information about the mapserver-dev mailing list