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

Karl Lehenbauer karllehenbauer at gmail.com
Fri Mar 6 13:52:51 EST 2009


Steve (and the mapserver team et al),

Thanks for the reply.

I'll file tickets with patches for Mapscript/Tcl modernization.  I  
don't have a patch for shadowsize bindings but it doesn't look too hard.

You are correct that the Tcl layer plugin isn't Mapscript at all; it's  
a scriptable way to provide geometry and attributes for a layer.  It's  
a studied copy of mappostgis.c, with all the PostgreSQL stuff stripped  
out and calls to a Tcl interpreter substituted.  To me, it seems  
pretty cool.  When a tcl plugin layer gets rendered, a Tcl array gets  
loaded with stuff from the layer such as the DATA and CONNECTION  
strings, and a Tcl proc named "geo_query" gets invoked with arguments  
being the attribute fields that the layer is expecting.  It returns  
the number of rows to be drawn.

Then for each row, the plugin invokes a proc called "get_geometry"  
that returns the geometry as a list of lists of point pairs.   
Depending on whether the layer type is points, lines or polygons, the  
points get handled accordingly.

As with the PostGIS plugin, if any geometry for a row is returned,  
attributes get set up that can be used based on the layer definition  
to control all the things that attributes can control.  In the Tcl  
plugin case, "get_attributes" gets called with the row number and  
returns a list corresponding to the attributes passed to geo_query.

It seems really powerful and promising, IMHO.  Another issue is that  
so far it needs to be built in the mapserver source directory.  I  
haven't looked at it closely but I may propose a Mapserver RFC to  
create something like gd's gdlib-config and PostgreSQL's pg_config,  
i.e. a program that the plugin's configure script can run with various  
arguments to determine the location of include files, libraries,  
compiler and linker flags, and so forth, that the plugin's build can  
use to find what it needs to compile and link against the mapserver  
library without residing in the mapserver build directory.

Karl

On Mar 4, 2009, at 10:54 AM, Steve Lime wrote:

> 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