Welcome, guest | Sign In | My Account | Store | Cart

As per the standard articles available on the internet, world map could be divided into four section top left, top right, bottom left and bottom right. if we associate numbers to identify them, for eg: 0 -> top left 1 -> top right 2 -> bottom left 3 -> bottom right it would be easier to dig into a tile or a section of the map using this system. A good documentation on the same is available on the 'Bing Map Tile System'. It would be a good idea to have some snippet of code that generates these sequence of numbers in this system so that world map could be traversed in a serial fashion. The class has 3 generator methods that produce the same sequence. Width corresponds to the zoom level.

Python, 70 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from itertools import product
import unittest

class QuadKeyGenerator:

    def __init__(self, width):
        self.width = width
        self.odometerValues = [0] * self.width  # max limit for each value on the odometer

    #--- odometer approach iterative ---
    def getNext(self):
        l = self.width-1
        i = 1
        while l >= 0 and i !=0:
            self.odometerValues[l] = ((self.odometerValues[l]+1) % self.width) # Odometer resets after reaching 3 to 0
            if self.odometerValues[l] == 0:
                i = 1
            else:
                i = 0
            l = l - 1

        if i != 0 and l < 0:
            return False
        return True

    def generateQuadKeys(self):
        while True:
            yield "".join(str(i) for i in self.odometerValues)
            if self.getNext() == False:
                break

    #--- recursive approach ---
    def generateQK(self, qk, level):
        if level == 0:
            yield qk
        else:
            for i in range(self.width): # QuadKey
                backUp = qk
                qk = qk + str(i)
                for g in self.generateQK(qk, level -1):
                    yield g
                qk = backUp

    #--- itertools approach ---
    def generateQKItertools(self):
        s = [x for x in range(self.width)]
        p = product(s, repeat=self.width)
        for qk in p:
            yield ''.join(map(str, qk))

class QuadKeyGeneratorTest(unittest.TestCase):
    def test_quadKeys_10(self):

        width = 4
        qkg = QuadKeyGenerator(width)

        nonIterGen = qkg.generateQuadKeys()
        recurGen = qkg.generateQK("", 4)
        iterGen = qkg.generateQKItertools()

        for x in range(width**4):
            nonIterQK = nonIterGen.next()
            recurQK = recurGen.next()
            iterQK = iterGen.next()

            self.assertTrue(nonIterQK == recurQK and recurQK == iterQK)


if __name__ == "__main__":
    unittest.main()

An elaborative discussion about the maps tile system is available here [http://msdn.microsoft.com/en-us/library/bb259689.aspx]. In your task or prototype, if there is a necessity to produce the quadkeys for a zoom level (width), the code exposed in this recipe may be of use.