to Gribouillis or someone else who wants to take a look:
my rotated function only works with square grids and not with grids with different height and width. I'm really stuck on this because everything else just works fine.
I think it has something to do with the initializing of my grid class or the __getitem__ method.
import os, glob
import csv
import sys
sys.path.append('G:\Afstuderen\Library')
from data_structure_6 import *
class Grid(object):
def __init__(self, width, height):
self.grid = []
self.width = width
self.height = height
self.length = width * height
for x in range(self.width):
col = []
for y in range(self.height):
col.append(Cell(x, y, self.grid))
self.grid.append(col)
def __getitem__(self, (x, y)):
return self.grid[x][y]
def getCellValue(self, (x, y)):
return self.grid[x][y].value
def fillBlock(self, left, right, top, bottom, value):
for x in range(left, right):
for y in range(top, bottom):
self[x, y].value = value
def firstFreeCell(self):
for y in range(self.height):
for x in range(self.width):
if self.grid[x][y].clusterId == -1:
return self.grid[x][y]
return None
def floodFill(self, x, y, clusterId, landUse):
if (x < 0 or y < 0 or x >= self.width or y >= self.height):
return
cell = self.grid[x][y]
cluster = Cluster()
if (cell.clusterId != -1 or cell.value != landUse):
return
cell.setClusterId(clusterId)
cluster.add(cell)
self.floodFill(x-1, y, clusterId, landUse)
self.floodFill(x+1, y, clusterId, landUse)
self.floodFill(x, y-1, clusterId, landUse)
self.floodFill(x, y+1, clusterId, landUse)
def analyze(self):
freeCell = self.firstFreeCell()
clusterId = 0
while freeCell != None:
self.floodFill(freeCell.x, freeCell.y, clusterId, freeCell.value)
freeCell = self.firstFreeCell()
clusterId += 1
def printClusterId(self, clusterId):
for y in range(self.height):
for x in range(self.width):
if self.grid[x][y].clusterId == clusterId:
print 'ClusterId:', clusterId, '=>', 'Cell-coordinates:',
'(', self.grid[x][y].x, ',', self.grid[x][y].y, ')',
'with a landUse value of:', self.grid[x][y].value
print "No cells with such clusterId left or the clusterId is not defined yet..."
def load(cls, filename):
loadGrid = []
reader = csv.reader(open(filename), delimiter=';')
for line in reader:
loadGrid.append(line)
width = len(loadGrid[0])
height = len(loadGrid)
grid = Grid(width, height)
for x in range(width):
for y in range(height):
grid[x, y].value = loadGrid[y][x]
return grid
load = classmethod(load)
def printGrid(self):
for y in range(len(self.grid[0])):
for x in range(len(self.grid)):
print self.grid[x][y].value,
print
def clusterBoundingBoxCentroid(self, clusterId):
x_values = []
y_values = []
for x in range(self.width):
for y in range(self.height):
if self.grid[x][y].clusterId == clusterId:
x_values.append(self.grid[x][y].x)
y_values.append(self.grid[x][y].y)
print float(max(x_values)-min(x_values))/2 + min(x_values), float(max(y_values)-min(y_values))/2 + min(y_values)
def clusterCentroid(self, clusterId):
cluster = Cluster()
for y in range(len(self.grid[0])):
for x in range(len(self.grid)):
if self.grid[x][y].clusterId == clusterId:
cluster.add(self.grid[x][y])
cluster_x = []
cluster_y = []
for i in range(len(cluster.cells)):
cluster_x.append(cluster.cells[i].x)
for i in range(len(cluster.cells)):
cluster_y.append(cluster.cells[i].y)
cx = float(sum(cluster_x))/len(cluster.cells)
cy = float(sum(cluster_y))/len(cluster.cells)
print cx, cy
def clusterCentroidX(self, clusterId):
cluster = Cluster()
for y in range(len(self.grid[0])):
for x in range(len(self.grid)):
if self.grid[x][y].clusterId == clusterId:
cluster.add(self.grid[x][y])
cluster_x = []
for i in range(len(cluster.cells)):
cluster_x.append(cluster.cells[i].x)
cx = float(sum(cluster_x))/len(cluster.cells)
return cx
def clusterCentroidY(self, clusterId):
cluster = Cluster()
for y in range(len(self.grid[0])):
for x in range(len(self.grid)):
if self.grid[x][y].clusterId == clusterId:
cluster.add(self.grid[x][y])
cluster_y = []
for i in range(len(cluster.cells)):
cluster_y.append(cluster.cells[i].y)
cy = float(sum(cluster_y))/len(cluster.cells)
return cy
def rotated(self, n):
L = self.toList()
n %=4
if n ==0 :
pass
elif n ==1 :
L =[list (x )for x in zip (*reversed (L))]
elif n ==2 :
L =[list (reversed (x ))for x in reversed (L)]
else :
L =[list (x )for x in reversed (zip (*L))]
return Grid.fromList(L)
def toList(self):
return [tuple(cell.value for cell in row) for row in self.grid]
@staticmethod
def fromList(L):
height, width = len(L), len(L[0])
self = Grid(width, height)
for x in range(height):
for y in range(width):
self[(x, y)].value = L[x][y]
return self
def cutbb(self, left, right, top, bottom):
# cut_grid heeft x, y coordinaten van 0 tot width, en 0 tot height
cut_grid = Grid(right - left, bottom - top)
for x in range(left, right):
for y in range(top, bottom):
if x < 0 or x >= self.width or y < 0 or y >= self.height:
value = -1
else:
value = self[x, y].value
cut_grid[x-left, y-top].value = value
return cut_grid
def cut(self, x, y, width, height):
left = x - width // 2
top = y - height // 2
return self.cutbb(left, left + width, top, top + height)
def cutFromTemplate(self, template):
width = template.width
height = template.height
x = int(round(self.clusterCentroidX(1)))
y = int(round(self.clusterCentroidY(1)))
return self.cut(x, y, width, height)
def compare(self, temp):
score = 0
cut = self.cutFromTemplate(temp)
for x in range(cut.width):
for y in range(cut.height):
if cut[x, y].value == temp[x, y].value:
if cut[x, y].value == '0':
score += 1
if cut[x, y].value == '1':
score += 3
if self[x, y].value != temp[x, y].value:
score -= 1
return score
def assignTemplates(self):
pass
# Load templates for living_type = 1
#templates_1 = []
#for i in csv_list_1:
# i = Grid.load(i)
# templates_1.append(i)
#print templates_1
# Create a list of comparison scores to eventually get the maximum score
#comparison_scores = []
# Create comparison scores for 4 rotations
#for template in templates_1:
# for rotation in range(4):
# score = self.compare(template.rotated(rotation))
# comparison_scores.append(score)
#print comparison_scores
# Print the comparison scores
#print comparison_scores
# Get the maximum value
#m = max(comparison_scores)
# Get the position (rotation index)
#p = comparison_scores.index(m)
# Print the maximum score, and the template belonging to the maximum score
#print 'The comparison score is: ', m
#print 'The cut out cluster:'
#cut = self.cutFromTemplate(temp).printGrid()
#print 'The best matching template:'
#temp.rotated(p).printGrid()
class Cell(object):
def __init__(self, x, y, grid):
self.x = x
self.y = y
self.grid = grid
self.value = 0
self.clusterId = -1
def setClusterId(self, clusterId):
self.clusterId = clusterId
def getClusterId(self):
return self.clusterId
class Cluster(object):
def __init__(self):
self.cells = []
def __getitem__(self):
return self.cells[x][y]
def add(self, i):
self.cells.append(i)
target = Grid.load('target.csv')
target.printGrid()
print ('-'*20)
target.analyze()
# load a template (1.csv)
# Make a cut out of the original grid with center based on
# the centroid of a given cluster, and a width and height
# defined through the width and height of the loaded template
#target.cutFromTemplate(template1)
# Compare the template and the cut out
my_grid = Grid(5, 3)
my_grid.printGrid()
my_grid.rotated(1)
Gives a list index out of range IndexError:
Traceback (most recent call last):
File "<string>", line 11, in ?
File "grid_cell_clusterc.py", line 276, in ?
my_grid.rotated(1)
File "grid_cell_clusterc.py", line 154, in rotated
return Grid.fromList(L)
File "grid_cell_clusterc.py", line 165, in fromList
self[(x, y)].value = L[x][y]
File "grid_cell_clusterc.py", line 21, in __getitem__
return self.grid[x][y]
IndexError: list index out of range
Hmm I'm kinda stuck with that part, the rest all works fine as long as I use square grids. If I could only get this rotated method to work on rectangular grids I would be much helped.