| 16 | |
| 17 | * http://weait.com/content/build-your-own-openstreetmap-server |
| 18 | * http://weait.com/content/make-your-first-map |
| 19 | * http://dbsgeo.com/foss4g2010/pdf/osm-rendering-foss4g2010.pdf |
| 20 | |
| 21 | !OpenStreetMap data can be stored in a PostGIS database & rendered using Mapnik. |
| 22 | |
| 23 | To support !Key/Value pairs: |
| 24 | {{{ |
| 25 | apt-get install postgresql-contrib-8.4 |
| 26 | su postgres |
| 27 | psql -d gis -f /usr/share/postgresql/8.4/contrib/hstore.sql |
| 28 | }}} |
| 29 | |
| 30 | To support Planet diff files: |
| 31 | {{{ |
| 32 | su postgres |
| 33 | psql gis < /usr/share/postgresql/8.4/contrib/_int.sql |
| 34 | }}} |
| 35 | |
| 36 | === Osm2pgsql === |
| 37 | * http://wiki.openstreetmap.org/wiki/Osm2pgsql |
| 38 | |
| 39 | It is recommended to use the latest version from source rather than an out of date package: |
| 40 | {{{ |
| 41 | apt-get install build-essential libxml2-dev libgeos-dev libpq-dev libbz2-dev proj autoconf subversion libtool |
| 42 | svn export http://svn.openstreetmap.org/applications/utils/export/osm2pgsql/ |
| 43 | Optional (patch updated from original here): http://www.mail-archive.com/dev@openstreetmap.org/msg12768.html |
| 44 | #wget http://eden.sahanafoundation.org/raw-attachment/wiki/InstallationGuidelinesGISDataLinux/osm2pgsql_centroid.patch |
| 45 | cd osm2pgsql |
| 46 | #patch -p0 < ../osm2pgsql_centroid.patch |
| 47 | ./autogen.sh |
| 48 | ./configure |
| 49 | sed -i 's/-g -O2/-O2 -march=native -fomit-frame-pointer/' Makefile |
| 50 | make |
| 51 | make install |
| 52 | # Fix needed for SVN version 0.70.5 |
| 53 | cp default.style /usr/local/share |
| 54 | }}} |
| 55 | |
| 56 | === Mapnik === |
| 57 | * http://wiki.openstreetmap.org/wiki/Mapnik |
| 58 | * http://mike.teczno.com/notes/mapnik.html (Advanced Tips) |
| 59 | |
| 60 | 0.7.1 is packaged for Squeeze: |
| 61 | {{{ |
| 62 | apt-get install python-mapnik unzip |
| 63 | }}} |
| 64 | |
| 65 | Download the !OpenStreetMap extensions for Mapnik: |
| 66 | {{{ |
| 67 | cd |
| 68 | svn export http://svn.openstreetmap.org/applications/rendering/mapnik |
| 69 | }}} |
| 70 | |
| 71 | Download/decompress Coastlines: |
| 72 | {{{ |
| 73 | cd |
| 74 | wget http://tile.openstreetmap.org/world_boundaries-spherical.tgz |
| 75 | wget http://tile.openstreetmap.org/processed_p.tar.bz2 |
| 76 | wget http://tile.openstreetmap.org/shoreline_300.tar.bz2 |
| 77 | wget http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/10m-populated-places.zip |
| 78 | wget http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/cultural/110m-admin-0-boundary-lines.zip |
| 79 | cd ~/mapnik |
| 80 | tar zxvf ~/world_boundaries-spherical.tgz |
| 81 | tar jxvf ~/processed_p.tar.bz2 -C world_boundaries |
| 82 | tar jxvf ~/shoreline_300.tar.bz2 -C world_boundaries |
| 83 | unzip ~/10m-populated-places.zip -d world_boundaries |
| 84 | unzip ~/110m-admin-0-boundary-lines.zip -d world_boundaries |
| 85 | }}} |
| 86 | |
| 87 | Disable autovacuum: |
| 88 | {{{ |
| 89 | vim /etc/postgresql/8.4/main/postgresql.conf |
| 90 | #autovacuum = on |
| 91 | /etc/init.d/postgresql restart |
| 92 | }}} |
| 93 | |
| 94 | Download/Import area of interest, e.g.: |
| 95 | {{{ |
| 96 | #wget http://downloads.cloudmade.com/north_america/haiti/haiti.osm.bz2 |
| 97 | #su postgres |
| 98 | #osm2pgsql -s -d gis haiti.osm.bz2 |
| 99 | wget http://labs.geofabrik.de/haiti/2010-11-24-14-43.osm.bz2 |
| 100 | su postgres |
| 101 | osm2pgsql -s -d gis 2010-11-24-14-43.osm.bz2 |
| 102 | }}} |
| 103 | |
| 104 | Re-enable autovacuum: |
| 105 | {{{ |
| 106 | vim /etc/postgresql/8.4/main/postgresql.conf |
| 107 | autovacuum = on |
| 108 | /etc/init.d/postgresql restart |
| 109 | }}} |
| 110 | |
| 111 | Setup XML file: |
| 112 | {{{ |
| 113 | cd ~/mapnik |
| 114 | ./generate_xml.py --accept-none --dbname gis --symbols ./symbols/ --world_boundaries ./world_boundaries/ |
| 115 | }}} |
| 116 | |
| 117 | Render tiles: |
| 118 | {{{ |
| 119 | cd ~/mapnik |
| 120 | vim generate_tiles.py |
| 121 | render_tiles(bbox, mapfile, tile_dir, 0, 8, "World") |
| 122 | #minZoom = 10 |
| 123 | #maxZoom = 16 |
| 124 | #bbox = (-2, 50.0,1.0,52.0) |
| 125 | #render_tiles(bbox, mapfile, tile_dir, minZoom, maxZoom) |
| 126 | # Haiti |
| 127 | bbox = (-74.668, 17.884, -71.659, 20.232) |
| 128 | render_tiles(bbox, mapfile, tile_dir, 9, 17, "Haiti") |
| 129 | # Muenchen |
| 130 | # comment all under here |
| 131 | |
| 132 | mkdir /var/www/tiles |
| 133 | chown postgres /var/www/tiles |
| 134 | ln -s /var/www/tiles |
| 135 | su postgres |
| 136 | MAPNIK_MAP_FILE="osm.xml" MAPNIK_TILE_DIR="tiles/" ./generate_tiles.py |
| 137 | }}} |
| 138 | === Contours === |
| 139 | * http://wiki.openstreetmap.org/wiki/Contours#The_PostGIS_approach |
| 140 | |
| 141 | {{{ |
| 142 | apt-get install gdal-bin |
| 143 | }}} |
| 144 | |
| 145 | [http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/ SRTM3] data: |
| 146 | {{{ |
| 147 | mkdir ~/mapnik/srtm |
| 148 | cd ~/mapnik/srtm |
| 149 | wget http://mapnik-utils.googlecode.com/svn@170/sandbox/testing/hillshading/srtm_generate_hdr.sh |
| 150 | chmod +x srtm_generate_hdr.sh |
| 151 | cp srtm_generate_hdr.sh /usr/local/bin |
| 152 | vim process_srtm3.sh |
| 153 | #!/bin/bash |
| 154 | PREP_TABLE="1" |
| 155 | for X in *.hgt.zip; do |
| 156 | yes | srtm_generate_hdr.sh $X |
| 157 | rm -f "${X%%.zip}" |
| 158 | |
| 159 | # Import 10m contours |
| 160 | rm -f "${X%%.hgt.zip}.shp" "${X%%.hgt.zip}.shx" "${X%%.hgt.zip}.dbf" |
| 161 | gdal_contour -i 10 -snodata 32767 -a height "${X%%.hgt.zip}.tif" "${X%%.hgt.zip}.shp" |
| 162 | [ "$PREP_TABLE" ] && shp2pgsql -p -I -g way "${X%%.hgt.zip}" contours | psql -q gis |
| 163 | shp2pgsql -a -g way "${X%%.hgt.zip}" contours | psql -q gis |
| 164 | |
| 165 | rm -f "${X%%.hgt.zip}.shp" "${X%%.hgt.zip}.shx" "${X%%.hgt.zip}.dbf" |
| 166 | rm -f "${X%%.hgt.zip}.bil" |
| 167 | rm -f "${X%%.hgt.zip}.hdr" |
| 168 | rm -f "${X%%.hgt.zip}.prj" |
| 169 | rm -f "${X%%.hgt.zip}.tif" |
| 170 | unset PREP_TABLE |
| 171 | done |
| 172 | |
| 173 | # Haiti |
| 174 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N17W072.hgt.zip |
| 175 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N18W072.hgt.zip |
| 176 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N18W073.hgt.zip |
| 177 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N18W074.hgt.zip |
| 178 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N18W075.hgt.zip |
| 179 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N19W072.hgt.zip |
| 180 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N19W073.hgt.zip |
| 181 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N19W074.hgt.zip |
| 182 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N19W075.hgt.zip |
| 183 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N20W073.hgt.zip |
| 184 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N20W074.hgt.zip |
| 185 | wget http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/North_America/N20W075.hgt.zip |
| 186 | |
| 187 | chown postgres . |
| 188 | su postgres |
| 189 | sh process_srtm3.sh |
| 190 | }}} |
| 191 | |
| 192 | Since we are non-commercial, we should be able to use the SRTM4.1 data from [http://srtm.csi.cgiar.org CGIAR], however the Shapefile production crashed when it reached 2Gb.[[BR]] |
| 193 | Example for Haiti: |
| 194 | {{{ |
| 195 | cd ~/mapnik/srtm |
| 196 | wget http://srtm.csi.cgiar.org/SRT-ZIP/SRTM_V41/SRTM_Data_GeoTiff/srtm_22_09.zip |
| 197 | unzip srtm_22_09.zip |
| 198 | gdal_contour -i 10 -snodata 32767 -a height "srtm_22_09.tif" "srtm_22_09.shp" |
| 199 | su postgres |
| 200 | shp2pgsql -p -I -g way "srtm_22_09" contours | psql -q gis |
| 201 | shp2pgsql -a -g way "srtm_22_09" contours | psql -q gis |
| 202 | }}} |
| 203 | |
| 204 | Configure Mapnik: |
| 205 | {{{ |
| 206 | vim ~/mapnik/osm.xml |
| 207 | # Under line &layer-shapefiles; |
| 208 | &layer-contours; |
| 209 | vim ~/mapnik/inc/layer-contours.xml.inc |
| 210 | <Style name="contours10"> |
| 211 | <Rule> |
| 212 | &maxscale_zoom14; |
| 213 | &minscale_zoom17; |
| 214 | <LineSymbolizer> |
| 215 | <CssParameter name="stroke">#9cb197</CssParameter> |
| 216 | <CssParameter name="stroke-width">0.5</CssParameter> |
| 217 | </LineSymbolizer> |
| 218 | </Rule> |
| 219 | </Style> |
| 220 | <Style name="contours50"> |
| 221 | <Rule> |
| 222 | &maxscale_zoom14; |
| 223 | &minscale_zoom17; |
| 224 | <LineSymbolizer> |
| 225 | <CssParameter name="stroke">#9cb197</CssParameter> |
| 226 | <CssParameter name="stroke-width">0.6</CssParameter> |
| 227 | </LineSymbolizer> |
| 228 | </Rule> |
| 229 | <Rule> |
| 230 | &maxscale_zoom12; |
| 231 | &minscale_zoom13; |
| 232 | <LineSymbolizer> |
| 233 | <CssParameter name="stroke">#747b90</CssParameter> |
| 234 | <CssParameter name="stroke-width">0.6</CssParameter> |
| 235 | </LineSymbolizer> |
| 236 | </Rule> |
| 237 | </Style> |
| 238 | <Style name="contours100"> |
| 239 | <Rule> |
| 240 | &maxscale_zoom14; |
| 241 | &minscale_zoom17; |
| 242 | <LineSymbolizer> |
| 243 | <CssParameter name="stroke">#9cb197</CssParameter> |
| 244 | <CssParameter name="stroke-width">0.7</CssParameter> |
| 245 | </LineSymbolizer> |
| 246 | </Rule> |
| 247 | <Rule> |
| 248 | &maxscale_zoom12; |
| 249 | &minscale_zoom13; |
| 250 | <LineSymbolizer> |
| 251 | <CssParameter name="stroke">#747b90</CssParameter> |
| 252 | <CssParameter name="stroke-width">0.7</CssParameter> |
| 253 | </LineSymbolizer> |
| 254 | </Rule> |
| 255 | <Rule> |
| 256 | &maxscale_zoom10; |
| 257 | &minscale_zoom11; |
| 258 | <LineSymbolizer> |
| 259 | <CssParameter name="stroke">#855d62</CssParameter> |
| 260 | <CssParameter name="stroke-width">0.7</CssParameter> |
| 261 | </LineSymbolizer> |
| 262 | </Rule> |
| 263 | </Style> |
| 264 | <Style name="contours-text50"> |
| 265 | <Rule> |
| 266 | &maxscale_zoom14; |
| 267 | &minscale_zoom17; |
| 268 | <TextSymbolizer name="height" face_name="DejaVu Sans Book" size="8" fill="#747b90" halo_radius="1" placement="line" /> |
| 269 | </Rule> |
| 270 | </Style> |
| 271 | <Style name="contours-text100"> |
| 272 | <Rule> |
| 273 | &maxscale_zoom14; |
| 274 | &minscale_zoom17; |
| 275 | <TextSymbolizer name="height" face_name="DejaVu Sans Book" size="8" fill="#747b90" halo_radius="1" placement="line" /> |
| 276 | </Rule> |
| 277 | <Rule> |
| 278 | &maxscale_zoom12; |
| 279 | &minscale_zoom13; |
| 280 | <TextSymbolizer name="height" face_name="DejaVu Sans Book" size="8" fill="#855d62" halo_radius="1" placement="line" /> |
| 281 | </Rule> |
| 282 | </Style> |
| 283 | <Layer name="srtm_10" status="on" srs="+proj=latlong +datum=WGS84"> |
| 284 | <StyleName>contours10</StyleName> |
| 285 | <StyleName>contours-text10</StyleName> |
| 286 | <Datasource> |
| 287 | <Parameter name="table">(select way,height from contours WHERE height::integer % 10 = 0 AND height::integer % 50 != 0 AND height::integer % 100 != 0) as "contours-10"</Parameter> |
| 288 | &datasource-settings; |
| 289 | </Datasource> |
| 290 | </Layer> |
| 291 | <Layer name="srtm_50" status="on" srs="+proj=latlong +datum=WGS84"> |
| 292 | <StyleName>contours50</StyleName> |
| 293 | <StyleName>contours-text50</StyleName> |
| 294 | <Datasource> |
| 295 | <Parameter name="table">(select way,height from contours WHERE height::integer % 50 = 0 AND height::integer % 100 != 0) as "contours-50"</Parameter> |
| 296 | &datasource-settings; |
| 297 | </Datasource> |
| 298 | </Layer> |
| 299 | <Layer name="srtm_100" status="on" srs="+proj=latlong +datum=WGS84"> |
| 300 | <StyleName>contours100</StyleName> |
| 301 | <StyleName>contours-text100</StyleName> |
| 302 | <Datasource> |
| 303 | <Parameter name="table">(select way,height from contours WHERE height::integer % 100 = 0) as "contours-100"</Parameter> |
| 304 | &datasource-settings; |
| 305 | </Datasource> |
| 306 | </Layer> |
| 307 | }}} |
| 308 | |
| 309 | ==== Hillshading ==== |
| 310 | * http://wiki.openstreetmap.org/wiki/HikingBikingMaps#Hill_Shading |
| 311 | |
| 312 | === Serve Tiles === |
| 313 | Tiles can simply be served by Apache: |
| 314 | {{{ |
| 315 | vim /etc/apache2/sites-available/mysite |
| 316 | <VirtualHost *:80> |
| 317 | ServerName mysite.org |
| 318 | Alias /tiles /var/www/tiles |
| 319 | <LocationMatch "/tiles/"> |
| 320 | Order Allow,Deny |
| 321 | Allow from all |
| 322 | </LocationMatch> |
| 323 | </VirtualHost> |
| 324 | apache2ctl restart |
| 325 | }}} |
| 326 | |
| 327 | === WMS === |
| 328 | In order to serve the OSM data via WMS then can use mod_mapnik_wms: |
| 329 | * http://wiki.openstreetmap.org/wiki/Mod_mapnik_wms |
| 330 | {{{ |
| 331 | gpg --gen-key |
| 332 | apt-get install pbuilder debsigs apache2-prefork-dev libmapnik-dev libgd2-xpm-dev |
| 333 | svn export http://svn.openstreetmap.org/applications/utils/mod_mapnik_wms |
| 334 | cd mod_mapnik_wms |
| 335 | sh autogen.sh |
| 336 | vim debian/mapnik_wms.load |
| 337 | LoadFile /usr/lib/libmapnik.so.0.7 |
| 338 | |
| 339 | debuild |
| 340 | }}} |
| 341 | |
| 342 | This data can then be converted by !GeoServer into a KML !SuperOverlay to display in Google Earth: |
| 343 | * http://geoserver.org/display/GEOS/GSIP+47+-+WMS+cascading |
| 344 | * http://docs.geoserver.org/stable/en/user/googleearth/tutorials/superoverlaysgwc.html |
| 345 | |
| 346 | === Rails Port === |
| 347 | This is needed to allow editing of the data using Potlatch, JOSM, etc |
| 348 | * http://wiki.openstreetmap.org/wiki/The_Rails_Port |
| 349 | |
| 350 | {{{ |
| 351 | apt-get install imagemagick libmagick9-dev |
| 352 | apt-get install ruby ruby1.8-dev libxml2-dev libxml-ruby1.8 libxml-parser-ruby1.8 rubygems librmagick-ruby |
| 353 | gem install -v=2.3.8 rails |
| 354 | #gem install libxml-ruby |
| 355 | #gem install composite_primary_keys |
| 356 | #gem install rmagick |
| 357 | gem install timecop |
| 358 | gem install pg |
| 359 | gem install oauth |
| 360 | |
| 361 | #svn co http://railsexpress.de/svn/plugins/sql_session_store/trunk sql_session_store |
| 362 | |
| 363 | apt-get install postgresql-contrib libpq-dev |
| 364 | su postgres |
| 365 | createuser openstreetmap -s -P |
| 366 | createdb -E UTF8 -O openstreetmap openstreetmap |
| 367 | createdb -E UTF8 -O openstreetmap osm_test |
| 368 | createdb -E UTF8 -O openstreetmap osm |
| 369 | psql -d openstreetmap < /usr/share/postgresql/8.4/contrib/btree_gist.sql |
| 370 | |
| 371 | apt-get install git |
| 372 | cd /home |
| 373 | git clone git://git.openstreetmap.org/rails.git |
| 374 | cd rails |
| 375 | cp config/postgres.example.database.yml config/database.yml |
| 376 | vim config/database.yml |
| 377 | |
| 378 | rake gems:install |
| 379 | rake db:migrate |
| 380 | env RAILS_ENV=production rake db:migrate |
| 381 | rake test |
| 382 | |
| 383 | osmosis --read-xml-0.6 file="planet.osm.bz2" --write-apidb-0.6 populateCurrentTables=yes host="localhost" database="openstreetmap" user="openstreetmap" password="openstreetmap" validateSchemaVersion=no |
| 384 | |
| 385 | select setval('acls_id_seq', (select max(id) from acls)); |
| 386 | select setval('changesets_id_seq', (select max(id) from changesets)); |
| 387 | select setval('countries_id_seq', (select max(id) from countries)); |
| 388 | select setval('current_nodes_id_seq', (select max(id) from current_nodes)); |
| 389 | select setval('current_relations_id_seq', (select max(id) from current_relations)); |
| 390 | select setval('current_ways_id_seq', (select max(id) from current_ways)); |
| 391 | select setval('diary_comments_id_seq', (select max(id) from diary_comments)); |
| 392 | select setval('diary_entries_id_seq', (select max(id) from diary_entries)); |
| 393 | select setval('friends_id_seq', (select max(id) from friends)); |
| 394 | select setval('gpx_file_tags_id_seq', (select max(id) from gpx_file_tags)); |
| 395 | select setval('gpx_files_id_seq', (select max(id) from gpx_files)); |
| 396 | select setval('messages_id_seq', (select max(id) from messages)); |
| 397 | select setval('sessions_id_seq', (select max(id) from sessions)); |
| 398 | select setval('user_tokens_id_seq', (select max(id) from user_tokens)); |
| 399 | select setval('users_id_seq', (select max(id) from users)); |
| 400 | |
| 401 | cd /home/rails |
| 402 | ruby script/server |
| 403 | |
| 404 | cd db/functions |
| 405 | make libpgosm.so |
| 406 | |
| 407 | * Log into PgSQL and execute the CREATE FUNCTION statement from maptile.c's comment: |
| 408 | |
| 409 | CREATE FUNCTION maptile_for_point(int8, int8, int4) RETURNS int4 |
| 410 | AS '/path/to/rails-port/db/functions/libpgosm', 'maptile_for_point' |
| 411 | LANGUAGE C STRICT; |
| 412 | |
| 413 | CREATE FUNCTION tile_for_point(int4, int4) RETURNS int8 |
| 414 | AS '/path/to/rails-port/db/functions/libpgosm', 'tile_for_point' |
| 415 | LANGUAGE C STRICT; |
| 416 | |
| 417 | }}} |
| 418 | |