[OSM-talk-fr] Faire son plan statique

Maurice maurice at mboucher.info
Mar 14 Déc 15:36:06 UTC 2010


Bonjour tous,

Nicolas Dumoulin <nicolas_openstreetmap.org at dumoulin63.net> écrivit :

>> > Plus de détails plus tard, mais voilà, j'ai été étonné de la facilité de
>> > mise en œuvre même si c'est pas toujours facile de trouver une doc
>> > complète.

>> Intéressant ! Tu peux nous montrer le résultat pour avoir une idée ?

Comme certains sur liste, je me suis senti frustré de ne pas pouvoir
imprimer mes cartes avec des critères choisis et votre discussion m'a
suggéré les petits fichiers ci-dessous. Je ne suis pas dev mais
seulement amateur de chez amateur.

Ici, les rues de la ville et les numéros des bâtiments pour vérifier
l'exactitude des données issues du cadastre.

Le rendu doit être lisible sur les pages a4 de ma petite imprimante n&b.

Bon, je me lance pour montrer mon travail.
http://www.cijoint.fr/cjlink.php?file=cj201012/cijeBGKCtL.pdf

J'ai appliqué la chaîne postgis, osmosis, osm2pgsql, tels que documentés
dans le wiki, sur la région Basse-Normandie que je reprends chez
Geofabrik. Par contre je suis incapable de retrouver la page qui m'a
inspiré ensuite sur le site d'un Anglais.

Un script bash (il me sert aussi pour tilecache) :

--8<---------------couper ici---------------début-------------8<---
#! /bin/bash

FIC="basse-normandie"
cd /home/momo/geographie/osm2sql

rm ${FIC}_old.osm
mv ${FIC}.osm ${FIC}_old.osm

echo "téléchargement..."
curl --silent -O "http://download.geofabrik.de/osm/europe/france/basse-normandie.osm.bz2"
bunzip2 *.osm.bz2

echo "fabrication du diff..."
/home/momo/bin/osmosis -q --read-xml file=${FIC}.osm --read-xml file=${FIC}_old.osm  --derive-change --write-xml-change file='diff.osc'

echo "mise à jour de la base osm..."
osm2pgsql -s -a -d osm diff.osc

echo "suppression du cache..."
cd /home/momo/geographie/tilecache
sudo /bin/rm -fr /home/momo/geographie/tilecache/osm

echo "fini" && mplayer -msglevel all=-1 /usr/share/sounds/KDE-Sys-App-Positive.ogg 2&> /dev/null

exit 0
--8<---------------couper ici---------------fin---------------8<---


Le script python (bien documenté !). Je crée une boucle page par page
avec un pas déterminé à partir d'un point  :

--8<---------------couper ici---------------début-------------8<---
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from math import pi,cos,sin,log,exp,atan
import mapnik
import cairo

mapfile = 'mapfile.xml'
map_output = 'mapfile.pdf'
projection = '+proj=latlong +datum=WGS84'

#---------------------------------------------------
#  Change this to the bounding box you want
originex = 0.197
originey = 48.930
deltax = 0.006
deltay = 0.006

imgx = 72 * 21 / 2.54
imgy = 72 * 29.7 / 2.54


