OpenStreetMap, come molti sanno, è un servizio online che realizza una mappa libera e gratuita di ogni parte del mondo, grazie a numerosissimi volontari che armati di gps e pazienza registrano informazioni geografiche e le inseriscono nel sistema. Uno dei servizi offerti da openstreetmap è la possibilità di scaricare, in modo facile, singole porzioni di mappa da utilizzare nei propri progetti.
Per scaricare un “quadratino” di mappa, vale a dire un PNG di 256×256 pixel, a partire da una coordinata GPS (latitudine e longitudine) e da un valore di zoom (da 1 a 18, 18 è molto dettagliato e 1 è molto ampio), bisogna per prima cosa calcolare le coordinate XY del quadratino stesso all’interno dei server di openstreetmap. Questo è il codice che uso normalmente, è in python ma può essere facilmente portato in qualunque altro linguaggio:
def deg2num(lat_deg, lon_deg, zoom):
lat_rad = math.radians(lat_deg)
n = 2.0 ** zoom
xtile = int((lon_deg + 180.0) / 360.0 * n)
ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
return (xtile, ytile)
A questo punto si scarica il quadratino stesso dall’URL:
http://tile.openstreetmap.org/[ZOOM]/[X]/[Y].png
Ad esempio, per vedere la facoltà di ingegneria di brescia [45.5648 N, 10.2318 E], con uno zoom abbastanza alto (16), calcoliamo le coordinate XY=(34630, 23428) e scarichiamo l’URL:
http://tile.openstreetmap.org/16/34630/23428.png
Ed ecco il risultato:
A questo punto, se vogliamo fare le cose in grande, possiamo costruire uno script python che scarica la mappa e la salva su un file:
import sys, math, os, urllib
import PIL, cStringIO
from PIL import ImageDraw
from PIL import Image as PILImage
def deg2num(lat_deg, lon_deg, zoom):
lat_rad = math.radians(lat_deg)
n = 2.0 ** zoom
xtile = int((lon_deg + 180.0) / 360.0 * n)
ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
return (xtile, ytile)
def gpsUrl(lat, lon, zoom, xshift=0, yshift=0):
(x, y) = deg2num(lat, lon, zoom)
imUrl = "http://tile.openstreetmap.org/%s/%s/%s.png"%(zoom, x+xshift, y+yshift)
return imUrl
def getImage(url):
file = urllib.urlopen(url)
imRead = cStringIO.StringIO(file.read())
return PIL.Image.open(imRead)
lat = 45.5648
lon = 10.2318
zoom = 16
mappa = getImage(gpsUrl(lat, lon, zoom,0,0))
mappa.save("file.png")
Il programma di cui sopra richiede l’installazione della libreria python PIL. Ulteriori informazioni per l’installazione e il download sono disponibili qui.