Web Mapping Setup
Tutorial of sorts describing the setup of Mapserver mapfiles, WMS/WCS/WFS servers, DHTML web mapping clients, PrimaGIS sites, etc.
Mapserver setup on the EBM server
Mapserver is just a cgi program installed to /usr/lib/cgi-bin
Mapscript (the programmatic API for accessing mapserver with other languages) is installed in various places depending on the language
The mapserver configuration files mainly reside in /mnt/raid/services/mapserver . There are 5 main directories within:
- fonts : stores the font configuration file (font.list) and any fonts used by mapserver
- maps: Mapfiles.. the glue between your data and their cartographic representation
- refmaps: small images used for overview maps
- symbols: symbol configuration files which define, well, cartographic symbols
- templates: these html files use mapserver template markup to place query info (ie dbf records)
Some applications of mapserver require that it store temporary images on the server. These are stored in /var/www/mapping-site/tmp/mapserver.
Ka-map, which is both a web client and a server-side caching framework, is installed to /var/www/mapping-site/ka-map or ka-map-1.0beta1. It uses php-mapscript to generate tiles and needs to store them in a web accessible directory (/var/www/mapping-site/tmp/kacache). Configuration requires editing /var/www/mapping-site/ka-map/include/config.php and pointing it to a valid mapfile.
An alternative to kamap is the up-and-coming combo of OpenLayers and TileCache with provide the client and server tiling respectively. OpenLayers is installed in /var/www/mapping-site/openlayers BUT, unless you're modifying code, you can simply point your html page to the openlayers server without needing to store a local copy. A good example of setting up openlayers through its javascript api exists at /mnt/raid/services/django/threats/templates/map_openlayers1.html
TileCache is highly recommended when setting up a slippy map. This resides in /mnt/raid/services/tilecache/ and is configured to run under mod_python via the apache site "ebm" (/etc/apache2/sites-available/ebm) . Configuring TileCache takes place in the /mnt/raid/services/tilecache/tilecache.cfg file. It is currently set up to cache everything to /mnt/storage/tmp/tilecache/.
Setting up a Mapserver Mapfile
This is just and overview so mapfile advice should really come from the existing mapfile samples, mapserver website, google, irc and the mapserver mailing list. Oh and check out the tutorial ..
testing your mapfile
First thing to test is the basic ability for your mapfile to create an image. Use the shp2img command which will bail out on any snytax errors and help you debug.
shp2img -m my_mapfile.map -o test.jpg
Once your mapfile syntax is clean, you can test the cartography with the mapfile viewer which will allow you to specify the mapfile and browse in an interactive viewer without having to build an interface. From here you can check on all the cartographic nuances, labels, colors, layer combos, scaling, etc.
Configuring a WMS Server using Mapserver
Really there's not much to do here once you have contructed a valid mapfile; Mapserver will automatically handle WMS requests against any valid mapfile. However to make things 100% OGC compliant, you have to fill in some extra metadata
in the MAP's WEB definition:
WEB
...
METADATA
"wms_title" "World"
"wms_onlineresource" "http://localhost/cgi-bin/mapserv?mapfile=/home/perrygeo/mapfiles/world.map"
"wms_srs" "EPSG:4326"
"wms_abstract" "A Map of the World"
END
...
END
in each LAYER:
LAYER
...
METADATA
"wms_title" "World Borders"
"wms_srs" "EPSG:4326"
"wms_abstract" "World borders as defined by some guy"
END
...
END
Configuring a WCS Server
Web Coverage Services (WCS) allow you to download raw raster data over the web.
To set it up, you need :
- A valid mapfile with the above WMS metadata
- Some custom output formats for defining the available download formats.
- Add "DUMP TRUE" to your raster layer
The best working example is in /maps/srtm_90m.map which can be accessed via a WCS request like so:
http://ebm.nceas.ucsb.edu/cgi-bin/mapserv?map=/maps/srtm_90m.map&Version=1.0.0&request=GetCoverage&Coverage=srtm&service=WCS&CRS=EPSG:4326&Format=image/hfaint16&resx=0.0008333333333&resy=0.0008333333333&BBOX=-120,34,-119,35
Check # for more info
Setting up Mapserver Web Widgets (DHTML client)
First you need to create a valid mapfile. Then with MWW installed and configured, go to /var/www/mww and you'll find an example template in templates/template1.php. Make a copy of it:
cd /var/www
cp mww/templates/template1.php ./demo.php
cp mww/templates/style1.css .
Now you just need to configure 2 lines in demo.php
$mapfile = '/home/perrygeo/mapfiles/world.map';
...
include("mww/mww.php");
Point your browser to http://host/demo.php and you should have a DHTML map interface to your mapfile.
The best resource for setting up MWW is to look at an existing example at /var/www/mapping-site/srtm.php4Setting up an OpenLayers client with TileCache
First step is to set up a valid mapfile as described above.
Second, set up tilecache.cfg to point the "base" variable to a valid cache directory
Next define the layers by pointing a tilecache layer to a valid mapfile-layer:
[base]
type=MapServerLayer
mapfile=/maps/threats.map
layers=nedrape
extension=jpeg
Third, Configure the openlayers html/js page to access the tilecache via WMS calls.
<script src="http://openlayers.org/api/OpenLayers.js"></script>Point your browser to the openlayers page and test it out. Check the image URL which will return a somewhat-helpful stacktrace if anything goes wrong.
.....
var base = new OpenLayers.Layer.WMS( "Base Map",
"http://ebm.nceas.ucsb.edu/tilecache/tilecache.py?", {layers: 'base', format: 'image/png' }, {isBaseLayer:true, reproject:false} );
map.addLayers([base]);
....
There are some tricks with transparency for overlay layers. In your openlayers Layer, you should use 'image/gif' as the format and set "isBaseLayer" to false. You'll also need to define the following outputformat in your mapfile:
OUTPUTFORMAT
NAME gif
DRIVER "GD/GIF"
MIMETYPE "image/gif"
IMAGEMODE PC256
TRANSPARENT ON
EXTENSION "gif"
END
You can pre-generate the tile cache if you feel the need (beware of disk space!) :
python /mnt/raid/services/tilecache/TileCache/Client.py "http://ebm.nceas.ucsb.edu/tilecache/tilecache.py?" cities 0 5
Where "cities" is the layer name as defined in tilecache.cfg and "0 5" is the range of zoom levels (0 is global, 16 is very detailed) .. for the sake of our raid array, don't do a "0 16"!
Setting up Ka-Map client
All of the configuration happens in /var/www/ka-map/include/config.php. You must first have a working mapfile. Here are the lines to change in order to point to your mapfile.
(Note: the scales array is a set of zoom levels indicated by the denominator of the nomial scale )
$aszGMap = array (
'title' => 'World',
'path' => '/home/perrygeo/mapfiles/world.map',
'scales' => array( 40000000, 25000000, 12000000, 7000000, 3000000, 1000000 ),
'format' =>'PNG'
);
$aszMapFiles = array( 'world' => $aszGMap );
$szMap = 'world';
You may also want to pre-generate the tile cache for speed. Set the max execution time very high (overriding the default 30 seconds in php.ini ) if you expect this to take long, which it most certainly will.
/usr/local/php4/bin/php -d max_execution_time=50000 ../htdocs/precache2.php
Now point your browser to http://host/ka-map/htdocs/ to view the map.
Setting up a Mapbuilder client
Mapbuilder uses WMS servers to provide the map layers. It uses the OGC Standard Web mapping context documents (WMC) to describe the WMS layers available in a given map interface. In order to create a context doc for any given mapfile:
cd /tmp
wget -O capabilities.xml 'http://host/cgi-bin/mapserv?map=/home/perrygeo/mapfiles/world.map&request=GetCapabilities&service=WMS'
xsltproc -o mycontext.xml /var/www/mapbuilder/lib/tool/xsl/Caps2Context.xsl capabilities.xml
# This process is not perfect
# - If you have Layer groupings, things will foul up so remove the "outer" layers (ie the groups) manually from the capabilities doc first
# - You must modify the online resource URL to provide the proper mapfile
vi mycontext.xml
<OnlineResource type="simple" xlink:href="http://host/cgi-bin/mapserv?map=/home/perrygeo/mapfiles/world.map"/>
# Go to the demo dir and make a copy of one of the demos to build off of
cd ~/www/mapbuilder/demo
cp -r basic mymap
cd mymap
# copy your context doc here
mv /tmp/mycontext.xml .
# Point to the new context doc
vi config.xml
<defaultModelUrl>./mycontext.xml</defaultModelUrl>
You can now access your WMS server through the mapbuilder client at http://host/mapbuilder/demo/mymap/
If you want to make any changes to the html, dig into ~/www/mapbuilder/demo/mymap/index.html. Notice the empty divs with ids such as mainMapPane, etc. These are intentionally empty and will be filled in based on the context document which is stored in the client's browser and transformed into html using client-side xslt. Mapbuilder was using AJAX before it was even a word ;-)
Setting up an msCross client
vi index.html
---------------
<html>
<head>
<title>msCross Sample Test</title>
<script src="/mscross/mscross.js" type="text/javascript"></script>
</head>
<body>
<div style="width: 800px; height: 400px;" id="map_tag"></div>
<hr/>
<div style="width: 300px; height: 150px;" id="ref_tag"></div>
<script type="text/javascript">
//<![CDATA[
var Xmin = -180;
var Xmax = 180;
var Ymin = -90;
myMap1 = new msMap( document.getElementById('map_tag') );
myMap1.setCgi( '/cgi-bin/mapserv' );
myMap1.setFullExtent( Xmin, Xmax, Ymin );
myMap1.setMapFile( '/home/perrygeo/mapfiles/world.map' );
myMap1.setLayers( 'worldborders' );
myMap2 = new msMap( document.getElementById('ref_tag') );
myMap1.setCgi( '/cgi-bin/mapserv' );
myMap2.setActionNone();
myMap2.setFullExtent( Xmin, Xmax, Ymin );
myMap2.setMapFile( '/home/perrygeo/mapfiles/world.map' );
myMap2.setLayers( 'worldborders' );
myMap1.setReferenceMap(myMap2);
myMap1.redraw(); myMap2.redraw();
//]]>
</script>
</body>
</html>
-----------
Adding layers and configuring PrimaGIS
Working with specific formats
MySQL Spatial
To load data into mysql using OGR:
ogr2ogr -f MySQL 'MYSQL:gisdata,user=perrygeo,host=localhost,password=shhh' -nln mgmt mgmt_areas.shp mgmt_areas -update -overwrite -lco GEOMETRY_NAME=SHAPE2