wiki:RenderingOsmData

Version 13 (modified by zenon, 14 years ago) ( diff )

--

This Page is still a work in progress, expect glitches!

Rendering OpenStreetMap Data with MapServer

The map displayed on the front page of the MapServer website is an example of MapServer's rendering capabilities.

OpenStreetMap data can be used freely under the terms of the Creative Commons Attribution-ShareAlike 2.0 license:

OpenStreetMap creates and provides free geographic data such as street maps to anyone who wants them. The project was started because most maps you think of as free actually have legal or technical restrictions on their use, holding back people from using them in creative, productive, or unexpected ways.

Which MapServer version to use

The mapfile presented here assumes a very recent version of MapServer is used, i.e. at least 5.4. You will have to include (at least) support for AGG rendering,postgis, and wms server.). Once you're done compiling, copy the mapserv binary to a cgi executable directory of your mapserver (/usr/lib/cgi-bin on debian)

Importing OpenStreetMap Data

This howto will take australian data as an example.

Download

Download the osm-mapserver utils

svn checkout http://mapserver-utils.googlecode.com/svn/trunk/ mapserver-utils-read-only

Import into Postgis

Preparing the postgis database

We'll assume that the data will be imported into a database named osm. We will also add the 900913 crs, and grant access to a www-data user. On a debian-ish system, this goes like:

# sudo su postgres
# createdb -E utf8 osm
# createlang plpgsql osm
# cat /usr/share/postgresql-8.3-postgis/lwpostgis.sql | psql -d osm
# cat /usr/share/postgresql-8.3-postgis/spatial_ref_sys.sql | psql -d osm

Now log into the created database (as postgres user):

# psql -d osm

And run these two commands:

INSERT INTO spatial_ref_sys (srid, auth_name, auth_srid, srtext, proj4text)
VALUES (900913, 'spatialreference.org', 900913,
  'PROJCS["unnamed",GEOGCS["unnamed ellipse",DATUM["unknown",
   SPHEROID["unnamed",6378137,0]],PRIMEM["Greenwich",0],
   UNIT["degree",0.0174532925199433]],PROJECTION["Mercator_2SP"],
   PARAMETER["standard_parallel_1",0],PARAMETER["central_meridian",0],
   PARAMETER["false_easting",0],PARAMETER["false_northing",0],
   UNIT["Meter",1],
   EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0
   +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs"]]',
   '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0
   +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs');

create user "www-data" with password 'www-data';

now add the 900913 projection to your epsg database (usually in /usr/share/proj/epsg):

<900913> +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs

Importing the OSM data

  • Run the importation process (as the postgres user) (this will take some time, depending on your processing power and the quantity of data you want to import):
# osm2pgsql -d osm -p osm -s  -C 1024 /path/to/australia.osm.bz2
  • Postprocess the imported data:

Optionally, edit mapserver-utils-read-only/postprocess.sql to comment out or remove the following two lines if you'd rather leave names unchanged:

-- optional, makes it easier to wrap place names
update osm_point set name = replace(name,'-',' ');

Then proceed with postprocessing:

# cat mapserver-utils-read-only/postprocess.sql | psql -d osm

Creating the Mapfile

checkout the mapfile and dependencies from http://code.google.com/p/mapserver-utils/source/checkout

this is a work in progress mapfile, that compiles a template and a style file into a full-blown MapServer mapfile. The supplied Makefile supposes that the C preprocessor is installed on your system. The fonts.lst file contains the path to the two fonts used: adapt to reference similar fonts if the ones in the file don't exist on your system.

You may need to edit the mapfile to change the EXTENT parameter to suit your own data. To find the correct extent, run this command:

# su postgres
# psql -d osm -c "SELECT extent(way) FROM osm_line"

Return should be (for France) something like:

                     extent
-------------------------------------------------
 BOX(-572406.4375 5067315,1064254.875 6637725.5)
(1 row)
# cd mapserverosm
# make

check that you now have a full mapfile, named osm.map, and that all the paths and database accesses are ok by running :

# /path/to/mapserver/shp2img -m osm.map -o osm.png

osm.png should be an image centered on sydney

Creating the OpenLayers page

copy/paste this block to a file accessible on your webserver. you will have to adapt at least the path to osm.map file, and the url of your mapserv binary. If necesary change also the maxExtent parameter with the extent found above:

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>

    <style type="text/css">
        body {
            width:100%;
            height:100%;
    border: 0px;
    margin: 0px;
    padding: 0px;
    font:sans-serif;
    font-size:small;
    }
    #map {
    width: 800px;
    height: 600px;
    border: 1px solid black;
    padding: 0px;
    margin:0px auto;
    margin-top:30px;
    position:relative;
    }
    </style>

    <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
    <script type="text/javascript">
      var lon = 16831422;
      var lat=-4012608;
    var zoom = 3;
    var map, layer;

        function init(){
            map = new OpenLayers.Map( 'map' );
        
        var wms = new OpenLayers.Layer.WMS( "WMS",

/*
change here to suit your setup
*/
                "http://myserver/cgi-bin/mapserv-trunk?",
                {map: '/path/to/osm.map', 


        layers: 'default', 
        format: 'aggpng24',
        transparent: 'off'},
                {maxExtent: new OpenLayers.Bounds(11548635,-5889094,18604187,-597430),
                scales: [5000,10000,25000,50000,100000,250000,500000,
                         1000000,2500000,5000000,10000000,25000000,50000000,100000000],
                units: 'm',
                projection:new OpenLayers.Projection("EPSG:900913"),
                gutter:0,
                ratio:1,
                wrapDateLine: true,
                isBaselayer:true,
                singleTile:true,
                transitionEffect:'resize'} );

            map.addLayers([wms]);
            if(!map.getCenter())
                map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
            map.addControl(new OpenLayers.Control.Scale('scale'));
            map.addControl(new OpenLayers.Control.Permalink('permalink'));
            map.addControl(new OpenLayers.Control.MousePosition());
        }
    </script>
  </head>

<body onload="init()">
    <div id="map">
    </div>
<div id="controls">
<span id="scale" style="float:left"></span>
<a href="#" id="permalink" style="float:right">lien direct</a>
</div>
</body>
</html>

And now?

  • you can change the color scheme by editing the osm1.style file, and rerunning make
  • feel free to edit this page to include any solutions to problems you might have had following these steps
  • for more info: thomas.bonfort at gmail dot com

Home

Note: See TracWiki for help on using the wiki.