[mapserver-users] Designing a wrapper around mapserv which can be used with fcgi
Andy Colson
andy at squeakycode.net
Wed Nov 4 06:38:52 PST 2009
>
> Andy Colson wrote:
>>> Andy Colson wrote:
>>>> Adrian Popa wrote:
>>>>> Hello everyone,
>>>>>
>>>>> I am currently using a wrapper around mapserv which receives the
>>>>> URL parameters, builds the map file (actually I only need to set
>>>>> some filters in the map file, but the filters need to be built
>>>>> after running some SQL queries with the passed in parameters).
>>>>> After the map file is built, mapserv is called (as a shell script),
>>>>> and the map gets sent to the user. Currently this wrapper is
>>>>> written in perl - so it's not terribly fast as a cgi process.
>>>>>
>>>>> While this approach works, it is terribly inefficient. I would like
>>>>> to use mapserv as a fcgi process (or something faster than plain
>>>>> cgi). My question is - how can I /should I build a wrapper around
>>>>> mapserv that can "customize" the MAP file on the fly and run as a
>>>>> fcgi process?
>>>>>
>>>>> Any ideas on where I should start? An example of such a wrapper?
>>>>>
>>>>> Also, I suspect I can send parameters to mapserver and use some
>>>>> sort of variables in the map file to set up my filters - but I
>>>>> haven't seen an example. Can someone point me to such a documentation?
>>>>>
>>>>> Thanks,
>>>>> Adrian
>>>>
>>>> Have you seen mapscript? You can use mapserver directly from perl.
>>>> And perl can do fast-cgi. Here is a little, ad-hoc, non-tested,
>>>> perl fcgi:
>>>>
>>>>
>>>> #!/usr/bin/perl
>>>>
>>>> use strict;
>>>> use mapscript;
>>>> use FCGI;
>>>>
>>>>
>>>> my $request = FCGI::Request( );
>>>> while($request->Accept() >= 0)
>>>> {
>>>> my($req, $x, $at, $xmap, $xpin, $sid, $y, $q);
>>>>
>>>> $req = new mapscript::OWSRequest();
>>>> $req->loadParams();
>>>>
>>>> $xmap = $req->getValueByName('map');
>>>> $xpin = $req->getValueByName('pin');
>>>>
>>>> my $map = new mapscript::mapObj( "/maps/$xmap.map" );
>>>> if (! $map)
>>>> {
>>>> #print STDERR "----- Error loading map: $xmap.map\n";
>>>> print("Content-type: text/text\r\n\r\n");
>>>> print "cant load $xmap.map";
>>>> $request->Finish();
>>>> next;
>>>> }
>>>>
>>>> mapscript::msIO_installStdoutToBuffer();
>>>>
>>>> $x = $map->OWSDispatch( $req );
>>>> if ($x)
>>>> {
>>>> print STDERR "OWSDispatch: $x\n";
>>>> my $errObj = new mapscript::errorObj();
>>>> while ($errObj) {
>>>> print STDERR "ERROR:
>>>> $errObj->{code}:$errObj->{message}:$errObj->{routine} \n";
>>>> $errObj = $errObj->next();
>>>> }
>>>> }
>>>>
>>>> my $content_type =
>>>> mapscript::msIO_stripStdoutBufferContentType();
>>>>
>>>> $x = mapscript::msIO_getStdoutBufferBytes();
>>>>
>>>>
>>>> print("Content-type: $content_type\r\n\r\n");
>>>> if (mapscript::msGetVersionInt() >= 50500)
>>>> {
>>>> print $$x;
>>>> } else {
>>>> print $x;
>>>> }
>>>>
>>>> mapscript::msIO_resetHandlers();
>>>> $request->Finish();
>>>> }
>>>>
>>>>
>>>>
>>>> I'd recommend using mapserver 5.6.0.
>>>>
>>>> -Andy
>>>>
>>>
>>
>> Adrian Popa wrote:
>> > Thank you,
>> >
>> > I will look into it. I guess through mapscript I can redefine the
>> > parameters that get sent to mapserver? Or do I rewrite the whole map?
>> >
>>
>>
>> You can load a map into memory (I assume you were already doing that).
>> You said "..perl.. receives the URL parameters ...and... builds the
>> map file".
>>
>>
>> I assume your perl does: use mapscript?
>>
>> and at some point: my $map = new mapscript::mapObj( "/maps/$xmap.map" );
>>
>> You kind of imbed mapserver into your perl script, and can call its
>> functions and what not. After you load the map you can do things to
>> it, in memory.
>>
>> In my example above, I'm using the WMS features ($map->OWSDispatch),
>> but you can also generate an image:
>>
>> my $img = $map->draw();
>> $img->save('x.jpg', $mapscript::MS_JPG);
>>
>> -Andy
>>
>
>
Adrian Popa wrote:
> Thank you Andy for explaining.
>
> Actually my wrapper is very hard-core, meaning I don't use mapscript
> (because I had to build it quickly and didn't have time to research
> which was the best approach). Now I have more time and I'd like to tune
> things up, so I will definitely start studying mapscript (If you have a
> link to a good tutorial/function reference for it I am in your debt).
>
> My wrapper just copied over a template map file, edited it (rewrites
> some filters) and then it set
> $ENV{'QUERY_STRING'} = $ENV{'QUERY_STRING'}."&map=$file";
>
> ...and then called
>
> print `/var/www/cgi-bin/mapserv`;
>
>
> It's barbaric, I know, but it worked for me. :)
> It will take a bit of rewrite to add fcgi support and mapscript, but in
> the long run it will be more mantainable... :)
>
> Thanks again,
> Adrian
So are you using the template html stuff? Humm... I've never used that
stuff, not sure how it'll all translate.
For documentation, I used the mapscript reference:
http://mapserver.org/mapscript/mapscript.html
I found a few example perl scripts that helped with the syntax (my $c =
new mapscript::colorObj(), $c->{blue} = 255;, etc...). Other than that,
I had more problems comming up with nice looking colors for my map, than
actually writing the perl code.
-Andy
More information about the MapServer-users
mailing list