I recently decided that I was feeling too limited by the very high-quality but super-simple ArcGIS Online. I understand they're not in the business of giving me the best for free, but I'm also not going to pay for ArcGIS, and I need features that I'm not getting in their online version - like being able to force map label visibility. I'm not even sure I'm going to get that with mapserver, but I have been meaning to get back into it for a while anyway.
I am running Devuan 5, which is based on Debian 12, and I decided to see if there was a reasonable version of mapserver included. I found that it has version 8, which is at least the right major version (even if it's a bit outdated version of it) and decided to give it a shot. A quick glance at it revealed that it has been built with pretty much all of the formats, which is all I really ask anyway. I installed it and away I went trying to get it to actually display a map.
Long story short, there's quite a few steps which don't seem to be done for you at all. Mapserver expects not just your map file but also a config file, and there doesn't seem to have been any thought given to that at all. I addressed this for the CGI version only so far, although I do plan to step up to looking at Mapscript next.
I wound up with a config file at /etc/mapserver.conf, which seemed a likely location. You can specify a different config file every time you run mapserver if you want, but one way to configure it is in the web host config. Here's all the steps you will need to think about for CGI mapserver:
1. CGI support in the web server
Commands are provided for manipulating apache2 conf conveniently. They are named a2{en|dis}{conf,mod,site} and a2query. Example:
sudo a2enmod cgi
will quickly enable CGI functionality. However, this enables CGI for all vhosts; if this is not what you want, follow this up with:
$ sudo a2disconf serve-cgi-bin
Conf serve-cgi-bin disabled.
To activate the new configuration, you need to run:
service apache2 reload
$ sudo a2query -m cgi
No module matches cgi (disabled by site administrator)
$ sudo a2enmod cgi
Enabling module cgi.
To activate the new configuration, you need to run:
service apache2 restart
$ sudo a2query -c serve-cgi-bin
No conf matches serve-cgi-bin (disabled by site administrator)
$ sudo a2enconf serve-cgi-bin
Enabling conf serve-cgi-bin.
To activate the new configuration, you need to run:
service apache2 reload
I have multiple vhosts configured on my PC for various purposes which are irrelevant to this article. However, I do configure a default vhost to let me do simple web stuff on my PC which I simply access via the name localhost. Here's the relevant bits of the config, with all of the comments taken out:
<VirtualHost localhost:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SetEnv MAPSERVER_CONFIG_FILE "/etc/mapserver.conf"
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
Note the commented config line; if you skip the last command shown above (a2enconf serve-cgi-bin) and uncomment the above line, it will enable CGI for this vhost alone.
Note also the SetEnv line in the VirtualHost above, this is in general how the mapserver config file is specified. We are doing it here so that it affects the entire vhost.
Here's the good bits of the /etc/mapserver.conf:
CONFIG
ENV
MS_MAP_PATTERN "^/var/www/map" ## required when referencing mapfiles by path
MS_DEBUGLEVEL "5" # suggested minimum: 2
MS_ERRORFILE /var/log/mapserver/mapserv.log
CPL_DEBUG "ON"
CPL_TIMESTAMP "ON"
PROJ_LIB "/usr/share/proj"
MS_MAPFILE "/var/www/map/tiger-basic-example.map"
END
END
We need this config file mostly to set logging options. The log directory is completely up to you, and so is how much logging you do. If you're trying to solve a problem, you will want it cranked up to the max of 5. In normal use, 2 is suggested, and turn off the CPL options. 0 is allowed, to suppress logging. To make the log directory writable by apache with the default user and password, set the user and/or group of the log directory to www-data and give the appropriate write permissions.
My map data is US Census TIGER, which is reasonably high quality and comes at the right price of free. Downloading it can be a bit irritating, but using it with mapserver is even moreso when you've forgotten how this stuff works. Right now I'm interested particularly in doing some generation of maps in California, so that's where I'm focused. First, I've downloaded the full TIGER data set. I used get-tiger, which did a pretty mediocre job in general but did help with some of the irritating parts. I found that it had failed to download a lot of stuff, so I went in and created the directories manually and used the "ftp" interface on the website, which actually is a http index interface or a close facsimile. I copied the lists of files and used the "cut" command to get the filenames alone out of it, then used a for loop in the bash shell to download them. You could just use their download interface, but I wanted all of the data, and this was a much less click-intensive way to get it than just using the browser. I did try to use the FTP site, but sadly I was unable to actually download any files that way even after forcing passive mode.
After a bit of hacking and whacking, this is the map file I came up with, which resides at /var/www/map/tiger-basic-example.map:
MAP
IMAGETYPE PNG
EXTENT -125.0 32 -114 43 # california
#EXTENT -125.0 24.5 -66.9 49.0 # continental US
#EXTENT -179.148909 -14.548699 179.778470 71.365162 # world
SIZE 800 600
SHAPEPATH "/mnt/storage/Mapdata/TIGER"
IMAGECOLOR 48 64 255
LAYER
NAME "state"
TYPE POLYGON
STATUS DEFAULT
DATA "STATE/cb_2021_us_state_500k.shp"
CLASS
STYLE
COLOR 255 200 128
OUTLINECOLOR 0 0 0
END #style
END #class
END #layer
LAYER
NAME "watera"
TYPE POLYGON
STATUS DEFAULT
DATA "AREAWATER/tl_2021_06_areawater"
CLASS
STYLE
COLOR 100 128 255
OUTLINECOLOR 140 160 255
END #style
END #class
END #layer
LAYER
NAME "waterl"
TYPE LINE
STATUS OFF
DATA "LINEARWATER/tl_2021_06_linearwater"
CLASS
STYLE
COLOR 100 128 255
#OUTLINECOLOR 140 160 255
END #style
END #class
END #layer
LAYER
NAME "psroads"
TYPE LINE
STATUS DEFAULT
DATA "PRISECROADS/tl_2021_06_prisecroads"
CLASS
STYLE
COLOR 63 63 63
END #style
END #class
END #layer
END #map file
What's the TIGER directory look like? Good question, here's what's in it now.
TIGER$ ls
AREAWATER COUNTY LINEARWATER PRISECROADS STATE
mapserver is clever enough to try different options when you ask for a file without an extension, and it will try ESRI Shapefiles and find one with the name specified for DATA with .shp on the end of it. The map data is found with the combination of the SHAPEPATH element and the DATA element. You can also specify a data source with a full path, or to load it from a database or via WMS.
If you're getting errors, make sure that the apache2 user (again, by default, user www-data in group www-data) has read access to your files. mapserver will not simply tell you that it doesn't have read access to the file, it will just tell you that it had an error opening it.