def render_tile(bbox, titre):
    mapnik_map = mapnik.Map(int(imgx), int(imgy))
    mapnik.load_map(mapnik_map, mapfile)

    prj = mapnik.Projection("+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 +over")
    c0 = prj.forward(mapnik.Coord(bbox[0],bbox[1]))
    c1 = prj.forward(mapnik.Coord(bbox[2],bbox[3]))
    bbox = mapnik.Envelope(c0.x,c0.y,c1.x,c1.y)
    mapnik_map.zoom_to_box(bbox)

    map_output = "%s.pdf" %titre
    file = open(map_output, 'wb')
    surface = cairo.PDFSurface(file.name, mapnik_map.width, mapnik_map.height)
    ctx = cairo.Context(surface)
    mapnik.render(mapnik_map, ctx)
    
    ctx = cairo.Context(surface)
    ctx.select_font_face("Arial Black", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    ctx.set_font_size(8)
    ctx.translate(20, (72 * 11) - 10)
    ctx.show_text(titre)

    logoSf = cairo.ImageSurface.create_from_png("Osm_linkage.png")
    ctx = cairo.Context(surface)
    width = logoSf.get_width()
    ctx.translate(72 * 8 -100 , (72 * 11) - 30 ) 
    ctx.scale(0.5, 0.5)
    ctx.set_source_surface(logoSf , 0, 0)
    ctx.paint()

    ctx = cairo.Context(surface)
    ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    ctx.set_font_size(8)
    ctx.translate(8 * 72 / 2, (72 * 11) - 12)
    width = ctx.text_extents("100 m")[4]
    ctx.translate(-width / 2, 0)
    ctx.show_text("100 m")

    ctx = cairo.Context(surface)
    npixels = round(100 / mapnik_map.scale())
    ctx.set_line_width(0.5)
    ctx.move_to((8 * 72 / 2) - (npixels / 2) , 72 * 11 - 10)
    ctx.rel_line_to(0, 2)
    ctx.rel_line_to( npixels, 0)
    ctx.rel_line_to( 0, -2)
    ctx.stroke()
    
    surface.finish()


def loop(width=1, height=1, titre=""):
    ancienx = originex
    for w in range(width):
        nouveaux = ancienx + deltax
        ancieny = originey
        for h in range(height):
            nouveauy = ancieny - deltay
            bbox = ancienx, ancieny, nouveaux, nouveauy
            ancieny = nouveauy
            map_output = "%s_%s" %(titre, w + h)
            render_tile(bbox, map_output)
        ancienx = nouveaux


if __name__ == "__main__":
    loop(1,1, 'Vimoutiers')
--8<---------------couper ici---------------fin---------------8<---

le fichier xml :

--8<---------------couper ici---------------début-------------8<---
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map>
<Map bgcolor="#ffffff" srs="+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 +over">
  <!-- buildings -->
  <Style name="buildings">
    <Rule>
      <PolygonSymbolizer>
        <CssParameter name="fill">#aaa</CssParameter>
      </PolygonSymbolizer>
    </Rule>
  </Style>
  <Layer name="buildings" status="on" srs="+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 +over">
    <StyleName>buildings</StyleName>
    <Datasource>
      <Parameter name="type">postgis</Parameter>
      <Parameter name="user">momo</Parameter>
      <Parameter name="dbname">osm</Parameter>
      <Parameter name="table">
        (select way,building from planet_osm_polygon 
        where building is not null 
        order by z_order,way_area desc) as buildings
      </Parameter>
      <Parameter name="estimate_extent">false</Parameter>
      <Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>
    </Datasource>
  </Layer>
  <!-- water-areas -->
  <Style name="water_areas">
    <Rule>
      <PolygonSymbolizer>
        <CssParameter name="fill">#bbb</CssParameter>
      </PolygonSymbolizer>
    </Rule>
  </Style>
  <Layer name="water_areas" status="on" srs="+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 +over">
    <StyleName>water_areas</StyleName>
    <Datasource>
      <Parameter name="type">postgis</Parameter>
      <Parameter name="user">momo</Parameter>
      <Parameter name="dbname">osm</Parameter>
      <Parameter name="estimate_extent">false</Parameter>
      <Parameter name="table">(select way, waterway from planet_osm_polygon where waterway='riverbank') as water_areas
      </Parameter>
      <Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>
    </Datasource>
  </Layer>
  <!-- water-lines -->
  <Style name="water_lines">
    <Rule>
      <Filter>[waterway]='river'</Filter>
      <LineSymbolizer>
        <CssParameter name="stroke">#ddd</CssParameter>
        <CssParameter name="stroke-width">2</CssParameter>
        <CssParameter name="stroke-linejoin">round</CssParameter>
        <CssParameter name="stroke-linecap">round</CssParameter>
      </LineSymbolizer>
      <TextSymbolizer name="name" face_name="DejaVu Sans Book" size="8" fill="#666" halo_radius="1" placement="line"/>
    </Rule>
  </Style>
  <Layer name="water_lines" status="on" srs="+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 +over">
    <StyleName>water_lines</StyleName>
    <StyleName>dam</StyleName>
    <Datasource>
      <Parameter name="type">postgis</Parameter>
      <Parameter name="user">momo</Parameter>
      <Parameter name="dbname">osm</Parameter>
      <Parameter name="estimate_extent">false</Parameter>
      <Parameter name="table">(select way, waterway, name from planet_osm_line where waterway IS NOT NULL order by z_order) as water_lines
      </Parameter>
      <Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>
    </Datasource>
  </Layer>
  <!-- roads -->
  <Style name="roads">
    <Rule>
      <Filter>
        [highway]='primary' or [highway]='secondary' or [highway]='tertiary'
      </Filter>
      <LineSymbolizer>
        <CssParameter name="stroke">#888</CssParameter>
        <CssParameter name="stroke-width">4</CssParameter>
      </LineSymbolizer>
      <LineSymbolizer>
        <CssParameter name="stroke">#eee</CssParameter>
        <CssParameter name="stroke-width">1</CssParameter>
      </LineSymbolizer>
    </Rule>
    <Rule>
      <Filter>
        [highway]='residential' or [highway]='unclassified' or [highway]='service'
      </Filter>
      <LineSymbolizer>
        <CssParameter name="stroke">#888</CssParameter>
        <CssParameter name="stroke-width">2</CssParameter>
      </LineSymbolizer>
    </Rule>
    <Rule>
      <ElseFilter/>
      <LineSymbolizer>
        <CssParameter name="stroke">#888</CssParameter>
        <CssParameter name="stroke-width">2</CssParameter>
        <CssParameter name="stroke-dasharray">2,2</CssParameter>
      </LineSymbolizer>
    </Rule>
  </Style>
  <Layer name="roads" status="on" srs="+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 +over">
    <StyleName>roads</StyleName>
    <Datasource>
      <Parameter name="type">postgis</Parameter>
      <Parameter name="user">momo</Parameter>
      <Parameter name="dbname">osm</Parameter>
      <Parameter name="table">
        (select way, highway from planet_osm_line where highway in ('primary', 'secondary', 'tertiary', 'unclassified', 'residential', 'service', 'track', 'path', 'cycleway', 'footway')
        order by z_order, way_area desc) as roads
      </Parameter>
      <Parameter name="estimate_extent">false</Parameter>
      <Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>
    </Datasource>
  </Layer>
  <!-- nom des rues -->
  <Style name="text">
    <Rule>
      <TextSymbolizer name="name" face_name="DejaVu Sans Book" size="7" fill="#333" halo_radius="1" halo_fill="#eee" placement="line"/>
    </Rule>
  </Style>
  <Layer name="text" status="on" srs="+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 +over">
    <StyleName>text</StyleName>
    <Datasource>
      <Parameter name="type">postgis</Parameter>
      <Parameter name="user">momo</Parameter>
      <Parameter name="dbname">osm</Parameter>
      <Parameter name="table">
        (select way, highway, name from planet_osm_line
        where highway in
        ('primary',  'secondary', 'tertiary','residential','unclassified','pedestrian','service','footway','track', 'path', 'alley')
        order by z_order, way_area desc) as text
      </Parameter>
      <Parameter name="estimate_extent">false</Parameter>
      <Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>
    </Datasource>
  </Layer>
  <!-- numéros -->
  <Style name="node_numbers">
    <Rule>
      <TextSymbolizer name="addr:housenumber" face_name="DejaVu Sans Book" size="5" fill="#000" placement="point"/>
    </Rule>
  </Style>
  <Layer name="housenumb_nodes" status="on" srs="+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 +over">
    <StyleName>node_numbers</StyleName>
    <Datasource>
      <Parameter name="type">postgis</Parameter>
      <Parameter name="user">momo</Parameter>
      <Parameter name="dbname">osm</Parameter>
      <Parameter name="table">(select way,"addr:housenumber" from planet_osm_point where "addr:housenumber" is not null) as node_numbers
      </Parameter>
      <Parameter name="estimate_extent">false</Parameter>
      <Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>
    </Datasource>
  </Layer>
</Map>
--8<---------------couper ici---------------fin---------------8<---

*Pas résolu*

Je suis persuadé que l'échelle du rendu est fausse parce que je ne
maîtrise pas les bonnes projections. Une idée ?

Maurice





Plus d'informations sur la liste de diffusion Talk-fr