[OSM-talk-fr] Calculer l'échelle ( Était : Un rendu statique pour ma commune)

Maurice maurice at mboucher.info
Dim 6 Fév 19:20:20 UTC 2011


Salut Nicolas,

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

> Après vérification, il y a bien une erreur. Elle ne semble pas linéaire, donc 
> je ne peux pas juste tricher avec un facteur mesuré au doigt mouillé.
> Quelqu'un sait comment on peut faire exactement ?
> Sinon, je vais aller discuter de ça sur la liste mapnik.
> Merci Maurice pour ta sagacité.
>
> Bonne soirée

Je fais part de mes dernières réflexions :

Trois notions doivent être prises en compte pour dessiner une échelle,

1) la valeur de chaque pixel : 
- map.scale() qui donne le nombre de mètres par pixel;
- map.scale_denominator() qui donne l'échelle = 1/map.scale_denominator()

2) la résolution de l'impression 
par exemple si tu veux 300 PPI à l'impression (ne pas oublier de régler
l'imprimante) pour une page aA, tu donnes (à l'entier le plus proche) 
largeur = 8 * 300 * 2.54 pixels 
longueur = 11 * 300 * 2.54 pixels comme taille de l'image

(tu avais choisi 72 ppi/inch, ce qui correspond à la résolution pdf)

3) la projection google (epsg:3785) qui est celle d'osm par défaut dans
   Postgis correspond aux distances à l'Équateur, quand on monte en
   latitude, elles sont exagérées.
   Donc le map.scale() ci-dessus correspond à un distance à *l'Équateur*

   Il faut recalculer le map_scale dans la projection qui va bien, pour
   toi 3946 avec les valeurs de ta « bounding box »

def scale_lat(bbox):    
    prj = mapnik.Projection('+init=epsg:3946')
    c0 = prj.forward(mapnik.Coord(bbox[0], bbox[1]))
    c1 = prj.forward(mapnik.Coord(bbox[2], bbox[3]))
    lat5_map = mapnik.Map(int(imgx), int(imgy), "+init=epsg:3946")
    env = mapnik.Envelope(c0.x, c0.y, c1.x, c1.y)
    lat5_map.zoom_to_box(env)
    return lat5_map.scale()

cette valeur est la taille du pixel devant être utilisée pour le calcul
de l'échelle.

dans cairo, pour une échelle de 100 m, on obtient le nombre de pixels :
npixels = round(100 / scale_lat5(bbox))

Je n'ai pas encore fait, mais il semble plus commun de faire le calcul
inverse cad une échelle lisible (1/2500 = 1/map.scale_denominator()) et
recalculer la taille de la bounding box.

Après, il y a plein de trucs vicieux pour la finesse des détails en
fonction du map.scale_denominator(), dans le fichier xml on les rapporte
<MinScaleDenominator>25000</MinScaleDenominator>
<MaxScaleDenominator>400000</MaxScaleDenominator>
C'est ainsi que le site d'osm gère les zooms et la taille des symboles.

Mes sources (et j'ai gogolé comme un malade pour échapper à Windows):
http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
http://trac.mapnik.org/wiki/ScaleAndPpi
http://www.britishideas.com/2009/09/22/map-scales-and-printing-with-mapnik/

J'espère avoir été assez clair, et ne pas avoir écrit trop de conneries !

Tu me rapporteras tes conclusions stp, 

Maurice (alias momovimout).




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