module HSlippyMap ( Tile, tlat, tlong, tx, ty, tz, tilesFromBBox, tileFromLatLong, tileFromXY ) where type Lat = Float type Long = Float type X = Integer type Y = Integer type ZLevel = Integer data Tile = Tile { tlat :: Lat, tlong :: Long, tx :: X, ty :: Y, tz :: ZLevel } instance Show Tile where show (Tile lat long x y z) = "http://tile.openstreetmap.org/" ++ show z ++ "/" ++ show x ++ "/" ++ show y ++ ".png" -- if not same z-level == Nothing tilesFromBBox :: Tile -> Tile -> Maybe [Tile] tilesFromBBox min max | (tz min) == (tz max) = Just $ concat $ map (\(x,y) -> map (\y'-> Tile (tlat min) (tlong min) x y' z) y) [(x,[(minimum [tymin, tymax])..(maximum [tymin,tymax])]) | x <- [(minimum [txmin, txmax])..(maximum [txmin, txmax])]] | otherwise = Nothing where txmax = tx max txmin = tx min tymax = ty max tymin = ty min z = tz min tileFromLatLong :: Lat -> Long -> ZLevel -> Tile tileFromLatLong lat lon z = Tile lat lon x y z where x = long2tilex lon z y = lat2tiley lat z tileFromXY :: X -> Y -> ZLevel -> Tile tileFromXY x y z = Tile lat lon x y z where lat = tilex2long x z lon = tiley2lat y z long2tilex lon z = floor((lon + 180) / 360 * (2** fromInteger z::Long)) lat2tiley lat z = floor((1.0 - log( tan(lat * pi/180.0) + 1.0 / cos(lat * pi/180.0)) / pi) / 2.0 * (2 ** fromInteger z::Long)) tilex2long x z = (fromInteger x::Long) / (2.0 ** fromInteger z::Long) * 360.0 - 180 tiley2lat y z = 180.0 / pi * atan(0.5 * (exp n - exp(-n))) where n = pi - 2.0 * pi * (fromInteger y::Long) / (2.0 ** fromInteger z::Long)