Personal tools
Home » Members » perry » Web Mapping Setup
Document Actions

Web Mapping Setup

by Matthew Perry last modified 20-12-2006 15:36

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 http://portal.nceas.ucsb.edu/Members/perry/accessing-90-meter-srtm-data-at-nceas 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.php4

Setting 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>

.....

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]);

....
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.

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



Built with Plone