Skip to content

Commit

Permalink
implemented quadkey, tests don't pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Buck Heroux authored and Buck Heroux committed Mar 6, 2014
1 parent e136237 commit a96ad8d
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 11 deletions.
Empty file modified clean
100644 → 100755
Empty file.
Binary file added quadkey/.__init__.py.swp
Binary file not shown.
19 changes: 11 additions & 8 deletions quadkey/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

class QuadKey:

def __init__(self, lat, lon, level):
def __init__(self, geo, level):
# assert lat, lon and level are valid
self.key = QuadKey.get_quadkey(lat, lon, level)
self.lat = lat
self.lon = lon
self.key = QuadKey.get_quadkey(geo, level)
self.geo = geo
self.level = level

def __str__(self):
Expand All @@ -19,12 +18,16 @@ def __repr__(self):
@classmethod
def from_str(cls, key):
level = len(key)
lat, lon = QuadKey.get_coordinates(key)
return cls(lat, lon, level)
geo = QuadKey.get_coordinates(key)
return cls(geo, level)

@staticmethod
def get_quadkey(lat, lon, level):
pass
def get_quadkey(geo, level):
pixel = TileSystem.geo_to_pixel(geo, level)
tile = TileSystem.pixel_to_tile(pixel)
quadkey = TileSystem.tile_to_quadkey(tile, level)
print geo, pixel, tile, quadkey
return quadkey

@staticmethod
def get_coordinates(key):
Expand Down
65 changes: 63 additions & 2 deletions quadkey/tile_system.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from util import precondition
from math import cos, pi
from math import sin, cos, atan, exp, log, pi

def valid_level(level):
LEVEL_RANGE = (1,23)
Expand All @@ -9,7 +9,6 @@ class TileSystem:
"""
Class with static method to build quadkeys from lat, lon, levels
see http://msdn.microsoft.com/en-us/library/bb259689.aspx
"""

EARTH_RADIUS = 6378137
Expand Down Expand Up @@ -41,3 +40,65 @@ def map_scale(lat, level, dpi):
"""Gets the scale of the map expressed as ratio 1 : N. Returns N"""
return TileSystem.ground_resolution(lat, level) * dpi / 0.0254

@staticmethod
@precondition(lambda geo, lvl: valid_level(lvl))
def geo_to_pixel(geo, level):
"""Transform from geo coordinates to pixel coordinates"""
lat, lon = geo
lat = TileSystem.clip(lat, TileSystem.LATITUDE_RANGE)
lon = TileSystem.clip(lon, TileSystem.LONGITUDE_RANGE)
x = (lon + 180) / 360
sin_lat = sin(lat * pi / 180)
y = 0.5 - log((1 + sin_lat) / (1 - sin_lat) / (4 * pi))
# might need to cast to uint
map_size = TileSystem.map_size(level)
pixel_x = int(TileSystem.clip(x * map_size + 0.5, (0, map_size - 1)))
pixel_y = int(TileSystem.clip(y * map_size + 0.5, (0, map_size - 1)))
return pixel_x, pixel_y

@staticmethod
@precondition(lambda pix, lvl: valid_level(lvl))
def pixel_to_geo(pixel, level):
"""Transform from pixel to geo coordinates"""
pixel_x = pixel[0]
pixel_y = pixel[1]
map_size = float(TileSystem.map_size(level))
x = (TileSystem.clip(pixel_x, (0, map_size - 1)) / map_size) - 0.5
y = 0.5 - ( TileSystem.clip(pixel_y, (0, map_size - 1)) / map_size)
lat = 90 - 360 * atan(exp(-y * 2 * pi)) / pi
lon = 360 * x
return lat, lon

@staticmethod
def pixel_to_tile(pixel):
"""Transform pixel to tile coordinates"""
return pixel[0] / 256, pixel[1] / 256

@staticmethod
def tile_to_pixel(tile):
"""Transform tile to pixel coordinates"""
return tile[0] * 256, tile[1] * 256

@staticmethod
@precondition(lambda tile, lvl: valid_level(lvl))
def tile_to_quadkey(tile, level):
"""Transform tile coordinates to a quadkey"""
tile_x = tile[0]
tile_y = tile[1]
quadkey = ""
for i in xrange(level):
bit = level - i
digit = ord('0')
mask = 1 << (bit - 1) #if (bit - 1) > 0 else 1 >> (bit - 1)
if (tile_x & mask) is not 0:
digit += 1
if (tile_y & mask) is not 0:
digit += 2
quadkey += chr(digit)
return quadkey

@staticmethod
def quadkey_to_tile(quadkey):
"""Transform quadkey to tile coordinates"""
pass

5 changes: 4 additions & 1 deletion tests/quadkey_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ def testToString(self):
pass

def testGetQuadKey(self):
pass
geo = (40, -105)
level = 9
key = '023101012'
self.assertEqual(key, QuadKey.get_quadkey(geo, level))

def testGetCoordinates(self):
pass
9 changes: 9 additions & 0 deletions tests/tile_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,28 @@ def testMapScale(self):
TileSystem.map_scale(45, 7, 45)

def testGeoToPixel(self):
geo = (-105, 45)
level = 7
TileSystem.geo_to_pixel(geo, level)

def testPixelToGeo(self):
pixel = (50, 45)
level = 7
TileSystem.pixel_to_geo(pixel, level)

def testPixelToTile(self):
pixel = (50, 45)
TileSystem.pixel_to_tile(pixel)

def testTileToPixel(self):
tile = (3,3)
TileSystem.tile_to_pixel(tile)

def testTileToQuadkey(self):
tile = (3,3)
level = 7
TileSystem.tile_to_quadkey(tile, level)

def testQuadkeyToTile(self):
quadkey = '00'
TileSystem.quadkey_to_tile(quadkey)

0 comments on commit a96ad8d

Please sign in to comment.