[mapserver-dev] Tcl player plugin for Mapscript;can't bind shadowsize

Steve Lime Steve.Lime at dnr.state.mn.us
Wed Mar 4 10:54:26 EST 2009


Hi Karl: It would help if you could create trac tickets around these issues. I
believe there are 3 of them:

  - MapScript/TCL modernization
  - loadable layer plugin (doesn't sound MapScript'ish, is it?)
  - shadowsize bindings

1 & 3 are no brainers, not sure on the second one. Patches can be attached
to the appropriate tickets then as necessary and we can assign to the appropriate
dev staff.

Steve

>>> Karl Lehenbauer <karllehenbauer at gmail.com> 03/02/09 2:38 PM >>>
Hi Mapscript Developers...
We have been stuck on Mapscript 4.6 or so for quite some time because we
generated all of our aircraft, airport, data block and flight track lines by
explicitly building them up with SWIG from points, lines, shapes, etc, and
kludging to show the aircraft's heading in a way that Mapscript 5 broke.

So I learned over time I kind of did it the wrong way, but I needed a data
source besides static file types and databases.  So recognizing that only by
generating geometry and attributes as rows are we going to get to the latest
stuff plus get access to the parameterizable elements that you can't get to
directly, and possessed of some custom memory-resident databases for stuff
for which real databases are just too slow, I set out to write a loadable
layer plugin built around Tcl and succeeded with that.

I'm gonna paste the README below and we're going to be open sourcing it.

One of the touches in our FlightAware maps is that we indicate the aircraft
altitude, roughly, with a drop shadow.  Issue now is that you can't bind
attributes for shadowsize.  It looks like it would be pretty simple to add.
 Are you guys OK with something like this?

Karl

---------------------------------------- snip
-----------------------------------------------
TclPlug is a mapserver layer database plugin.

You define one or more layers in your map file as connection type PLUGIN and
add a PLUGIN line.

    CONNECTIONTYPE plugin
    PLUGIN "/home/karl/src/mapscript-svn/mapserver/maptclplug.so"

The first time a plugin layer is rendered, a full-powered Tcl interpreter is
created and a file called tclplug.tcl is loaded.  It is retained and used
for all layers using the plugin connection type and referencing/loading the
tclplug shared library.

It evaluates the connection string as Tcl source, so you can source in
a file there or do a package require.

Your package/file must define some procs:

    geo_query
    get_geometry
    get_attributes

GEO_QUERY

When any tclplug layer is being rendered, geo_query is called to perform the
query.

It is passed one argument, which is a list of named attributes that the
mapscript library is expecting due to what's been defined as
bound attributes in the layer.

For instance, say the map layer is:

    LAYER
        NAME "plugin"
        PROJECTION "+proj=latlong +ellps=GRS80" END
        STATUS on
        DEBUG 10

        CONNECTIONTYPE plugin
        PLUGIN "/home/karl/src/mapscript-svn/mapserver/maptclplug.so"
        CONNECTION "package require mytclplug"
        DATA "search -originOrDestination {KJFK KTEB KLGA KEWR}""
        TYPE LINE
        FILTER "CFCC LIKE 'A5%' OR CFCC LIKE 'A6%' OR CFCC LIKE 'A0%'"

        LABELITEM myDataBlock
        TRANSPARENCY 50
        TOLERANCE 10
        CLASS
            TEMPLATE roads.html
            LABEL
                ANGLE [myAngle]
                TYPE TRUETYPE
                ANTIALIAS TRUE
                COLOR [myColor]
                #COLOR 195 195 255
                #OUTLINECOLOR 96 96 96
                MINDISTANCE 200
                #MINFEATURESIZE auto
                MINFEATURESIZE 10
                POSITION UC
                SIZE 8
                OFFSET 0 2
                FONT "chalkboard"
            END
            STYLE
                COLOR 96 96 96
                SYMBOL 1
                SIZE 5
            END
            STYLE
                COLOR 200 225 255
                SYMBOL 1
                SIZE 3
            END
        END
    END


This then causes the layer to be rendered by drawing the map or
something. geo_query will be called with {myDataBlock myAngle myColor} as
its argument.

geo_query is expected to perform its search or whatever, and return the
 number of rows resulting from the query.

What the query is is entirely up to you, but your geo_query must return a
number of rows.

LAYER ARRAY

A global array named layer is created with several elements in it.  For the
above map payer, when geo_query is called, the layer array would contain:

layer(connection)     = here's my connection info
layer(data)           = here's my data
layer(name)           = plugin
layer(plugin_library) = /home/karl/src/mapscript-svn/mapserver/maptclplug.so
layer(rectange)       = -114.560132712 8.33658444212 -65.4398672878
41.2751764447
layer(type)           = line

Type can be "line", "point", "polygon", "chart", "annotation", or "query".
No testing has been done with chart, annotation or query.


Note that you can use rectangle to constrain the geometry of your search.

STARTUP

The contents of the connection string are evaluated.  This should be a
source command or a package require or something that causes  three procs to
be created in a namespace that matches layer name.

ROW PROCESSING

GEOMETRY

Now as the layer is rendered, for each row that you said you
have, get_geometry is called with the corresponding row number.

For instance if your geo_query returned 8, get_geometry will be called eight
times with its argument starting at 0 and going through 7.

Your get_geometry returns geometry.

It returns a list of lists of x, y coordinate pairs.

If the layer type is points, each point in every list is inserted into
the layer as a point.

If the layer type is line, each list of points is inserted into the layer as
a line.

If the layer type is polygon, each list of points is inserted into the
layer as a polygon.

If for some reason for a certain row you do not wish to emit geometry,
no problem, just return an empty list and no geometry will be emitted.

ATTRIBUTES

If geometry was emitted, TclPlug will come back and request the
needed attributes' values to complete processing the row.

get_attributes is called with the corresponding row number that
get_geometry was called with.  get_geometry should return a list of
values corresponding positionally to the element names passed to geo_qery.

For the example layer, the list should be the values for
myDataBlock, myAngle, and myColor.



More information about the mapserver-dev mailing list