Build AJAX-Based Web Maps Using ka-Map
August 10, 2005
The recent popularization of certain web technologies used by Google Maps has encouraged the development of more interactive web mapping techniques. Google's web mapping tools use a technology known as AJAX (Asynchronous JavaScript and XML). AJAX is a style of web application development that uses a mix of modern web technologies to provide a more interactive user experience. Wikipedia has a good discussion of AJAX technology.
By using AJAX, Google's maps draw and zoom quickly, pan smoothly, and can be extended to display a wide variety of information. This article shows how to make similar AJAX-based web mapping sites using an open source web mapping toolkit called ka-Map. ka-Map uses the MapServer web mapping server behind the scenes with AJAX and PHP to serve up the map content. All this comes together to provide a highly interactive means to viewing maps online.
Google Maps provides some very powerful tools, but once you want to add your own data layers, or further customize your own components, it may be easier to use your own toolkits. Tools exist for creating your own AJAX-based web mapping sites and are fairly easy to use. ka-Map coupled with MapServer is a powerful combination of open source web-mapping technologies. For a good example of a ka-Map application see DM Solutions Group's Maps for MapServer site.
AJAX Mapping Power
The open source MapServer web-mapping platform is the tool of choice for many web developers wanting to publish maps online. MapServer's robust set of features and widespread use provide a solid base for a stable, interactive web-mapping experience. However, MapServer alone doesn't provide the level of interactivity, prerendering, caching of tile images, smooth panning, etc. that many users are turning to AJAX for.
ka-Map is also open source and works directly with MapServer. MapServer prepares the map images, ka-Map serves them to the web browser. ka-Map also caches (saves copies of) maps as they are created by MapServer. When the same area on the map is viewed again, MapServer sits idle while ka-Map grabs the cached map image tiles. This is a departure from the traditional cycle: start map application, click to zoom in, wait for entire map image to be created, wait for the browser to receive the image, click again, repeat. Instead, small pieces of the map are created once when first requested and stored on the server. As they are created, they are sent to the web browser and the web browser pieces them together as they are received.
Preparing MapServer
To use ka-Map, you need to have a working MapServer application configuration file. In traditional (non-AJAX) MapServer applications, you create web pages, prepare data, create a configuration file that points to the data, and set up the look and feel of the map. For a ka-Map application you can ignore the web page set up by using the default one that comes with it. Instead, the focus is on preparing map data and setting up the MapServer application configuration file.
MapScript Programming Library
You must have the MapServer programming library, MapScript, up and running. ka-Map uses the PHP MapScript API to render maps. The easiest way to do this is to use one of the binary MapServer installers that are available.
The Windows installer is called MapServer For Windows (MS4W). You simply unzip some files onto your drive and you are ready to go. You can then install other packages that make certain functionality available, e.g. ka-Map. See here to get started with MS4W: http://maptools.org/ms4w.
The Linux installer is called the FOSS GIS Suite (FGS). FGS includes a standardized set of modules, including all library dependencies preconfigured to run together. FGS has an installer shell script, which takes a module and automatically extracts it to your system. It also checks dependencies and grabs other packages as required. Get started with FGS here: http://maptools.org/fgs.
The MapServer website has more installation instructions if you want to start from source code. I also walk through this process in Web Mapping Illustrated.
Data Preparation
Before you move on to creating a simple MapServer configuration file, you need some
map
data. Global country border data are available here as part of a FreeGIS.org world data package.
It provides a basic set of map data in the ESRI Shapefile format. You will need the
files
starting with countries_simpl
. These are low-resolution files to keep the file
size small. If you want a higher resolution dataset, grab the one from here instead.
As an image backdrop, you will use a global cloud image from here. It was created from Xplanet data and a weather map hack from the book Mapping Hacks. Using their hack you can download a new image every six hours and have it automatically update your web mapping applications with current global cloud cover. The image is a TIFF file, with an additional TFW file that provides the information to geolocate the image.
Extract both the country boundaries and image file into a folder called data.
MapServer Configuration
Next, you need to create a MapServer application configuration file. This is a simple
text
file that tells MapServer how to access data and draw the map. This file is commonly
called
a mapfile. It contains several sections called objects. They start with a keyword for
the object type and close with the END
keyword.
Here is a basic map file using the two data layers mentioned above:
MAP NAME global_map STATUS ON SIZE 600 300 EXTENT -180 -90 180 90 UNITS DD IMAGECOLOR 255 255 255 IMAGETYPE png WEB IMAGEPATH "/opt/fgs/apps/kamap-0.1.1/htdocs/tmp/" IMAGEURL "/ka-map/tmp/" END LEGEND TRANSPARENT TRUE END SCALEBAR TRANSPARENT TRUE END LAYER NAME clouds TYPE RASTER STATUS ON DATA "data/day_clouds.tif" END LAYER NAME countries TYPE LINE STATUS ON DATA "data/countries_simpl.shp" CLASS NAME "Country Boundaries" STYLE COLOR 200 100 100 END END END END
Save the above into a simple text file named global.map
.
Testing the Map File
Incorrect settings in your map file will cause problems. Before trying to use a map file with ka-Map, you should test it.
Depending on how you have MapServer installed, you may have a program called
shp2img
. This command-line tool uses the map file to create an image file.
You run it like:
> shp2img -m global.map -o test.png
If all goes well, there should be a test.png
image file containing a map. If
the program fails or gives errors, then you have a problem with your map file.
Further testing may be required to fully guarantee that the map file is working, but this test is a good first cut. To make sure that the maps created from the map file are going to be readily accessible to a web server, you should also test it in a web environment. This is discussed further in the "Further Adventures" section below.
Preparing ka-Map
If you were building a traditional MapServer web map, the next step would be to create some HTML form pages and process it with the MapServer CGI executable. With ka-Map, you can get started out-of-the-box with minimal configuration. First, you need to have ka-Map's configuration files and PHP scripts.
ka-Map comes in three different packages.
- A g'zipped tar ball archive
- A zip format archive
- An online CVS repository
-
As a module for the FGS Linux Installer, grab it by using the command:
fgs install kamap-base:0.1.1 http://dl.maptools.org/dl/fgs/modules/
-
As a zip package for MapServer For Windows (MS4W).
The ka-Map 0.1.1 distribution is comprised of about 38 files:
-
Two JavaScript scripts
-
Two text files
-
Two HTML files
-
Eight PHP scripts
-
24 GIF/JPEG/PNG images
You may have more files than this if you acquired a different version of ka-Map.
The files are stored in a very simple folder structure:
.../kamap-0.1.1/ .../kamap-0.1.1/htdocs/ .../kamap-0.1.1/htdocs/images/
You then create another folder for storing map-image tiles generated by ka-Map:
.../kamap-0.1.1/htdocs/tmp/
All the files you are going to deal with are in the htdocs
folder. To keep
things really simple, move the map file and data folder here as well. Your structure
should
look like:
.../kamap-0.1.1/htdocs/global.map .../kamap-0.1.1/htdocs/data/countries_simpl.* .../kamap-0.1.1/htdocs/data/day_clouds.*
Security Warning
In a production or public environment it is not a good practice to put your
globa
file in a publicly accessible location. This
example is meant only for internal testing and to keep folder management to a minimum
for
getting started. Because l.map
global.map
is in the htdocs
folder it can
be accessed through a web URL. This is a particularly bad idea if you are connecting
to
databases in your map file where database user names may be explicitly set.
This commonly used folder structure keeps the htdocs
folder separate from the
map file and data:
.../kamap-0.1.1/map/global.map .../kamap-0.1.1/data/countries_simpl.* .../kamap-0.1.1/data/day_clouds.*
Web Server Aliases
To allow your web server to use ka-Map, you need to set some web server aliases. With
FGS
and MS4W this may be done for you automatically. Otherwise, you will need to add something
like this to your web server configuration, for example in an Apache httpd.conf
file:
Alias /ka-map/ "/opt/fgs/apps/kmap-0.1.1/htdocs/" <Directory "/opt/fgs/apps/kmap-0.1.1/htdocs/"> Options Indexes AllowOverride None Order allow,deny Allow from all </Directory>
This allows you to enter a simple URL (/ka-map/
) and have it point to the file
path where ka-Map content is stored.
ka-Map Configuration Files
ka-Map comes with one main configuration file:
.../kamap-0.1.1/htdocs/config.php
Once the handful of settings in this file are set, you will have a fully functioning
ka-Map
application. For FGS and MS4W packages, many of these settings are already taken
care of. There is documentation throughout config.php
to guide you
through each setting. There are only three different types of settings that you really
need
to worry about.
Setting Up Library Pointers
ka-Map requires both PHP MapScript and the GD module for PHP. config.php
needs
to point to these library files (around line 23):
$szPHPMapScriptModule = 'php_mapscript_cvs_rel.4.6.0.beta2.'.PHP_SHLIB_SUFFIX; $szPHPGDModule = 'php_gd.'.PHP_SHLIB_SUFFIX;
The first one points to the file name prefix for the PHP MapScript library. This looks
somewhat verbose, because the above example uses a very recent beta version of PHP
MapScript. You change this to match the filename for the php_mapscript
library
that is on your system. In many cases this looks as simple as:
$szPHPMapScriptModule = 'php_mapscript.'.PHP_SHLIB_SUFFIX;
Or:
$szPHPMapScriptModule = 'php_mapscript_46.'.PHP_SHLIB_SUFFIX;
The documentation says that the pointer to php_gd
will likely need to be
changed to php_gd2
, if running on Windows.
Note that the PHP_SHLIB_SUFFIX
variable will automatically add the filename
suffix. For example, .so
or .dll
, depending on your operating
system. Don't include the suffix in this filename setting.
Adding Your Map File
To have your custom application show up in ka-Map, you need to tell ka-Map where your
map
file is, as well as some other map-specific settings. Around line 80 you'll find the
settings for the $aszMapFiles
array. It will already be set to use a mapping
application called GMap
, but you can change it to match this one:
$aszMapFiles = array( "weather" => array( "Global Weather", "/opt/fgs/apps/kamap-0.1.1/htdocs/global.map", array( 100000000, 50000000, 15000000 ), "PNG") );
This sets up an array of information, all stored within the $aszMapFiles
variable. The first setting is the name of the ka-Map instance you are configuring;
in this
case the application is called "weather"
and uses the
global.map
file you created earlier. This name is used in other places, as
you will see later on.
The second setting is the text, "Global Weather"
, which is the name
that will appear in the drop-down box on the web page. From this drop-down you can
choose
which map file you want to use.
The third setting points to the location of the global.map
file. Depending on
how your system is configured, this will vary. In this example, global.map
was
stored in the ka-Map htdocs
folder, alongside the data folder.
Setting Map Scales and Image Formats
The fourth setting is a list of scales. These are the map scales that the user will be allowed to view the map at. For example, 1,000 would be the map scale as a representative fraction of 1:1,000. This means that one inch on screen represents one thousand inches on the ground.
The final setting is the output image format to be used, in this case
"PNG"
.
Note that there are two closing parentheses, one after "PNG"
, which
ends the settings for the "weather"
array. If you want to add more
than one instance to ka-Map, put a comma after this parenthesis and create a whole
new
instance key.
The second closing parenthesis is on a separate line and followed by a semicolon.
It ends
the settings for the $aszMapFiles
array.
With those changes made to config.php
, you are ready to test your map.
Testing the Basic Application
If you've made changes to your web server configuration (e.g. set up new aliases) then you need to restart the web server.
Restart the Web Server
With FGS, it's as easy as initializing the FGS environment and then stopping-and-starting the FGS server:
> . /opt/fgs/setenv.sh * FGS runtime ready in '/opt/fgs', use fgs command. > fgs stop /opt/fgs/etc/init.d/apache stop: httpd stopped > fgs start Processing config directory: /opt/fgs/www/conf.d/*.conf Processing config file: /opt/fgs/www/conf.d/kamap.conf /opt/fgs/etc/init.d/apache start: httpd started
With MS4W you need to stop and restart the Apache process. This often runs as an
application in its own command window. You can open that window and press the
CTRL+C
key combination to stop the Apache web server. Then start it again by
launching the apache.exe
file found in C:\ms4w\apache\
. If Apache
was installed as a service, then it can be restarted using the Services application
in the Windows Control Panel, under Administrative Tools.
Load Map
Now you should be able to access your map using a modern web browser. Firefox and Internet Explorer work well with this example. Safari web browser on OS X seemed to only partially work as some of the page layout was broken.
Open up the URL to the ka-Map instance. For example, with the default FGS install you would open:
http://localhost:8080/ka-map/
When you install FGS, you are asked what port the web server should run on. The default
is
8080
. With MS4W it defaults to port 80
. The port number in the
URL should be replaced by your web server port, or left blank if it is running on
the
default port 80
.
Figure 1 is a screenshot of Firefox displaying the initial map. Adding the key/reference map in the lower-right corner will be introduced in another section.
Figure 1. Initial web page view of tutorial application
Be patient the first time around, as it may take a minute to get started. Each time you zoom in it will create a new master map, tile it up into tiny chunks, and store it on the server. Then it will send you just the pieces that you need.
Navigating the World
The interface is simple. Click Zoom In for more detail and Zoom Out for less. The image data used in this example is very low resolution, so zooming in doesn't look that great. But, you have the option of using any data you want for your application.
When you want to centre the map on a particular location, you have two choices. You can click-and-drag the map around until the area of interest is in the middle of the map. Then zoom in more if you'd like to see that area in detail.
Another way to move the map around is by quickly double-clicking on a location. This will automatically center the map on that location -- it's a neat effect.
Keyboard shortcuts include the plus (+) and minus (-) keys for zooming in and out. You can also use Page Up, Page Down, Home, End, and the arrow keys to pan the map. Click on the map once first to enable these controls.
Adding a Key/Reference Map
You don't need to have a reference in your application, but to add one you need a
REFERENCE
section in the global.map
file. You can add it right
after the SCALEBAR...END
section:
REFERENCE EXTENT -180 -90 180 90 SIZE 241 121 IMAGE data/keymap.png COLOR -1 -1 -1 OUTLINECOLOR 255 0 0 END
This example requires a reference map image named keymap.png
to be saved with
the cloud image and shapefiles in the data folder. You can download Figure 2 and use
it for
your reference map image.
Figure 2. Reference map image (keymap.png
):
ka-Map will automatically show the current extent of the map using a red box on top of the reference map, as shown in Figure 1.
Troubleshooting
Can't get ka-Map working? Here are some tips for improving your experience or finding problems with your setup.
- Use a more recent web browser version. AJAX is highly dependent on recent web browser technology.
- Check your web server aliases to make sure that the /ka-map/ directory points to
the
proper
.../kamap-0.1.1/htdocs
folder. - Test your map file by running
shp2img
. If you don't have this utility already, you should get it. If it doesn't work with your map file, then ka-Map won't either.shp2img
also comes as part of the precompiled FWTools collection. - Check your temporary/cache folders. For simplicity, your map file
IMAGEPATH
andIMAGEURL
should correspond to the$szBaseCacheDir
setting inconfig.php
. If no files are being made in that folder, then your settings are to blame. Ensure that the web server is allowed to write in that folder. - Turn on the debug option in config.php. Setting
$bDebug = true
will draw the rectangles of the tiles on top of your map data. If nothing appears, then you have a problem with the ka-Map installation. - Consider using a more recent version of ka-Map (e.g. using CVS). There are bug fixes, performance improvements, and new features in newer versions, but I have found 0.1.1 to be the most stable at present.
- More recent versions of ka-Map come with a
scripts
folder, which the user that the web server runs as must be able to write into that folder. - If you are familiar with JavaScript, you could also install a debugger that can help you debug configuration problems. Consider using Mozilla's Venkman debugger.
- If you are still having problems, you can try loading the
init.php
file in your URL to see more runtime settings and errors (e.g.http://localhost:8080/ka-map/init.php
).
Further Adventures
Testing the Map in a Web Context
The settings used in the global.map file are very simple, but in a production environment
you may need to change them. You may end up wanting to change the IMAGEPATH
and
IMAGEURL
settings to put your temporary map images somewhere else on your
filesystem. These settings also specify where the web browser will be able to find
the map
images. If you have IMAGEURL set wrong, then the web server won't be able to make
the map
available to the user.
The best way to test for this is to write a simple PHP script and test running it.
Take the
following PHP script, save it to your kamap-0.1.1/htdocs folder and then load it up
using a
URL like http://localhost:8080/ka-map/maptest.php
.
<?php dl('php_mapscript.'.PHP_SHLIB_SUFFIX ); $oMap = ms_newMapObj( 'global.map' ); $oImg = $oMap->draw(); $szURL = $oImg->saveWebImage(); echo "<img src=$szURL>"; ?>
If you map image is drawn, then things will work in ka-Map. If not, then you have some problems with your map file.
Customize Look and Feel
ka-Map doesn't automatically pick an appropriate scale for your web browser's window
size
or screen resolution. It always uses the first one you have specified in
config.php
. Therefore, it is difficult to know exactly what your map will
look like on another screen. This is more of a problem when the geographic extents
of your
application cover all your data. When there is more data outside your map area it
helps fill
the screen better.
Customising the index.html
code allows you to change the way the interface
looks. For example, you can change the colours, add logos, etc.
Cleaning Up the Cache
Sometimes you really need to clean out the cached tile data and start over, especially
if
you are modifying your map file or map scales. It would be good to have a more automated
way
of clearing the cache, e.g. a button on the web page. Until then, you need to delete
all the
files in your cache folder. For example, clear out all files and folders from
/opt/fgs/apps/kamap-0.1.1/htdocs/tmp/
.
Note that if you turn on the debug option, you will need to clear the cache when you turn it back off.
Prebuilding Map Tiles
Version 0.1.1 comes with a script called precache.php
. This is a powerful tool
that can really improve the initial performance of your application. You need to edit
several pieces of the script before you can use it. Supply the map name (changing
it from
the default gmap
) and set the scales that your map will be using. There is also
a setting that calls the tile.php
script. Make sure this points to
tile.php
on your server.
If you comfortable with PHP, you could modify the precache tool to pick up the settings
from config.php
. Then it could process all your maps for all the scales that
your application is set up for.
Legend Handling
There have been some bugs in the way that legends are generated. If you do not include
a
LEGEND
object in the global.map
file, then the legend doesn't
draw properly. Even if the LEGEND
object is empty, it will allow ka-Map to
render it properly. Having such a simple LEGEND
object isn't a very good
practice for normal MapServer applications, but works fine with ka-Map. By setting
the
TRANSPARENT
option, it makes the legend look good on top of the web page
background.
Advanced Functionality
More recent versions of ka-Map (i.e. CVS or version 0.2) have many more options and features. For example, an advanced, tree-like legend manager tool. This allows layers to be controlled as a group. This requires some more planning and appears to be somewhat unstable at present, but is certainly promising.
There are options for setting transparency for layers. You can then make one layer semitransparent and see it overlaid on top of another. Combine this with layer-visibility control and you can make some really interesting tools.
Some really powerful maps can be created using WMS data sources in your map file. This could, for instance, allow you to have one layer of changing data that is regularly updated, but never requires you to regenerate map tiles for all layers. This takes some thinking and caution, as you could easily flood a WMS provider, giving poor results, or mistreating a benevolent provider. Adding real-time WMS layers to your application is customisation that ka-Map does not come with out-of-the-box. If you want your WMS layers to be updated, then you will have to clear the cache and let it rebuild the cached tiles.
Conclusion
It took some time to get my first set up of ka-Map to work properly. I had switched between packaged source files and CVS, but found that the best way to get started was by using MS4W or FGS. The set up is relatively simple, but leaves little room for mistakes. Having an AJAX-based web-mapping platform is in high demand and ka-Map does a worthy job filling that need. Because it is an open source product, there is room for others to help develop it further. Whether you are a user or a developer, you can play a part in making the product better and more stable. I hope you enjoy using it as much as I have.
Links and Resources
In a previous article and some weblogs, I introduced some web-mapping tools. This is also the focus of my book, Web Mapping Illustrated. I have focused on the open source tools that are freely available, very powerful, in active use, and under continual development.
Here are links to some of the products and web sites mentioned in this article.
- MapTools - http://maptools.org/
- MapServer - http://ms.gis.umn.edu/
- ka-Map - http://ka-map.maptools.org/
- FreeGIS - http://www.freegis.org/
- FWTools - http://fwtools.maptools.org/
- Web Mapping Illustrated - http://oreilly.com/catalog/webmapping
- Mapping Hacks - http://oreilly.com/catalog/mappinghks
- My other articles and weblogs - http://www.oreillynet.com/pub/au/1898
In June 2005, O'Reilly Media, Inc., released Web Mapping Illustrated.
-
Chapter 3: Converting and Viewing Maps (PDF), is available free online.
-
You can also look at the Table of Contents, the Index, and the full description of the book.
-
For more information, or to order the book, click here.