def gen_tasks(self): """ Generator returning a tiles coordinates to render @todo: Replace naive implementation with collision detection :return: (zoom, x, y) """ for zoom in range(MIN_ZOOM, MAX_ZOOM + 1): seen = set() # (x, y) M = 2**zoom - 1 # Find all areas suitable for zoom for area in Area.objects.filter(is_active=True, min_zoom__lte=zoom, max_zoom__gte=zoom): # Get area tiles SW = ll_to_xy(zoom, area.SW) NE = ll_to_xy(zoom, area.NE) left = max(SW[0] - PAD_TILES, 0) right = min(NE[0] + PAD_TILES, M) top = max(NE[1] - PAD_TILES, 0) bottom = min(SW[1] + PAD_TILES, M) a_size = (right - left + 1) * (bottom - top + 1) self.log("Checking area '%s' at zoom level %d "\ " (%d x %d = %d tiles)" % (area.name, zoom, right - left + 1, bottom - top + 1, a_size)) seen |= set((tc.x, tc.y) for tc in TileCache.objects.filter( map=self.map.id, zoom=zoom).only("x", "y")) for x in range(left, right + 1): for y in range(top, bottom + 1): c = (x, y) if c in seen: continue seen.add(c) if not self.force: # Check tile is ready tc = TileCache.objects.filter(map=self.map.id, zoom=zoom, x=x, y=y).first() if tc and tc.ready: continue yield (zoom, x, y)
def test_zero_point(zoom_level): C = ll_to_xy(zoom_level, (0, 0)) assert C == (2**(zoom_level - 1), 2**(zoom_level - 1))